From c29f570c16249b9ae1472b08a3570f2985fa5532 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 21 Oct 2025 10:39:54 +0530 Subject: [PATCH 001/438] UPSTREAM: dt-bindings: usb: qcom,snps-dwc3: Add the SM8750 compatible Add qcom,sm8750-dwc3 compatible to flattened implementation binding. Link: https://lore.kernel.org/all/20251021050954.3462613-1-krishna.kurapati@oss.qualcomm.com/ Signed-off-by: Konrad Dybcio Signed-off-by: Krishna Kurapati Reviewed-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml index d49a58d5478ff..301e873684ae9 100644 --- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml @@ -67,6 +67,7 @@ properties: - qcom,sm8450-dwc3 - qcom,sm8550-dwc3 - qcom,sm8650-dwc3 + - qcom,sm8750-dwc3 - qcom,x1e80100-dwc3 - qcom,x1e80100-dwc3-mp - const: qcom,snps-dwc3 @@ -213,6 +214,7 @@ allOf: - qcom,sdx65-dwc3 - qcom,sdx75-dwc3 - qcom,sm6350-dwc3 + - qcom,sm8750-dwc3 then: properties: clocks: @@ -501,6 +503,7 @@ allOf: - qcom,sm8450-dwc3 - qcom,sm8550-dwc3 - qcom,sm8650-dwc3 + - qcom,sm8750-dwc3 then: properties: interrupts: From fc1b59c1f4305fd3630a4205d2db8f680626ef5c Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Tue, 21 Oct 2025 23:15:54 -0700 Subject: [PATCH 002/438] FROMLIST: dt-bindings: arm-smmu: Add compatible for Kaanapali and Glymur SoCs Qualcomm Kaanapali and Glymur SoCs include apps smmu that implements arm,mmu-500, which is used to translate device-visible virtual addresses to physical addresses. Add compatible for these items. Co-developed-by: Pankaj Patil Signed-off-by: Pankaj Patil Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251021-b4-knp-smmu-v2-1-88774e6d2def@oss.qualcomm.com/ --- Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml index 89495f094d52b..2ffc48a276dfb 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -35,6 +35,8 @@ properties: - description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500" items: - enum: + - qcom,glymur-smmu-500 + - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 - qcom,qcm2290-smmu-500 - qcom,qcs615-smmu-500 From 829c78b71ef815f34cfadc407ddf7438d396ef1d Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 22 Oct 2025 00:28:43 -0700 Subject: [PATCH 003/438] FROMLIST: dt-bindings: firmware: qcom,scm: Document SCM on Kaanapali SOC Document scm compatible for the Qualcomm Kaanapali SoC. Reviewed-by: Eugen Hristev Signed-off-by: Jingyi Wang Acked-by: Rob Herring (Arm) Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251022-knp-soc-binding-v2-3-3cd3f390f3e2@oss.qualcomm.com/ --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index ef97faac7e47c..340b754e63226 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -31,6 +31,7 @@ properties: - qcom,scm-ipq806x - qcom,scm-ipq8074 - qcom,scm-ipq9574 + - qcom,scm-kaanapali - qcom,scm-mdm9607 - qcom,scm-milos - qcom,scm-msm8226 @@ -202,6 +203,7 @@ allOf: compatible: contains: enum: + - qcom,scm-kaanapali - qcom,scm-milos - qcom,scm-sm8450 - qcom,scm-sm8550 From a6f7092e9a363fd462a5825ff15a82af744793cb Mon Sep 17 00:00:00 2001 From: Kamal Wadhwa Date: Thu, 18 Sep 2025 14:57:01 +0530 Subject: [PATCH 004/438] FROMGIT: dt-bindings: rpmh-regulator : Add compatibles for PMH01XX & PMCX0102 Add rpmh-regulator driver compatibles strings for below PMICs: - PMH0101 - PMH0104 - PMH0110 - PMCX0102 Also add the supply name properties for the regulators present on these PMICs. Co-developed-by: Jishnu Prakash Signed-off-by: Jishnu Prakash Signed-off-by: Kamal Wadhwa Link: https://patch.msgid.link/20250918-glymur-rpmh-regulator-driver-v3-1-184c09678be3@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Yijie Yang --- .../regulator/qcom,rpmh-regulator.yaml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index 4c5b0629aa3e6..40e57b10ebbeb 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -51,8 +51,12 @@ description: | For PM8450, smps1 - smps6, ldo1 - ldo4 For PM8550, smps1 - smps6, ldo1 - ldo17, bob1 - bob2 For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2 + For PMH0101, ldo1 - ldo18, bob1 - bob2 + For PMH0104, smps1 - smps4 + For PMH0110, smps1 - smps10, ldo1 - ldo4 For PMI8998, bob For PMC8380, smps1 - smps8, ldo1 - lodo3 + For PMCX0102, smps1 - smps10, ldo1 - ldo4 For PMR735A, smps1 - smps3, ldo1 - ldo7 For PMR735B, ldo1 - ldo12 For PMX55, smps1 - smps7, ldo1 - ldo16 @@ -85,7 +89,11 @@ properties: - qcom,pmc8180-rpmh-regulators - qcom,pmc8180c-rpmh-regulators - qcom,pmc8380-rpmh-regulators + - qcom,pmcx0102-rpmh-regulators - qcom,pmg1110-rpmh-regulators + - qcom,pmh0101-rpmh-regulators + - qcom,pmh0104-rpmh-regulators + - qcom,pmh0110-rpmh-regulators - qcom,pmi8998-rpmh-regulators - qcom,pmm8155au-rpmh-regulators - qcom,pmm8654au-rpmh-regulators @@ -246,6 +254,7 @@ allOf: compatible: enum: - qcom,pm8005-rpmh-regulators + - qcom,pmh0104-rpmh-regulators then: patternProperties: "^vdd-s[1-4]-supply$": true @@ -422,6 +431,34 @@ allOf: properties: vdd-s1-supply: true + - if: + properties: + compatible: + enum: + - qcom,pmh0101-rpmh-regulators + then: + properties: + vdd-l1-l4-l10-supply: true + vdd-l2-l13-l14-supply: true + vdd-l3-l11-supply: true + vdd-l5-l16-supply: true + vdd-l6-l7-supply: true + vdd-l8-l9-supply: true + patternProperties: + "^vdd-l(1[2578])-supply$": true + "^vdd-bob[1-2]-supply$": true + + - if: + properties: + compatible: + enum: + - qcom,pmcx0102-rpmh-regulators + - qcom,pmh0110-rpmh-regulators + then: + patternProperties: + "^vdd-l[1-4]-supply$": true + "^vdd-s([1-9]|10)-supply$": true + - if: properties: compatible: From 79c18d27199bcf4fa97427234339f96b18a083b2 Mon Sep 17 00:00:00 2001 From: Kamal Wadhwa Date: Thu, 18 Sep 2025 14:57:02 +0530 Subject: [PATCH 005/438] FROMGIT: dt-bindings: rpmh-regulator: Update pmic-id DT prop info for new CMD-DB Currently, CMD-DB names for RPMH regulators follow this format: `^(smps|ldo|bob|vs)[a-n][1-9][0-9]?$` Here, the `[a-n]` value is read from the `pmic-id` DT property, which is unique to each PMIC present on the board. Note that in this older CMD-DB name format the SPMI bus on which a particular PMIC regulator exists was not apparent from its CMD-DB name. New targets like Glymur, where we have multiple SPMI buses, overcome this limitation by following a new CMD-DB name format: `^(L|S|B)[1-9][0-9]?[A-N]_E[0-3]$` Here `[A-N]_E[0-3]` part will now be read from the `pmic-id` DT prop and it includes the SPMI bus id `[0-3]` as well. However, the PMIC ID part `[A-N]` of the CMD-DB name is now unique only to the SPMI bus that the PMIC regulator is present on. which means `L1B_E0` and `L1B_E1` are both possible CMD-DB names for two different regulator LDOs present on two different SPMI buses (bus id 0 and 1) on the same board. Note that since the new `pmic-id` DT property is a combo of PMIC ID and SPMI bus ID, so its still unique to each PMIC present on the board. Update the `pmic-id` property pattern information to reflect this change in the driver handling to support this new CMD-DB naming format while maintaining backward compatiblilty with old CMD-DB naming format which is still supported for older/existing targets. Signed-off-by: Kamal Wadhwa Link: https://patch.msgid.link/20250918-glymur-rpmh-regulator-driver-v3-2-184c09678be3@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Yijie Yang --- .../devicetree/bindings/regulator/qcom,rpmh-regulator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index 40e57b10ebbeb..40ddc64577e78 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -108,7 +108,7 @@ properties: RPMh resource name suffix used for the regulators found on this PMIC. $ref: /schemas/types.yaml#/definitions/string - enum: [a, b, c, d, e, f, g, h, i, j, k, l, m, n] + pattern: "^[a-n]|[A-N]_E[0-3]+$" qcom,always-wait-for-ack: description: | From 71f424fb76e46df5b2a53dd18f54efeb6a6b267e Mon Sep 17 00:00:00 2001 From: Kamal Wadhwa Date: Thu, 18 Sep 2025 14:57:03 +0530 Subject: [PATCH 006/438] FROMGIT: regulator: rpmh-regulator: Add support for new resource name format Currently rpmh-regulator resource name inside CMD-DB follows this format: `^(ldo|smp|bob|vs)[a-n][1-9][0-9]?$` (eg - ldob11, smpa2, bobc1 etc) Here `[a-n]` in the resource name signifies the `pmic-id`. However, newer firmware follows a different format that also includes the `bus_id` as well in the resource name. New format: `^(L|S|B)[1-9][0-9]?[A-N]_E[0-3]$` (eg - L11B_E1, S2A_E0, B1C_E0 etc) Here `_E[0-3]` at the end is the `bus_id`, and upper case `[A-N]` is used to denote `pmic-id`, while the regulator `(ldo|smp|bob)` is replaced with their initials in upper case `(L|S|B|VA)`. To handle this properly, do the following: - Remove the `resource_name` member from vreg init data - Add `index` and `regulator_hw_type` new members, which will contain the index number and the regulator hardware type (SMPS/LDO/BOB/VS) which can be combined with the pmic-id read from the devicetree to generate the resource_name. - Choose new resource name format if `pmic-id` contains `_E` in it, else fallback to old format. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Kamal Wadhwa Link: https://patch.msgid.link/20250918-glymur-rpmh-regulator-driver-v3-3-184c09678be3@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Yijie Yang --- drivers/regulator/qcom-rpmh-regulator.c | 1135 ++++++++++++----------- 1 file changed, 587 insertions(+), 548 deletions(-) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index 109f0aae09b1d..dfb5bf5b72a1e 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -32,6 +32,34 @@ enum rpmh_regulator_type { XOB, }; +/** + * enum regulator_hw_type - supported regulator types + * @SMPS: Switch mode power supply. + * @LDO: Linear Dropout regulator. + * @BOB: Buck/Boost type regulator. + * @VS: Simple voltage ON/OFF switch. + * @NUM_REGULATOR_TYPES: Number of regulator types. + */ +enum regulator_hw_type { + SMPS, + LDO, + BOB, + VS, + NUM_REGULATOR_TYPES, +}; + +struct resource_name_formats { + const char *rsc_name_fmt; + const char *rsc_name_fmt1; +}; + +static const struct resource_name_formats vreg_rsc_name_lookup[NUM_REGULATOR_TYPES] = { + [SMPS] = {"S%d%s", "smp%s%d"}, + [LDO] = {"L%d%s", "ldo%s%d"}, + [BOB] = {"B%d%s", "bob%s%d"}, + [VS] = {"VS%d%s", "vs%s%d"}, +}; + #define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0 #define RPMH_REGULATOR_REG_ENABLE 0x4 #define RPMH_REGULATOR_REG_VRM_MODE 0x8 @@ -64,6 +92,7 @@ enum rpmh_regulator_type { #define PMIC5_BOB_MODE_AUTO 6 #define PMIC5_BOB_MODE_PWM 7 +#define PMIC_ID_LEN 4 /** * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations * @regulator_type: RPMh accelerator type used to manage this @@ -136,17 +165,17 @@ struct rpmh_vreg { * struct rpmh_vreg_init_data - initialization data for an RPMh regulator * @name: Name for the regulator which also corresponds * to the device tree subnode name of the regulator - * @resource_name: RPMh regulator resource name format string. - * This must include exactly one field: '%s' which - * is filled at run-time with the PMIC ID provided - * by device tree property qcom,pmic-id. Example: - * "ldo%s1" for RPMh resource "ldoa1". + * @index: This is the index number of the regulator present + * on the PMIC. + * @vreg_hw_type: Regulator HW type enum, this must be BOB, SMPS, + * LDO, VS, based on the regulator HW type. * @supply_name: Parent supply regulator name * @hw_data: Configuration data for this PMIC regulator type */ struct rpmh_vreg_init_data { const char *name; - const char *resource_name; + enum regulator_hw_type vreg_hw_type; + int index; const char *supply_name; const struct rpmh_vreg_hw_data *hw_data; }; @@ -417,6 +446,7 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev, { struct regulator_config reg_config = {}; char rpmh_resource_name[20] = ""; + const char *rsc_name; const struct rpmh_vreg_init_data *rpmh_data; struct regulator_init_data *init_data; struct regulator_dev *rdev; @@ -433,8 +463,16 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev, return -EINVAL; } - scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name), - rpmh_data->resource_name, pmic_id); + if (strnlen(pmic_id, PMIC_ID_LEN) > 1 && strnstr(pmic_id, "_E", PMIC_ID_LEN)) { + rsc_name = vreg_rsc_name_lookup[rpmh_data->vreg_hw_type].rsc_name_fmt; + scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name), + rsc_name, rpmh_data->index, pmic_id); + + } else { + rsc_name = vreg_rsc_name_lookup[rpmh_data->vreg_hw_type].rsc_name_fmt1; + scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name), + rsc_name, pmic_id, rpmh_data->index); + } vreg->addr = cmd_db_read_addr(rpmh_resource_name); if (!vreg->addr) { @@ -904,671 +942,672 @@ static const struct rpmh_vreg_hw_data pmic5_bob = { .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode, }; -#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \ +#define RPMH_VREG(_name, _vreg_hw_type, _index, _hw_data, _supply_name) \ { \ .name = _name, \ - .resource_name = _resource_name, \ + .vreg_hw_type = _vreg_hw_type, \ + .index = _index, \ .hw_data = _hw_data, \ .supply_name = _supply_name, \ } static const struct rpmh_vreg_init_data pm8998_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic4_hfsmps3, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic4_hfsmps3, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic4_hfsmps3, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic4_ftsmps426, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic4_ftsmps426, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic4_ftsmps426, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic4_ftsmps426, "vdd-s9"), - RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"), - RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"), - RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"), - RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"), - RPMH_VREG("ldo1", "ldo%s1", &pmic4_nldo, "vdd-l1-l27"), - RPMH_VREG("ldo2", "ldo%s2", &pmic4_nldo, "vdd-l2-l8-l17"), - RPMH_VREG("ldo3", "ldo%s3", &pmic4_nldo, "vdd-l3-l11"), - RPMH_VREG("ldo4", "ldo%s4", &pmic4_nldo, "vdd-l4-l5"), - RPMH_VREG("ldo5", "ldo%s5", &pmic4_nldo, "vdd-l4-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic4_pldo, "vdd-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo8", "ldo%s8", &pmic4_nldo, "vdd-l2-l8-l17"), - RPMH_VREG("ldo9", "ldo%s9", &pmic4_pldo, "vdd-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic4_pldo, "vdd-l10-l23-l25"), - RPMH_VREG("ldo11", "ldo%s11", &pmic4_nldo, "vdd-l3-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo13", "ldo%s13", &pmic4_pldo, "vdd-l13-l19-l21"), - RPMH_VREG("ldo14", "ldo%s14", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo15", "ldo%s15", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic4_pldo, "vdd-l16-l28"), - RPMH_VREG("ldo17", "ldo%s17", &pmic4_nldo, "vdd-l2-l8-l17"), - RPMH_VREG("ldo18", "ldo%s18", &pmic4_pldo, "vdd-l18-l22"), - RPMH_VREG("ldo19", "ldo%s19", &pmic4_pldo, "vdd-l13-l19-l21"), - RPMH_VREG("ldo20", "ldo%s20", &pmic4_pldo, "vdd-l20-l24"), - RPMH_VREG("ldo21", "ldo%s21", &pmic4_pldo, "vdd-l13-l19-l21"), - RPMH_VREG("ldo22", "ldo%s22", &pmic4_pldo, "vdd-l18-l22"), - RPMH_VREG("ldo23", "ldo%s23", &pmic4_pldo, "vdd-l10-l23-l25"), - RPMH_VREG("ldo24", "ldo%s24", &pmic4_pldo, "vdd-l20-l24"), - RPMH_VREG("ldo25", "ldo%s25", &pmic4_pldo, "vdd-l10-l23-l25"), - RPMH_VREG("ldo26", "ldo%s26", &pmic4_nldo, "vdd-l26"), - RPMH_VREG("ldo27", "ldo%s27", &pmic4_nldo, "vdd-l1-l27"), - RPMH_VREG("ldo28", "ldo%s28", &pmic4_pldo, "vdd-l16-l28"), - RPMH_VREG("lvs1", "vs%s1", &pmic4_lvs, "vin-lvs-1-2"), - RPMH_VREG("lvs2", "vs%s2", &pmic4_lvs, "vin-lvs-1-2"), + RPMH_VREG("smps1", SMPS, 1, &pmic4_ftsmps426, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic4_ftsmps426, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic4_hfsmps3, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic4_hfsmps3, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic4_hfsmps3, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic4_ftsmps426, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic4_ftsmps426, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic4_ftsmps426, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic4_ftsmps426, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic4_ftsmps426, "vdd-s10"), + RPMH_VREG("smps11", SMPS, 11, &pmic4_ftsmps426, "vdd-s11"), + RPMH_VREG("smps12", SMPS, 12, &pmic4_ftsmps426, "vdd-s12"), + RPMH_VREG("smps13", SMPS, 13, &pmic4_ftsmps426, "vdd-s13"), + RPMH_VREG("ldo1", LDO, 1, &pmic4_nldo, "vdd-l1-l27"), + RPMH_VREG("ldo2", LDO, 2, &pmic4_nldo, "vdd-l2-l8-l17"), + RPMH_VREG("ldo3", LDO, 3, &pmic4_nldo, "vdd-l3-l11"), + RPMH_VREG("ldo4", LDO, 4, &pmic4_nldo, "vdd-l4-l5"), + RPMH_VREG("ldo5", LDO, 5, &pmic4_nldo, "vdd-l4-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic4_pldo, "vdd-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo8", LDO, 8, &pmic4_nldo, "vdd-l2-l8-l17"), + RPMH_VREG("ldo9", LDO, 9, &pmic4_pldo, "vdd-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic4_pldo, "vdd-l10-l23-l25"), + RPMH_VREG("ldo11", LDO, 11, &pmic4_nldo, "vdd-l3-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo13", LDO, 13, &pmic4_pldo, "vdd-l13-l19-l21"), + RPMH_VREG("ldo14", LDO, 14, &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo15", LDO, 15, &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic4_pldo, "vdd-l16-l28"), + RPMH_VREG("ldo17", LDO, 17, &pmic4_nldo, "vdd-l2-l8-l17"), + RPMH_VREG("ldo18", LDO, 18, &pmic4_pldo, "vdd-l18-l22"), + RPMH_VREG("ldo19", LDO, 19, &pmic4_pldo, "vdd-l13-l19-l21"), + RPMH_VREG("ldo20", LDO, 20, &pmic4_pldo, "vdd-l20-l24"), + RPMH_VREG("ldo21", LDO, 21, &pmic4_pldo, "vdd-l13-l19-l21"), + RPMH_VREG("ldo22", LDO, 22, &pmic4_pldo, "vdd-l18-l22"), + RPMH_VREG("ldo23", LDO, 23, &pmic4_pldo, "vdd-l10-l23-l25"), + RPMH_VREG("ldo24", LDO, 24, &pmic4_pldo, "vdd-l20-l24"), + RPMH_VREG("ldo25", LDO, 25, &pmic4_pldo, "vdd-l10-l23-l25"), + RPMH_VREG("ldo26", LDO, 26, &pmic4_nldo, "vdd-l26"), + RPMH_VREG("ldo27", LDO, 27, &pmic4_nldo, "vdd-l1-l27"), + RPMH_VREG("ldo28", LDO, 28, &pmic4_pldo, "vdd-l16-l28"), + RPMH_VREG("lvs1", VS, 1, &pmic4_lvs, "vin-lvs-1-2"), + RPMH_VREG("lvs2", VS, 2, &pmic4_lvs, "vin-lvs-1-2"), {} }; static const struct rpmh_vreg_init_data pmg1110_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), {} }; static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = { - RPMH_VREG("bob", "bob%s1", &pmic4_bob, "vdd-bob"), + RPMH_VREG("bob", BOB, 1, &pmic4_bob, "vdd-bob"), {} }; static const struct rpmh_vreg_init_data pm8005_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic4_ftsmps426, "vdd-s4"), + RPMH_VREG("smps1", SMPS, 1, &pmic4_ftsmps426, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic4_ftsmps426, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic4_ftsmps426, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic4_ftsmps426, "vdd-s4"), {} }; static const struct rpmh_vreg_init_data pm8150_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_hfsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_hfsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps510, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps510, "vdd-s9"), - RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l8-l11"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l10"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3-l4-l5-l18"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l3-l4-l5-l18"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l3-l4-l5-l18"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6-l9"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l1-l8-l11"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l2-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo, "vdd-l1-l8-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l16-l17"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16-l17"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"), - RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_hfsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_hfsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps510, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps510, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_ftsmps510, "vdd-s10"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l8-l11"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l10"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l6-l9"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l1-l8-l11"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l6-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l2-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_nldo, "vdd-l1-l8-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, "vdd-l3-l4-l5-l18"), {} }; static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_hfsmps510, "vdd-s8"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_pldo_lv, "vdd-l1-l8"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo, "vdd-l4-l5-l6"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l4-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l4-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-l11"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l1-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l9-l10"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l9-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l7-l11"), - RPMH_VREG("bob", "bob%s1", &pmic5_bob, "vdd-bob"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_hfsmps510, "vdd-s8"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_pldo_lv, "vdd-l1-l8"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo, "vdd-l4-l5-l6"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l4-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l4-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l7-l11"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo_lv, "vdd-l1-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l9-l10"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l9-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l7-l11"), + RPMH_VREG("bob", BOB, 1, &pmic5_bob, "vdd-bob"), {} }; static const struct rpmh_vreg_init_data pmm8155au_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_hfsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_hfsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps510, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps510, "vdd-s9"), - RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l8-l11"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l10"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3-l4-l5-l18"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l3-l4-l5-l18"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l3-l4-l5-l18"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6-l9"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l1-l8-l11"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l2-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo, "vdd-l1-l8-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l16-l17"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16-l17"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"), - RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_hfsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_hfsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps510, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps510, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_ftsmps510, "vdd-s10"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l8-l11"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l10"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo, "vdd-l3-l4-l5-l18"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l6-l9"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l1-l8-l11"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l6-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l2-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_nldo, "vdd-l1-l8-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, "vdd-l3-l4-l5-l18"), {} }; static const struct rpmh_vreg_init_data pmm8654au_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps527, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps527, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps527, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps527, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps527, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps527, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps527, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps527, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps527, "vdd-s9"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-s9"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-l3"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l2-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-s9"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo515, "vdd-s9"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo515, "vdd-l6-l7"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l6-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo515_mv, "vdd-l8-l9"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l8-l9"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps527, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps527, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps527, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps527, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps527, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps527, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps527, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps527, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps527, "vdd-s9"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-s9"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l2-l3"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l2-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo515, "vdd-s9"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo515, "vdd-s9"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo515, "vdd-l6-l7"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo515, "vdd-l6-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo515_mv, "vdd-l8-l9"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l8-l9"), {} }; static const struct rpmh_vreg_init_data pm8350_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps510, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps510, "vdd-s9"), - RPMH_VREG("smps10", "smp%s10", &pmic5_hfsmps510, "vdd-s10"), - RPMH_VREG("smps11", "smp%s11", &pmic5_hfsmps510, "vdd-s11"), - RPMH_VREG("smps12", "smp%s12", &pmic5_hfsmps510, "vdd-s12"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l4"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l7"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3-l5"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l1-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l3-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6-l9-l10"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l2-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9-l10"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l6-l9-l10"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps510, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps510, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_hfsmps510, "vdd-s10"), + RPMH_VREG("smps11", SMPS, 11, &pmic5_hfsmps510, "vdd-s11"), + RPMH_VREG("smps12", SMPS, 12, &pmic5_hfsmps510, "vdd-s12"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l4"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l7"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3-l5"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l1-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo, "vdd-l3-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l6-l9-l10"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l2-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l6-l9-l10"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_nldo, "vdd-l6-l9-l10"), {} }; static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps515, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps510, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps510, "vdd-s9"), - RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_pldo_lv, "vdd-l1-l12"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo_lv, "vdd-l2-l8"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l6-l9-l11"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l2-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l6-l9-l11"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l6-l9-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l1-l12"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), - RPMH_VREG("bob", "bob%s1", &pmic5_bob, "vdd-bob"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_hfsmps515, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps510, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps510, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_ftsmps510, "vdd-s10"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_pldo_lv, "vdd-l1-l12"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo_lv, "vdd-l2-l8"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l6-l9-l11"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo_lv, "vdd-l2-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l6-l9-l11"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_nldo, "vdd-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l6-l9-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo_lv, "vdd-l1-l12"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"), + RPMH_VREG("bob", BOB, 1, &pmic5_bob, "vdd-bob"), {} }; static const struct rpmh_vreg_init_data pm8450_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps520, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps520, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps520, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps520, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps520, "vdd-s6"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo_lv, "vdd-l4"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps520, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps520, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps520, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps520, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps520, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps520, "vdd-s6"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo_lv, "vdd-l4"), {} }; static const struct rpmh_vreg_init_data pm8550_vreg_data[] = { - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1-l4-l10"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l13-l14"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-l1-l4-l10"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l16"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l6-l7"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l6-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo, "vdd-l8-l9"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l8-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo515, "vdd-l1-l4-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo515, "vdd-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo515, "vdd-l12"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l2-l13-l14"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo, "vdd-l2-l13-l14"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo515, "vdd-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l5-l16"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l17"), - RPMH_VREG("bob1", "bob%s1", &pmic5_bob, "vdd-bob1"), - RPMH_VREG("bob2", "bob%s2", &pmic5_bob, "vdd-bob2"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1-l4-l10"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l13-l14"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo515, "vdd-l1-l4-l10"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l5-l16"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l6-l7"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l6-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, "vdd-l8-l9"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l8-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_nldo515, "vdd-l1-l4-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_nldo515, "vdd-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo515, "vdd-l12"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l2-l13-l14"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, "vdd-l2-l13-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo515, "vdd-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l5-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo, "vdd-l17"), + RPMH_VREG("bob1", BOB, 1, &pmic5_bob, "vdd-bob1"), + RPMH_VREG("bob2", BOB, 2, &pmic5_bob, "vdd-bob2"), {} }; static const struct rpmh_vreg_init_data pm8550vs_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525, "vdd-s6"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps525, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps525, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps525, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps525, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps525, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps525, "vdd-s6"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l3"), {} }; static const struct rpmh_vreg_init_data pm8550ve_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525, "vdd-s8"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps525, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps525, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps525, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps525, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps525, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps525, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps525, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps525, "vdd-s8"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l3"), {} }; static const struct rpmh_vreg_init_data pmc8380_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525, "vdd-s8"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps525, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps525, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps525, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps525, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps525, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps525, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps525, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps525, "vdd-s8"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l3"), {} }; static const struct rpmh_vreg_init_data pm8009_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps515, "vdd-s2"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_hfsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps515, "vdd-s2"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo_lv, "vdd-l7"), {} }; static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps515_1, "vdd-s2"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_hfsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps515_1, "vdd-s2"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo_lv, "vdd-l7"), {} }; static const struct rpmh_vreg_init_data pm8010_vreg_data[] = { - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo502, "vdd-l1-l2"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo502, "vdd-l1-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_pldo502ln, "vdd-l3-l4"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo502ln, "vdd-l3-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo502, "vdd-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo502ln, "vdd-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo502, "vdd-l7"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo502, "vdd-l1-l2"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo502, "vdd-l1-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo502ln, "vdd-l3-l4"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo502ln, "vdd-l3-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo502, "vdd-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo502ln, "vdd-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo502, "vdd-l7"), }; static const struct rpmh_vreg_init_data pm6150_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_hfsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_hfsmps510, "vdd-s5"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4-l7-l8"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo, "vdd-l4-l7-l8"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l4-l7-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo_lv, "vdd-l10-l14-l15"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo_lv, "vdd-l11-l12-l13"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l11-l12-l13"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo_lv, "vdd-l11-l12-l13"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo_lv, "vdd-l10-l14-l15"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo_lv, "vdd-l10-l14-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), - RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), - RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_hfsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_hfsmps510, "vdd-s5"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4-l7-l8"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo, "vdd-l4-l7-l8"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l4-l7-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo_lv, "vdd-l10-l14-l15"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo_lv, "vdd-l11-l12-l13"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo_lv, "vdd-l11-l12-l13"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo_lv, "vdd-l11-l12-l13"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo_lv, "vdd-l10-l14-l15"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_pldo_lv, "vdd-l10-l14-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), + RPMH_VREG("ldo19", LDO, 19, &pmic5_pldo, "vdd-l5-l16-l17-l18-l19"), {} }; static const struct rpmh_vreg_init_data pm6150l_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_hfsmps510, "vdd-s8"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_pldo_lv, "vdd-l1-l8"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo, "vdd-l4-l5-l6"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l4-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l4-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-l11"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo, "vdd-l1-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l9-l10"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l9-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l7-l11"), - RPMH_VREG("bob", "bob%s1", &pmic5_bob, "vdd-bob"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_hfsmps510, "vdd-s8"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_pldo_lv, "vdd-l1-l8"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo, "vdd-l4-l5-l6"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l4-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l4-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l7-l11"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, "vdd-l1-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l9-l10"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l9-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l7-l11"), + RPMH_VREG("bob", BOB, 1, &pmic5_bob, "vdd-bob"), {} }; static const struct rpmh_vreg_init_data pm6350_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, NULL), - RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps510, NULL), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, NULL), + RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, NULL), /* smps3 - smps5 not configured */ - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, NULL), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, NULL), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_pldo, NULL), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, NULL), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, NULL), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, NULL), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, NULL), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo, NULL), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, NULL), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, NULL), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, NULL), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo, NULL), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_nldo, NULL), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo, NULL), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo, NULL), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_nldo, NULL), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, NULL), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, NULL), + RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo, NULL), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, NULL), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, NULL), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, NULL), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, NULL), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, NULL), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, NULL), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, NULL), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, NULL), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo, NULL), + RPMH_VREG("ldo13", LDO, 13, &pmic5_nldo, NULL), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, NULL), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, NULL), + RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo, NULL), /* ldo17 not configured */ - RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, NULL), - RPMH_VREG("ldo19", "ldo%s19", &pmic5_nldo, NULL), - RPMH_VREG("ldo20", "ldo%s20", &pmic5_nldo, NULL), - RPMH_VREG("ldo21", "ldo%s21", &pmic5_nldo, NULL), - RPMH_VREG("ldo22", "ldo%s22", &pmic5_nldo, NULL), + RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, NULL), + RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo, NULL), + RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo, NULL), + RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo, NULL), + RPMH_VREG("ldo22", LDO, 22, &pmic5_nldo, NULL), }; static const struct rpmh_vreg_init_data pmx55_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_hfsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_hfsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_hfsmps510, "vdd-s7"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l2"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3-l9"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4-l12"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo, "vdd-l7-l8"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l7-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l3-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l10-l11-l13"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l10-l11-l13"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo, "vdd-l4-l12"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l10-l11-l13"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo, "vdd-l14"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo, "vdd-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l16"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_hfsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_hfsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_hfsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_hfsmps510, "vdd-s7"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l2"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l1-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3-l9"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4-l12"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo, "vdd-l7-l8"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l7-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l3-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l10-l11-l13"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l10-l11-l13"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo, "vdd-l4-l12"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l10-l11-l13"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_nldo, "vdd-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, "vdd-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l16"), {} }; static const struct rpmh_vreg_init_data pmx65_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps510, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps510, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_hfsmps510, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_hfsmps510, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_hfsmps510, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_hfsmps510, "vdd-s8"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2-l18"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6-l16"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6-l16"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo, "vdd-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l8-l9"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l8-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l11-l13"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo, "vdd-l12"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l11-l13"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo, "vdd-l14"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo, "vdd-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l5-l6-l16"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_nldo, "vdd-l17"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_hfsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_hfsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_hfsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps510, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_hfsmps510, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_hfsmps510, "vdd-s8"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l2-l18"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l5-l6-l16"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l5-l6-l16"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo, "vdd-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l8-l9"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l8-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l11-l13"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo, "vdd-l12"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l11-l13"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_nldo, "vdd-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, "vdd-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l5-l6-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_nldo, "vdd-l17"), /* ldo18 not configured */ - RPMH_VREG("ldo19", "ldo%s19", &pmic5_nldo, "vdd-l19"), - RPMH_VREG("ldo20", "ldo%s20", &pmic5_nldo, "vdd-l20"), - RPMH_VREG("ldo21", "ldo%s21", &pmic5_nldo, "vdd-l21"), + RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo, "vdd-l19"), + RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo, "vdd-l20"), + RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo, "vdd-l21"), {} }; static const struct rpmh_vreg_init_data pmx75_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525, "vdd-s8"), - RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps525, "vdd-s9"), - RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps525, "vdd-s10"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-18"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-l4-l16"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo_lv, "vdd-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo_lv, "vdd-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo515, "vdd-l8-l9"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo515, "vdd-l8-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l11-l13"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo515, "vdd-l12"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l11-l13"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo515, "vdd-l14"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo515, "vdd-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_nldo515, "vdd-l4-l16"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_nldo515, "vdd-l17"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps525, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps525, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps525, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps525, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps525, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps525, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps525, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps525, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps525, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_ftsmps525, "vdd-s10"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l2-18"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo515, "vdd-l4-l16"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo_lv, "vdd-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo_lv, "vdd-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo515, "vdd-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo515, "vdd-l8-l9"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo515, "vdd-l8-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l11-l13"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo515, "vdd-l12"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo, "vdd-l11-l13"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_nldo515, "vdd-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo515, "vdd-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo515, "vdd-l4-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_nldo515, "vdd-l17"), /* ldo18 not configured */ - RPMH_VREG("ldo19", "ldo%s19", &pmic5_nldo515, "vdd-l19"), - RPMH_VREG("ldo20", "ldo%s20", &pmic5_nldo515, "vdd-l20-l21"), - RPMH_VREG("ldo21", "ldo%s21", &pmic5_nldo515, "vdd-l20-l21"), + RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo515, "vdd-l19"), + RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo515, "vdd-l20-l21"), + RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo515, "vdd-l20-l21"), }; static const struct rpmh_vreg_init_data pm7325_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps520, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps520, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps520, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps520, "vdd-s6"), - RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps520, "vdd-s7"), - RPMH_VREG("smps8", "smp%s8", &pmic5_hfsmps510, "vdd-s8"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l4-l12-l15"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l7"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l1-l4-l12-l15"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6-l9-l10"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l2-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9-l10"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l6-l9-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo, "vdd-l1-l4-l12-l15"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_nldo, "vdd-l13"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo, "vdd-l14-l16"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo, "vdd-l1-l4-l12-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_nldo, "vdd-l14-l16"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), - RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), - RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_hfsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps520, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps520, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps520, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps520, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps520, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps520, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_hfsmps510, "vdd-s8"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l4-l12-l15"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l7"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l1-l4-l12-l15"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo, "vdd-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l6-l9-l10"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l2-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l6-l9-l10"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_nldo, "vdd-l6-l9-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo, "vdd-l1-l4-l12-l15"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_nldo, "vdd-l13"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_nldo, "vdd-l14-l16"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, "vdd-l1-l4-l12-l15"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo, "vdd-l14-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), + RPMH_VREG("ldo19", LDO, 19, &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), {} }; static const struct rpmh_vreg_init_data pm7550_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525, "vdd-s6"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-l3"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l2-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-l4-l5"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo515, "vdd-l4-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo515, "vdd-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo515, "vdd-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo515, "vdd-l9-l10"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo515, "vdd-l9-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo515, "vdd-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo515_mv, "vdd-l12-l14"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo515_mv, "vdd-l13-l16"), - RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo, "vdd-l12-l14"), - RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo20", "ldo%s20", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo21", "ldo%s21", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo22", "ldo%s22", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("ldo23", "ldo%s23", &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), - RPMH_VREG("bob", "bob%s1", &pmic5_bob, "vdd-bob"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps525, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps525, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps525, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps525, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps525, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps525, "vdd-s6"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l2-l3"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l2-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo515, "vdd-l4-l5"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo515, "vdd-l4-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo515, "vdd-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo515, "vdd-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo515, "vdd-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo515, "vdd-l9-l10"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_nldo515, "vdd-l9-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_nldo515, "vdd-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo515_mv, "vdd-l12-l14"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo515_mv, "vdd-l13-l16"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, "vdd-l12-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_pldo, "vdd-l13-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo19", LDO, 19, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo20", LDO, 20, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo21", LDO, 21, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo22", LDO, 22, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("ldo23", LDO, 23, &pmic5_pldo, "vdd-l15-l17-l18-l19-l20-l21-l22-l23"), + RPMH_VREG("bob", BOB, 1, &pmic5_bob, "vdd-bob"), {} }; static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps520, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps515, "vdd-s3"), - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l2"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo_lv, "vdd-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5-l6"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l5-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-bob"), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps520, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps520, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_hfsmps515, "vdd-s3"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l2"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l1-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo_lv, "vdd-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo, "vdd-l5-l6"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l5-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l7-bob"), {} }; static const struct rpmh_vreg_init_data pmr735b_vreg_data[] = { - RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l2"), - RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"), - RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo_lv, "vdd-l4"), - RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo, "vdd-l7-l8"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l7-l8"), - RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l9"), - RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo_lv, "vdd-l10"), - RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo, "vdd-l11"), - RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo, "vdd-l12"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1-l2"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo, "vdd-l1-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_pldo_lv, "vdd-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo, "vdd-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo, "vdd-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo, "vdd-l7-l8"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_nldo, "vdd-l7-l8"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_nldo, "vdd-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo_lv, "vdd-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_nldo, "vdd-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo, "vdd-l12"), {} }; static const struct rpmh_vreg_init_data pm660_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3"), - RPMH_VREG("smps4", "smp%s4", &pmic4_hfsmps3, "vdd-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic4_hfsmps3, "vdd-s5"), - RPMH_VREG("smps6", "smp%s6", &pmic4_hfsmps3, "vdd-s6"), - RPMH_VREG("ldo1", "ldo%s1", &pmic4_nldo, "vdd-l1-l6-l7"), - RPMH_VREG("ldo2", "ldo%s2", &pmic4_nldo, "vdd-l2-l3"), - RPMH_VREG("ldo3", "ldo%s3", &pmic4_nldo, "vdd-l2-l3"), + RPMH_VREG("smps1", SMPS, 1, &pmic4_ftsmps426, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic4_ftsmps426, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic4_ftsmps426, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic4_hfsmps3, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic4_hfsmps3, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic4_hfsmps3, "vdd-s6"), + RPMH_VREG("ldo1", LDO, 1, &pmic4_nldo, "vdd-l1-l6-l7"), + RPMH_VREG("ldo2", LDO, 2, &pmic4_nldo, "vdd-l2-l3"), + RPMH_VREG("ldo3", LDO, 3, &pmic4_nldo, "vdd-l2-l3"), /* ldo4 is inaccessible on PM660 */ - RPMH_VREG("ldo5", "ldo%s5", &pmic4_nldo, "vdd-l5"), - RPMH_VREG("ldo6", "ldo%s6", &pmic4_nldo, "vdd-l1-l6-l7"), - RPMH_VREG("ldo7", "ldo%s7", &pmic4_nldo, "vdd-l1-l6-l7"), - RPMH_VREG("ldo8", "ldo%s8", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo9", "ldo%s9", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo10", "ldo%s10", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo11", "ldo%s11", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo12", "ldo%s12", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo13", "ldo%s13", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo14", "ldo%s14", &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), - RPMH_VREG("ldo15", "ldo%s15", &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), - RPMH_VREG("ldo16", "ldo%s16", &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), - RPMH_VREG("ldo17", "ldo%s17", &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), - RPMH_VREG("ldo18", "ldo%s18", &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), - RPMH_VREG("ldo19", "ldo%s19", &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), + RPMH_VREG("ldo5", LDO, 5, &pmic4_nldo, "vdd-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic4_nldo, "vdd-l1-l6-l7"), + RPMH_VREG("ldo7", LDO, 7, &pmic4_nldo, "vdd-l1-l6-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo9", LDO, 9, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo10", LDO, 10, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo11", LDO, 11, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo12", LDO, 12, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo13", LDO, 13, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo14", LDO, 14, &pmic4_pldo_lv, "vdd-l8-l9-l10-l11-l12-l13-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), + RPMH_VREG("ldo16", LDO, 16, &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), + RPMH_VREG("ldo17", LDO, 17, &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), + RPMH_VREG("ldo18", LDO, 18, &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), + RPMH_VREG("ldo19", LDO, 19, &pmic4_pldo, "vdd-l15-l16-l17-l18-l19"), {} }; static const struct rpmh_vreg_init_data pm660l_vreg_data[] = { - RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"), - RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"), - RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3-s4"), - RPMH_VREG("smps5", "smp%s5", &pmic4_ftsmps426, "vdd-s5"), - RPMH_VREG("ldo1", "ldo%s1", &pmic4_nldo, "vdd-l1-l9-l10"), - RPMH_VREG("ldo2", "ldo%s2", &pmic4_pldo, "vdd-l2"), - RPMH_VREG("ldo3", "ldo%s3", &pmic4_pldo, "vdd-l3-l5-l7-l8"), - RPMH_VREG("ldo4", "ldo%s4", &pmic4_pldo, "vdd-l4-l6"), - RPMH_VREG("ldo5", "ldo%s5", &pmic4_pldo, "vdd-l3-l5-l7-l8"), - RPMH_VREG("ldo6", "ldo%s6", &pmic4_pldo, "vdd-l4-l6"), - RPMH_VREG("ldo7", "ldo%s7", &pmic4_pldo, "vdd-l3-l5-l7-l8"), - RPMH_VREG("ldo8", "ldo%s8", &pmic4_pldo, "vdd-l3-l5-l7-l8"), - RPMH_VREG("bob", "bob%s1", &pmic4_bob, "vdd-bob"), + RPMH_VREG("smps1", SMPS, 1, &pmic4_ftsmps426, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic4_ftsmps426, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic4_ftsmps426, "vdd-s3-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic4_ftsmps426, "vdd-s5"), + RPMH_VREG("ldo1", LDO, 1, &pmic4_nldo, "vdd-l1-l9-l10"), + RPMH_VREG("ldo2", LDO, 2, &pmic4_pldo, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic4_pldo, "vdd-l3-l5-l7-l8"), + RPMH_VREG("ldo4", LDO, 4, &pmic4_pldo, "vdd-l4-l6"), + RPMH_VREG("ldo5", LDO, 5, &pmic4_pldo, "vdd-l3-l5-l7-l8"), + RPMH_VREG("ldo6", LDO, 6, &pmic4_pldo, "vdd-l4-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic4_pldo, "vdd-l3-l5-l7-l8"), + RPMH_VREG("ldo8", LDO, 8, &pmic4_pldo, "vdd-l3-l5-l7-l8"), + RPMH_VREG("bob", BOB, 1, &pmic4_bob, "vdd-bob"), {} }; From dc1fc4716b79cf36b2d7459de0dfda2b5f3eebba Mon Sep 17 00:00:00 2001 From: Kamal Wadhwa Date: Thu, 18 Sep 2025 14:57:04 +0530 Subject: [PATCH 007/438] FROMGIT: regulator: rpmh-regulator: Add RPMH regulator support for Glymur Add support for PMH0101/PMCX0102/PMH0110/PMH0104 PMIC voltage regulators which are present on Glymur boards. Introduce new LDOs & SMPSs under them (PMIC5 subtype 530 for both). For these new LDOs support a new optimum power mode(OPM). In this mode LDO will automatically switch between high power mode (HPM) and low power mode (LPM) based on the real-time LDO load current. Its operation is analogous to SMPS AUTO mode. Reviewed-by: Dmitry Baryshkov Co-developed-by: Jishnu Prakash Signed-off-by: Jishnu Prakash Signed-off-by: Kamal Wadhwa Link: https://patch.msgid.link/20250918-glymur-rpmh-regulator-driver-v3-4-184c09678be3@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Yijie Yang --- drivers/regulator/qcom-rpmh-regulator.c | 188 +++++++++++++++++++++++- 1 file changed, 187 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index dfb5bf5b72a1e..0a561f1d94523 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. -// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -92,6 +92,11 @@ static const struct resource_name_formats vreg_rsc_name_lookup[NUM_REGULATOR_TYP #define PMIC5_BOB_MODE_AUTO 6 #define PMIC5_BOB_MODE_PWM 7 +#define PMIC530_LDO_MODE_RETENTION 3 +#define PMIC530_LDO_MODE_LPM 4 +#define PMIC530_LDO_MODE_OPM 5 +#define PMIC530_LDO_MODE_HPM 7 + #define PMIC_ID_LEN 4 /** * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations @@ -557,6 +562,14 @@ static const int pmic_mode_map_pmic5_ldo_hpm[REGULATOR_MODE_STANDBY + 1] = { [REGULATOR_MODE_FAST] = -EINVAL, }; +static const int pmic_mode_map_pmic530_ldo[REGULATOR_MODE_STANDBY + 1] = { + [REGULATOR_MODE_INVALID] = -EINVAL, + [REGULATOR_MODE_STANDBY] = PMIC530_LDO_MODE_RETENTION, + [REGULATOR_MODE_IDLE] = PMIC530_LDO_MODE_LPM, + [REGULATOR_MODE_NORMAL] = PMIC530_LDO_MODE_OPM, + [REGULATOR_MODE_FAST] = PMIC530_LDO_MODE_HPM, +}; + static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode) { unsigned int mode; @@ -579,6 +592,30 @@ static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode) return mode; } +static unsigned int rpmh_regulator_pmic530_ldo_of_map_mode(unsigned int rpmh_mode) +{ + unsigned int mode; + + switch (rpmh_mode) { + case RPMH_REGULATOR_MODE_HPM: + mode = REGULATOR_MODE_FAST; + break; + case RPMH_REGULATOR_MODE_AUTO: + mode = REGULATOR_MODE_NORMAL; + break; + case RPMH_REGULATOR_MODE_LPM: + mode = REGULATOR_MODE_IDLE; + break; + case RPMH_REGULATOR_MODE_RET: + mode = REGULATOR_MODE_STANDBY; + break; + default: + mode = REGULATOR_MODE_INVALID; + break; + } + return mode; +} + static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = { [REGULATOR_MODE_INVALID] = -EINVAL, [REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION, @@ -942,6 +979,71 @@ static const struct rpmh_vreg_hw_data pmic5_bob = { .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode, }; +static const struct rpmh_vreg_hw_data pmic5_nldo530 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(320000, 0, 210, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 211, + .hpm_min_load_uA = 30000, + .pmic_mode_map = pmic_mode_map_pmic530_ldo, + .of_map_mode = rpmh_regulator_pmic530_ldo_of_map_mode, +}; + +static const struct rpmh_vreg_hw_data pmic5_pldo530_mvp150 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 256, + .hpm_min_load_uA = 10000, + .pmic_mode_map = pmic_mode_map_pmic530_ldo, + .of_map_mode = rpmh_regulator_pmic530_ldo_of_map_mode, +}; + +static const struct rpmh_vreg_hw_data pmic5_pldo530_mvp300 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 256, + .hpm_min_load_uA = 20000, + .pmic_mode_map = pmic_mode_map_pmic530_ldo, + .of_map_mode = rpmh_regulator_pmic530_ldo_of_map_mode, +}; + +static const struct rpmh_vreg_hw_data pmic5_pldo530_mvp600 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 256, + .hpm_min_load_uA = 40000, + .pmic_mode_map = pmic_mode_map_pmic530_ldo, + .of_map_mode = rpmh_regulator_pmic530_ldo_of_map_mode, +}; + +static const struct rpmh_vreg_hw_data pmic5_ftsmps530 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_ops, + .voltage_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(252000, 0, 305, 4000), + REGULATOR_LINEAR_RANGE(1480000, 306, 464, 8000), + }, + .n_linear_ranges = 2, + .n_voltages = 465, + .pmic_mode_map = pmic_mode_map_pmic5_smps, + .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, +}; + #define RPMH_VREG(_name, _vreg_hw_type, _index, _hw_data, _supply_name) \ { \ .name = _name, \ @@ -1376,6 +1478,74 @@ static const struct rpmh_vreg_init_data pm6350_vreg_data[] = { RPMH_VREG("ldo22", LDO, 22, &pmic5_nldo, NULL), }; +static const struct rpmh_vreg_init_data pmcx0102_vreg_data[] = { + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps530, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps530, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps530, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps530, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps530, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps530, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps530, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps530, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps530, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_ftsmps530, "vdd-s10"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo530, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo530, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo530, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo530, "vdd-l4"), + {} +}; + +static const struct rpmh_vreg_init_data pmh0101_vreg_data[] = { + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo530, "vdd-l1-l4-l10"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo530_mvp300, "vdd-l2-l13-l14"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo530, "vdd-l3-l11"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo530, "vdd-l1-l4-l10"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo530_mvp150, "vdd-l5-l16"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo530_mvp300, "vdd-l6-l7"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo530_mvp300, "vdd-l6-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo530_mvp150, "vdd-l8-l9"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo515_mv, "vdd-l8-l9"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_nldo530, "vdd-l1-l4-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_nldo530, "vdd-l3-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_nldo530, "vdd-l12"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_pldo530_mvp150, "vdd-l2-l13-l14"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo530_mvp150, "vdd-l2-l13-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo530, "vdd-l15"), + RPMH_VREG("ldo16", LDO, 15, &pmic5_pldo530_mvp600, "vdd-l5-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_pldo515_mv, "vdd-l17"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo530, "vdd-l18"), + RPMH_VREG("bob1", BOB, 1, &pmic5_bob, "vdd-bob1"), + RPMH_VREG("bob2", BOB, 2, &pmic5_bob, "vdd-bob2"), + {} +}; + +static const struct rpmh_vreg_init_data pmh0104_vreg_data[] = { + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps530, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps530, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps530, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps530, "vdd-s4"), + {} +}; + +static const struct rpmh_vreg_init_data pmh0110_vreg_data[] = { + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps530, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_ftsmps530, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps530, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps530, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps530, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_ftsmps530, "vdd-s6"), + RPMH_VREG("smps7", SMPS, 7, &pmic5_ftsmps530, "vdd-s7"), + RPMH_VREG("smps8", SMPS, 8, &pmic5_ftsmps530, "vdd-s8"), + RPMH_VREG("smps9", SMPS, 9, &pmic5_ftsmps530, "vdd-s9"), + RPMH_VREG("smps10", SMPS, 10, &pmic5_ftsmps530, "vdd-s10"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo530, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo530, "vdd-l2"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo530, "vdd-l3"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo530, "vdd-l4"), + {} +}; + static const struct rpmh_vreg_init_data pmx55_vreg_data[] = { RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, "vdd-s2"), @@ -1728,6 +1898,22 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = { .compatible = "qcom,pmc8380-rpmh-regulators", .data = pmc8380_vreg_data, }, + { + .compatible = "qcom,pmcx0102-rpmh-regulators", + .data = pmcx0102_vreg_data, + }, + { + .compatible = "qcom,pmh0101-rpmh-regulators", + .data = pmh0101_vreg_data, + }, + { + .compatible = "qcom,pmh0104-rpmh-regulators", + .data = pmh0104_vreg_data, + }, + { + .compatible = "qcom,pmh0110-rpmh-regulators", + .data = pmh0110_vreg_data, + }, { .compatible = "qcom,pmm8155au-rpmh-regulators", .data = pmm8155au_vreg_data, From 3931fba21b2961780b482efa047dff5d86b69de7 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 16:30:48 -0700 Subject: [PATCH 008/438] FROMGIT: regulator: rpmh-regulator: Add RPMH regulator support for PMR735D Add support for PMR735D PMIC voltage regulators which are present on Kaanapali boards. Signed-off-by: Jishnu Prakash Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20250924-knp-regulator-v1-2-d9cde9a98a44@oss.qualcomm.com/ --- drivers/regulator/qcom-rpmh-regulator.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index 0a561f1d94523..6e4cb2871fca8 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -1735,6 +1735,17 @@ static const struct rpmh_vreg_init_data pmr735b_vreg_data[] = { {} }; +static const struct rpmh_vreg_init_data pmr735d_vreg_data[] = { + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo515, "vdd-l1-l2-l5"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_nldo515, "vdd-l1-l2-l5"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_nldo515, "vdd-l3-l4"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo515, "vdd-l3-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_nldo515, "vdd-l1-l2-l5"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_nldo515, "vdd-l6"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_nldo515, "vdd-l7"), + {} +}; + static const struct rpmh_vreg_init_data pm660_vreg_data[] = { RPMH_VREG("smps1", SMPS, 1, &pmic4_ftsmps426, "vdd-s1"), RPMH_VREG("smps2", SMPS, 2, &pmic4_ftsmps426, "vdd-s2"), @@ -1950,6 +1961,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = { .compatible = "qcom,pmr735b-rpmh-regulators", .data = pmr735b_vreg_data, }, + { + .compatible = "qcom,pmr735d-rpmh-regulators", + .data = pmr735d_vreg_data, + }, { .compatible = "qcom,pm660-rpmh-regulators", .data = pm660_vreg_data, From 81fc8fbf0f0a02a7b2d855aee574b88bd7d59107 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 16:30:47 -0700 Subject: [PATCH 009/438] FROMGIT: regulator: dt-bindings: qcom,rpmh: Add support for PMR735D Add support for PMR735D PMIC used on Kaanapali boards. Signed-off-by: Jishnu Prakash Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20250924-knp-regulator-v1-1-d9cde9a98a44@oss.qualcomm.com/ --- .../bindings/regulator/qcom,rpmh-regulator.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index 40ddc64577e78..4669095039c8c 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -59,6 +59,7 @@ description: | For PMCX0102, smps1 - smps10, ldo1 - ldo4 For PMR735A, smps1 - smps3, ldo1 - ldo7 For PMR735B, ldo1 - ldo12 + For PMR735D, ldo1 - ldo7 For PMX55, smps1 - smps7, ldo1 - ldo16 For PMX65, smps1 - smps8, ldo1 - ldo21 For PMX75, smps1 - smps10, ldo1 - ldo21 @@ -99,6 +100,7 @@ properties: - qcom,pmm8654au-rpmh-regulators - qcom,pmr735a-rpmh-regulators - qcom,pmr735b-rpmh-regulators + - qcom,pmr735d-rpmh-regulators - qcom,pmx55-rpmh-regulators - qcom,pmx65-rpmh-regulators - qcom,pmx75-rpmh-regulators @@ -496,6 +498,18 @@ allOf: patternProperties: "^vdd-l([3-6]|9|1[0-2])-supply$": true + - if: + properties: + compatible: + enum: + - qcom,pmr735d-rpmh-regulators + then: + properties: + vdd-l1-l2-l5-supply: true + vdd-l3-l4-supply: true + patternProperties: + "^vdd-l[6-7]-supply$": true + - if: properties: compatible: From 486bcf7a4a94e54abf5fd9e6cc6bf68eea22a5d6 Mon Sep 17 00:00:00 2001 From: Jyothi Kumar Seerapu Date: Wed, 5 Nov 2025 19:00:42 -0800 Subject: [PATCH 010/438] FROMLIST: dt-bindings: dma: qcom,gpi: Document GPI DMA engine for Kaanapali and Glymur SoCs Document the GPI DMA engine on the Kaanapali and Glymur platforms. Link: https://lore.kernel.org/lkml/20251105-knp-bus-v2-1-ed3095c7013a@oss.qualcomm.com/ Signed-off-by: Jyothi Kumar Seerapu Signed-off-by: Pankaj Patil Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sibi Sankar --- Documentation/devicetree/bindings/dma/qcom,gpi.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml index bbe4da2a11054..4cd867854a5fd 100644 --- a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml +++ b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml @@ -24,6 +24,8 @@ properties: - qcom,sm6350-gpi-dma - items: - enum: + - qcom,glymur-gpi-dma + - qcom,kaanapali-gpi-dma - qcom,milos-gpi-dma - qcom,qcm2290-gpi-dma - qcom,qcs8300-gpi-dma From a50984a91bb9d551ee48136ee2db90eca0929979 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 18 Sep 2025 19:47:38 +0530 Subject: [PATCH 011/438] FROMLIST: dt-bindings: firmware: qcom,scm: Document Glymur scm Document the SCM compatible for Qualcomm Glymur SoC. Secure Channel Manager(SCM) is used to communicate with secure firmware. Link: https://lore.kernel.org/all/20250918141738.2524269-1-pankaj.patil@oss.qualcomm.com/ Signed-off-by: Pankaj Patil Acked-by: Rob Herring (Arm) Signed-off-by: Sibi Sankar --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index 340b754e63226..d66459f1d84e4 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -23,6 +23,7 @@ properties: - enum: - qcom,scm-apq8064 - qcom,scm-apq8084 + - qcom,scm-glymur - qcom,scm-ipq4019 - qcom,scm-ipq5018 - qcom,scm-ipq5332 From 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 Mon Sep 17 00:00:00 2001 From: Melody Olvera Date: Wed, 15 Oct 2025 16:22:07 +0530 Subject: [PATCH 012/438] FROMLIST: dt-bindings: usb: qcom,dwc3: Correct the SM8750 compatible SM8750 does not require an XO clock in the dt as it is the parent of the TCSR refclk_src, so move the compatible to a section where the XO clock is not required. Acked-by: Krzysztof Kozlowski Signed-off-by: Melody Olvera Signed-off-by: Krishna Kurapati Link: https://lore.kernel.org/all/20251015105207.2819689-1-krishna.kurapati@oss.qualcomm.com/#r Signed-off-by: Yash Gupta --- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index a792434c59db2..298b1472ccbc4 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -227,6 +227,7 @@ allOf: - qcom,sdx65-dwc3 - qcom,sdx75-dwc3 - qcom,sm6350-dwc3 + - qcom,sm8750-dwc3 then: properties: clocks: @@ -366,7 +367,6 @@ allOf: - qcom,sm8450-dwc3 - qcom,sm8550-dwc3 - qcom,sm8650-dwc3 - - qcom,sm8750-dwc3 then: properties: clocks: From 22ea4bf1d0fb65028b8886987e6a28b78f7a5376 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:33:57 +0100 Subject: [PATCH 013/438] FROMLIST: dmaengine: Add DMA_PREP_LOCK/DMA_PREP_UNLOCK flags Some DMA engines may be accessed from linux and the TrustZone simultaneously. In order to allow synchronization, add lock and unlock flags for the command descriptor that allow the caller to request the controller to be locked for the duration of the transaction in an implementation-dependent way. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-1-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- Documentation/driver-api/dmaengine/provider.rst | 9 +++++++++ include/linux/dmaengine.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst index 1594598b33178..6428211405472 100644 --- a/Documentation/driver-api/dmaengine/provider.rst +++ b/Documentation/driver-api/dmaengine/provider.rst @@ -630,6 +630,15 @@ DMA_CTRL_REUSE - This flag is only supported if the channel reports the DMA_LOAD_EOT capability. +- DMA_PREP_LOCK + + - If set, the DMA controller will be locked for the duration of the current + transaction. + +- DMA_PREP_UNLOCK + + - If set, DMA will release he controller lock. + General Design Notes ==================== diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 99efe2b9b4ea9..c02be4bc8ac4c 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -200,6 +200,10 @@ struct dma_vec { * transaction is marked with DMA_PREP_REPEAT will cause the new transaction * to never be processed and stay in the issued queue forever. The flag is * ignored if the previous transaction is not a repeated transaction. + * @DMA_PREP_LOCK: tell the driver that there is a lock bit set on command + * descriptor. + * @DMA_PREP_UNLOCK: tell the driver that there is a un-lock bit set on command + * descriptor. */ enum dma_ctrl_flags { DMA_PREP_INTERRUPT = (1 << 0), @@ -212,6 +216,8 @@ enum dma_ctrl_flags { DMA_PREP_CMD = (1 << 7), DMA_PREP_REPEAT = (1 << 8), DMA_PREP_LOAD_EOT = (1 << 9), + DMA_PREP_LOCK = (1 << 10), + DMA_PREP_UNLOCK = (1 << 11), }; /** From 88da45e444b4fdb7223b2687afb5dcc0c3173ba3 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:33:58 +0100 Subject: [PATCH 014/438] FROMLIST: dmaengine: qcom: bam_dma: Extend the driver's device match data In preparation for supporting the pipe locking feature flag, extend the amount of information we can carry in device match data: create a separate structure and make the register information one of its fields. This way, in subsequent patches, it will be just a matter of adding a new field to the device data. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-2-ecddca23ca26@linaro.org/ Reviewed-by: Dmitry Baryshkov Signed-off-by: Bartosz Golaszewski --- drivers/dma/qcom/bam_dma.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 2cf060174795f..8861245314b1d 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -111,6 +111,10 @@ struct reg_offset_data { unsigned int pipe_mult, evnt_mult, ee_mult; }; +struct bam_device_data { + const struct reg_offset_data *reg_info; +}; + static const struct reg_offset_data bam_v1_3_reg_info[] = { [BAM_CTRL] = { 0x0F80, 0x00, 0x00, 0x00 }, [BAM_REVISION] = { 0x0F84, 0x00, 0x00, 0x00 }, @@ -140,6 +144,10 @@ static const struct reg_offset_data bam_v1_3_reg_info[] = { [BAM_P_FIFO_SIZES] = { 0x1020, 0x00, 0x40, 0x00 }, }; +static const struct bam_device_data bam_v1_3_data = { + .reg_info = bam_v1_3_reg_info, +}; + static const struct reg_offset_data bam_v1_4_reg_info[] = { [BAM_CTRL] = { 0x0000, 0x00, 0x00, 0x00 }, [BAM_REVISION] = { 0x0004, 0x00, 0x00, 0x00 }, @@ -169,6 +177,10 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = { [BAM_P_FIFO_SIZES] = { 0x1820, 0x00, 0x1000, 0x00 }, }; +static const struct bam_device_data bam_v1_4_data = { + .reg_info = bam_v1_4_reg_info, +}; + static const struct reg_offset_data bam_v1_7_reg_info[] = { [BAM_CTRL] = { 0x00000, 0x00, 0x00, 0x00 }, [BAM_REVISION] = { 0x01000, 0x00, 0x00, 0x00 }, @@ -198,6 +210,10 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = { [BAM_P_FIFO_SIZES] = { 0x13820, 0x00, 0x1000, 0x00 }, }; +static const struct bam_device_data bam_v1_7_data = { + .reg_info = bam_v1_7_reg_info, +}; + /* BAM CTRL */ #define BAM_SW_RST BIT(0) #define BAM_EN BIT(1) @@ -391,7 +407,7 @@ struct bam_device { bool powered_remotely; u32 active_channels; - const struct reg_offset_data *layout; + const struct bam_device_data *dev_data; struct clk *bamclk; int irq; @@ -409,7 +425,7 @@ struct bam_device { static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe, enum bam_reg reg) { - const struct reg_offset_data r = bdev->layout[reg]; + const struct reg_offset_data r = bdev->dev_data->reg_info[reg]; return bdev->regs + r.base_offset + r.pipe_mult * pipe + @@ -1225,9 +1241,9 @@ static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan, } static const struct of_device_id bam_of_match[] = { - { .compatible = "qcom,bam-v1.3.0", .data = &bam_v1_3_reg_info }, - { .compatible = "qcom,bam-v1.4.0", .data = &bam_v1_4_reg_info }, - { .compatible = "qcom,bam-v1.7.0", .data = &bam_v1_7_reg_info }, + { .compatible = "qcom,bam-v1.3.0", .data = &bam_v1_3_data }, + { .compatible = "qcom,bam-v1.4.0", .data = &bam_v1_4_data }, + { .compatible = "qcom,bam-v1.7.0", .data = &bam_v1_7_data }, {} }; @@ -1251,7 +1267,7 @@ static int bam_dma_probe(struct platform_device *pdev) return -ENODEV; } - bdev->layout = match->data; + bdev->dev_data = match->data; bdev->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(bdev->regs)) From 67be6e002d88be4f081ec71f6876c256cf13321e Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:33:59 +0100 Subject: [PATCH 015/438] FROMLIST: dmaengine: qcom: bam_dma: Add bam_pipe_lock flag support Extend the device match data with a flag indicating whether the IP supports the BAM lock/unlock feature. Set it to true on BAM IP versions 1.4.0 and above. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-3-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/dma/qcom/bam_dma.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 8861245314b1d..68921d22ad7ab 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -58,6 +58,8 @@ struct bam_desc_hw { #define DESC_FLAG_EOB BIT(13) #define DESC_FLAG_NWD BIT(12) #define DESC_FLAG_CMD BIT(11) +#define DESC_FLAG_LOCK BIT(10) +#define DESC_FLAG_UNLOCK BIT(9) struct bam_async_desc { struct virt_dma_desc vd; @@ -113,6 +115,7 @@ struct reg_offset_data { struct bam_device_data { const struct reg_offset_data *reg_info; + bool bam_pipe_lock; }; static const struct reg_offset_data bam_v1_3_reg_info[] = { @@ -179,6 +182,7 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = { static const struct bam_device_data bam_v1_4_data = { .reg_info = bam_v1_4_reg_info, + .bam_pipe_lock = true, }; static const struct reg_offset_data bam_v1_7_reg_info[] = { @@ -212,6 +216,7 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = { static const struct bam_device_data bam_v1_7_data = { .reg_info = bam_v1_7_reg_info, + .bam_pipe_lock = true, }; /* BAM CTRL */ @@ -386,6 +391,9 @@ struct bam_chan { struct list_head desc_list; struct list_head node; + + /* Is the BAM currently locked? */ + bool locked; }; static inline struct bam_chan *to_bam_chan(struct dma_chan *common) @@ -667,6 +675,7 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, { struct bam_chan *bchan = to_bam_chan(chan); struct bam_device *bdev = bchan->bdev; + const struct bam_device_data *bdata = bdev->dev_data; struct bam_async_desc *async_desc; struct scatterlist *sg; u32 i; @@ -707,9 +716,34 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, unsigned int curr_offset = 0; do { - if (flags & DMA_PREP_CMD) + if (flags & DMA_PREP_CMD) { + if (!bdata->bam_pipe_lock && + (flags & (DMA_PREP_LOCK | DMA_PREP_UNLOCK))) { + dev_err(bdev->dev, "Device doesn't support BAM locking\n"); + return NULL; + } + desc->flags |= cpu_to_le16(DESC_FLAG_CMD); + if (bdata->bam_pipe_lock && (flags & DMA_PREP_LOCK)) { + if (bchan->locked) { + dev_err(bdev->dev, "BAM already locked\n"); + return NULL; + } + + desc->flags |= cpu_to_le16(DESC_FLAG_LOCK); + bchan->locked = true; + } else if (bdata->bam_pipe_lock && (flags & DMA_PREP_UNLOCK)) { + if (!bchan->locked) { + dev_err(bdev->dev, "BAM is not locked\n"); + return NULL; + } + + desc->flags |= cpu_to_le16(DESC_FLAG_UNLOCK); + bchan->locked = false; + } + } + desc->addr = cpu_to_le32(sg_dma_address(sg) + curr_offset); From 88c822026c45f1a56623c4d4871c555c1066722b Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:00 +0100 Subject: [PATCH 016/438] FROMLIST: crypto: qce - Include algapi.h in the core.h header The header defines a struct embedding struct crypto_queue whose size needs to be known and which is defined in crypto/algapi.h. Move the inclusion from core.c to core.h. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-4-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/core.c | 1 - drivers/crypto/qce/core.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index b966f3365b7de..65205100c3df9 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "core.h" diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h index eb6fa7a8b64a8..f092ce2d3b04a 100644 --- a/drivers/crypto/qce/core.h +++ b/drivers/crypto/qce/core.h @@ -8,6 +8,7 @@ #include #include +#include #include "dma.h" From 20ac178866876878e466c93b583ce7599bf3f225 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:01 +0100 Subject: [PATCH 017/438] FROMLIST: crypto: qce - Remove unused ignore_buf It's unclear what the purpose of this field is. It has been here since the initial commit but without any explanation. The driver works fine without it. We still keep allocating more space in the result buffer, we just don't need to store its address. While at it: move the QCE_IGNORE_BUF_SZ definition into dma.c as it's not used outside of this compilation unit. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-5-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/dma.c | 4 ++-- drivers/crypto/qce/dma.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c index 68cafd4741ad3..08bf3e8ec1243 100644 --- a/drivers/crypto/qce/dma.c +++ b/drivers/crypto/qce/dma.c @@ -9,6 +9,8 @@ #include "dma.h" +#define QCE_IGNORE_BUF_SZ (2 * QCE_BAM_BURST_SIZE) + static void qce_dma_release(void *data) { struct qce_dma_data *dma = data; @@ -41,8 +43,6 @@ int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma) goto error_nomem; } - dma->ignore_buf = dma->result_buf + QCE_RESULT_BUF_SZ; - return devm_add_action_or_reset(dev, qce_dma_release, dma); error_nomem: diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h index 31629185000e1..fc337c435cd14 100644 --- a/drivers/crypto/qce/dma.h +++ b/drivers/crypto/qce/dma.h @@ -23,7 +23,6 @@ struct qce_result_dump { u32 status2; }; -#define QCE_IGNORE_BUF_SZ (2 * QCE_BAM_BURST_SIZE) #define QCE_RESULT_BUF_SZ \ ALIGN(sizeof(struct qce_result_dump), QCE_BAM_BURST_SIZE) @@ -31,7 +30,6 @@ struct qce_dma_data { struct dma_chan *txchan; struct dma_chan *rxchan; struct qce_result_dump *result_buf; - void *ignore_buf; }; int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma); From 32cdabe75da355e06786cf1d1ebaa944612da8c0 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:02 +0100 Subject: [PATCH 018/438] FROMLIST: crypto: qce - Simplify arguments of devm_qce_dma_request() This function can extract all the information it needs from struct qce_device alone so simplify its arguments. This is done in preparation for adding support for register I/O over DMA which will require accessing even more fields from struct qce_device. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-6-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/core.c | 2 +- drivers/crypto/qce/dma.c | 5 ++++- drivers/crypto/qce/dma.h | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index 65205100c3df9..8b7bcd0c420c4 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -226,7 +226,7 @@ static int qce_crypto_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_qce_dma_request(qce->dev, &qce->dma); + ret = devm_qce_dma_request(qce); if (ret) return ret; diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c index 08bf3e8ec1243..c29b0abe94453 100644 --- a/drivers/crypto/qce/dma.c +++ b/drivers/crypto/qce/dma.c @@ -7,6 +7,7 @@ #include #include +#include "core.h" #include "dma.h" #define QCE_IGNORE_BUF_SZ (2 * QCE_BAM_BURST_SIZE) @@ -20,8 +21,10 @@ static void qce_dma_release(void *data) kfree(dma->result_buf); } -int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma) +int devm_qce_dma_request(struct qce_device *qce) { + struct qce_dma_data *dma = &qce->dma; + struct device *dev = qce->dev; int ret; dma->txchan = dma_request_chan(dev, "tx"); diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h index fc337c435cd14..483789d9fa98e 100644 --- a/drivers/crypto/qce/dma.h +++ b/drivers/crypto/qce/dma.h @@ -8,6 +8,8 @@ #include +struct qce_device; + /* maximum data transfer block size between BAM and CE */ #define QCE_BAM_BURST_SIZE 64 @@ -32,7 +34,7 @@ struct qce_dma_data { struct qce_result_dump *result_buf; }; -int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma); +int devm_qce_dma_request(struct qce_device *qce); int qce_dma_prep_sgs(struct qce_dma_data *dma, struct scatterlist *sg_in, int in_ents, struct scatterlist *sg_out, int out_ents, dma_async_tx_callback cb, void *cb_param); From 8bbc3c84a5d6f61817df15323e5a0d116b6b62ac Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Mon, 22 Dec 2025 16:46:30 +0530 Subject: [PATCH 019/438] FROMLIST: crypto: qce - Use existing devres APIs in devm_qce_dma_request() Switch to devm_kmalloc() and devm_dma_alloc_chan() in devm_qce_dma_request(). This allows us to drop two labels and shrink the function. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-7-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/dma.c | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c index c29b0abe94453..6518bff871949 100644 --- a/drivers/crypto/qce/dma.c +++ b/drivers/crypto/qce/dma.c @@ -12,47 +12,25 @@ #define QCE_IGNORE_BUF_SZ (2 * QCE_BAM_BURST_SIZE) -static void qce_dma_release(void *data) -{ - struct qce_dma_data *dma = data; - - dma_release_channel(dma->txchan); - dma_release_channel(dma->rxchan); - kfree(dma->result_buf); -} - int devm_qce_dma_request(struct qce_device *qce) { struct qce_dma_data *dma = &qce->dma; struct device *dev = qce->dev; - int ret; - dma->txchan = dma_request_chan(dev, "tx"); + dma->txchan = devm_dma_request_chan(dev, "tx"); if (IS_ERR(dma->txchan)) return dev_err_probe(dev, PTR_ERR(dma->txchan), "Failed to get TX DMA channel\n"); - dma->rxchan = dma_request_chan(dev, "rx"); - if (IS_ERR(dma->rxchan)) { - ret = dev_err_probe(dev, PTR_ERR(dma->rxchan), - "Failed to get RX DMA channel\n"); - goto error_rx; - } - - dma->result_buf = kmalloc(QCE_RESULT_BUF_SZ + QCE_IGNORE_BUF_SZ, - GFP_KERNEL); - if (!dma->result_buf) { - ret = -ENOMEM; - goto error_nomem; - } + dma->rxchan = devm_dma_request_chan(dev, "rx"); + if (IS_ERR(dma->rxchan)) + return PTR_ERR(dma->rxchan); - return devm_add_action_or_reset(dev, qce_dma_release, dma); + dma->result_buf = devm_kmalloc(dev, QCE_RESULT_BUF_SZ + QCE_IGNORE_BUF_SZ, GFP_KERNEL); + if (!dma->result_buf) + return -ENOMEM; -error_nomem: - dma_release_channel(dma->rxchan); -error_rx: - dma_release_channel(dma->txchan); - return ret; + return 0; } struct scatterlist * From b849a69922d805f532786419820e56a9cad967e0 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:04 +0100 Subject: [PATCH 020/438] FROMLIST: crypto: qce - Map crypto memory for DMA As the first step in converting the driver to using DMA for register I/O, let's map the crypto memory range. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-8-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/core.c | 25 +++++++++++++++++++++++-- drivers/crypto/qce/core.h | 6 ++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index 8b7bcd0c420c4..2667fcd67fee8 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -185,10 +185,19 @@ static int qce_check_version(struct qce_device *qce) return 0; } +static void qce_crypto_unmap_dma(void *data) +{ + struct qce_device *qce = data; + + dma_unmap_resource(qce->dev, qce->base_dma, qce->dma_size, + DMA_BIDIRECTIONAL, 0); +} + static int qce_crypto_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct qce_device *qce; + struct resource *res; int ret; qce = devm_kzalloc(dev, sizeof(*qce), GFP_KERNEL); @@ -198,7 +207,7 @@ static int qce_crypto_probe(struct platform_device *pdev) qce->dev = dev; platform_set_drvdata(pdev, qce); - qce->base = devm_platform_ioremap_resource(pdev, 0); + qce->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(qce->base)) return PTR_ERR(qce->base); @@ -244,7 +253,19 @@ static int qce_crypto_probe(struct platform_device *pdev) qce->async_req_enqueue = qce_async_request_enqueue; qce->async_req_done = qce_async_request_done; - return devm_qce_register_algs(qce); + ret = devm_qce_register_algs(qce); + if (ret) + return ret; + + qce->dma_size = resource_size(res); + qce->base_dma = dma_map_resource(dev, res->start, qce->dma_size, + DMA_BIDIRECTIONAL, 0); + qce->base_phys = res->start; + ret = dma_mapping_error(dev, qce->base_dma); + if (ret) + return ret; + + return devm_add_action_or_reset(qce->dev, qce_crypto_unmap_dma, qce); } static const struct of_device_id qce_crypto_of_match[] = { diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h index f092ce2d3b04a..a80e12eac6c87 100644 --- a/drivers/crypto/qce/core.h +++ b/drivers/crypto/qce/core.h @@ -27,6 +27,9 @@ * @dma: pointer to dma data * @burst_size: the crypto burst size * @pipe_pair_id: which pipe pair id the device using + * @base_dma: base DMA address + * @base_phys: base physical address + * @dma_size: size of memory mapped for DMA * @async_req_enqueue: invoked by every algorithm to enqueue a request * @async_req_done: invoked by every algorithm to finish its request */ @@ -43,6 +46,9 @@ struct qce_device { struct qce_dma_data dma; int burst_size; unsigned int pipe_pair_id; + dma_addr_t base_dma; + phys_addr_t base_phys; + size_t dma_size; int (*async_req_enqueue)(struct qce_device *qce, struct crypto_async_request *req); void (*async_req_done)(struct qce_device *qce, int ret); From e1170f20fb7839d48aa84b406f25eb59f4a123ef Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:05 +0100 Subject: [PATCH 021/438] FROMLIST: crypto: qce - Add BAM DMA support for crypto register I/O Implement the infrastructure for performing register I/O over BAM DMA, not CPU. No functional change yet. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-9-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/core.h | 4 ++ drivers/crypto/qce/dma.c | 109 ++++++++++++++++++++++++++++++++++++++ drivers/crypto/qce/dma.h | 5 ++ 3 files changed, 118 insertions(+) diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h index a80e12eac6c87..d238097f834e4 100644 --- a/drivers/crypto/qce/core.h +++ b/drivers/crypto/qce/core.h @@ -30,6 +30,8 @@ * @base_dma: base DMA address * @base_phys: base physical address * @dma_size: size of memory mapped for DMA + * @read_buf: Buffer for DMA to write back to + * @read_buf_dma: Mapped address of the read buffer * @async_req_enqueue: invoked by every algorithm to enqueue a request * @async_req_done: invoked by every algorithm to finish its request */ @@ -49,6 +51,8 @@ struct qce_device { dma_addr_t base_dma; phys_addr_t base_phys; size_t dma_size; + __le32 *read_buf; + dma_addr_t read_buf_dma; int (*async_req_enqueue)(struct qce_device *qce, struct crypto_async_request *req); void (*async_req_done)(struct qce_device *qce, int ret); diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c index 6518bff871949..c46074ee8bd4f 100644 --- a/drivers/crypto/qce/dma.c +++ b/drivers/crypto/qce/dma.c @@ -4,6 +4,8 @@ */ #include +#include +#include #include #include @@ -11,6 +13,98 @@ #include "dma.h" #define QCE_IGNORE_BUF_SZ (2 * QCE_BAM_BURST_SIZE) +#define QCE_BAM_CMD_SGL_SIZE 128 +#define QCE_BAM_CMD_ELEMENT_SIZE 128 +#define QCE_MAX_REG_READ 8 + +struct qce_desc_info { + struct dma_async_tx_descriptor *dma_desc; + enum dma_data_direction dir; +}; + +struct qce_bam_transaction { + struct bam_cmd_element bam_ce[QCE_BAM_CMD_ELEMENT_SIZE]; + struct scatterlist wr_sgl[QCE_BAM_CMD_SGL_SIZE]; + struct qce_desc_info *desc; + u32 bam_ce_idx; + u32 pre_bam_ce_idx; + u32 wr_sgl_cnt; +}; + +void qce_clear_bam_transaction(struct qce_device *qce) +{ + struct qce_bam_transaction *bam_txn = qce->dma.bam_txn; + + bam_txn->bam_ce_idx = 0; + bam_txn->wr_sgl_cnt = 0; + bam_txn->bam_ce_idx = 0; + bam_txn->pre_bam_ce_idx = 0; +} + +int qce_submit_cmd_desc(struct qce_device *qce) +{ + struct qce_desc_info *qce_desc = qce->dma.bam_txn->desc; + struct qce_bam_transaction *bam_txn = qce->dma.bam_txn; + struct dma_async_tx_descriptor *dma_desc; + struct dma_chan *chan = qce->dma.rxchan; + unsigned long attrs = DMA_PREP_CMD; + dma_cookie_t cookie; + unsigned int mapped; + int ret; + + mapped = dma_map_sg_attrs(qce->dev, bam_txn->wr_sgl, bam_txn->wr_sgl_cnt, + DMA_TO_DEVICE, attrs); + if (!mapped) + return -ENOMEM; + + dma_desc = dmaengine_prep_slave_sg(chan, bam_txn->wr_sgl, bam_txn->wr_sgl_cnt, + DMA_MEM_TO_DEV, attrs); + if (!dma_desc) { + dma_unmap_sg(qce->dev, bam_txn->wr_sgl, bam_txn->wr_sgl_cnt, DMA_TO_DEVICE); + return -ENOMEM; + } + + qce_desc->dma_desc = dma_desc; + cookie = dmaengine_submit(qce_desc->dma_desc); + + ret = dma_submit_error(cookie); + if (ret) + return ret; + + qce_dma_issue_pending(&qce->dma); + + return 0; +} + +static void qce_prep_dma_cmd_desc(struct qce_device *qce, struct qce_dma_data *dma, + unsigned int addr, void *buf) +{ + struct qce_bam_transaction *bam_txn = dma->bam_txn; + struct bam_cmd_element *bam_ce_buf; + int bam_ce_size, cnt, idx; + + idx = bam_txn->bam_ce_idx; + bam_ce_buf = &bam_txn->bam_ce[idx]; + bam_prep_ce_le32(bam_ce_buf, addr, BAM_WRITE_COMMAND, *((__le32 *)buf)); + + bam_ce_buf = &bam_txn->bam_ce[bam_txn->pre_bam_ce_idx]; + bam_txn->bam_ce_idx++; + bam_ce_size = (bam_txn->bam_ce_idx - bam_txn->pre_bam_ce_idx) * sizeof(*bam_ce_buf); + + cnt = bam_txn->wr_sgl_cnt; + + sg_set_buf(&bam_txn->wr_sgl[cnt], bam_ce_buf, bam_ce_size); + + ++bam_txn->wr_sgl_cnt; + bam_txn->pre_bam_ce_idx = bam_txn->bam_ce_idx; +} + +void qce_write_dma(struct qce_device *qce, unsigned int offset, u32 val) +{ + unsigned int reg_addr = ((unsigned int)(qce->base_phys) + offset); + + qce_prep_dma_cmd_desc(qce, &qce->dma, reg_addr, &val); +} int devm_qce_dma_request(struct qce_device *qce) { @@ -30,6 +124,21 @@ int devm_qce_dma_request(struct qce_device *qce) if (!dma->result_buf) return -ENOMEM; + dma->bam_txn = devm_kzalloc(dev, sizeof(*dma->bam_txn), GFP_KERNEL); + if (!dma->bam_txn) + return -ENOMEM; + + dma->bam_txn->desc = devm_kzalloc(dev, sizeof(*dma->bam_txn->desc), GFP_KERNEL); + if (!dma->bam_txn->desc) + return -ENOMEM; + + sg_init_table(dma->bam_txn->wr_sgl, QCE_BAM_CMD_SGL_SIZE); + + qce->read_buf = dmam_alloc_coherent(qce->dev, QCE_MAX_REG_READ * sizeof(*qce->read_buf), + &qce->read_buf_dma, GFP_KERNEL); + if (!qce->read_buf) + return -ENOMEM; + return 0; } diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h index 483789d9fa98e..f05dfa9e6b25b 100644 --- a/drivers/crypto/qce/dma.h +++ b/drivers/crypto/qce/dma.h @@ -8,6 +8,7 @@ #include +struct qce_bam_transaction; struct qce_device; /* maximum data transfer block size between BAM and CE */ @@ -32,6 +33,7 @@ struct qce_dma_data { struct dma_chan *txchan; struct dma_chan *rxchan; struct qce_result_dump *result_buf; + struct qce_bam_transaction *bam_txn; }; int devm_qce_dma_request(struct qce_device *qce); @@ -43,5 +45,8 @@ int qce_dma_terminate_all(struct qce_dma_data *dma); struct scatterlist * qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add, unsigned int max_len); +void qce_write_dma(struct qce_device *qce, unsigned int offset, u32 val); +int qce_submit_cmd_desc(struct qce_device *qce); +void qce_clear_bam_transaction(struct qce_device *qce); #endif /* _DMA_H_ */ From 67a9ac3a484b8efd1593025a5fa355eb7aeff918 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:06 +0100 Subject: [PATCH 022/438] FROMLIST: crypto: qce - Add support for BAM locking Implement the infrastructure for using the new DMA controller lock/unlock feature of the BAM driver. No functional change for now. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-10-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/common.c | 18 ++++++++++++++++++ drivers/crypto/qce/dma.c | 19 +++++++++++++++++-- drivers/crypto/qce/dma.h | 4 ++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c index 04253a8d33409..74756c222fed6 100644 --- a/drivers/crypto/qce/common.c +++ b/drivers/crypto/qce/common.c @@ -593,3 +593,21 @@ void qce_get_version(struct qce_device *qce, u32 *major, u32 *minor, u32 *step) *minor = (val & CORE_MINOR_REV_MASK) >> CORE_MINOR_REV_SHIFT; *step = (val & CORE_STEP_REV_MASK) >> CORE_STEP_REV_SHIFT; } + +int qce_bam_lock(struct qce_device *qce) +{ + qce_clear_bam_transaction(qce); + /* Dummy write to acquire the lock on the BAM pipe. */ + qce_write(qce, REG_AUTH_SEG_CFG, 0); + + return qce_submit_cmd_desc_lock(qce); +} + +int qce_bam_unlock(struct qce_device *qce) +{ + qce_clear_bam_transaction(qce); + /* Dummy write to release the lock on the BAM pipe. */ + qce_write(qce, REG_AUTH_SEG_CFG, 0); + + return qce_submit_cmd_desc_unlock(qce); +} diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c index c46074ee8bd4f..de13a49cb2754 100644 --- a/drivers/crypto/qce/dma.c +++ b/drivers/crypto/qce/dma.c @@ -41,13 +41,13 @@ void qce_clear_bam_transaction(struct qce_device *qce) bam_txn->pre_bam_ce_idx = 0; } -int qce_submit_cmd_desc(struct qce_device *qce) +static int qce_do_submit_cmd_desc(struct qce_device *qce, unsigned long flags) { struct qce_desc_info *qce_desc = qce->dma.bam_txn->desc; struct qce_bam_transaction *bam_txn = qce->dma.bam_txn; struct dma_async_tx_descriptor *dma_desc; struct dma_chan *chan = qce->dma.rxchan; - unsigned long attrs = DMA_PREP_CMD; + unsigned long attrs = DMA_PREP_CMD | flags; dma_cookie_t cookie; unsigned int mapped; int ret; @@ -76,6 +76,21 @@ int qce_submit_cmd_desc(struct qce_device *qce) return 0; } +int qce_submit_cmd_desc(struct qce_device *qce) +{ + return qce_do_submit_cmd_desc(qce, 0); +} + +int qce_submit_cmd_desc_lock(struct qce_device *qce) +{ + return qce_do_submit_cmd_desc(qce, DMA_PREP_LOCK); +} + +int qce_submit_cmd_desc_unlock(struct qce_device *qce) +{ + return qce_do_submit_cmd_desc(qce, DMA_PREP_UNLOCK); +} + static void qce_prep_dma_cmd_desc(struct qce_device *qce, struct qce_dma_data *dma, unsigned int addr, void *buf) { diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h index f05dfa9e6b25b..4b3ee17db72e2 100644 --- a/drivers/crypto/qce/dma.h +++ b/drivers/crypto/qce/dma.h @@ -47,6 +47,10 @@ qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add, unsigned int max_len); void qce_write_dma(struct qce_device *qce, unsigned int offset, u32 val); int qce_submit_cmd_desc(struct qce_device *qce); +int qce_submit_cmd_desc_lock(struct qce_device *qce); +int qce_submit_cmd_desc_unlock(struct qce_device *qce); void qce_clear_bam_transaction(struct qce_device *qce); +int qce_bam_lock(struct qce_device *qce); +int qce_bam_unlock(struct qce_device *qce); #endif /* _DMA_H_ */ From fa6b06add383d99c6ee75331081bc25a6986e2e0 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:34:07 +0100 Subject: [PATCH 023/438] FROMLIST: crypto: qce - Switch to using BAM DMA for crypto I/O With everything else in place, we can now switch to actually using the BAM DMA for register I/O with DMA engine locking. Link: https://lore.kernel.org/lkml/20251106-qcom-qce-cmd-descr-v8-11-ecddca23ca26@linaro.org/ Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/aead.c | 10 ++++++++++ drivers/crypto/qce/common.c | 21 ++++++++++----------- drivers/crypto/qce/sha.c | 8 ++++++++ drivers/crypto/qce/skcipher.c | 7 +++++++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c index 97b56e92ea33f..1e6e1f5bcca45 100644 --- a/drivers/crypto/qce/aead.c +++ b/drivers/crypto/qce/aead.c @@ -63,6 +63,10 @@ static void qce_aead_done(void *data) sg_free_table(&rctx->dst_tbl); } + error = qce_bam_unlock(qce); + if (error) + dev_err(qce->dev, "aead: failed to unlock the BAM\n"); + error = qce_check_status(qce, &status); if (error < 0 && (error != -EBADMSG)) dev_err(qce->dev, "aead operation error (%x)\n", status); @@ -188,6 +192,8 @@ qce_aead_ccm_prepare_buf_assoclen(struct aead_request *req) struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct qce_aead_reqctx *rctx = aead_request_ctx_dma(req); struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct qce_alg_template *tmpl = to_aead_tmpl(crypto_aead_reqtfm(req)); + struct qce_device *qce = tmpl->qce; unsigned int assoclen = rctx->assoclen; unsigned int adata_header_len, cryptlen, totallen; gfp_t gfp; @@ -200,6 +206,10 @@ qce_aead_ccm_prepare_buf_assoclen(struct aead_request *req) cryptlen = rctx->cryptlen; totallen = cryptlen + req->assoclen; + ret = qce_bam_lock(qce); + if (ret) + return ret; + /* Get the msg */ msg_sg = scatterwalk_ffwd(__sg, req->src, req->assoclen); diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c index 74756c222fed6..930006aaba4ac 100644 --- a/drivers/crypto/qce/common.c +++ b/drivers/crypto/qce/common.c @@ -14,6 +14,7 @@ #include "cipher.h" #include "common.h" #include "core.h" +#include "dma.h" #include "regs-v5.h" #include "sha.h" #include "aead.h" @@ -25,7 +26,7 @@ static inline u32 qce_read(struct qce_device *qce, u32 offset) static inline void qce_write(struct qce_device *qce, u32 offset, u32 val) { - writel(val, qce->base + offset); + qce_write_dma(qce, offset, val); } static inline void qce_write_array(struct qce_device *qce, u32 offset, @@ -82,6 +83,8 @@ static void qce_setup_config(struct qce_device *qce) { u32 config; + qce_clear_bam_transaction(qce); + /* get big endianness */ config = qce_config_reg(qce, 0); @@ -90,12 +93,14 @@ static void qce_setup_config(struct qce_device *qce) qce_write(qce, REG_CONFIG, config); } -static inline void qce_crypto_go(struct qce_device *qce, bool result_dump) +static int qce_crypto_go(struct qce_device *qce, bool result_dump) { if (result_dump) qce_write(qce, REG_GOPROC, BIT(GO_SHIFT) | BIT(RESULTS_DUMP_SHIFT)); else qce_write(qce, REG_GOPROC, BIT(GO_SHIFT)); + + return qce_submit_cmd_desc(qce); } #if defined(CONFIG_CRYPTO_DEV_QCE_SHA) || defined(CONFIG_CRYPTO_DEV_QCE_AEAD) @@ -223,9 +228,7 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req) config = qce_config_reg(qce, 1); qce_write(qce, REG_CONFIG, config); - qce_crypto_go(qce, true); - - return 0; + return qce_crypto_go(qce, true); } #endif @@ -386,9 +389,7 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req) config = qce_config_reg(qce, 1); qce_write(qce, REG_CONFIG, config); - qce_crypto_go(qce, true); - - return 0; + return qce_crypto_go(qce, true); } #endif @@ -535,9 +536,7 @@ static int qce_setup_regs_aead(struct crypto_async_request *async_req) qce_write(qce, REG_CONFIG, config); /* Start the process */ - qce_crypto_go(qce, !IS_CCM(flags)); - - return 0; + return qce_crypto_go(qce, !IS_CCM(flags)); } #endif diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index 71b748183cfa8..a9db92b741c90 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c @@ -60,6 +60,10 @@ static void qce_ahash_done(void *data) rctx->byte_count[0] = cpu_to_be32(result->auth_byte_count[0]); rctx->byte_count[1] = cpu_to_be32(result->auth_byte_count[1]); + error = qce_bam_unlock(qce); + if (error) + dev_err(qce->dev, "ahash: failed to unlock the BAM\n"); + error = qce_check_status(qce, &status); if (error < 0) dev_dbg(qce->dev, "ahash operation error (%x)\n", status); @@ -90,6 +94,10 @@ static int qce_ahash_async_req_handle(struct crypto_async_request *async_req) rctx->authklen = AES_KEYSIZE_128; } + ret = qce_bam_lock(qce); + if (ret) + return ret; + rctx->src_nents = sg_nents_for_len(req->src, req->nbytes); if (rctx->src_nents < 0) { dev_err(qce->dev, "Invalid numbers of src SG.\n"); diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index ffb334eb5b346..a34a0b14a959b 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c @@ -51,6 +51,9 @@ static void qce_skcipher_done(void *data) dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); sg_free_table(&rctx->dst_tbl); + error = qce_bam_unlock(qce); + if (error) + dev_err(qce->dev, "skcipher: failed to unlock the BAM\n"); error = qce_check_status(qce, &status); if (error < 0) @@ -78,6 +81,10 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req) rctx->ivsize = crypto_skcipher_ivsize(skcipher); rctx->cryptlen = req->cryptlen; + ret = qce_bam_lock(qce); + if (ret) + return ret; + diff_dst = (req->src != req->dst) ? true : false; dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL; From 486a41c9cca3b010d1a93f0a3e968d8e13dd3915 Mon Sep 17 00:00:00 2001 From: Charan Teja Kalla Date: Tue, 9 Dec 2025 10:53:23 +0530 Subject: [PATCH 024/438] FROMGIT: iommu/arm-smmu-qcom: add actlr settings for mdss on Qualcomm platforms Add ACTLR settings for missing MDSS devices on Qualcomm platforms. These are QoS settings and are specific to per SoC thus different settings, eg: some have shallow prefetch while others have no prefetch. Aswell, this prefetch feature is not implemented for all the platforms, capturing to those are implemented to the best of my knowledge. Link: https://lore.kernel.org/all/20251209052323.1133495-1-bibek.patro@oss.qualcomm.com/ Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Charan Teja Kalla Signed-off-by: Bibek Kumar Patro --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 57c097e876130..c6645df97bbce 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -41,12 +41,38 @@ static const struct of_device_id qcom_smmu_actlr_client_of_match[] = { .data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) }, { .compatible = "qcom,fastrpc", .data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) }, + { .compatible = "qcom,qcm2290-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, { .compatible = "qcom,sc7280-mdss", .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, { .compatible = "qcom,sc7280-venus", .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sc8180x-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sc8280xp-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm6115-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm6125-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm6350-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm8150-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm8250-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm8350-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sm8450-mdss", + .data = (const void *) (PREFETCH_DEFAULT | CMTLB) }, { .compatible = "qcom,sm8550-mdss", .data = (const void *) (PREFETCH_DEFAULT | CMTLB) }, + { .compatible = "qcom,sm8650-mdss", + .data = (const void *) (PREFETCH_DEFAULT | CMTLB) }, + { .compatible = "qcom,sm8750-mdss", + .data = (const void *) (PREFETCH_DEFAULT | CMTLB) }, + { .compatible = "qcom,x1e80100-mdss", + .data = (const void *) (PREFETCH_DEFAULT | CMTLB) }, { } }; From 4cff31be02c7cce3434b096cb6cba4c11fc7f3c7 Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Sat, 10 Jan 2026 01:27:51 +0530 Subject: [PATCH 025/438] FROMLIST: iommu/arm-smmu-qcom: Restore ACTLR settings for MDSS on sa8775p The ACTLR configuration for the sa8775p MDSS client was inadvertently dropped while reworking the commit f91879fdf70b ("iommu/arm-smmu-qcom: Add actlr settings for mdss on Qualcomm platforms"). Without this entry, the sa8775p MDSS block does not receive the intended default ACTLR configuration. Restore the missing compatible entry so that the platform receives the expected behavior. Link: https://lore.kernel.org/all/20260120151105.614792-1-bibek.patro@oss.qualcomm.com/ Signed-off-by: Bibek Kumar Patro --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index c6645df97bbce..7f2c30e6f659c 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -43,6 +43,8 @@ static const struct of_device_id qcom_smmu_actlr_client_of_match[] = { .data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) }, { .compatible = "qcom,qcm2290-mdss", .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,sa8775p-mdss", + .data = (const void *) (PREFETCH_DEFAULT | CMTLB) }, { .compatible = "qcom,sc7280-mdss", .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, { .compatible = "qcom,sc7280-venus", From 0251934412a63354a0247b9750e121120dfe68a0 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Tue, 20 Jan 2026 09:30:10 +0000 Subject: [PATCH 026/438] interconnect: qcom: qcs8300: fix the num_links for nsp icc node The qxm_nsp node is configured with an incorrect num_links value, causing remoteproc driver to fail probing because it cannot acquire the interconnect path for qxm_nsp -> ebi. This results in the following error in dmesg: platform 26300000.remoteproc: deferred probe pending: qcom_q6v5_pas: failed to acquire interconnect path Set num_links to 2 to match the two link_nodes, allowing remoteproc clients to obtain the correct path handle and vote on qxm_nsp -> ebi. Fixes: 874be3339c85 ("interconnect: qcom: qcs8300: convert to dynamic IDs") Signed-off-by: Raviteja Laggyshetty Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260120-monaco_num_links_fix_nsp_ebi_path-v3-1-536be21ce3ff@oss.qualcomm.com --- drivers/interconnect/qcom/qcs8300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interconnect/qcom/qcs8300.c b/drivers/interconnect/qcom/qcs8300.c index 70a377bbcf293..bc403a9bf68c6 100644 --- a/drivers/interconnect/qcom/qcs8300.c +++ b/drivers/interconnect/qcom/qcs8300.c @@ -629,7 +629,7 @@ static struct qcom_icc_node qxm_nsp = { .name = "qxm_nsp", .channels = 2, .buswidth = 32, - .num_links = 1, + .num_links = 2, .link_nodes = { &qns_hcp, &qns_nsp_gemnoc }, }; From 2eb377339ad20e90f0a13ac82018c929f17f73c5 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Tue, 27 Jan 2026 03:22:06 +0000 Subject: [PATCH 027/438] dt-bindings: interconnect: document the RPMh Network-On-Chip interconnect in Mahua SoC Document the RPMh Network-on-Chip (NoC) interconnect for the Qualcomm Mahua platform. Mahua is a derivative of the Glymur SoC. Many interconnect nodes are identical and continue to use Glymur fallback compatibles. Mahua introduces SoC-specific configurations and topologies for several NoC blocks, including CNOC, HSCNOC, PCIe West ANoC/Slave NoCs. This updates the existing Glymur yaml schema to include Mahua-specific compatible strings, using two-cell "fallback" compatibles wherever the hardware is identical with Glymur. Co-developed-by: Odelu Kukatla Signed-off-by: Odelu Kukatla Signed-off-by: Raviteja Laggyshetty Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260127-mahua_icc-v2-1-f0d8ddf7afca@oss.qualcomm.com --- .../interconnect/qcom,glymur-rpmh.yaml | 132 +++++++++++++++--- 1 file changed, 109 insertions(+), 23 deletions(-) diff --git a/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml index d55a7bcf5591e..723ae547ae060 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/interconnect/qcom,glymur-rpmh.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm RPMh Network-On-Chip Interconnect on GLYMUR +title: Qualcomm RPMh Network-On-Chip Interconnect on Glymur and Mahua SoCs maintainers: - Raviteja Laggyshetty @@ -21,28 +21,98 @@ description: | properties: compatible: - enum: - - qcom,glymur-aggre1-noc - - qcom,glymur-aggre2-noc - - qcom,glymur-aggre3-noc - - qcom,glymur-aggre4-noc - - qcom,glymur-clk-virt - - qcom,glymur-cnoc-cfg - - qcom,glymur-cnoc-main - - qcom,glymur-hscnoc - - qcom,glymur-lpass-ag-noc - - qcom,glymur-lpass-lpiaon-noc - - qcom,glymur-lpass-lpicx-noc - - qcom,glymur-mc-virt - - qcom,glymur-mmss-noc - - qcom,glymur-nsinoc - - qcom,glymur-nsp-noc - - qcom,glymur-oobm-ss-noc - - qcom,glymur-pcie-east-anoc - - qcom,glymur-pcie-east-slv-noc - - qcom,glymur-pcie-west-anoc - - qcom,glymur-pcie-west-slv-noc - - qcom,glymur-system-noc + oneOf: + - items: + - enum: + - qcom,mahua-clk-virt + - const: qcom,glymur-clk-virt + - items: + - enum: + - qcom,mahua-cnoc-main + - const: qcom,glymur-cnoc-main + - items: + - enum: + - qcom,mahua-system-noc + - const: qcom,glymur-system-noc + - items: + - enum: + - qcom,mahua-pcie-east-anoc + - const: qcom,glymur-pcie-east-anoc + - items: + - enum: + - qcom,mahua-aggre1-noc + - const: qcom,glymur-aggre1-noc + - items: + - enum: + - qcom,mahua-aggre2-noc + - const: qcom,glymur-aggre2-noc + - items: + - enum: + - qcom,mahua-aggre3-noc + - const: qcom,glymur-aggre3-noc + - items: + - enum: + - qcom,mahua-aggre4-noc + - const: qcom,glymur-aggre4-noc + - items: + - enum: + - qcom,mahua-mmss-noc + - const: qcom,glymur-mmss-noc + - items: + - enum: + - qcom,mahua-pcie-east-slv-noc + - const: qcom,glymur-pcie-east-slv-noc + - items: + - enum: + - qcom,mahua-lpass-lpiaon-noc + - const: qcom,glymur-lpass-lpiaon-noc + - items: + - enum: + - qcom,mahua-lpass-lpicx-noc + - const: qcom,glymur-lpass-lpicx-noc + - items: + - enum: + - qcom,mahua-lpass-ag-noc + - const: qcom,glymur-lpass-ag-noc + - items: + - enum: + - qcom,mahua-nsinoc + - const: qcom,glymur-nsinoc + - items: + - enum: + - qcom,mahua-oobm-ss-noc + - const: qcom,glymur-oobm-ss-noc + - items: + - enum: + - qcom,mahua-nsp-noc + - const: qcom,glymur-nsp-noc + - enum: + - qcom,glymur-aggre1-noc + - qcom,glymur-aggre2-noc + - qcom,glymur-aggre3-noc + - qcom,glymur-aggre4-noc + - qcom,glymur-clk-virt + - qcom,glymur-cnoc-cfg + - qcom,glymur-cnoc-main + - qcom,glymur-hscnoc + - qcom,glymur-lpass-ag-noc + - qcom,glymur-lpass-lpiaon-noc + - qcom,glymur-lpass-lpicx-noc + - qcom,glymur-mc-virt + - qcom,glymur-mmss-noc + - qcom,glymur-nsinoc + - qcom,glymur-nsp-noc + - qcom,glymur-oobm-ss-noc + - qcom,glymur-pcie-east-anoc + - qcom,glymur-pcie-east-slv-noc + - qcom,glymur-pcie-west-anoc + - qcom,glymur-pcie-west-slv-noc + - qcom,glymur-system-noc + - qcom,mahua-mc-virt + - qcom,mahua-cnoc-cfg + - qcom,mahua-pcie-west-anoc + - qcom,mahua-pcie-west-slv-noc + - qcom,mahua-hscnoc reg: maxItems: 1 @@ -63,6 +133,7 @@ allOf: enum: - qcom,glymur-clk-virt - qcom,glymur-mc-virt + - qcom,mahua-mc-virt then: properties: reg: false @@ -85,6 +156,20 @@ allOf: - description: aggre PCIE_4 WEST AXI clock - description: aggre PCIE_6 WEST AXI clock + - if: + properties: + compatible: + contains: + enum: + - qcom,mahua-pcie-west-anoc + then: + properties: + clocks: + items: + - description: aggre PCIE_3B WEST AXI clock + - description: aggre PCIE_4 WEST AXI clock + - description: aggre PCIE_6 WEST AXI clock + - if: properties: compatible: @@ -132,6 +217,7 @@ allOf: contains: enum: - qcom,glymur-pcie-west-anoc + - qcom,mahua-pcie-west-anoc - qcom,glymur-pcie-east-anoc - qcom,glymur-aggre2-noc - qcom,glymur-aggre4-noc From e9171e9aefb18c3343ba123d70c676de820b7ac5 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Tue, 27 Jan 2026 03:22:07 +0000 Subject: [PATCH 028/438] interconnect: qcom: glymur: Add Mahua SoC support Mahua is a derivative of the Glymur SoC. Extend the Glymur driver to support Mahua by: 1. Adding new node definitions for interconnects that differ from Glymur (Config NoC, High-Speed Coherent NoC, PCIe West ANOC/Slave NoC). 2. Reusing existing Glymur definitions for identical NoCs. 3. Overriding the channel and buswidth, with Mahua specific values for the differing NoCs Co-developed-by: Odelu Kukatla Signed-off-by: Odelu Kukatla Signed-off-by: Raviteja Laggyshetty Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260127-mahua_icc-v2-2-f0d8ddf7afca@oss.qualcomm.com --- drivers/interconnect/qcom/glymur.c | 38 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/interconnect/qcom/glymur.c b/drivers/interconnect/qcom/glymur.c index e5c07795a6c67..cfe061c1a75a6 100644 --- a/drivers/interconnect/qcom/glymur.c +++ b/drivers/interconnect/qcom/glymur.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "bcm-voter.h" @@ -1985,7 +1986,7 @@ static struct qcom_icc_bcm * const cnoc_cfg_bcms[] = { &bcm_cn1, }; -static struct qcom_icc_node * const cnoc_cfg_nodes[] = { +static struct qcom_icc_node *cnoc_cfg_nodes[] = { [MASTER_CNOC_CFG] = &qsm_cfg, [SLAVE_AHB2PHY_SOUTH] = &qhs_ahb2phy0, [SLAVE_AHB2PHY_NORTH] = &qhs_ahb2phy1, @@ -2093,7 +2094,7 @@ static struct qcom_icc_bcm * const hscnoc_bcms[] = { &bcm_sh1, }; -static struct qcom_icc_node * const hscnoc_nodes[] = { +static struct qcom_icc_node *hscnoc_nodes[] = { [MASTER_GPU_TCU] = &alm_gpu_tcu, [MASTER_PCIE_TCU] = &alm_pcie_qtc, [MASTER_SYS_TCU] = &alm_sys_tcu, @@ -2377,7 +2378,7 @@ static struct qcom_icc_bcm * const pcie_west_anoc_bcms[] = { &bcm_sn6, }; -static struct qcom_icc_node * const pcie_west_anoc_nodes[] = { +static struct qcom_icc_node *pcie_west_anoc_nodes[] = { [MASTER_PCIE_WEST_ANOC_CFG] = &qsm_pcie_west_anoc_cfg, [MASTER_PCIE_2] = &xm_pcie_2, [MASTER_PCIE_3A] = &xm_pcie_3a, @@ -2409,7 +2410,7 @@ static struct qcom_icc_bcm * const pcie_west_slv_noc_bcms[] = { &bcm_sn6, }; -static struct qcom_icc_node * const pcie_west_slv_noc_nodes[] = { +static struct qcom_icc_node *pcie_west_slv_noc_nodes[] = { [MASTER_HSCNOC_PCIE_WEST] = &qnm_hscnoc_pcie_west, [MASTER_CNOC_PCIE_WEST_SLAVE_CFG] = &qsm_cnoc_pcie_west_slave_cfg, [SLAVE_HSCNOC_PCIE_WEST_MS_MPU_CFG] = &qhs_hscnoc_pcie_west_ms_mpu_cfg, @@ -2470,6 +2471,28 @@ static const struct qcom_icc_desc glymur_system_noc = { .num_bcms = ARRAY_SIZE(system_noc_bcms), }; +static int glymur_qnoc_probe(struct platform_device *pdev) +{ + if (device_is_compatible(&pdev->dev, "qcom,mahua-mc-virt")) { + llcc_mc.channels = 8; + ebi.channels = 8; + } else if (device_is_compatible(&pdev->dev, "qcom,mahua-hscnoc")) { + qns_llcc.channels = 8; + chm_apps.channels = 4; + qnm_pcie_west.buswidth = 32; + hscnoc_nodes[MASTER_WLAN_Q6] = NULL; + } else if (device_is_compatible(&pdev->dev, "qcom,mahua-pcie-west-anoc")) { + qns_pcie_west_mem_noc.buswidth = 32; + pcie_west_anoc_nodes[MASTER_PCIE_3A] = NULL; + } else if (device_is_compatible(&pdev->dev, "qcom,mahua-cnoc-cfg")) { + cnoc_cfg_nodes[SLAVE_PCIE_3A_CFG] = NULL; + } else if (device_is_compatible(&pdev->dev, "qcom,mahua-pcie-west-slv-noc")) { + pcie_west_slv_noc_nodes[SLAVE_PCIE_3A] = NULL; + } + + return qcom_icc_rpmh_probe(pdev); +} + static const struct of_device_id qnoc_of_match[] = { { .compatible = "qcom,glymur-aggre1-noc", .data = &glymur_aggre1_noc}, { .compatible = "qcom,glymur-aggre2-noc", .data = &glymur_aggre2_noc}, @@ -2477,12 +2500,15 @@ static const struct of_device_id qnoc_of_match[] = { { .compatible = "qcom,glymur-aggre4-noc", .data = &glymur_aggre4_noc}, { .compatible = "qcom,glymur-clk-virt", .data = &glymur_clk_virt}, { .compatible = "qcom,glymur-cnoc-cfg", .data = &glymur_cnoc_cfg}, + { .compatible = "qcom,mahua-cnoc-cfg", .data = &glymur_cnoc_cfg}, { .compatible = "qcom,glymur-cnoc-main", .data = &glymur_cnoc_main}, { .compatible = "qcom,glymur-hscnoc", .data = &glymur_hscnoc}, + { .compatible = "qcom,mahua-hscnoc", .data = &glymur_hscnoc}, { .compatible = "qcom,glymur-lpass-ag-noc", .data = &glymur_lpass_ag_noc}, { .compatible = "qcom,glymur-lpass-lpiaon-noc", .data = &glymur_lpass_lpiaon_noc}, { .compatible = "qcom,glymur-lpass-lpicx-noc", .data = &glymur_lpass_lpicx_noc}, { .compatible = "qcom,glymur-mc-virt", .data = &glymur_mc_virt}, + { .compatible = "qcom,mahua-mc-virt", .data = &glymur_mc_virt}, { .compatible = "qcom,glymur-mmss-noc", .data = &glymur_mmss_noc}, { .compatible = "qcom,glymur-nsinoc", .data = &glymur_nsinoc}, { .compatible = "qcom,glymur-nsp-noc", .data = &glymur_nsp_noc}, @@ -2490,14 +2516,16 @@ static const struct of_device_id qnoc_of_match[] = { { .compatible = "qcom,glymur-pcie-east-anoc", .data = &glymur_pcie_east_anoc}, { .compatible = "qcom,glymur-pcie-east-slv-noc", .data = &glymur_pcie_east_slv_noc}, { .compatible = "qcom,glymur-pcie-west-anoc", .data = &glymur_pcie_west_anoc}, + { .compatible = "qcom,mahua-pcie-west-anoc", .data = &glymur_pcie_west_anoc}, { .compatible = "qcom,glymur-pcie-west-slv-noc", .data = &glymur_pcie_west_slv_noc}, + { .compatible = "qcom,mahua-pcie-west-slv-noc", .data = &glymur_pcie_west_slv_noc}, { .compatible = "qcom,glymur-system-noc", .data = &glymur_system_noc}, { } }; MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { - .probe = qcom_icc_rpmh_probe, + .probe = glymur_qnoc_probe, .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-glymur", From a5f139ef98c4f13cd27d12c6b8030c334b161325 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Fri, 28 Nov 2025 16:02:40 +0530 Subject: [PATCH 029/438] FROMLIST: remoteproc: qcom: Fix NULL pointer issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a scenario, when fatal interrupt triggers rproc crash handling while a user-space recovery is initiated in parallel. The overlapping recovery/stop sequences race on rproc state and subdevice teardown, resulting in a NULL pointer dereference in the GLINK SMEM unregister path. Process-A Process-B fatal error interrupt happens rproc_crash_handler_work() mutex_lock_interruptible(&rproc->lock); ... rproc->state = RPROC_CRASHED; ... mutex_unlock(&rproc->lock); rproc_trigger_recovery() mutex_lock_interruptible(&rproc->lock); qcom_pas_stop() qcom_q6v5_pas 20c00000.remoteproc: failed to shutdown: -22 remoteproc remoteproc3: can't stop rproc: -22 mutex_unlock(&rproc->lock); echo enabled > /sys/class/remoteproc/remoteprocX/recovery recovery_store() rproc_trigger_recovery() mutex_lock_interruptible(&rproc->lock); rproc_stop() glink_subdev_stop() qcom_glink_smem_unregister() ==| | V Unable to handle kernel NULL pointer dereference at virtual address 0000000000000358 It is tempting to introduce a remoteproc state that could be set from the ->ops->stop() callback, which would have avoided the second attempt and prevented the crash. However, making remoteproc recovery dependent on manual intervention or a system reboot is not ideal. We should always try to recover the remote processor if possible. A failure in the ->ops->stop() callback might be temporary or caused by a timeout, and a recovery attempt could still succeed, as seen in similar scenarios. Therefore, instead of adding a restrictive state, let’s add a NULL check at the appropriate places to avoid a kernel crash and allow the system to move forward gracefully. Link: https://lore.kernel.org/r/20251128103240.1723386-1-mukesh.ojha@oss.qualcomm.com Signed-off-by: Mukesh Ojha Reviewed-by: Bryan O'Donoghue --- drivers/remoteproc/qcom_common.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 8c8688f99f0ab..6480293d2f617 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -209,6 +209,9 @@ static void glink_subdev_stop(struct rproc_subdev *subdev, bool crashed) { struct qcom_rproc_glink *glink = to_glink_subdev(subdev); + if (!glink->edge) + return; + qcom_glink_smem_unregister(glink->edge); glink->edge = NULL; } @@ -320,6 +323,9 @@ static void smd_subdev_stop(struct rproc_subdev *subdev, bool crashed) { struct qcom_rproc_subdev *smd = to_smd_subdev(subdev); + if (!smd->edge) + return; + qcom_smd_unregister_edge(smd->edge); smd->edge = NULL; } From 30c009dbd069a78fcf26f45fd1a491114e84f059 Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Tue, 23 Dec 2025 18:02:21 +0530 Subject: [PATCH 030/438] FROMLIST: remoteproc: qcom: probe all child devices Generalise the qcom,bam-dmux child node support by probing all remoteproc children with of_platform_populate(). This will be used to enable support for devices which are best represented as subnodes of the remoteproc, such as those representing QMI clients. Signed-off-by: Casey Connolly Link: https://lore.kernel.org/r/20251223123227.1317244-3-gaurav.kohli@oss.qualcomm.com --- drivers/remoteproc/qcom_q6v5.c | 4 ++++ drivers/remoteproc/qcom_q6v5_mss.c | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c index 58d5b85e58cda..a02839c7ed8c2 100644 --- a/drivers/remoteproc/qcom_q6v5.c +++ b/drivers/remoteproc/qcom_q6v5.c @@ -6,6 +6,7 @@ * Copyright (C) 2014 Sony Mobile Communications AB * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -351,6 +352,8 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, return dev_err_probe(&pdev->dev, PTR_ERR(q6v5->path), "failed to acquire interconnect path\n"); + of_platform_populate(q6v5->dev->of_node, NULL, NULL, q6v5->dev); + return 0; } EXPORT_SYMBOL_GPL(qcom_q6v5_init); @@ -361,6 +364,7 @@ EXPORT_SYMBOL_GPL(qcom_q6v5_init); */ void qcom_q6v5_deinit(struct qcom_q6v5 *q6v5) { + of_platform_depopulate(q6v5->dev); qmp_put(q6v5->qmp); } EXPORT_SYMBOL_GPL(qcom_q6v5_deinit); diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 91940977ca898..d40565c1cc623 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -238,7 +238,6 @@ struct q6v5 { struct qcom_rproc_pdm pdm_subdev; struct qcom_rproc_ssr ssr_subdev; struct qcom_sysmon *sysmon; - struct platform_device *bam_dmux; bool need_mem_protection; bool has_alt_reset; bool has_mba_logs; @@ -2029,7 +2028,6 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) static int q6v5_probe(struct platform_device *pdev) { const struct rproc_hexagon_res *desc; - struct device_node *node; struct q6v5 *qproc; struct rproc *rproc; const char *mba_image; @@ -2163,10 +2161,6 @@ static int q6v5_probe(struct platform_device *pdev) if (ret) goto remove_sysmon_subdev; - node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux"); - qproc->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev); - of_node_put(node); - return 0; remove_sysmon_subdev: @@ -2186,8 +2180,6 @@ static void q6v5_remove(struct platform_device *pdev) struct q6v5 *qproc = platform_get_drvdata(pdev); struct rproc *rproc = qproc->rproc; - if (qproc->bam_dmux) - of_platform_device_destroy(&qproc->bam_dmux->dev, NULL); rproc_del(rproc); qcom_q6v5_deinit(&qproc->q6v5); From 99f9852f438ea61e7c9558178491495aec83488f Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 25 Sep 2025 00:07:25 +0530 Subject: [PATCH 031/438] FROMLIST: dt-bindings: remoteproc: qcom,sm8550-pas: Document Glymur ADSP Document compatible for Qualcomm Glymur SoC ADSP which is fully compatible with SM8750 ADSP. Also with the Linux Host running on EL2, the remoteprocs need to be hypervisor independent, the iommu property is mandatory to ensure proper functionality. Link: https://lore.kernel.org/linux-arm-msm/20250924183726.509202-1-sibi.sankar@oss.qualcomm.com/T/#mdcb5d79189b598b0ab6f5f5d179b88caa26e050d Signed-off-by: Sibi Sankar Signed-off-by: Pradyot Kumar Nayak --- .../bindings/remoteproc/qcom,sm8550-pas.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index 2dd479cf48217..cba45ce2865e4 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -28,7 +28,9 @@ properties: - qcom,x1e80100-adsp-pas - qcom,x1e80100-cdsp-pas - items: - - const: qcom,sm8750-adsp-pas + - enum: + - qcom,glymur-adsp-pas + - qcom,sm8750-adsp-pas - const: qcom,sm8550-adsp-pas - items: - const: qcom,sm8750-cdsp-pas @@ -95,6 +97,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-adsp-pas - qcom,sm8750-adsp-pas then: properties: @@ -185,6 +188,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-adsp-pas - qcom,sm8550-adsp-pas - qcom,sm8650-adsp-pas - qcom,sm8750-adsp-pas @@ -238,6 +242,16 @@ allOf: - const: cx - const: mxc - const: nsp + - if: + properties: + compatible: + enum: + - qcom,glymur-adsp-pas + then: + properties: + iommus: + minItems: 1 + maxItems: 1 unevaluatedProperties: false From 231dada2290a688100ed1da038fc3b77bec5f5a6 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 25 Sep 2025 00:07:26 +0530 Subject: [PATCH 032/438] FROMLIST: dt-bindings: remoteproc: qcom,sm8550-pas: Document Glymur CDSP Document compatible for Qualcomm Glymur SoC CDSP which is fully compatible with SM8550 CDSP. Also with the Linux Host running on EL2, the remoteprocs need to be hypervisor independent, the iommu property is mandatory to ensure proper functionality. Link:https://lore.kernel.org/linux-arm-msm/20250924183726.509202-1-sibi.sankar@oss.qualcomm.com/T/#mdcb5d79189b598b0ab6f5f5d179b88caa26e050d Signed-off-by: Sibi Sankar Acked-by: Rob Herring (Arm) Signed-off-by: Pradyot Kumar Nayak --- .../devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index cba45ce2865e4..8a15e0c47a78e 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -35,6 +35,9 @@ properties: - items: - const: qcom,sm8750-cdsp-pas - const: qcom,sm8650-cdsp-pas + - items: + - const: qcom,glymur-cdsp-pas + - const: qcom,sm8550-cdsp-pas reg: maxItems: 1 @@ -98,6 +101,7 @@ allOf: contains: enum: - qcom,glymur-adsp-pas + - qcom,glymur-cdsp-pas - qcom,sm8750-adsp-pas then: properties: @@ -227,6 +231,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-cdsp-pas - qcom,sm8550-cdsp-pas - qcom,sm8650-cdsp-pas - qcom,x1e80100-cdsp-pas @@ -247,6 +252,7 @@ allOf: compatible: enum: - qcom,glymur-adsp-pas + - qcom,glymur-cdsp-pas then: properties: iommus: From c3ef00606ff81effb1fd6dc1254771572d74a552 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 24 Sep 2025 16:37:25 -0700 Subject: [PATCH 033/438] FROMLIST: dt-bindings: remoteproc: qcom,pas: Document pas for Kaanapali SoCCP Document the component used to boot SoCCP on Kaanapali SoC. Link:https://lore.kernel.org/linux-arm-msm/20250924-knp-remoteproc-v1-0-611bf7be8329@oss.qualcomm.com/T/#t Signed-off-by: Jingyi Wang Signed-off-by: Pradyot Kumar Nayak --- .../remoteproc/qcom,kaanapali-soccp-pas.yaml | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml new file mode 100644 index 0000000000000..79f678f5f7d95 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml @@ -0,0 +1,174 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/remoteproc/qcom,kaanapali-soccp-pas.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Kaanapali SoCCP Peripheral Authentication Service + +maintainers: + - Jingyi Wang + +description: + The SoC Control Processor (SoCCP) is small RISC-V MCU that controls USB + Type-C, battery charging and various other functions on Qualcomm SoCs, somewhat + analogous to traditional PC Embedded Controllers. This document describes + the Peripheral Authentication Service loads and boots firmware for SoCCP. + +properties: + compatible: + enum: + - qcom,kaanapali-soccp-pas + + reg: + maxItems: 1 + + interrupts: + items: + - description: Watchdog interrupt + - description: Fatal interrupt + - description: Ready interrupt + - description: Handover interrupt + - description: Stop acknowledge interrupt + - description: Pong interrupt + - description: Wake acknowledge interrupt + + interrupt-names: + items: + - const: wdog + - const: fatal + - const: ready + - const: handover + - const: stop-ack + - const: pong + - const: wake-ack + + clocks: + items: + - description: XO clock + + clock-names: + items: + - const: xo + + power-domains: + items: + - description: CX power domain + - description: MX power domain + + power-domain-names: + items: + - const: cx + - const: mx + + firmware-name: + $ref: /schemas/types.yaml#/definitions/string-array + items: + - description: Firmware name of the Hexagon core + - description: Firmware name of the Hexagon Devicetree + + memory-region: + items: + - description: Memory region for main Firmware authentication + - description: Memory region for Devicetree Firmware authentication + + qcom,smem-states: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: States used by the AP to signal the Hexagon core + items: + - description: Stop the remoteproc + - description: wakeup the remoteproc + - description: make remoteproc sleep + - description: ping the remoteproc + + qcom,smem-state-names: + description: The names of the state bits used for SMP2P output + items: + - const: stop + - const: wakeup + - const: sleep + - const: ping + + glink-edge: + $ref: /schemas/remoteproc/qcom,glink-edge.yaml# + unevaluatedProperties: false + description: | + Qualcomm G-Link subnode which represents communication edge, channels + and devices related to the Remoteproc. + +required: + - compatible + - reg + - memory-region + - clocks + - clock-names + - interrupts + - interrupt-names + - qcom,smem-states + - qcom,smem-state-names + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + #include + + remoteproc@d00000 { + compatible = "qcom,kaanapali-soccp-pas"; + reg = <0x00d00000 0x200000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interrupts-extended = <&intc GIC_SPI 167 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 9 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 10 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "pong", + "wake-ack"; + + memory-region = <&soccp_mem>, + <&soccp_dtb_mem_mem>; + + firmware-name = "qcom/kaanapali/soccp.mbn", + "qcom/kaanapali/soccp_dtb.mbn"; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + power-domain-names = "cx", + "mx"; + + qcom,smem-states = <&soccp_smp2p_out 0>, + <&soccp_smp2p_out 10>, + <&soccp_smp2p_out 9>, + <&soccp_smp2p_out 8>; + qcom,smem-state-names = "stop", + "wakeup", + "sleep", + "ping"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "soccp"; + qcom,remote-pid = <19>; + + /* ... */ + }; + }; From a254cad3616ffd0ecfad2c85d6d6abe0c7529603 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 25 Sep 2025 05:50:34 +0530 Subject: [PATCH 034/438] FROMLIST: dt-bindings: remoteproc: qcom,pas: Document SoCCP PAS for Glymur Document compatible for Qualcomm Glymur SoC SoCCP (SoC Control Processor) PAS which is fully compatible with Kaanapali. Link: https://lore.kernel.org/linux-arm-msm/20250925002034.856692-1-sibi.sankar@oss.qualcomm.com/ Signed-off-by: Sibi Sankar Signed-off-by: Pradyot Kumar Nayak --- .../bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml index 79f678f5f7d95..8089e0869ed20 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,kaanapali-soccp-pas.yaml @@ -17,8 +17,13 @@ description: properties: compatible: - enum: - - qcom,kaanapali-soccp-pas + oneOf: + - items: + - enum: + - qcom,glymur-soccp-pas + - const: qcom,kaanapali-soccp-pas + - enum: + - qcom,kaanapali-soccp-pas reg: maxItems: 1 From 24fb0c3dc65045b40f0330953add62528aec482a Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:49 +0530 Subject: [PATCH 035/438] FROMLIST: dt-bindings: remoteproc: qcom,pas: Add iommus property On most Qualcomm platforms, the Qualcomm Hypervisor Execution Environment (QHEE) is either used as a standalone hypervisor or co-exists as a module with the Gunyah hypervisor. When QHEE is present, it configures firmware streams for remote processors. If QHEE is not available, the operating system must perform these configurations instead and for that remote processor firmware stream should be presented to the operating system. To support this, add the iommus property as an optional property for PAS-supported devices. Acked-by: Rob Herring (Arm) Reviewed-by: Bryan O'Donoghue Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-1-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/remoteproc/qcom,pas-common.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml index 63a82e7a8bf88..68c17bf18987c 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml @@ -44,6 +44,9 @@ properties: - const: stop-ack - const: shutdown-ack + iommus: + maxItems: 1 + power-domains: minItems: 1 maxItems: 3 From 298daa780044e03aa33e8f301d67c8dc9707bd8c Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:50 +0530 Subject: [PATCH 036/438] FROMLIST: firmware: qcom_scm: Remove redundant piece of code The qcom_scm_pas_metadata_release() function already frees the allocated memory and sets ctx->ptr to NULL. Resetting ctx->phys and ctx->size to zero is unnecessary because the context is expected to be discarded after release. Lets removes redundant assignments. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-2-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 1a6f85e463e06..6461408c58a3e 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -650,8 +650,6 @@ void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx) dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys); ctx->ptr = NULL; - ctx->phys = 0; - ctx->size = 0; } EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release); From 76df56341e2e2168d1ca94cca209cbd6c86ee361 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:51 +0530 Subject: [PATCH 037/438] FROMLIST: firmware: qcom_scm: Rename peripheral as pas_id Peripheral and pas_id refers to unique id for a subsystem and used only when peripheral authentication service from secure world is utilized. Lets rename peripheral to pas_id to reflect closer to its meaning. Reviewed-by: Bryan O'Donoghue Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-3-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 30 +++++++++++++------------- include/linux/firmware/qcom/qcom_scm.h | 10 ++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 6461408c58a3e..1e1057638e984 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -562,7 +562,7 @@ static void qcom_scm_set_download_mode(u32 dload_mode) * qcom_scm_pas_init_image() - Initialize peripheral authentication service * state machine for a given peripheral, using the * metadata - * @peripheral: peripheral id + * @pas_id: peripheral authentication service id * @metadata: pointer to memory containing ELF header, program header table * and optional blob of data used for authenticating the metadata * and the rest of the firmware @@ -575,7 +575,7 @@ static void qcom_scm_set_download_mode(u32 dload_mode) * track the metadata allocation, this needs to be released by invoking * qcom_scm_pas_metadata_release() by the caller. */ -int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, +int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, struct qcom_scm_pas_metadata *ctx) { dma_addr_t mdata_phys; @@ -585,7 +585,7 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW), - .args[0] = peripheral, + .args[0] = pas_id, .owner = ARM_SMCCC_OWNER_SIP, }; struct qcom_scm_res res; @@ -656,20 +656,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release); /** * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral * for firmware loading - * @peripheral: peripheral id + * @pas_id: peripheral authentication service id * @addr: start address of memory area to prepare * @size: size of the memory area to prepare * * Returns 0 on success. */ -int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) +int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size) { int ret; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, .arginfo = QCOM_SCM_ARGS(3), - .args[0] = peripheral, + .args[0] = pas_id, .args[1] = addr, .args[2] = size, .owner = ARM_SMCCC_OWNER_SIP, @@ -697,18 +697,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup); /** * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware * and reset the remote processor - * @peripheral: peripheral id + * @pas_id: peripheral authentication service id * * Return 0 on success. */ -int qcom_scm_pas_auth_and_reset(u32 peripheral) +int qcom_scm_pas_auth_and_reset(u32 pas_id) { int ret; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, .arginfo = QCOM_SCM_ARGS(1), - .args[0] = peripheral, + .args[0] = pas_id, .owner = ARM_SMCCC_OWNER_SIP, }; struct qcom_scm_res res; @@ -733,18 +733,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset); /** * qcom_scm_pas_shutdown() - Shut down the remote processor - * @peripheral: peripheral id + * @pas_id: peripheral authentication service id * * Returns 0 on success. */ -int qcom_scm_pas_shutdown(u32 peripheral) +int qcom_scm_pas_shutdown(u32 pas_id) { int ret; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, .arginfo = QCOM_SCM_ARGS(1), - .args[0] = peripheral, + .args[0] = pas_id, .owner = ARM_SMCCC_OWNER_SIP, }; struct qcom_scm_res res; @@ -770,18 +770,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown); /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial - * @peripheral: peripheral id + * @pas_id: peripheral authentication service id * * Returns true if PAS is supported for this peripheral, otherwise false. */ -bool qcom_scm_pas_supported(u32 peripheral) +bool qcom_scm_pas_supported(u32 pas_id) { int ret; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, .arginfo = QCOM_SCM_ARGS(1), - .args[0] = peripheral, + .args[0] = pas_id, .owner = ARM_SMCCC_OWNER_SIP, }; struct qcom_scm_res res; diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index a55ca771286bf..a13f703b16cd4 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -72,13 +72,13 @@ struct qcom_scm_pas_metadata { ssize_t size; }; -int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, +int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, struct qcom_scm_pas_metadata *ctx); void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); -int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size); -int qcom_scm_pas_auth_and_reset(u32 peripheral); -int qcom_scm_pas_shutdown(u32 peripheral); -bool qcom_scm_pas_supported(u32 peripheral); +int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size); +int qcom_scm_pas_auth_and_reset(u32 pas_id); +int qcom_scm_pas_shutdown(u32 pas_id); +bool qcom_scm_pas_supported(u32 pas_id); int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); From d3be6b3cbd612277519f4a4f75e8a44bfa632290 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:52 +0530 Subject: [PATCH 038/438] FROMLIST: firmware: qcom_scm: Introduce PAS context allocator helper function When the Peripheral Authentication Service (PAS) method runs on a SoC where Linux operates at EL2 (i.e., without the Gunyah hypervisor), the reset sequences are handled by TrustZone. In such cases, Linux must perform additional steps before invoking PAS SMC calls, such as creating a SHM bridge. Therefore, PAS SMC calls require awareness and handling of these additional steps when Linux runs at EL2. To support this, there is a need for a data structure that can be initialized prior to invoking any SMC or MDT functions. This structure allows those functions to determine whether they are operating in the presence or absence of the Gunyah hypervisor and behave accordingly. Currently, remoteproc and non-remoteproc subsystems use different variants of the MDT loader helper API, primarily due to differences in metadata context handling. Remoteproc subsystems retain the metadata context until authentication and reset are completed, while non-remoteproc subsystems (e.g., video, graphics, IPA, etc.) do not retain the metadata context and can free it within the qcom_scm_pas_init() call by passing a NULL context parameter and due to these differences, it is not possible to extend metadata context handling to support remoteproc and non remoteproc subsystem use PAS operations, when Linux operates at EL2. Add PAS context data structure allocator helper function. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-4-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 34 ++++++++++++++++++++++++++ include/linux/firmware/qcom/qcom_scm.h | 14 +++++++++++ 2 files changed, 48 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 1e1057638e984..5162c02f5f88f 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -558,6 +558,40 @@ static void qcom_scm_set_download_mode(u32 dload_mode) dev_err(__scm->dev, "failed to set download mode: %d\n", ret); } +/** + * devm_qcom_scm_pas_context_alloc() - Allocate peripheral authentication service + * context for a given peripheral + * + * PAS context is device-resource managed, so the caller does not need + * to worry about freeing the context memory. + * + * @dev: PAS firmware device + * @pas_id: peripheral authentication service id + * @mem_phys: Subsystem reserve memory start address + * @mem_size: Subsystem reserve memory size + * + * Returns: The new PAS context, or ERR_PTR() on failure. + */ +struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, + u32 pas_id, + phys_addr_t mem_phys, + size_t mem_size) +{ + struct qcom_scm_pas_context *ctx; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return ERR_PTR(-ENOMEM); + + ctx->dev = dev; + ctx->pas_id = pas_id; + ctx->mem_phys = mem_phys; + ctx->mem_size = mem_size; + + return ctx; +} +EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc); + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service * state machine for a given peripheral, using the diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index a13f703b16cd4..5045f8fe876da 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -72,6 +72,20 @@ struct qcom_scm_pas_metadata { ssize_t size; }; +struct qcom_scm_pas_context { + struct device *dev; + u32 pas_id; + phys_addr_t mem_phys; + size_t mem_size; + void *ptr; + dma_addr_t phys; + ssize_t size; +}; + +struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, + u32 pas_id, + phys_addr_t mem_phys, + size_t mem_size); int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, struct qcom_scm_pas_metadata *ctx); void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); From 685e78d44bdbce12b2ad3dc20297fe5f1e42e5a4 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:53 +0530 Subject: [PATCH 039/438] FROMLIST: remoteproc: pas: Replace metadata context with PAS context structure As a superset of the existing metadata context, the PAS context structure enables both remoteproc and non-remoteproc subsystems to better support scenarios where the SoC runs with or without the Gunyah hypervisor. To reflect this, relevant SCM and metadata functions are updated to incorporate PAS context awareness and remove metadata context data structure completely. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-5-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 8 +++--- drivers/remoteproc/qcom_q6v5_pas.c | 38 ++++++++++++++++++-------- drivers/soc/qcom/mdt_loader.c | 4 +-- include/linux/firmware/qcom/qcom_scm.h | 10 ++----- include/linux/soc/qcom/mdt_loader.h | 6 ++-- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 5162c02f5f88f..4edd475ef8481 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc); * and optional blob of data used for authenticating the metadata * and the rest of the firmware * @size: size of the metadata - * @ctx: optional metadata context + * @ctx: optional pas context * * Return: 0 on success. * @@ -610,7 +610,7 @@ EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc); * qcom_scm_pas_metadata_release() by the caller. */ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, - struct qcom_scm_pas_metadata *ctx) + struct qcom_scm_pas_context *ctx) { dma_addr_t mdata_phys; void *mdata_buf; @@ -674,9 +674,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image); /** * qcom_scm_pas_metadata_release() - release metadata context - * @ctx: metadata context + * @ctx: pas context */ -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx) +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx) { if (!ctx->ptr) return; diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 52680ac995893..bfcb65aed0086 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -117,8 +117,8 @@ struct qcom_pas { struct qcom_rproc_ssr ssr_subdev; struct qcom_sysmon *sysmon; - struct qcom_scm_pas_metadata pas_metadata; - struct qcom_scm_pas_metadata dtb_pas_metadata; + struct qcom_scm_pas_context *pas_ctx; + struct qcom_scm_pas_context *dtb_pas_ctx; }; static void qcom_pas_segment_dump(struct rproc *rproc, @@ -211,9 +211,9 @@ static int qcom_pas_unprepare(struct rproc *rproc) * auth_and_reset() was successful, but in other cases clean it up * here. */ - qcom_scm_pas_metadata_release(&pas->pas_metadata); + qcom_scm_pas_metadata_release(pas->pas_ctx); if (pas->dtb_pas_id) - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); return 0; } @@ -241,7 +241,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, pas->dtb_pas_id, pas->dtb_mem_phys, - &pas->dtb_pas_metadata); + pas->dtb_pas_ctx); if (ret) goto release_dtb_firmware; @@ -255,7 +255,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) return 0; release_dtb_metadata: - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); release_dtb_firmware: release_firmware(pas->dtb_firmware); @@ -306,7 +306,7 @@ static int qcom_pas_start(struct rproc *rproc) } ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, - pas->mem_phys, &pas->pas_metadata); + pas->mem_phys, pas->pas_ctx); if (ret) goto disable_px_supply; @@ -332,9 +332,9 @@ static int qcom_pas_start(struct rproc *rproc) goto release_pas_metadata; } - qcom_scm_pas_metadata_release(&pas->pas_metadata); + qcom_scm_pas_metadata_release(pas->pas_ctx); if (pas->dtb_pas_id) - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); /* firmware is used to pass reference from qcom_pas_start(), drop it now */ pas->firmware = NULL; @@ -342,9 +342,9 @@ static int qcom_pas_start(struct rproc *rproc) return 0; release_pas_metadata: - qcom_scm_pas_metadata_release(&pas->pas_metadata); + qcom_scm_pas_metadata_release(pas->pas_ctx); if (pas->dtb_pas_id) - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); disable_px_supply: if (pas->px_supply) regulator_disable(pas->px_supply); @@ -760,6 +760,22 @@ static int qcom_pas_probe(struct platform_device *pdev) } qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); + + pas->pas_ctx = devm_qcom_scm_pas_context_alloc(pas->dev, pas->pas_id, + pas->mem_phys, pas->mem_size); + if (IS_ERR(pas->pas_ctx)) { + ret = PTR_ERR(pas->pas_ctx); + goto remove_ssr_sysmon; + } + + pas->dtb_pas_ctx = devm_qcom_scm_pas_context_alloc(pas->dev, pas->dtb_pas_id, + pas->dtb_mem_phys, + pas->dtb_mem_size); + if (IS_ERR(pas->dtb_pas_ctx)) { + ret = PTR_ERR(pas->dtb_pas_ctx); + goto remove_ssr_sysmon; + } + ret = rproc_add(rproc); if (ret) goto remove_ssr_sysmon; diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index c239107cb9301..b125140100db7 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -234,13 +234,13 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata); * @fw_name: name of the firmware, for construction of segment file names * @pas_id: PAS identifier * @mem_phys: physical address of allocated memory region - * @ctx: PAS metadata context, to be released by caller + * @ctx: PAS context, ctx->metadata to be released by caller * * Returns 0 on success, negative errno otherwise. */ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, phys_addr_t mem_phys, - struct qcom_scm_pas_metadata *ctx) + struct qcom_scm_pas_context *ctx) { const struct elf32_phdr *phdrs; const struct elf32_phdr *phdr; diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 5045f8fe876da..ad69b51fe6fcc 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -66,12 +66,6 @@ int qcom_scm_set_warm_boot_addr(void *entry); void qcom_scm_cpu_power_down(u32 flags); int qcom_scm_set_remote_state(u32 state, u32 id); -struct qcom_scm_pas_metadata { - void *ptr; - dma_addr_t phys; - ssize_t size; -}; - struct qcom_scm_pas_context { struct device *dev; u32 pas_id; @@ -87,8 +81,8 @@ struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, phys_addr_t mem_phys, size_t mem_size); int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, - struct qcom_scm_pas_metadata *ctx); -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); + struct qcom_scm_pas_context *ctx); +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx); int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size); int qcom_scm_pas_auth_and_reset(u32 pas_id); int qcom_scm_pas_shutdown(u32 pas_id); diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 8ea8230579a20..07c2788418166 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -10,14 +10,14 @@ struct device; struct firmware; -struct qcom_scm_pas_metadata; +struct qcom_scm_pas_context; #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) ssize_t qcom_mdt_get_size(const struct firmware *fw); int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, phys_addr_t mem_phys, - struct qcom_scm_pas_metadata *pas_metadata_ctx); + struct qcom_scm_pas_context *pas_ctx); int qcom_mdt_load(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size, @@ -39,7 +39,7 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw) static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, phys_addr_t mem_phys, - struct qcom_scm_pas_metadata *pas_metadata_ctx) + struct qcom_scm_pas_context *pas_ctx) { return -ENODEV; } From f0753a3fe8d8aeaab0f7e76824619d71ac289bb4 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:54 +0530 Subject: [PATCH 040/438] FROMLIST: soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function Introduce a new PAS context-aware function, qcom_mdt_pas_load(), for remote processor drivers. This function utilizes the PAS context pointer returned from qcom_scm_pas_ctx_init() to perform firmware metadata verification and memory setup via SMC calls. The qcom_mdt_pas_load() and qcom_mdt_load() functions are largely similar, but the former is designed for clients using the PAS context-based data structure. Over time, all users of qcom_mdt_load() can be migrated to use qcom_mdt_pas_load() for consistency and improved abstraction. As the remoteproc PAS driver (qcom_q6v5_pas) has already adopted the PAS context-based approach, update it to use qcom_mdt_pas_load(). Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-6-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 24 +++++----------------- drivers/soc/qcom/mdt_loader.c | 31 +++++++++++++++++++++++++++++ include/linux/soc/qcom/mdt_loader.h | 10 ++++++++++ 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index bfcb65aed0086..f746d2f39a1d8 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -239,15 +239,9 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) return ret; } - ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, - pas->dtb_pas_id, pas->dtb_mem_phys, - pas->dtb_pas_ctx); - if (ret) - goto release_dtb_firmware; - - ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, - pas->dtb_mem_region, pas->dtb_mem_phys, - pas->dtb_mem_size, &pas->dtb_mem_reloc); + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, + pas->dtb_firmware_name, pas->dtb_mem_region, + &pas->dtb_mem_reloc); if (ret) goto release_dtb_metadata; } @@ -256,8 +250,6 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) release_dtb_metadata: qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); - -release_dtb_firmware: release_firmware(pas->dtb_firmware); return ret; @@ -305,14 +297,8 @@ static int qcom_pas_start(struct rproc *rproc) } } - ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, - pas->mem_phys, pas->pas_ctx); - if (ret) - goto disable_px_supply; - - ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, - pas->mem_region, pas->mem_phys, pas->mem_size, - &pas->mem_reloc); + ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware, + pas->mem_region, &pas->mem_reloc); if (ret) goto release_pas_metadata; diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index b125140100db7..50c6a3c6b2a3e 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -478,5 +478,36 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, } EXPORT_SYMBOL_GPL(qcom_mdt_load); +/** + * qcom_mdt_pas_load - Loads and authenticates the metadata of the firmware + * (typically contained in the .mdt file), followed by loading the actual + * firmware segments (e.g., .bXX files). Authentication of the segments done + * by a separate call. + * + * The PAS context must be initialized using qcom_scm_pas_context_init() + * prior to invoking this function. + * + * @ctx: Pointer to the PAS (Peripheral Authentication Service) context + * @fw: Firmware object representing the .mdt file + * @firmware: Name of the firmware used to construct segment file names + * @mem_region: Memory region allocated for loading the firmware + * @reloc_base: Physical address adjusted after relocation + * + * Return: 0 on success or a negative error code on failure. + */ +int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw, + const char *firmware, void *mem_region, phys_addr_t *reloc_base) +{ + int ret; + + ret = qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys, ctx); + if (ret) + return ret; + + return qcom_mdt_load_no_init(ctx->dev, fw, firmware, mem_region, ctx->mem_phys, + ctx->mem_size, reloc_base); +} +EXPORT_SYMBOL_GPL(qcom_mdt_pas_load); + MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 07c2788418166..7d57746fbbfa5 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -23,6 +23,9 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, phys_addr_t mem_phys, size_t mem_size, phys_addr_t *reloc_base); +int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw, + const char *firmware, void *mem_region, phys_addr_t *reloc_base); + int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, const char *fw_name, void *mem_region, phys_addr_t mem_phys, size_t mem_size, @@ -52,6 +55,13 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw, return -ENODEV; } +static inline int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, + const struct firmware *fw, const char *firmware, + void *mem_region, phys_addr_t *reloc_base) +{ + return -ENODEV; +} + static inline int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, const char *fw_name, void *mem_region, From 5a2873ee4c9f326918a1af34c09b3865b9e93899 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:55 +0530 Subject: [PATCH 041/438] FROMLIST: soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols qcom_mdt_pas_init() was previously used only by the remoteproc driver (drivers/remoteproc/qcom_q6v5_pas.c). Since that driver has now transitioned to using PAS context-based qcom_mdt_pas_load() function, making qcom_mdt_pas_init() obsolete for external use. Removes qcom_mdt_pas_init() from the list of exported symbols and make it static to limit its scope to internal use within mdtloader. Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-7-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/mdt_loader.c | 22 +++++----------------- include/linux/soc/qcom/mdt_loader.h | 10 ---------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 50c6a3c6b2a3e..c004d444d6985 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -227,20 +227,9 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, } EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata); -/** - * qcom_mdt_pas_init() - initialize PAS region for firmware loading - * @dev: device handle to associate resources with - * @fw: firmware object for the mdt file - * @fw_name: name of the firmware, for construction of segment file names - * @pas_id: PAS identifier - * @mem_phys: physical address of allocated memory region - * @ctx: PAS context, ctx->metadata to be released by caller - * - * Returns 0 on success, negative errno otherwise. - */ -int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, - const char *fw_name, int pas_id, phys_addr_t mem_phys, - struct qcom_scm_pas_context *ctx) +static int __qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, + const char *fw_name, int pas_id, phys_addr_t mem_phys, + struct qcom_scm_pas_context *ctx) { const struct elf32_phdr *phdrs; const struct elf32_phdr *phdr; @@ -302,7 +291,6 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, out: return ret; } -EXPORT_SYMBOL_GPL(qcom_mdt_pas_init); static bool qcom_mdt_bins_are_split(const struct firmware *fw) { @@ -469,7 +457,7 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, { int ret; - ret = qcom_mdt_pas_init(dev, fw, fw_name, pas_id, mem_phys, NULL); + ret = __qcom_mdt_pas_init(dev, fw, fw_name, pas_id, mem_phys, NULL); if (ret) return ret; @@ -500,7 +488,7 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *f { int ret; - ret = qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys, ctx); + ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys, ctx); if (ret) return ret; diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 7d57746fbbfa5..82372e0db0a18 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -15,9 +15,6 @@ struct qcom_scm_pas_context; #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) ssize_t qcom_mdt_get_size(const struct firmware *fw); -int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, - const char *fw_name, int pas_id, phys_addr_t mem_phys, - struct qcom_scm_pas_context *pas_ctx); int qcom_mdt_load(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size, @@ -40,13 +37,6 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw) return -ENODEV; } -static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, - const char *fw_name, int pas_id, phys_addr_t mem_phys, - struct qcom_scm_pas_context *pas_ctx) -{ - return -ENODEV; -} - static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, void *mem_region, phys_addr_t mem_phys, From e73ef2b0071e6028cb03fce1f01a950e2c6bc8aa Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:56 +0530 Subject: [PATCH 042/438] FROMLIST: firmware: qcom_scm: Add a prep version of auth_and_reset function For memory passed to TrustZone (TZ), it must either be part of a pool registered with TZ or explicitly registered via SHMbridge SMC calls. When Gunyah hypervisor is present, PAS SMC calls from Linux running at EL1 are trapped by Gunyah running @ EL2, which handles SHMbridge creation for both metadata and remoteproc carveout memory before invoking the calls to TZ. On SoCs running with a non-Gunyah-based hypervisor, Linux must take responsibility for creating the SHM bridge before invoking PAS SMC calls. For the auth_and_reset() call, the remoteproc carveout memory must first be registered with TZ via a SHMbridge SMC call and once authentication and reset are complete, the SHMbridge memory can be deregistered. Introduce qcom_scm_pas_prepare_and_auth_reset(), which sets up the SHM bridge over the remoteproc carveout memory when Linux operates at EL2. This behavior is indicated by a new field added to the PAS context data structure. The function then invokes the auth_and_reset SMC call. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-8-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 47 ++++++++++++++++++++++++++ include/linux/firmware/qcom/qcom_scm.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 4edd475ef8481..d3783166fea1b 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -765,6 +765,53 @@ int qcom_scm_pas_auth_and_reset(u32 pas_id) } EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset); +/** + * qcom_scm_pas_prepare_and_auth_reset() - Prepare, authenticate, and reset the + * remote processor + * + * @ctx: Context saved during call to qcom_scm_pas_context_init() + * + * This function performs the necessary steps to prepare a PAS subsystem, + * authenticate it using the provided metadata, and initiate a reset sequence. + * + * It should be used when Linux is in control setting up the IOMMU hardware + * for remote subsystem during secure firmware loading processes. The preparation + * step sets up a shmbridge over the firmware memory before TrustZone accesses the + * firmware memory region for authentication. The authentication step verifies + * the integrity and authenticity of the firmware or configuration using secure + * metadata. Finally, the reset step ensures the subsystem starts in a clean and + * sane state. + * + * Return: 0 on success, negative errno on failure. + */ +int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx) +{ + u64 handle; + int ret; + + /* + * When Linux running @ EL1, Gunyah hypervisor running @ EL2 traps the + * auth_and_reset call and create an shmbridge on the remote subsystem + * memory region and then invokes a call to TrustZone to authenticate. + */ + if (!ctx->use_tzmem) + return qcom_scm_pas_auth_and_reset(ctx->pas_id); + + /* + * When Linux runs @ EL2 Linux must create the shmbridge itself and then + * subsequently call TrustZone for authenticate and reset. + */ + ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle); + if (ret) + return ret; + + ret = qcom_scm_pas_auth_and_reset(ctx->pas_id); + qcom_tzmem_shm_bridge_delete(handle); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset); + /** * qcom_scm_pas_shutdown() - Shut down the remote processor * @pas_id: peripheral authentication service id diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index ad69b51fe6fcc..d6d83888bb75c 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -74,6 +74,7 @@ struct qcom_scm_pas_context { void *ptr; dma_addr_t phys; ssize_t size; + bool use_tzmem; }; struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, @@ -87,6 +88,7 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size); int qcom_scm_pas_auth_and_reset(u32 pas_id); int qcom_scm_pas_shutdown(u32 pas_id); bool qcom_scm_pas_supported(u32 pas_id); +int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx); int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); From 43d4234280bdb1ff3cdc69d45948d022e8f47a0b Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:57 +0530 Subject: [PATCH 043/438] FROMLIST: firmware: qcom_scm: Refactor qcom_scm_pas_init_image() Refactor qcom_scm_pas_init_image() by moving the memory allocation, copy, and free operations to a higher-level function, and isolate the actual SMC call in a separate function. The main intention is to allow flexibility for different allocators and to respect any constraints that the allocator API may impose before invoking the actual SCM function. Reviewed-by: Bryan O'Donoghue Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-9-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 58 ++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index d3783166fea1b..bc3b8dc7d3e48 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -592,6 +592,37 @@ struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, } EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc); +static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys, + struct qcom_scm_res *res) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, + .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW), + .args[0] = pas_id, + .owner = ARM_SMCCC_OWNER_SIP, + }; + int ret; + + ret = qcom_scm_clk_enable(); + if (ret) + return ret; + + ret = qcom_scm_bw_enable(); + if (ret) + goto disable_clk; + + desc.args[1] = mdata_phys; + + ret = qcom_scm_call(__scm->dev, &desc, res); + qcom_scm_bw_disable(); + +disable_clk: + qcom_scm_clk_disable(); + + return ret; +} + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service * state machine for a given peripheral, using the @@ -612,17 +643,10 @@ EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc); int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, struct qcom_scm_pas_context *ctx) { + struct qcom_scm_res res; dma_addr_t mdata_phys; void *mdata_buf; int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, - .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW), - .args[0] = pas_id, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; /* * During the scm call memory protection will be enabled for the meta @@ -643,23 +667,7 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, memcpy(mdata_buf, metadata, size); - ret = qcom_scm_clk_enable(); - if (ret) - goto out; - - ret = qcom_scm_bw_enable(); - if (ret) - goto disable_clk; - - desc.args[1] = mdata_phys; - - ret = qcom_scm_call(__scm->dev, &desc, &res); - qcom_scm_bw_disable(); - -disable_clk: - qcom_scm_clk_disable(); - -out: + ret = __qcom_scm_pas_init_image(pas_id, mdata_phys, &res); if (ret < 0 || !ctx) { dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys); } else if (ctx) { From 30651e72ad721c6cfa1cc8c54f3164dcd63d729d Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:58 +0530 Subject: [PATCH 044/438] FROMLIST: firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE On SoCs running with a non-Gunyah-based hypervisor, Linux must take responsibility for creating the SHM bridge both for metadata (before calling qcom_scm_pas_init_image()) and for remoteproc memory (before calling qcom_scm_pas_auth_and_reset()). We have taken care the things required for qcom_scm_pas_auth_and_reset(). Lets put these awareness of above conditions into qcom_scm_pas_init_image() and qcom_scm_pas_metadata_release(). Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-10-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index bc3b8dc7d3e48..4ce892d8fb251 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -623,6 +623,30 @@ static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys, return ret; } +static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_context *ctx, + const void *metadata, size_t size) +{ + struct qcom_scm_res res; + phys_addr_t mdata_phys; + void *mdata_buf; + int ret; + + mdata_buf = qcom_tzmem_alloc(__scm->mempool, size, GFP_KERNEL); + if (!mdata_buf) + return -ENOMEM; + + memcpy(mdata_buf, metadata, size); + mdata_phys = qcom_tzmem_to_phys(mdata_buf); + + ret = __qcom_scm_pas_init_image(ctx->pas_id, mdata_phys, &res); + if (ret < 0) + qcom_tzmem_free(mdata_buf); + else + ctx->ptr = mdata_buf; + + return ret ? : res.result[0]; +} + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service * state machine for a given peripheral, using the @@ -648,6 +672,9 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, void *mdata_buf; int ret; + if (ctx && ctx->use_tzmem) + return qcom_scm_pas_prep_and_init_image(ctx, metadata, size); + /* * During the scm call memory protection will be enabled for the meta * data blob, so make sure it's physically contiguous, 4K aligned and @@ -689,7 +716,10 @@ void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx) if (!ctx->ptr) return; - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys); + if (ctx->use_tzmem) + qcom_tzmem_free(ctx->ptr); + else + dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys); ctx->ptr = NULL; } From cb58e58b81fa4e1a5015fb81981345131b982b90 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:52:59 +0530 Subject: [PATCH 045/438] FROMLIST: firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Qualcomm remote processor may rely on Static and Dynamic resources for it to be functional. Static resources are fixed like for example, memory-mapped addresses required by the subsystem and dynamic resources, such as shared memory in DDR etc., are determined at runtime during the boot process. For most of the Qualcomm SoCs, when run with Gunyah or older QHEE hypervisor, all the resources whether it is static or dynamic, is managed by the hypervisor. Dynamic resources if it is present for a remote processor will always be coming from secure world via SMC call while static resources may be present in remote processor firmware binary or it may be coming qcom_scm_pas_get_rsc_table() SMC call along with dynamic resources. Some of the remote processor drivers, such as video, GPU, IPA, etc., do not check whether resources are present in their remote processor firmware binary. In such cases, the caller of this function should set input_rt and input_rt_size as NULL and zero respectively. Remoteproc framework has method to check whether firmware binary contain resources or not and they should be pass resource table pointer to input_rt and resource table size to input_rt_size and this will be forwarded to TrustZone for authentication. TrustZone will then append the dynamic resources and return the complete resource table in the passed output buffer. More about documentation on resource table format can be found in include/linux/remoteproc.h Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-11-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 171 +++++++++++++++++++++++++ drivers/firmware/qcom/qcom_scm.h | 1 + include/linux/firmware/qcom/qcom_scm.h | 4 + 3 files changed, 176 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 4ce892d8fb251..918613d5a1516 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -111,6 +112,8 @@ enum qcom_scm_qseecom_tz_cmd_info { QSEECOM_TZ_CMD_INFO_VERSION = 3, }; +#define RSCTABLE_BUFFER_NOT_SUFFICIENT 20 + #define QSEECOM_MAX_APP_NAME_SIZE 64 #define SHMBRIDGE_RESULT_NOTSUPP 4 @@ -766,6 +769,174 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size) } EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup); +static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm, + size_t input_rt_size, + size_t *output_rt_size) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_GET_RSCTABLE, + .arginfo = QCOM_SCM_ARGS(5, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, + QCOM_SCM_RW, QCOM_SCM_VAL), + .args[0] = pas_id, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + void *output_rt_tzm; + int ret; + + output_rt_tzm = qcom_tzmem_alloc(__scm->mempool, *output_rt_size, GFP_KERNEL); + if (!output_rt_tzm) + return ERR_PTR(-ENOMEM); + + desc.args[1] = qcom_tzmem_to_phys(input_rt_tzm); + desc.args[2] = input_rt_size; + desc.args[3] = qcom_tzmem_to_phys(output_rt_tzm); + desc.args[4] = *output_rt_size; + + /* + * Whether SMC fail or pass, res.result[2] will hold actual resource table + * size. + * + * If passed 'output_rt_size' buffer size is not sufficient to hold the + * resource table TrustZone sends, response code in res.result[1] as + * RSCTABLE_BUFFER_NOT_SUFFICIENT so that caller can retry this SMC call + * with output_rt_tzm buffer with res.result[2] size however, It should not + * be of unresonable size. + */ + ret = qcom_scm_call(__scm->dev, &desc, &res); + if (!ret && res.result[2] > SZ_1G) { + ret = -E2BIG; + goto free_output_rt; + } + + *output_rt_size = res.result[2]; + if (ret && res.result[1] == RSCTABLE_BUFFER_NOT_SUFFICIENT) + ret = -EOVERFLOW; + +free_output_rt: + if (ret) + qcom_tzmem_free(output_rt_tzm); + + return ret ? ERR_PTR(ret) : output_rt_tzm; +} + +/** + * qcom_scm_pas_get_rsc_table() - Retrieve the resource table in passed output buffer + * for a given peripheral. + * + * Qualcomm remote processor may rely on both static and dynamic resources for + * its functionality. Static resources typically refer to memory-mapped addresses + * required by the subsystem and are often embedded within the firmware binary + * and dynamic resources, such as shared memory in DDR etc., are determined at + * runtime during the boot process. + * + * On Qualcomm Technologies devices, it's possible that static resources are not + * embedded in the firmware binary and instead are provided by TrustZone However, + * dynamic resources are always expected to come from TrustZone. This indicates + * that for Qualcomm devices, all resources (static and dynamic) will be provided + * by TrustZone via the SMC call. + * + * If the remote processor firmware binary does contain static resources, they + * should be passed in input_rt. These will be forwarded to TrustZone for + * authentication. TrustZone will then append the dynamic resources and return + * the complete resource table in output_rt_tzm. + * + * If the remote processor firmware binary does not include a resource table, + * the caller of this function should set input_rt as NULL and input_rt_size + * as zero respectively. + * + * More about documentation on resource table data structures can be found in + * include/linux/remoteproc.h + * + * @ctx: PAS context + * @pas_id: peripheral authentication service id + * @input_rt: resource table buffer which is present in firmware binary + * @input_rt_size: size of the resource table present in firmware binary + * @output_rt_size: TrustZone expects caller should pass worst case size for + * the output_rt_tzm. + * + * Return: + * On success, returns a pointer to the allocated buffer containing the final + * resource table and output_rt_size will have actual resource table size from + * TrustZone. The caller is responsible for freeing the buffer. On failure, + * returns ERR_PTR(-errno). + */ +struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx, + void *input_rt, + size_t input_rt_size, + size_t *output_rt_size) +{ + struct resource_table empty_rsc = {}; + size_t size = SZ_16K; + void *output_rt_tzm; + void *input_rt_tzm; + void *tbl_ptr; + int ret; + + ret = qcom_scm_clk_enable(); + if (ret) + return ERR_PTR(ret); + + ret = qcom_scm_bw_enable(); + if (ret) + goto disable_clk; + + /* + * TrustZone can not accept buffer as NULL value as argument hence, + * we need to pass a input buffer indicating that subsystem firmware + * does not have resource table by filling resource table structure. + */ + if (!input_rt) { + input_rt = &empty_rsc; + input_rt_size = sizeof(empty_rsc); + } + + input_rt_tzm = qcom_tzmem_alloc(__scm->mempool, input_rt_size, GFP_KERNEL); + if (!input_rt_tzm) { + ret = -ENOMEM; + goto disable_scm_bw; + } + + memcpy(input_rt_tzm, input_rt, input_rt_size); + + output_rt_tzm = __qcom_scm_pas_get_rsc_table(ctx->pas_id, input_rt_tzm, + input_rt_size, &size); + if (PTR_ERR(output_rt_tzm) == -EOVERFLOW) + /* Try again with the size requested by the TZ */ + output_rt_tzm = __qcom_scm_pas_get_rsc_table(ctx->pas_id, + input_rt_tzm, + input_rt_size, + &size); + if (IS_ERR(output_rt_tzm)) { + ret = PTR_ERR(output_rt_tzm); + goto free_input_rt; + } + + tbl_ptr = kzalloc(size, GFP_KERNEL); + if (!tbl_ptr) { + qcom_tzmem_free(output_rt_tzm); + ret = -ENOMEM; + goto free_input_rt; + } + + memcpy(tbl_ptr, output_rt_tzm, size); + *output_rt_size = size; + qcom_tzmem_free(output_rt_tzm); + +free_input_rt: + qcom_tzmem_free(input_rt_tzm); + +disable_scm_bw: + qcom_scm_bw_disable(); + +disable_clk: + qcom_scm_clk_disable(); + + return ret ? ERR_PTR(ret) : tbl_ptr; +} +EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table); + /** * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware * and reset the remote processor diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index a56c8212cc0c4..50d87c628d78b 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -105,6 +105,7 @@ int qcom_scm_shm_bridge_enable(struct device *scm_dev); #define QCOM_SCM_PIL_PAS_SHUTDOWN 0x06 #define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x07 #define QCOM_SCM_PIL_PAS_MSS_RESET 0x0a +#define QCOM_SCM_PIL_PAS_GET_RSCTABLE 0x21 #define QCOM_SCM_SVC_IO 0x05 #define QCOM_SCM_IO_READ 0x01 diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index d6d83888bb75c..5747bd191bf15 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -88,6 +88,10 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size); int qcom_scm_pas_auth_and_reset(u32 pas_id); int qcom_scm_pas_shutdown(u32 pas_id); bool qcom_scm_pas_supported(u32 pas_id); +struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx, + void *input_rt, size_t input_rt_size, + size_t *output_rt_size); + int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx); int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); From 601c75e932da11a1d31d2435d06df5d72583cb0c Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:53:00 +0530 Subject: [PATCH 046/438] FROMLIST: remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call Qualcomm remote processor may rely on static and dynamic resources for it to be functional. For most of the Qualcomm SoCs, when run with Gunyah or older QHEE hypervisor, all the resources whether it is static or dynamic, is managed by the hypervisor. Dynamic resources if it is present for a remote processor will always be coming from secure world via SMC call while static resources may be present in remote processor firmware binary or it may be coming from SMC call along with dynamic resources. Remoteproc already has method like rproc_elf_load_rsc_table() to check firmware binary has resources or not and if it is not having then we pass NULL and zero as input resource table and its size argument respectively to qcom_scm_pas_get_rsc_table() and while it has resource present then it should pass the present resources to Trustzone(TZ) so that it could authenticate the present resources and append dynamic resource to return in output_rt argument along with authenticated resources. Extend parse_fw callback to include SMC call to get resources from Trustzone and to leverage resource table parsing and mapping and unmapping code from the remoteproc framework. Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-12-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 59 +++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index f746d2f39a1d8..e0c7bf94bfc67 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -413,6 +413,61 @@ static void *qcom_pas_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is return pas->mem_region + offset; } +static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *fw) +{ + struct qcom_pas *pas = rproc->priv; + struct resource_table *table = NULL; + size_t output_rt_size; + void *output_rt; + size_t table_sz; + int ret; + + ret = qcom_register_dump_segments(rproc, fw); + if (ret) { + dev_err(pas->dev, "Error in registering dump segments\n"); + return ret; + } + + if (!rproc->has_iommu) + return 0; + + ret = rproc_elf_load_rsc_table(rproc, fw); + if (ret) + dev_dbg(&rproc->dev, "Failed to load resource table from firmware\n"); + + table = rproc->table_ptr; + table_sz = rproc->table_sz; + + /* + * The resources consumed by Qualcomm remote processors fall into two categories: + * static (such as the memory carveouts for the rproc firmware) and dynamic (like + * shared memory pools). Both are managed by a Qualcomm hypervisor (such as QHEE + * or Gunyah), if one is present. Otherwise, a resource table must be retrieved + * via an SCM call. That table will list all dynamic resources (if any) and possibly + * the static ones. The static resources may also come from a resource table embedded + * in the rproc firmware instead. + * + * Here, we call rproc_elf_load_rsc_table() to check firmware binary has resources + * or not and if it is not having then we pass NULL and zero as input resource + * table pointer and size respectively to the argument of qcom_scm_pas_get_rsc_table() + * and this is even true for Qualcomm remote processor who does follow remoteproc + * framework. + */ + output_rt = qcom_scm_pas_get_rsc_table(pas->pas_ctx, table, table_sz, &output_rt_size); + ret = IS_ERR(output_rt) ? PTR_ERR(output_rt) : 0; + if (ret) { + dev_err(pas->dev, "Error in getting resource table: %d\n", ret); + return ret; + } + + kfree(rproc->cached_table); + rproc->cached_table = output_rt; + rproc->table_ptr = rproc->cached_table; + rproc->table_sz = output_rt_size; + + return ret; +} + static unsigned long qcom_pas_panic(struct rproc *rproc) { struct qcom_pas *pas = rproc->priv; @@ -425,7 +480,7 @@ static const struct rproc_ops qcom_pas_ops = { .start = qcom_pas_start, .stop = qcom_pas_stop, .da_to_va = qcom_pas_da_to_va, - .parse_fw = qcom_register_dump_segments, + .parse_fw = qcom_pas_parse_firmware, .load = qcom_pas_load, .panic = qcom_pas_panic, }; @@ -435,7 +490,7 @@ static const struct rproc_ops qcom_pas_minidump_ops = { .start = qcom_pas_start, .stop = qcom_pas_stop, .da_to_va = qcom_pas_da_to_va, - .parse_fw = qcom_register_dump_segments, + .parse_fw = qcom_pas_parse_firmware, .load = qcom_pas_load, .panic = qcom_pas_panic, .coredump = qcom_pas_minidump, From 53b8ced13b8fbbf3e2e4547648cbc647e408b7e0 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 5 Jan 2026 18:53:01 +0530 Subject: [PATCH 047/438] FROMLIST: remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Most Qualcomm platforms feature Gunyah hypervisor, which typically handles IOMMU configuration. This includes mapping memory regions and device memory resources for remote processors by intercepting qcom_scm_pas_auth_and_reset() calls. These mappings are later removed during teardown. Additionally, SHM bridge setup is required to enable memory protection for both remoteproc metadata and its memory regions. When the aforementioned hypervisor is absent, the operating system must perform these configurations instead. When Linux runs as the hypervisor (@ EL2) on a SoC, it will have its own device tree overlay file that specifies the firmware stream ID now managed by Linux for a particular remote processor. If the iommus property is specified in the remoteproc device tree node, it indicates that IOMMU configuration must be handled by Linux. In this case, the has_iommu flag is set for the remote processor, which ensures that the resource table, carveouts, and SHM bridge are properly configured before memory is passed to TrustZone for authentication. Otherwise, the has_iommu flag remains unset, which indicates default behavior. Enables Secure PAS support for remote processors when IOMMU configuration is managed by Linux. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-13-022e96815380@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 48 ++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index e0c7bf94bfc67..46204da046fad 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,22 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) return ret; } +static void qcom_pas_unmap_carveout(struct rproc *rproc, phys_addr_t mem_phys, size_t size) +{ + if (rproc->has_iommu) + iommu_unmap(rproc->domain, mem_phys, size); +} + +static int qcom_pas_map_carveout(struct rproc *rproc, phys_addr_t mem_phys, size_t size) +{ + int ret = 0; + + if (rproc->has_iommu) + ret = iommu_map(rproc->domain, mem_phys, mem_phys, size, + IOMMU_READ | IOMMU_WRITE, GFP_KERNEL); + return ret; +} + static int qcom_pas_start(struct rproc *rproc) { struct qcom_pas *pas = rproc->priv; @@ -289,11 +306,15 @@ static int qcom_pas_start(struct rproc *rproc) } if (pas->dtb_pas_id) { - ret = qcom_scm_pas_auth_and_reset(pas->dtb_pas_id); + ret = qcom_pas_map_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size); + if (ret) + goto disable_px_supply; + + ret = qcom_scm_pas_prepare_and_auth_reset(pas->dtb_pas_ctx); if (ret) { dev_err(pas->dev, "failed to authenticate dtb image and release reset\n"); - goto disable_px_supply; + goto unmap_dtb_carveout; } } @@ -304,18 +325,22 @@ static int qcom_pas_start(struct rproc *rproc) qcom_pil_info_store(pas->info_name, pas->mem_phys, pas->mem_size); - ret = qcom_scm_pas_auth_and_reset(pas->pas_id); + ret = qcom_pas_map_carveout(rproc, pas->mem_phys, pas->mem_size); + if (ret) + goto release_pas_metadata; + + ret = qcom_scm_pas_prepare_and_auth_reset(pas->pas_ctx); if (ret) { dev_err(pas->dev, "failed to authenticate image and release reset\n"); - goto release_pas_metadata; + goto unmap_carveout; } ret = qcom_q6v5_wait_for_start(&pas->q6v5, msecs_to_jiffies(5000)); if (ret == -ETIMEDOUT) { dev_err(pas->dev, "start timed out\n"); qcom_scm_pas_shutdown(pas->pas_id); - goto release_pas_metadata; + goto unmap_carveout; } qcom_scm_pas_metadata_release(pas->pas_ctx); @@ -327,10 +352,16 @@ static int qcom_pas_start(struct rproc *rproc) return 0; +unmap_carveout: + qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size); release_pas_metadata: qcom_scm_pas_metadata_release(pas->pas_ctx); if (pas->dtb_pas_id) qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); + +unmap_dtb_carveout: + if (pas->dtb_pas_id) + qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size); disable_px_supply: if (pas->px_supply) regulator_disable(pas->px_supply); @@ -386,8 +417,12 @@ static int qcom_pas_stop(struct rproc *rproc) ret = qcom_scm_pas_shutdown(pas->dtb_pas_id); if (ret) dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret); + + qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size); } + qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size); + handover = qcom_q6v5_unprepare(&pas->q6v5); if (handover) qcom_pas_handover(&pas->q6v5); @@ -738,6 +773,7 @@ static int qcom_pas_probe(struct platform_device *pdev) return -ENOMEM; } + rproc->has_iommu = of_property_present(pdev->dev.of_node, "iommus"); rproc->auto_boot = desc->auto_boot; rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); @@ -817,6 +853,8 @@ static int qcom_pas_probe(struct platform_device *pdev) goto remove_ssr_sysmon; } + pas->pas_ctx->use_tzmem = rproc->has_iommu; + pas->dtb_pas_ctx->use_tzmem = rproc->has_iommu; ret = rproc_add(rproc); if (ret) goto remove_ssr_sysmon; From c828f10cd2c53b7ff2cc061e73b239973ee17bc6 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 13 Jan 2026 18:41:59 +0200 Subject: [PATCH 048/438] arm64: dts: qcom: agatti: enable FastRPC on the ADSP On Agatti platform the ADSP provides FastRPC support. Add corresponding device node, in order to be able to utilize the DSP offload from the Linux side. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/agatti.dtsi | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi index 8bf5c5583fc22..5756b90e1b3bb 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -2235,6 +2235,47 @@ }; }; }; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + + qcom,non-secure-domain; + + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1c3 0x0>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1c4 0x0>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1c5 0x0>; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x1c6 0x0>; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x1c7 0x0>; + }; + }; }; }; From a6ce790e0668cc6f98549c390017c5d1be5d983d Mon Sep 17 00:00:00 2001 From: Udit Tiwari Date: Thu, 20 Nov 2025 11:54:43 +0530 Subject: [PATCH 049/438] FROMLIST: crypto: qce - Add runtime PM and interconnect bandwidth scaling support The Qualcomm Crypto Engine (QCE) driver currently lacks support for runtime power management (PM) and interconnect bandwidth control. As a result, the hardware remains fully powered and clocks stay enabled even when the device is idle. Additionally, static interconnect bandwidth votes are held indefinitely, preventing the system from reclaiming unused bandwidth. Address this by enabling runtime PM and dynamic interconnect bandwidth scaling to allow the system to suspend the device when idle and scale interconnect usage based on actual demand. Improve overall system efficiency by reducing power usage and optimizing interconnect resource allocation. Make the following changes as part of this integration: - Add support for pm_runtime APIs to manage device power state transitions. - Implement runtime_suspend() and runtime_resume() callbacks to gate clocks and vote for interconnect bandwidth only when needed. - Replace devm_clk_get_optional_enabled() with devm_pm_clk_create() + pm_clk_add() and let the PM core manage device clocks during runtime PM and system sleep. - Register dev_pm_ops with the platform driver to hook into the PM framework. Tested: - Verify that ICC votes drop to zero after probe and upon request completion. - Confirm that runtime PM usage count increments during active requests and decrements afterward. - Observe that the device correctly enters the suspended state when idle. Signed-off-by: Udit Tiwari Link: https://lore.kernel.org/r/20251120062443.2016084-1-quic_utiwari@quicinc.com --- drivers/crypto/qce/core.c | 105 +++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 18 deletions(-) diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index 2667fcd67fee8..391a6bc6e6cbd 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include #include @@ -89,13 +92,17 @@ static int qce_handle_queue(struct qce_device *qce, struct crypto_async_request *async_req, *backlog; int ret = 0, err; + ret = pm_runtime_resume_and_get(qce->dev); + if (ret < 0) + return ret; + scoped_guard(mutex, &qce->lock) { if (req) ret = crypto_enqueue_request(&qce->queue, req); /* busy, do not dequeue request */ if (qce->req) - return ret; + goto qce_suspend; backlog = crypto_get_backlog(&qce->queue); async_req = crypto_dequeue_request(&qce->queue); @@ -104,7 +111,7 @@ static int qce_handle_queue(struct qce_device *qce, } if (!async_req) - return ret; + goto qce_suspend; if (backlog) { scoped_guard(mutex, &qce->lock) @@ -117,6 +124,8 @@ static int qce_handle_queue(struct qce_device *qce, schedule_work(&qce->done_work); } +qce_suspend: + pm_runtime_put_autosuspend(qce->dev); return ret; } @@ -215,37 +224,47 @@ static int qce_crypto_probe(struct platform_device *pdev) if (ret < 0) return ret; - qce->core = devm_clk_get_optional_enabled(qce->dev, "core"); - if (IS_ERR(qce->core)) - return PTR_ERR(qce->core); + /* PM clock helpers: register device clocks */ + ret = devm_pm_clk_create(dev); + if (ret) + return ret; - qce->iface = devm_clk_get_optional_enabled(qce->dev, "iface"); - if (IS_ERR(qce->iface)) - return PTR_ERR(qce->iface); + ret = pm_clk_add(dev, "core"); + if (ret) + return ret; - qce->bus = devm_clk_get_optional_enabled(qce->dev, "bus"); - if (IS_ERR(qce->bus)) - return PTR_ERR(qce->bus); + ret = pm_clk_add(dev, "iface"); + if (ret) + return ret; - qce->mem_path = devm_of_icc_get(qce->dev, "memory"); + ret = pm_clk_add(dev, "bus"); + if (ret) + return ret; + + qce->mem_path = devm_of_icc_get(dev, "memory"); if (IS_ERR(qce->mem_path)) return PTR_ERR(qce->mem_path); - ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH, QCE_DEFAULT_MEM_BANDWIDTH); + /* Enable runtime PM after clocks and ICC are acquired */ + ret = devm_pm_runtime_enable(dev); if (ret) return ret; - ret = devm_qce_dma_request(qce); + ret = pm_runtime_resume_and_get(dev); if (ret) return ret; + ret = devm_qce_dma_request(qce); + if (ret) + goto err_pm; + ret = qce_check_version(qce); if (ret) - return ret; + goto err_pm; ret = devm_mutex_init(qce->dev, &qce->lock); if (ret) - return ret; + goto err_pm; INIT_WORK(&qce->done_work, qce_req_done_work); crypto_init_queue(&qce->queue, QCE_QUEUE_LENGTH); @@ -255,19 +274,68 @@ static int qce_crypto_probe(struct platform_device *pdev) ret = devm_qce_register_algs(qce); if (ret) - return ret; + goto err_pm; qce->dma_size = resource_size(res); qce->base_dma = dma_map_resource(dev, res->start, qce->dma_size, DMA_BIDIRECTIONAL, 0); qce->base_phys = res->start; ret = dma_mapping_error(dev, qce->base_dma); + if (ret) + goto err_pm; + + ret = devm_add_action_or_reset(qce->dev, qce_crypto_unmap_dma, qce); + if (ret) + goto err_pm; + + /* Configure autosuspend after successful init */ + pm_runtime_set_autosuspend_delay(dev, 100); + pm_runtime_use_autosuspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; + +err_pm: + pm_runtime_put(dev); + + return ret; +} + +static int __maybe_unused qce_runtime_suspend(struct device *dev) +{ + struct qce_device *qce = dev_get_drvdata(dev); + + icc_disable(qce->mem_path); + + return 0; +} + +static int __maybe_unused qce_runtime_resume(struct device *dev) +{ + struct qce_device *qce = dev_get_drvdata(dev); + int ret = 0; + + ret = icc_enable(qce->mem_path); if (ret) return ret; - return devm_add_action_or_reset(qce->dev, qce_crypto_unmap_dma, qce); + ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH, QCE_DEFAULT_MEM_BANDWIDTH); + if (ret) + goto err_icc; + + return 0; + +err_icc: + icc_disable(qce->mem_path); + return ret; } +static const struct dev_pm_ops qce_crypto_pm_ops = { + SET_RUNTIME_PM_OPS(qce_runtime_suspend, qce_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) +}; + static const struct of_device_id qce_crypto_of_match[] = { { .compatible = "qcom,crypto-v5.1", }, { .compatible = "qcom,crypto-v5.4", }, @@ -281,6 +349,7 @@ static struct platform_driver qce_crypto_driver = { .driver = { .name = KBUILD_MODNAME, .of_match_table = qce_crypto_of_match, + .pm = &qce_crypto_pm_ops, }, }; module_platform_driver(qce_crypto_driver); From e254daed78f7b24bf852df097b78455ca142666a Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Fri, 23 Jan 2026 15:18:28 +0530 Subject: [PATCH 050/438] FROMLIST: ufs: ufs-qcom: Fix sequential read variance The current devfreq downdifferential threshold of 5% causes overly aggressive frequency downscaling, leading to performance degradation sometimes during sequential read workloads. Update the UFS devfreq downdifferential threshold to 65. This widens the hysteresis window and prevents overly aggressive downscaling, ensuring that frequency is maintained for loads above 5% and scaling down occurs only when utilization falls below this level, while scale-up still triggers above the 70% threshold. Signed-off-by: Nitin Rawat Reviewed-by: Konrad Dybcio Signed-off-by: Pradeep P V K Link: https://lore.kernel.org/all/20260122141331.239354-4-nitin.rawat@oss.qualcomm.com/ --- drivers/ufs/host/ufs-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 8ebee0cc53137..38067a2c24961 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -1957,7 +1957,7 @@ static void ufs_qcom_config_scaling_param(struct ufs_hba *hba, p->polling_ms = 60; p->timer = DEVFREQ_TIMER_DELAYED; d->upthreshold = 70; - d->downdifferential = 5; + d->downdifferential = 65; hba->clk_scaling.suspend_on_no_request = true; } From dd9d4c82f853cc5df6f428df64155d553bb5c913 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 24 Dec 2025 12:35:01 +0200 Subject: [PATCH 051/438] FROMLIST: dt-bindings: phy: sc8280xp-qmp-pcie: Document Glymur PCIe Gen4 2-lanes PHY The fourth and sixth PCIe instances on Glymur are both Gen4 2-lane PHY. So document the compatible. Signed-off-by: Abel Vesa Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251224-phy-qcom-pcie-add-glymur-v3-1-57396145bc22@oss.qualcomm.com --- .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml index f5068df20cfe6..2b3be35ea0e8a 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml @@ -16,6 +16,7 @@ description: properties: compatible: enum: + - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,qcs615-qmp-gen3x1-pcie-phy - qcom,qcs8300-qmp-gen4x2-pcie-phy @@ -178,6 +179,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,qcs8300-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x2-pcie-phy @@ -202,6 +204,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,sm8550-qmp-gen4x2-pcie-phy - qcom,sm8650-qmp-gen4x2-pcie-phy From e14cf42553bf18fce387080d7a54aa6f5be4bde8 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 24 Dec 2025 12:35:02 +0200 Subject: [PATCH 052/438] FROMLIST: phy: qcom: qmp-pcie: Add support for Glymur PCIe Gen4x2 PHY Glymur platform has two Gen4 2-lanes controllers, the fourth and sixth instances. Add support for their PHYs. Signed-off-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251224-phy-qcom-pcie-add-glymur-v3-2-57396145bc22@oss.qualcomm.com --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 86b1b7e2da86a..f65a8b9586c48 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -4441,6 +4441,22 @@ static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = { .phy_status = PHYSTATUS_4_20, }; +static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v8_0, + + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + + .regs = pciephy_v8_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS_4_20, +}; + static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -5192,6 +5208,9 @@ static int qmp_pcie_probe(struct platform_device *pdev) static const struct of_device_id qmp_pcie_of_match_table[] = { { + .compatible = "qcom,glymur-qmp-gen4x2-pcie-phy", + .data = &glymur_qmp_gen4x2_pciephy_cfg, + }, { .compatible = "qcom,glymur-qmp-gen5x4-pcie-phy", .data = &glymur_qmp_gen5x4_pciephy_cfg, }, { From fb9c1632f424ecdcd7fef1205499a1b64d477cdc Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Fri, 23 Jan 2026 17:16:17 +0530 Subject: [PATCH 053/438] FROMLIST: bus: mhi: host: pci_generic: Add Qualcomm SDX35 modem Add support for sdx35 modem. Similar to SDX75, SDX35 can take longer to transition to ready during power up, so use modem_qcom_v2_mhiv_config configurations. 01:00.0 Unassigned class [ff00]: Qualcomm Device 011a Subsystem: Qualcomm Device 011a Link: https://lore.kernel.org/r/20260123-mhi_sdx35-v1-1-79440abf0c92@oss.qualcomm.com Signed-off-by: Krishna Chaitanya Chundru --- drivers/bus/mhi/host/pci_generic.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index e3bc737313a2f..138ab21d9685f 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -423,6 +423,16 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { .sideband_wake = false, }; +static const struct mhi_pci_dev_info mhi_qcom_sdx35_info = { + .name = "qcom-sdx35m", + .config = &modem_qcom_v2_mhiv_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, + .mru_default = 32768, + .sideband_wake = false, + .edl_trigger = true, +}; + static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = { .name = "qcom-sdx24", .edl = "qcom/prog_firehose_sdx24.mbn", @@ -925,6 +935,8 @@ static const struct pci_device_id mhi_pci_id_table[] = { /* Telit FN920C04 (sdx35) */ {PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2020), .driver_data = (kernel_ulong_t) &mhi_telit_fn920c04_info }, + { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x011a), + .driver_data = (kernel_ulong_t) &mhi_qcom_sdx35_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c), From 9f60b8cc6c68252a3048e7a48abd10bdd1ec8cd4 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:45 +0200 Subject: [PATCH 054/438] dt-bindings: drm/bridge: anx7625: describe Type-C connector ANX7625 can be used to mux converted video stream with the USB signals on a Type-C connector. Describe the optional connector subnode, make it exclusive with the AUX bus and port@1 as it is impossible to have both eDP panel and USB-C connector. Signed-off-by: Dmitry Baryshkov Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260121-anx7625-typec-v2-1-d14f31256a17@oss.qualcomm.com --- .../display/bridge/analogix,anx7625.yaml | 98 ++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml index a1ed1004651b9..6ad466952c02d 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -85,6 +85,11 @@ properties: aux-bus: $ref: /schemas/display/dp-aux-bus.yaml# + connector: + type: object + $ref: /schemas/connector/usb-connector.yaml# + unevaluatedProperties: false + ports: $ref: /schemas/graph.yaml#/properties/ports @@ -117,7 +122,6 @@ properties: required: - port@0 - - port@1 required: - compatible @@ -127,6 +131,28 @@ required: - vdd33-supply - ports +allOf: + - if: + required: + - aux-bus + - connector + then: + false + + - if: + required: + - connector + then: + properties: + ports: + properties: + port@1: false + else: + properties: + ports: + required: + - port@1 + additionalProperties: false examples: @@ -185,3 +211,73 @@ examples: }; }; }; + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + encoder@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>; + vdd10-supply = <&pp1000_mipibrdg>; + vdd18-supply = <&pp1800_mipibrdg>; + vdd33-supply = <&pp3300_mipibrdg>; + analogix,audio-enable; + analogix,lane0-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + analogix,lane1-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + + connector { + compatible = "usb-c-connector"; + power-role = "dual"; + data-role = "dual"; + vbus-supply = <&vbus_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + endpoint { + remote-endpoint = <&usb_hs>; + }; + }; + + port@1 { + reg = <1>; + + endpoint { + remote-endpoint = <&usb_ss>; + }; + }; + + port@2 { + reg = <2>; + + endpoint { + remote-endpoint = <&usb_sbu>; + }; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + endpoint { + remote-endpoint = <&mipi_dsi>; + bus-type = <7>; + data-lanes = <0 1 2 3>; + }; + }; + }; + }; + }; From ad8487399a6d97b99f0fb2fe9d0f8c6e577c760c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:46 +0200 Subject: [PATCH 055/438] drm: bridge: anx7625: implement minimal Type-C support ANX7625 can be used as a USB-C controller, handling USB and DP data streams. Provide minimal Type-C support necessary for ANX7625 to register the Type-C port device and properly respond to data / power role events from the Type-C partner. While ANX7625 provides TCPCI interface, using it would circumvent the on-chip running firmware. Analogix recommended using the higher-level interface instead of TCPCI. Reviewed-by: Xin Ji Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260121-anx7625-typec-v2-2-d14f31256a17@oss.qualcomm.com --- drivers/gpu/drm/bridge/analogix/Kconfig | 1 + drivers/gpu/drm/bridge/analogix/anx7625.c | 155 ++++++++++++++++++++-- drivers/gpu/drm/bridge/analogix/anx7625.h | 22 ++- 3 files changed, 168 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig index 4846b2e9be7c2..f3448b0631fea 100644 --- a/drivers/gpu/drm/bridge/analogix/Kconfig +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -34,6 +34,7 @@ config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support" depends on DRM depends on OF + depends on TYPEC || !TYPEC select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 4e49e4f28d552..8dc6e3b169682 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -3,6 +3,7 @@ * Copyright(c) 2020, Analogix Semiconductor. All rights reserved. * */ +#include #include #include #include @@ -15,6 +16,9 @@ #include #include #include +#include +#include +#include #include #include @@ -1325,7 +1329,7 @@ static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) { struct device *dev = ctx->dev; - int ret, val; + int ret; /* Reset main ocm */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@ -1339,6 +1343,11 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n"); else DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n"); +} + +static void anx7625_configure_hpd(struct anx7625_data *ctx) +{ + int val; /* * Make sure the HPD GPIO already be configured after OCM release before @@ -1369,7 +1378,9 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx) if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK) return -ENODEV; - anx7625_disable_pd_protocol(ctx); + if (!ctx->typec_port) + anx7625_disable_pd_protocol(ctx); + anx7625_configure_hpd(ctx); DRM_DEV_DEBUG_DRIVER(dev, "Firmware ver %02x%02x,", anx7625_reg_read(ctx, @@ -1472,6 +1483,107 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret); } +#if IS_REACHABLE(CONFIG_TYPEC) +static void anx7625_typec_set_orientation(struct anx7625_data *ctx) +{ + u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); + + if (val & (CC1_RP | CC1_RD)) + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NORMAL); + else if (val & (CC2_RP | CC2_RD)) + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_REVERSE); + else + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NONE); +} + +static void anx7625_typec_set_status(struct anx7625_data *ctx, + unsigned int intr_status, + unsigned int intr_vector) +{ + if (intr_vector & CC_STATUS) + anx7625_typec_set_orientation(ctx); + if (intr_vector & DATA_ROLE_STATUS) { + enum typec_data_role data_role = (intr_status & DATA_ROLE_STATUS) ? + TYPEC_HOST : TYPEC_DEVICE; + usb_role_switch_set_role(ctx->role_sw, + (intr_status & DATA_ROLE_STATUS) ? + USB_ROLE_HOST : USB_ROLE_DEVICE); + typec_set_data_role(ctx->typec_port, data_role); + ctx->typec_data_role = data_role; + } + if (intr_vector & VBUS_STATUS) + typec_set_pwr_role(ctx->typec_port, + (intr_status & VBUS_STATUS) ? + TYPEC_SOURCE : TYPEC_SINK); + if (intr_vector & VCONN_STATUS) + typec_set_vconn_role(ctx->typec_port, + (intr_status & VCONN_STATUS) ? + TYPEC_SOURCE : TYPEC_SINK); +} + +static int anx7625_typec_register(struct anx7625_data *ctx) +{ + struct typec_capability typec_cap = { }; + struct fwnode_handle *fwnode __free(fwnode_handle) = + device_get_named_child_node(ctx->dev, "connector"); + u32 val; + int ret; + + if (!fwnode) + return 0; + + ret = typec_get_fw_cap(&typec_cap, fwnode); + if (ret < 0) + return ret; + + typec_cap.revision = 0x0120; + typec_cap.pd_revision = 0x0300; + typec_cap.usb_capability = USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3; + typec_cap.orientation_aware = true; + + typec_cap.driver_data = ctx; + + ctx->typec_port = typec_register_port(ctx->dev, &typec_cap); + if (IS_ERR(ctx->typec_port)) + return PTR_ERR(ctx->typec_port); + + ctx->role_sw = fwnode_usb_role_switch_get(fwnode); + if (IS_ERR(ctx->role_sw)) { + typec_unregister_port(ctx->typec_port); + return PTR_ERR(ctx->role_sw); + } + + val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); + + anx7625_typec_set_status(ctx, val, + CC_STATUS | DATA_ROLE_STATUS | + VBUS_STATUS | VCONN_STATUS); + + return 0; +} + +static void anx7625_typec_unregister(struct anx7625_data *ctx) +{ + usb_role_switch_put(ctx->role_sw); + typec_unregister_port(ctx->typec_port); +} +#else +static void anx7625_typec_set_status(struct anx7625_data *ctx, + unsigned int intr_status, + unsigned int intr_vector) +{ +} + +static int anx7625_typec_register(struct anx7625_data *ctx) +{ + return 0; +} + +static void anx7625_typec_unregister(struct anx7625_data *ctx) +{ +} +#endif + static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) { return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); @@ -1566,7 +1678,7 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) } } -static int anx7625_hpd_change_detect(struct anx7625_data *ctx) +static int anx7625_intr_status(struct anx7625_data *ctx) { int intr_vector, status; struct device *dev = ctx->dev; @@ -1593,9 +1705,6 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx) return status; } - if (!(intr_vector & HPD_STATUS_CHANGE)) - return -ENOENT; - status = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); if (status < 0) { @@ -1604,6 +1713,12 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx) } DRM_DEV_DEBUG_DRIVER(dev, "0x7e:0x45=%x\n", status); + + anx7625_typec_set_status(ctx, status, intr_vector); + + if (!(intr_vector & HPD_STATUS)) + return -ENOENT; + dp_hpd_change_handler(ctx, status & HPD_STATUS); return 0; @@ -1622,7 +1737,7 @@ static void anx7625_work_func(struct work_struct *work) return; } - event = anx7625_hpd_change_detect(ctx); + event = anx7625_intr_status(ctx); mutex_unlock(&ctx->lock); @@ -2741,11 +2856,29 @@ static int anx7625_i2c_probe(struct i2c_client *client) } if (!platform->pdata.low_power_mode) { - anx7625_disable_pd_protocol(platform); + struct fwnode_handle *fwnode; + + fwnode = device_get_named_child_node(dev, "connector"); + if (fwnode) + fwnode_handle_put(fwnode); + else + anx7625_disable_pd_protocol(platform); + + anx7625_configure_hpd(platform); + pm_runtime_get_sync(dev); _anx7625_hpd_polling(platform, 5000 * 100); } + if (platform->pdata.intp_irq) + anx7625_reg_write(platform, platform->i2c.rx_p0_client, + INTERFACE_CHANGE_INT_MASK, 0); + + /* After getting runtime handle */ + ret = anx7625_typec_register(platform); + if (ret) + goto pm_suspend; + /* Add work function */ if (platform->pdata.intp_irq) { enable_irq(platform->pdata.intp_irq); @@ -2759,6 +2892,10 @@ static int anx7625_i2c_probe(struct i2c_client *client) return 0; +pm_suspend: + if (!platform->pdata.low_power_mode) + pm_runtime_put_sync_suspend(&client->dev); + free_wq: if (platform->workqueue) destroy_workqueue(platform->workqueue); @@ -2774,6 +2911,8 @@ static void anx7625_i2c_remove(struct i2c_client *client) { struct anx7625_data *platform = i2c_get_clientdata(client); + anx7625_typec_unregister(platform); + drm_bridge_remove(&platform->bridge); if (platform->pdata.intp_irq) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index eb5580f1ab2f8..a18561c213af9 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -51,9 +51,21 @@ #define INTR_RECEIVED_MSG BIT(5) #define SYSTEM_STSTUS 0x45 +#define INTERFACE_CHANGE_INT_MASK 0x43 #define INTERFACE_CHANGE_INT 0x44 -#define HPD_STATUS_CHANGE 0x80 -#define HPD_STATUS 0x80 +#define VCONN_STATUS BIT(2) +#define VBUS_STATUS BIT(3) +#define CC_STATUS BIT(4) +#define DATA_ROLE_STATUS BIT(5) +#define HPD_STATUS BIT(7) + +#define NEW_CC_STATUS 0x46 +#define CC1_RD BIT(0) +#define CC1_RA BIT(1) +#define CC1_RP (BIT(2) | BIT(3)) +#define CC2_RD BIT(4) +#define CC2_RA BIT(5) +#define CC2_RP (BIT(6) | BIT(7)) /******** END of I2C Address 0x58 ********/ @@ -447,9 +459,15 @@ struct anx7625_i2c_client { struct i2c_client *tcpc_client; }; +struct typec_port; +struct usb_role_switch; + struct anx7625_data { struct anx7625_platform_data pdata; struct platform_device *audio_pdev; + struct typec_port *typec_port; + struct usb_role_switch *role_sw; + int typec_data_role; int hpd_status; int hpd_high_cnt; int dp_en; From 3a880a75b0f8d8370b85c053232a59cb69a22803 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:47 +0200 Subject: [PATCH 056/438] drm: bridge: anx7625: implement message sending Swapping the data role requires sending the message to the other USB-C side. Implement sending these messages through the OCM. The code is largely based on the anx7411.c USB-C driver. Signed-off-by: Dmitry Baryshkov Reviewed-by: Xin Ji Link: https://patch.msgid.link/20260121-anx7625-typec-v2-3-d14f31256a17@oss.qualcomm.com --- drivers/gpu/drm/bridge/analogix/anx7625.c | 68 +++++++++++++++++++++++ drivers/gpu/drm/bridge/analogix/anx7625.h | 12 ++++ 2 files changed, 80 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 8dc6e3b169682..c43519097a457 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1484,6 +1484,73 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) } #if IS_REACHABLE(CONFIG_TYPEC) +static u8 anx7625_checksum(u8 *buf, u8 len) +{ + u8 ret = 0; + u8 i; + + for (i = 0; i < len; i++) + ret += buf[i]; + + return ret; +} + +static int anx7625_read_msg_ctrl_status(struct anx7625_data *ctx) +{ + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, CMD_SEND_BUF); +} + +static int anx7625_wait_msg_empty(struct anx7625_data *ctx) +{ + int val; + + return readx_poll_timeout(anx7625_read_msg_ctrl_status, ctx, + val, (val < 0) || (val == 0), + 2000, 2000 * 150); +} + +static int anx7625_send_msg(struct anx7625_data *ctx, u8 type, u8 *buf, u8 size) +{ + struct fw_msg *msg = &ctx->send_msg; + u8 crc; + int ret; + + size = min_t(u8, size, (u8)MAX_BUF_LEN); + memcpy(msg->buf, buf, size); + msg->msg_type = type; + + /* msg len equals buffer length + msg_type */ + msg->msg_len = size + 1; + + crc = anx7625_checksum((u8 *)msg, size + HEADER_LEN); + msg->buf[size] = 0 - crc; + + ret = anx7625_wait_msg_empty(ctx); + if (ret) + return ret; + + ret = anx7625_reg_block_write(ctx, ctx->i2c.rx_p0_client, + CMD_SEND_BUF + 1, size + HEADER_LEN, + &msg->msg_type); + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, CMD_SEND_BUF, + msg->msg_len); + return ret; +} + +static int anx7625_typec_dr_set(struct typec_port *port, enum typec_data_role role) +{ + struct anx7625_data *ctx = typec_get_drvdata(port); + + if (role == ctx->typec_data_role) + return 0; + + return anx7625_send_msg(ctx, 0x11, NULL, 0); +} + +static const struct typec_operations anx7625_typec_ops = { + .dr_set = anx7625_typec_dr_set, +}; + static void anx7625_typec_set_orientation(struct anx7625_data *ctx) { u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); @@ -1542,6 +1609,7 @@ static int anx7625_typec_register(struct anx7625_data *ctx) typec_cap.orientation_aware = true; typec_cap.driver_data = ctx; + typec_cap.ops = &anx7625_typec_ops; ctx->typec_port = typec_register_port(ctx->dev, &typec_cap); if (IS_ERR(ctx->typec_port)) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index a18561c213af9..957d234ec07c8 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -67,6 +67,9 @@ #define CC2_RA BIT(5) #define CC2_RP (BIT(6) | BIT(7)) +#define CMD_SEND_BUF 0xC0 +#define CMD_RECV_BUF 0xE0 + /******** END of I2C Address 0x58 ********/ /***************************************************************/ @@ -462,6 +465,14 @@ struct anx7625_i2c_client { struct typec_port; struct usb_role_switch; +#define MAX_BUF_LEN 30 +struct fw_msg { + u8 msg_len; + u8 msg_type; + u8 buf[MAX_BUF_LEN]; +} __packed; +#define HEADER_LEN 2 + struct anx7625_data { struct anx7625_platform_data pdata; struct platform_device *audio_pdev; @@ -497,6 +508,7 @@ struct anx7625_data { struct drm_connector *connector; struct mipi_dsi_device *dsi; struct drm_dp_aux aux; + struct fw_msg send_msg; }; #endif /* __ANX7625_H__ */ From 8f524e2677432aaaa68ace08361d53bd56cce68b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 11 Feb 2026 11:17:27 +0200 Subject: [PATCH 057/438] drm: bridge: anx7625: correctly detect if PD can be disabled During initial checks the ANX7625 bridge can be powered on before setting up the Type-C port. At this point, when anx7625_ocm_loading_check() checks if it can disable PD or not, it will notice that typec_port is not set and disable PD, breaking orientation and HPD handling. Unify the check between anx7625_ocm_loading_check() anx7625_i2c_probe() and anx7625_typec_register() and check for the presence of the "connector" node. Fixes: 8ad0f7d2e6fd ("drm: bridge: anx7625: implement message sending") Signed-off-by: Dmitry Baryshkov Reviewed-by: Xin Ji Tested-by: Loic Poulain Link: https://patch.msgid.link/20260211-anx7625-fix-pd-v1-1-1dd31451b06f@oss.qualcomm.com --- drivers/gpu/drm/bridge/analogix/anx7625.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index c43519097a457..1157a58cf1b19 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1363,6 +1363,18 @@ static void anx7625_configure_hpd(struct anx7625_data *ctx) anx7625_hpd_timer_config(ctx); } +static bool anx7625_need_pd(struct anx7625_data *ctx) +{ + struct fwnode_handle *fwnode; + + fwnode = device_get_named_child_node(ctx->dev, "connector"); + if (!fwnode) + return false; + + fwnode_handle_put(fwnode); + return true; +} + static int anx7625_ocm_loading_check(struct anx7625_data *ctx) { int ret; @@ -1378,7 +1390,7 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx) if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK) return -ENODEV; - if (!ctx->typec_port) + if (!anx7625_need_pd(ctx)) anx7625_disable_pd_protocol(ctx); anx7625_configure_hpd(ctx); @@ -2924,12 +2936,7 @@ static int anx7625_i2c_probe(struct i2c_client *client) } if (!platform->pdata.low_power_mode) { - struct fwnode_handle *fwnode; - - fwnode = device_get_named_child_node(dev, "connector"); - if (fwnode) - fwnode_handle_put(fwnode); - else + if (!anx7625_need_pd(platform)) anx7625_disable_pd_protocol(platform); anx7625_configure_hpd(platform); From 7d096e7d9cb338218acdcf4acb766685c4b1ed51 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 22 Jan 2026 17:40:40 +0530 Subject: [PATCH 058/438] dt-bindings: display: msm: qcm2290-mdss: Fix iommus property Fix IOMMU DT propety for display via dropping SMMU stream IDs which relates to secure context bank. Assigning Linux kernel (HLOS) VMID to secure context bank stream IDs is incorrect. The maximum value for iommus property is updated accordingly. These DT bindings changes should be backwards compatible. Signed-off-by: Sumit Garg Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260122121042.579270-2-sumit.garg@kernel.org --- .../devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml index f0cdb54226885..2772cdec7e42a 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml @@ -33,7 +33,7 @@ properties: - const: core iommus: - maxItems: 2 + maxItems: 1 interconnects: items: @@ -107,9 +107,7 @@ examples: interconnect-names = "mdp0-mem", "cpu-cfg"; - iommus = <&apps_smmu 0x420 0x2>, - <&apps_smmu 0x421 0x0>; - ranges; + iommus = <&apps_smmu 0x420 0x2>; display-controller@5e01000 { compatible = "qcom,qcm2290-dpu"; From 08ed8fa01042bedccd81f9feb7e8ed228870643c Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 22 Jan 2026 17:40:41 +0530 Subject: [PATCH 059/438] dt-bindings: media: venus: Fix iommus property Fix IOMMU DT propety for venus via dropping SMMU stream IDs which relates to secure context bank. Assigning Linux kernel (HLOS) VMID to secure context bank stream IDs is incorrect. The maximum value for iommus property is updated accordingly. These DT bindings changes should be backwards compatible. Signed-off-by: Sumit Garg Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260122121042.579270-3-sumit.garg@kernel.org --- .../devicetree/bindings/media/qcom,qcm2290-venus.yaml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml b/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml index 3f3ee82fc878b..7e6dc410c2d2b 100644 --- a/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml +++ b/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml @@ -42,7 +42,7 @@ properties: - const: vcodec0_bus iommus: - maxItems: 5 + maxItems: 2 interconnects: maxItems: 2 @@ -102,10 +102,7 @@ examples: memory-region = <&pil_video_mem>; iommus = <&apps_smmu 0x860 0x0>, - <&apps_smmu 0x880 0x0>, - <&apps_smmu 0x861 0x04>, - <&apps_smmu 0x863 0x0>, - <&apps_smmu 0x804 0xe0>; + <&apps_smmu 0x880 0x0>; interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, From 11470ae893020f7b2337e2834f13cdd3bb2cad05 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 22 Jan 2026 17:40:42 +0530 Subject: [PATCH 060/438] arm64: dts: qcom: agatti: Fix IOMMU DT properties Fix IOMMU DT propeties for GPU, display and video peripherals via dropping SMMU stream IDs which relates to secure context bank. This problem only surfaced when the Gunyah based firmware stack is ported on Agatti replacing the legacy QHEE based firmware stack. Assigning Linux kernel (HLOS) VMID to secure context bank stream IDs is treated as a fault by Gunyah hypervisor which were previously ignored by QHEE hypervisor. The DT changes should be backwards compatible with legacy QHEE based firmware stack too. Suggested-by: Prakash Gupta Reviewed-by: Konrad Dybcio Reviewed-by: Akhil P Oommen Reviewed-by: Dmitry Baryshkov Signed-off-by: Sumit Garg Link: https://patch.msgid.link/20260122121042.579270-4-sumit.garg@kernel.org --- arch/arm64/boot/dts/qcom/agatti.dtsi | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi index 76b93b7bd50f9..893cb06890130 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -1669,8 +1669,7 @@ &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>; interconnect-names = "gfx-mem"; - iommus = <&adreno_smmu 0 1>, - <&adreno_smmu 2 0>; + iommus = <&adreno_smmu 0 1>; operating-points-v2 = <&gpu_opp_table>; power-domains = <&rpmpd QCM2290_VDDCX>; qcom,gmu = <&gmu_wrapper>; @@ -1951,8 +1950,7 @@ power-domains = <&dispcc MDSS_GDSC>; - iommus = <&apps_smmu 0x420 0x2>, - <&apps_smmu 0x421 0x0>; + iommus = <&apps_smmu 0x420 0x2>; interconnects = <&mmrt_virt MASTER_MDP0 RPM_ALWAYS_TAG &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG @@ -2436,10 +2434,7 @@ memory-region = <&pil_video_mem>; iommus = <&apps_smmu 0x860 0x0>, - <&apps_smmu 0x880 0x0>, - <&apps_smmu 0x861 0x04>, - <&apps_smmu 0x863 0x0>, - <&apps_smmu 0x804 0xe0>; + <&apps_smmu 0x880 0x0>; interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, From 4660a7bf377a4841cb2397cb9f427e567f278eae Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Mon, 9 Feb 2026 14:24:25 +0000 Subject: [PATCH 061/438] dt-bindings: mfd: qcom,spmi-pmic: add compatibles for pm4124-codec Qualcomm Agatti SoC has PM4125 PMIC, which includes audio codec. Audio codec has TX and RX soundwire slave devices to connect to on-chip soundwire master. Add missing qcom,pm4125-codec compatible to pattern of audio-codec node properties in mfd qcom,spmi-pmic schema to complete the audio codec support. Signed-off-by: Alexey Klimov [Srini: reworked the patch] Signed-off-by: Srinivas Kandagatla Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260209142428.214428-2-srinivas.kandagatla@oss.qualcomm.com --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index e5931d18d9984..f58a85562c268 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -145,7 +145,11 @@ patternProperties: "^audio-codec@[0-9a-f]+$": type: object - $ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml# + oneOf: + - $ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml# + - properties: + compatible: + const: qcom,pm4125-codec "^battery@[0-9a-f]+$": type: object From 33618a1539379dd169f33cf44424a03a7e87694d Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Mon, 9 Feb 2026 14:24:26 +0000 Subject: [PATCH 062/438] arm64: dts: qcom: agatti: add LPASS devices The rxmacro, txmacro, vamacro, soundwire nodes, lpass clock controllers are required to support audio playback and audio capture on sm6115 and its derivatives. Signed-off-by: Alexey Klimov Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260209142428.214428-3-srinivas.kandagatla@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/agatti.dtsi | 189 +++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi index 893cb06890130..00e961482a995 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -758,6 +758,42 @@ drive-strength = <8>; }; }; + + lpass_tx_swr_active: lpass-tx-swr-active-state { + clk-pins { + pins = "gpio0"; + function = "swr_tx_clk"; + drive-strength = <10>; + slew-rate = <3>; + bias-disable; + }; + + data-pins { + pins = "gpio1", "gpio2"; + function = "swr_tx_data"; + drive-strength = <10>; + slew-rate = <3>; + bias-bus-hold; + }; + }; + + lpass_rx_swr_active: lpass-rx-swr-active-state { + clk-pins { + pins = "gpio3"; + function = "swr_rx_clk"; + drive-strength = <10>; + slew-rate = <3>; + bias-disable; + }; + + data-pins { + pins = "gpio4", "gpio5"; + function = "swr_rx_data"; + drive-strength = <10>; + slew-rate = <3>; + bias-bus-hold; + }; + }; }; gcc: clock-controller@1400000 { @@ -2186,6 +2222,159 @@ }; }; + rxmacro: codec@a600000 { + compatible = "qcom,sm6115-lpass-rx-macro"; + reg = <0x0 0xa600000 0x0 0x1000>; + + clocks = <&q6afecc LPASS_CLK_ID_RX_CORE_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_CLK_ID_RX_CORE_NPL_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&vamacro>; + clock-names = "mclk", + "npl", + "dcodec", + "fsgen"; + assigned-clocks = <&q6afecc LPASS_CLK_ID_RX_CORE_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_CLK_ID_RX_CORE_NPL_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + assigned-clock-rates = <22579200>, + <22579200>; + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + }; + + swr1: soundwire@a610000 { + compatible = "qcom,soundwire-v1.6.0"; + reg = <0x0 0x0a610000 0x0 0x2000>; + interrupts = ; + + clocks = <&rxmacro>; + clock-names = "iface"; + + resets = <&lpass_audiocc 0>; + reset-names = "swr_audio_cgcr"; + + label = "RX"; + qcom,din-ports = <0>; + qcom,dout-ports = <5>; + + qcom,ports-sinterval-low = /bits/ 8 <0x03 0x1f 0x1f 0x07 0x00>; + qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x0b 0x01 0x00>; + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x0b 0x00 0x00>; + qcom,ports-hstart = /bits/ 8 <0xff 0x03 0xff 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0x06 0xff 0xff 0xff>; + qcom,ports-word-length = /bits/ 8 <0x01 0x07 0x04 0xff 0xff>; + qcom,ports-block-pack-mode = /bits/ 8 <0xff 0x00 0x01 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0x00>; + qcom,ports-lane-control = /bits/ 8 <0x01 0x00 0x00 0x00 0x00>; + + status = "disabled"; + + #sound-dai-cells = <1>; + #address-cells = <2>; + #size-cells = <0>; + }; + + + txmacro: codec@a620000 { + compatible = "qcom,sm6115-lpass-tx-macro"; + reg = <0x0 0x0a620000 0x0 0x1000>; + + clocks = <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_CLK_ID_TX_CORE_NPL_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&vamacro>; + clock-names = "mclk", + "npl", + "dcodec", + "fsgen"; + assigned-clocks = <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_CLK_ID_TX_CORE_NPL_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + assigned-clock-rates = <19200000>, + <19200000>; + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + }; + + lpass_audiocc: clock-controller@a6a9000 { + compatible = "qcom,sm6115-lpassaudiocc"; + reg = <0x0 0x0a6a9000 0x0 0x1000>; + #reset-cells = <1>; + }; + + vamacro: codec@a730000 { + compatible = "qcom,sm6115-lpass-va-macro"; + reg = <0x0 0x0a730000 0x0 0x1000>; + + clocks = <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_CLK_ID_TX_CORE_NPL_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "mclk", + "dcodec", + "npl"; + assigned-clocks = <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_CLK_ID_TX_CORE_NPL_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + assigned-clock-rates = <19200000>, + <19200000>; + #clock-cells = <0>; + clock-output-names = "fsgen"; + #sound-dai-cells = <1>; + }; + + swr0: soundwire@a740000 { + compatible = "qcom,soundwire-v1.6.0"; + reg = <0x0 0x0a740000 0x0 0x2000>; + interrupts = , + ; + clocks = <&txmacro>; + clock-names = "iface"; + + resets = <&lpasscc 0>; + reset-names = "swr_audio_cgcr"; + + label = "VA_TX"; + qcom,din-ports = <3>; + qcom,dout-ports = <0>; + + qcom,ports-sinterval-low = /bits/ 8 <0x03 0x03 0x03>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x01>; + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x00>; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff>; + qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0x00 0x00 0x00>; + + status = "disabled"; + + #sound-dai-cells = <1>; + #address-cells = <2>; + #size-cells = <0>; + }; + + lpasscc: clock-controller@a7ec000 { + compatible = "qcom,sm6115-lpasscc"; + reg = <0x0 0x0a7ec000 0x0 0x1000>; + #reset-cells = <1>; + }; + remoteproc_adsp: remoteproc@ab00000 { compatible = "qcom,qcm2290-adsp-pas", "qcom,sm6115-adsp-pas"; reg = <0x0 0x0ab00000 0x0 0x100>; From f348d927afe0209dabbf1c85c22e0d03d14e9619 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 9 Feb 2026 14:24:27 +0000 Subject: [PATCH 063/438] arm64: dts: arduino-imola: add support for sound Add support for sound on Arduino UNO Q board, which includes - Headset playback and record. - Lineout Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260209142428.214428-4-srinivas.kandagatla@oss.qualcomm.com --- .../boot/dts/qcom/qrb2210-arduino-imola.dts | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index 197ab6eb1666f..f36f7ff962522 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -109,6 +109,98 @@ leds = <&ledr>, <&ledg>, <&ledb>; }; + sound { + compatible = "qcom,qrb2210-sndcard"; + model = "Arduino-Imola-HPH-LOUT"; + audio-routing = "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2"; + + mm1-dai-link { + link-name = "MultiMedia1"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + link-name = "MultiMedia2"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + mm3-dai-link { + link-name = "MultiMedia3"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + + hph-playback-dai-link { + link-name = "HPH Playback"; + cpu { + sound-dai = <&q6afedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&pmic4125_codec 0>, <&swr1 0>, <&rxmacro 0>; + }; + }; + + lo-playback-dai-link { + link-name = "LO Playback"; + cpu { + sound-dai = <&q6afedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&pmic4125_codec 0>, <&swr1 0>, <&rxmacro 0>; + }; + }; + + ear-playback-dai-link { + link-name = "Ear Playback"; + cpu { + sound-dai = <&q6afedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&pmic4125_codec 0>, <&swr1 0>, <&rxmacro 0>; + }; + }; + + hph-capture-dai-link { + link-name = "HP Capture"; + cpu { + sound-dai = <&q6afedai TX_CODEC_DMA_TX_3>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&pmic4125_codec 1>, <&swr0 0>, <&txmacro 0>; + }; + }; + }; + /* PM4125 charger out, supplied by VBAT */ vph_pwr: regulator-vph-pwr { compatible = "regulator-fixed"; @@ -333,6 +425,51 @@ }; }; +&spmi_bus { + pmic@0 { + pmic4125_codec: audio-codec@f000{ + compatible = "qcom,pm4125-codec"; + reg =<0xf000>; + vdd-io-supply = <&pm4125_l15>; + vdd-cp-supply = <&pm4125_s4>; + vdd-pa-vpos-supply = <&pm4125_s4>; + + vdd-mic-bias-supply = <&pm4125_l22>; + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + + qcom,rx-device = <&pm4125_rx>; + qcom,tx-device = <&pm4125_tx>; + #sound-dai-cells = <1>; + }; + }; +}; + +&swr0 { + pinctrl-0 = <&lpass_tx_swr_active>; + pinctrl-names = "default"; + status = "okay"; + + pm4125_tx: codec@0,3 { + compatible = "sdw20217010c00"; + reg = <0 3>; + qcom,tx-port-mapping = <1 1 2 3>; + }; +}; + +&swr1 { + pinctrl-0 = <&lpass_rx_swr_active>; + pinctrl-names = "default"; + status = "okay"; + + pm4125_rx: codec@0,4 { + compatible = "sdw20217010c00"; + reg = <0 4>; + qcom,rx-port-mapping = <1 2 3 4 5>; + }; +}; + &tlmm { spidev_cs: spidev-cs-state { pins = "gpio17"; From 3b08aab40157ad151840e25c6b2cf514107e1190 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 9 Feb 2026 14:24:28 +0000 Subject: [PATCH 064/438] arm64: defconfig: Enable Agatti audio drivers Enable reset controller and pm4125 audio codec driver that are required to enable audio support on Qualcomm Agatti SoC based platforms. Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260209142428.214428-5-srinivas.kandagatla@oss.qualcomm.com --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index b67d5b1fc45b0..6db35c1605a0e 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1146,6 +1146,7 @@ CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_GTM601=m CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PM4125_SDW=m CONFIG_SND_SOC_PCM3168A_I2C=m CONFIG_SND_SOC_RK3308=m CONFIG_SND_SOC_RK817=m @@ -1550,6 +1551,7 @@ CONFIG_SM_GPUCC_8350=m CONFIG_SM_GPUCC_8450=m CONFIG_SM_GPUCC_8550=m CONFIG_SM_GPUCC_8650=m +CONFIG_SM_LPASSCC_6115=m CONFIG_SM_TCSRCC_8550=y CONFIG_SM_TCSRCC_8650=y CONFIG_SM_TCSRCC_8750=m From a63bb2e1a933ff1bcff3061f2ab0a86141210437 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 13 Feb 2026 19:25:25 +0200 Subject: [PATCH 065/438] arm64: dts: qcom: qrb2210-arduino-imola: describe DSI / DP bridge Aruino Uno-Q uses Analogix ANX7625 DSI-to-DP bridge to convert DSI signals to the connected USB-C DisplayPort dongles. Decribe the chip, USB-C connector and routing of USB and display signals. Co-developed-by: Martino Facchin Signed-off-by: Martino Facchin Tested-by: Loic Poulain Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20260213-uno-q-anx7625-v2-1-c23359616528@oss.qualcomm.com --- .../boot/dts/qcom/qrb2210-arduino-imola.dts | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index f36f7ff962522..2bdb0377231de 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "agatti.dtsi" #include "pm4125.dtsi" @@ -201,6 +202,15 @@ }; }; + vreg_anx_30: regulator-anx-30 { + compatible = "regulator-fixed"; + regulator-name = "anx30"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + }; + /* PM4125 charger out, supplied by VBAT */ vph_pwr: regulator-vph-pwr { compatible = "regulator-fixed"; @@ -234,6 +244,86 @@ clock-frequency = <100000>; status = "okay"; + + anx7625: encoder@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + interrupts-extended = <&tlmm 81 IRQ_TYPE_EDGE_FALLING>; + vdd10-supply = <&pm4125_l11>; + vdd18-supply = <&pm4125_l15>; + vdd33-supply = <&vreg_anx_30>; + analogix,audio-enable; + analogix,lane0-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + analogix,lane1-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + + pinctrl-0 = <&anx7625_int_pin>, <&anx7625_cable_det_pin>; + + connector { + compatible = "usb-c-connector"; + power-role = "sink"; + data-role = "dual"; + try-power-role = "sink"; + + pd-revision = /bits/ 8 <0x03 0x00 0x00 0x00>; + op-sink-microwatt = <15000000>; + sink-pdos = ; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + anx_hs_in: endpoint { + remote-endpoint = <&usb_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + anx_ss_in: endpoint { + remote-endpoint = <&usb_qmpphy_out>; + }; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + anx_dsi0_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + data-lanes = <0 1 2 3>; + }; + }; + }; + }; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&pm4125_l5>; + + status = "okay"; +}; + +&mdss_dsi0_out { + remote-endpoint = <&anx_dsi0_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + status = "okay"; }; &pm4125_vbus { @@ -498,6 +588,22 @@ output-disable; }; + anx7625_cable_det_pin: anx7625-cable-det-pins-state { + pins = "gpio46"; + function = "gpio"; + drive-strength = <16>; + output-disable; + bias-pull-up; + }; + + anx7625_int_pin: anx7625-int-pins-state { + pins = "gpio81"; + function = "gpio"; + drive-strength = <16>; + output-disable; + bias-pull-up; + }; + key_volp_n: key-volp-n-state { pins = "gpio96"; function = "gpio"; @@ -565,6 +671,10 @@ status = "okay"; }; +&usb_dwc3_hs { + remote-endpoint = <&anx_hs_in>; +}; + &usb_hsphy { vdd-supply = <&pm4125_l12>; vdda-pll-supply = <&pm4125_l13>; @@ -580,6 +690,10 @@ status = "okay"; }; +&usb_qmpphy_out { + remote-endpoint = <&anx_ss_in>; +}; + &wifi { vdd-0.8-cx-mx-supply = <&pm4125_l7>; vdd-1.8-xo-supply = <&pm4125_l13>; From 20fd3f5c1c24581ba5d43b76fa38e0ed6beb14fc Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Sun, 15 Feb 2026 03:30:02 +0200 Subject: [PATCH 066/438] drm: bridge: anx7625: don't crash if Type-C port is not used The typec_set_*() functions do not tolerate being passed the NULL typec_port instance. However, if CONFIG_TYPEC is enabled, but anx7625 DT node doesn't have the usb-c connector fwnode, then typec_port remains NULL, crashing the kernel. Prevent calling typec_set_foo() functions by checking that ctx->typec_port is not NULL in anx7625_typec_set_status(). Call trace: typec_set_orientation+0x18/0x68 (P) anx7625_typec_set_status+0x108/0x13c anx7625_work_func+0x124/0x438 process_one_work+0x214/0x648 worker_thread+0x1b4/0x358 kthread+0x14c/0x214 ret_from_fork+0x10/0x20 Code: 910003fd a90153f3 aa0003f3 2a0103f4 (f9431400) Fixes: f81455b2d332 ("drm: bridge: anx7625: implement minimal Type-C support") Reported-by: Salendarsingh Gaud Signed-off-by: Loic Poulain [db: dropped chunk anx7625_typec_unregister(), wrote commit message] Cc: Amit Kucheria Signed-off-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260215-anx-fix-no-typec-v1-1-75172a5ca88b@oss.qualcomm.com --- drivers/gpu/drm/bridge/analogix/anx7625.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 1157a58cf1b19..763519ef0d38b 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1579,6 +1579,9 @@ static void anx7625_typec_set_status(struct anx7625_data *ctx, unsigned int intr_status, unsigned int intr_vector) { + if (!ctx->typec_port) + return; + if (intr_vector & CC_STATUS) anx7625_typec_set_orientation(ctx); if (intr_vector & DATA_ROLE_STATUS) { From 50fc22d04efbe62319935a1e654c4a537b8f235a Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Fri, 13 Feb 2026 11:10:02 +0100 Subject: [PATCH 067/438] arm64: dts: qcom: arduino-imola: fix faulty spidev node CS pin added on pinctrl0 property is causing spidev to return -ENODEV since that GPIO is already part of spi5 pinmuxing. Fixes: 3f745bc0f11f ("arm64: dts: qcom: qrb2210: add dts for Arduino unoq") Signed-off-by: Riccardo Mereu Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20260213101002.105238-1-r.mereu.kernel@arduino.cc --- arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index 2bdb0377231de..5266f89feaaf2 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -507,11 +507,9 @@ &spi5 { status = "okay"; - spidev@0 { - reg = <0>; + mcu@0 { compatible = "arduino,unoq-mcu"; - pinctrl-0 = <&spidev_cs>; - pinctrl-names = "default"; + reg = <0>; }; }; @@ -561,12 +559,6 @@ }; &tlmm { - spidev_cs: spidev-cs-state { - pins = "gpio17"; - function = "gpio"; - drive-strength = <16>; - }; - jmisc_gpio18: jmisc-gpio18-state { pins = "gpio18"; function = "gpio"; From b392691156f531e39b61c7d00d9b4c0ca7067ef1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 19 Feb 2026 14:19:14 +0200 Subject: [PATCH 068/438] drm/msm: add missing MODULE_DEVICE_ID definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The drm/msm module bundles several drivers, each of them having a separate OF match table, however only MDSS (subsystem) and KMS devices had corresponding MODULE_DEVICE_ID tables. Thus, if the platform has enabled only the GPU device (without enabling display counterparts), the module will not be picked up and loaded by userspace. Add MODULE_DEVICE_ID to the GPU driver and to all other drivers in this module. Fixes: 55459968176f ("drm/msm: add a330/apq8x74") Reported-by: Loïc Minier Signed-off-by: Dmitry Baryshkov Reviewed-by: Akhil P Oommen Link: https://patch.msgid.link/20260219-msm-device-id-v1-1-9e7315a6fd20@oss.qualcomm.com --- drivers/gpu/drm/msm/adreno/adreno_device.c | 1 + drivers/gpu/drm/msm/dp/dp_display.c | 1 + drivers/gpu/drm/msm/dsi/dsi.c | 1 + drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 1 + drivers/gpu/drm/msm/hdmi/hdmi.c | 1 + drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 1 + 6 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 554d746f115b2..4edfe80c5be7c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -302,6 +302,7 @@ static const struct of_device_id dt_match[] = { { .compatible = "qcom,kgsl-3d0" }, {} }; +MODULE_DEVICE_TABLE(of, dt_match); static int adreno_runtime_resume(struct device *dev) { diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 476848bf8cd16..d2124d6254855 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -210,6 +210,7 @@ static const struct of_device_id msm_dp_dt_match[] = { { .compatible = "qcom,x1e80100-dp", .data = &msm_dp_desc_x1e80100 }, {} }; +MODULE_DEVICE_TABLE(of, msm_dp_dt_match); static struct msm_dp_display_private *dev_get_dp_display_private(struct device *dev) { diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index d8bb40ef820e2..3c9f01ed62713 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -198,6 +198,7 @@ static const struct of_device_id dt_match[] = { { .compatible = "qcom,dsi-ctrl-6g-qcm2290" }, {} }; +MODULE_DEVICE_TABLE(of, dt_match); static const struct dev_pm_ops dsi_pm_ops = { SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 7937266de1d28..c59375aaae197 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -582,6 +582,7 @@ static const struct of_device_id dsi_phy_dt_match[] = { #endif {} }; +MODULE_DEVICE_TABLE(of, dsi_phy_dt_match); /* * Currently, we only support one SoC for each PHY type. When we have multiple diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 5afac09c0d334..d5ef5089c9e9c 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -441,6 +441,7 @@ static const struct of_device_id msm_hdmi_dt_match[] = { { .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8960_config }, {} }; +MODULE_DEVICE_TABLE(of, msm_hdmi_dt_match); static struct platform_driver msm_hdmi_driver = { .probe = msm_hdmi_dev_probe, diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 667573f1db7c6..f726555bb6810 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -204,6 +204,7 @@ static const struct of_device_id msm_hdmi_phy_dt_match[] = { .data = &msm_hdmi_phy_8998_cfg }, {} }; +MODULE_DEVICE_TABLE(of, msm_hdmi_phy_dt_match); static struct platform_driver msm_hdmi_phy_platform_driver = { .probe = msm_hdmi_phy_probe, From 82a10b995c3d74aefb68d66eb128265113b57b31 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 9 Feb 2026 12:49:11 -0800 Subject: [PATCH 069/438] FROMLIST: dt-bindings: soc: qcom: qcom,pmic-glink: Add Glymur and Kaanapali compatibles Glymur (a recent compute platform) and Kaanapali (a recent mobile platform) have the charger FW running on a new subsystem SOCCP (SOC Control Processor) instead of on ADSP like in previous platforms. Because of this, pmic_glink interface on Glymur and Kaanapali platforms are not compatible with previous platforms. Hence, add new compatible strings for Glymur and Kaanapali. Signed-off-by: Anjelique Melendez Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/all/20260209204915.1983997-2-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml index 7085bf88afaba..ff01d2f3ee5be 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml @@ -23,6 +23,8 @@ properties: oneOf: - items: - enum: + - qcom,glymur-pmic-glink + - qcom,kaanapali-pmic-glink - qcom,qcm6490-pmic-glink - qcom,sc8180x-pmic-glink - qcom,sc8280xp-pmic-glink From 53713ad5375eac7e4676cba0e692309654c28a1b Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 9 Feb 2026 12:49:12 -0800 Subject: [PATCH 070/438] FROMLIST: soc: qcom: pmic_glink: Add charger PDR service information to client data Currently, the charger PD service path and service name are hard coded however these paths are not guaranteed to be the same between SOCs. Define charger PDR service path and service name as client data so that each PMIC generation can properly define these paths. Signed-off-by: Anjelique Melendez Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20260209204915.1983997-3-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/soc/qcom/pmic_glink.c | 58 ++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index 627f96ca322e1..df2fd03d3b334 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -23,13 +23,19 @@ enum { PMIC_GLINK_CLIENT_UCSI, }; +struct pmic_glink_data { + unsigned long client_mask; + const char *charger_pdr_service_name; + const char *charger_pdr_service_path; +}; + struct pmic_glink { struct device *dev; struct pdr_handle *pdr; struct rpmsg_endpoint *ept; - unsigned long client_mask; + const struct pmic_glink_data *data; struct auxiliary_device altmode_aux; struct auxiliary_device ps_aux; @@ -292,7 +298,6 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = { static int pmic_glink_probe(struct platform_device *pdev) { - const unsigned long *match_data; struct pdr_service *service; struct pmic_glink *pg; int ret; @@ -309,12 +314,10 @@ static int pmic_glink_probe(struct platform_device *pdev) spin_lock_init(&pg->client_lock); mutex_init(&pg->state_lock); - match_data = (unsigned long *)of_device_get_match_data(&pdev->dev); - if (!match_data) + pg->data = of_device_get_match_data(&pdev->dev); + if (!pg->data) return -EINVAL; - pg->client_mask = *match_data; - 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), @@ -322,27 +325,30 @@ static int pmic_glink_probe(struct platform_device *pdev) return ret; } - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) { + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) { ret = pmic_glink_add_aux_device(pg, &pg->ucsi_aux, "ucsi"); if (ret) goto out_release_pdr_handle; } - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) { + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) { ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode"); if (ret) goto out_release_ucsi_aux; } - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) { + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) { ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply"); if (ret) goto out_release_altmode_aux; } - 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_aux_devices; + if (pg->data->charger_pdr_service_name && pg->data->charger_pdr_service_path) { + service = pdr_add_lookup(pg->pdr, pg->data->charger_pdr_service_name, + pg->data->charger_pdr_service_path); + if (IS_ERR(service)) { + ret = dev_err_probe(&pdev->dev, PTR_ERR(service), + "failed adding pdr lookup for charger_pd\n"); + goto out_release_aux_devices; + } } mutex_lock(&__pmic_glink_lock); @@ -352,13 +358,13 @@ static int pmic_glink_probe(struct platform_device *pdev) return 0; out_release_aux_devices: - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) pmic_glink_del_aux_device(pg, &pg->ps_aux); out_release_altmode_aux: - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) pmic_glink_del_aux_device(pg, &pg->altmode_aux); out_release_ucsi_aux: - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) pmic_glink_del_aux_device(pg, &pg->ucsi_aux); out_release_pdr_handle: pdr_handle_release(pg->pdr); @@ -372,23 +378,27 @@ static void pmic_glink_remove(struct platform_device *pdev) pdr_handle_release(pg->pdr); - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) pmic_glink_del_aux_device(pg, &pg->ps_aux); - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) pmic_glink_del_aux_device(pg, &pg->altmode_aux); - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) pmic_glink_del_aux_device(pg, &pg->ucsi_aux); guard(mutex)(&__pmic_glink_lock); __pmic_glink = NULL; } -static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | - BIT(PMIC_GLINK_CLIENT_ALTMODE) | - BIT(PMIC_GLINK_CLIENT_UCSI); +static const struct pmic_glink_data pmic_glink_adsp_data = { + .client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | + BIT(PMIC_GLINK_CLIENT_ALTMODE) | + BIT(PMIC_GLINK_CLIENT_UCSI), + .charger_pdr_service_name = "tms/servreg", + .charger_pdr_service_path = "msm/adsp/charger_pd", +}; static const struct of_device_id pmic_glink_of_match[] = { - { .compatible = "qcom,pmic-glink", .data = &pmic_glink_sm8450_client_mask }, + { .compatible = "qcom,pmic-glink", .data = &pmic_glink_adsp_data }, {} }; MODULE_DEVICE_TABLE(of, pmic_glink_of_match); From ce1cfbcde20b6622653aebe5e7e813854c4dee7f Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 9 Feb 2026 12:49:13 -0800 Subject: [PATCH 071/438] FROMLIST: soc: qcom: pmic_glink: Add support for Glymur and Kaanapali On Glymur, a compute platform, and Kaanapali, a mobile platform, charger FW runs on SOCCP (another subsystem). SOCCP does not have any specific charger PDs defined. So, add support for Glymur and Kaanapali compatible strings. Signed-off-by: Anjelique Melendez Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20260209204915.1983997-4-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/soc/qcom/pmic_glink.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index df2fd03d3b334..3042261578aad 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -397,7 +397,15 @@ static const struct pmic_glink_data pmic_glink_adsp_data = { .charger_pdr_service_path = "msm/adsp/charger_pd", }; +static const struct pmic_glink_data pmic_glink_soccp_data = { + .client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | + BIT(PMIC_GLINK_CLIENT_ALTMODE) | + BIT(PMIC_GLINK_CLIENT_UCSI), +}; + static const struct of_device_id pmic_glink_of_match[] = { + { .compatible = "qcom,glymur-pmic-glink", .data = &pmic_glink_soccp_data }, + { .compatible = "qcom,kaanapali-pmic-glink", .data = &pmic_glink_soccp_data }, { .compatible = "qcom,pmic-glink", .data = &pmic_glink_adsp_data }, {} }; From 86ab2854906d5bb3439937de254d3bb296d77be6 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 9 Feb 2026 12:49:14 -0800 Subject: [PATCH 072/438] FROMLIST: usb: typec: ucsi: ucsi_glink: Add support for Glymur and Kaanapali Add Glymur and Kaanapali compatible strings which both need UCSI_DELAY_DEVICE_PDOS quirk. Signed-off-by: Anjelique Melendez Reviewed-by: Dmitry Baryshkov Reviewed-by: Heikki Krogerus Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20260209204915.1983997-5-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/usb/typec/ucsi/ucsi_glink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 11b3e24e34e2b..c7878ea0d37ae 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -373,6 +373,8 @@ static unsigned long quirk_sc8280xp = UCSI_NO_PARTNER_PDOS | UCSI_DELAY_DEVICE_P static unsigned long quirk_sm8450 = UCSI_DELAY_DEVICE_PDOS; static const struct of_device_id pmic_glink_ucsi_of_quirks[] = { + { .compatible = "qcom,glymur-pmic-glink", .data = &quirk_sm8450, }, + { .compatible = "qcom,kaanapali-pmic-glink", .data = &quirk_sm8450, }, { .compatible = "qcom,qcm6490-pmic-glink", .data = &quirk_sc8280xp, }, { .compatible = "qcom,sc8180x-pmic-glink", .data = &quirk_sc8180x, }, { .compatible = "qcom,sc8280xp-pmic-glink", .data = &quirk_sc8280xp, }, From 68b8082e909b7bb6f9b09e6503f83278f89778c0 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 9 Feb 2026 12:49:15 -0800 Subject: [PATCH 073/438] FROMLIST: power: supply: qcom_battmgr: Add support for Glymur and Kaanapali Glymur is a compute platform which has the same power supply properties as X1E80100 and Kaanapali is a mobile platform which has the same power supply properties as SM8550. Add support for the Glymur and Kaanapali compatible strings. Signed-off-by: Anjelique Melendez Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20260209204915.1983997-6-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/power/supply/qcom_battmgr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c index 80572ee945b4f..490137a23d00e 100644 --- a/drivers/power/supply/qcom_battmgr.c +++ b/drivers/power/supply/qcom_battmgr.c @@ -1611,6 +1611,8 @@ static void qcom_battmgr_pdr_notify(void *priv, int state) } static const struct of_device_id qcom_battmgr_of_variants[] = { + { .compatible = "qcom,glymur-pmic-glink", .data = (void *)QCOM_BATTMGR_X1E80100 }, + { .compatible = "qcom,kaanapali-pmic-glink", .data = (void *)QCOM_BATTMGR_SM8550 }, { .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)QCOM_BATTMGR_SC8280XP }, { .compatible = "qcom,sc8280xp-pmic-glink", .data = (void *)QCOM_BATTMGR_SC8280XP }, { .compatible = "qcom,sm8550-pmic-glink", .data = (void *)QCOM_BATTMGR_SM8550 }, From add06e9b04c47fd31ab3e322d24a21cf076c3316 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 9 Feb 2026 16:24:35 +0530 Subject: [PATCH 074/438] FROMLIST: dt-bindings: iio: adc: Split out QCOM VADC channel properties Split out the common channel properties for QCOM VADC devices into a separate file so that it can be included as a reference for devices using them. This will be needed for the upcoming ADC5 Gen3 binding support patch, as ADC5 Gen3 also uses all of these common properties. Reviewed-by: Krzysztof Kozlowski Acked-by: Jonathan Cameron Link: https://lore.kernel.org/all/20260209105438.596339-2-jishnu.prakash@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- .../iio/adc/qcom,spmi-vadc-common.yaml | 84 +++++++++++++++++++ .../bindings/iio/adc/qcom,spmi-vadc.yaml | 76 +---------------- 2 files changed, 86 insertions(+), 74 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml new file mode 100644 index 0000000000000..3ae252c17b91a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-vadc-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SPMI PMIC ADC channels + +maintainers: + - Jishnu Prakash + +description: + This defines the common properties used to define Qualcomm VADC channels. + +properties: + reg: + description: + ADC channel number (PMIC-specific for versions after PMIC5 ADC). + maxItems: 1 + + label: + description: + ADC input of the platform as seen in the schematics. + For thermistor inputs connected to generic AMUX or GPIO inputs + these can vary across platform for the same pins. Hence select + the platform schematics name for this channel. + + qcom,decimation: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + This parameter is used to decrease ADC sampling rate. + Quicker measurements can be made by reducing decimation ratio. + + qcom,pre-scaling: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Used for scaling the channel input signal before the signal is + fed to VADC. The configuration for this node is to know the + pre-determined ratio and use it for post scaling. It is a pair of + integers, denoting the numerator and denominator of the fraction by which + input signal is multiplied. For example, <1 3> indicates the signal is scaled + down to 1/3 of its value before ADC measurement. + If property is not found default value depending on chip will be used. + oneOf: + - items: + - const: 1 + - enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ] + - items: + - const: 10 + - const: 81 + + qcom,ratiometric: + type: boolean + description: | + Channel calibration type. + - For compatible property "qcom,spmi-vadc", if this property is + specified VADC will use the VDD reference (1.8V) and GND for + channel calibration. If property is not found, channel will be + calibrated with 0.625V and 1.25V reference channels, also + known as absolute calibration. + - For other compatible properties, if this property is specified + VADC will use the VDD reference (1.875V) and GND for channel + calibration. If property is not found, channel will be calibrated + with 0V and 1.25V reference channels, also known as absolute calibration. + + qcom,hw-settle-time: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Time between AMUX getting configured and the ADC starting + conversion. The 'hw_settle_time' is an index used from valid values + and programmed in hardware to achieve the hardware settling delay. + + qcom,avg-samples: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Number of samples to be used for measurement. + Averaging provides the option to obtain a single measurement + from the ADC that is an average of multiple samples. The value + selected is 2^(value). + +required: + - reg + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index b9dc04b0d307c..16c80709a3eed 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -56,7 +56,7 @@ required: patternProperties: "^channel@[0-9a-f]+$": type: object - additionalProperties: false + unevaluatedProperties: false description: | Represents the external channels which are connected to the ADC. For compatible property "qcom,spmi-vadc" following channels, also known as @@ -64,79 +64,7 @@ patternProperties: configuration nodes should be defined: VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV, VADC_GND_REF and VADC_VDD_VADC. - - properties: - reg: - maxItems: 1 - description: | - ADC channel number. - See include/dt-bindings/iio/qcom,spmi-vadc.h - For PMIC7 ADC, the channel numbers are specified separately per PMIC - in the PMIC-specific files in include/dt-bindings/iio/. - - label: - description: | - ADC input of the platform as seen in the schematics. - For thermistor inputs connected to generic AMUX or GPIO inputs - these can vary across platform for the same pins. Hence select - the platform schematics name for this channel. - - qcom,decimation: - $ref: /schemas/types.yaml#/definitions/uint32 - description: | - This parameter is used to decrease ADC sampling rate. - Quicker measurements can be made by reducing decimation ratio. - - qcom,pre-scaling: - description: | - Used for scaling the channel input signal before the signal is - fed to VADC. The configuration for this node is to know the - pre-determined ratio and use it for post scaling. It is a pair of - integers, denoting the numerator and denominator of the fraction by which - input signal is multiplied. For example, <1 3> indicates the signal is scaled - down to 1/3 of its value before ADC measurement. - If property is not found default value depending on chip will be used. - $ref: /schemas/types.yaml#/definitions/uint32-array - oneOf: - - items: - - const: 1 - - enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ] - - items: - - const: 10 - - const: 81 - - qcom,ratiometric: - description: | - Channel calibration type. - - For compatible property "qcom,spmi-vadc", if this property is - specified VADC will use the VDD reference (1.8V) and GND for - channel calibration. If property is not found, channel will be - calibrated with 0.625V and 1.25V reference channels, also - known as absolute calibration. - - For compatible property "qcom,spmi-adc5", "qcom,spmi-adc7" and - "qcom,spmi-adc-rev2", if this property is specified VADC will use - the VDD reference (1.875V) and GND for channel calibration. If - property is not found, channel will be calibrated with 0V and 1.25V - reference channels, also known as absolute calibration. - type: boolean - - qcom,hw-settle-time: - $ref: /schemas/types.yaml#/definitions/uint32 - description: | - Time between AMUX getting configured and the ADC starting - conversion. The 'hw_settle_time' is an index used from valid values - and programmed in hardware to achieve the hardware settling delay. - - qcom,avg-samples: - $ref: /schemas/types.yaml#/definitions/uint32 - description: | - Number of samples to be used for measurement. - Averaging provides the option to obtain a single measurement - from the ADC that is an average of multiple samples. The value - selected is 2^(value). - - required: - - reg + $ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml allOf: - if: From 3f98d16ee2196b0eff687661c2d87d9b9a4f8bdd Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 9 Feb 2026 16:24:36 +0530 Subject: [PATCH 075/438] FROMLIST: dt-bindings: iio: adc: Add support for QCOM PMIC5 Gen3 ADC For the PMIC5-Gen3 type PMICs, ADC peripheral is present in HW for the following PMICs: PMK8550, PM8550, PM8550B and PM8550VX PMICs. It is similar to PMIC5-Gen2, with SW communication to ADCs on all PMICs going through PBS(Programmable Boot Sequence) firmware through a single register interface. This interface is implemented on SDAM (Shared Direct Access Memory) peripherals on the master PMIC PMK8550 rather than a dedicated ADC peripheral. Add documentation for PMIC5 Gen3 ADC and update SPMI PMIC bindings to allow ADC5 Gen3 as adc@ subnode. Acked-by: Jonathan Cameron Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/all/20260209105438.596339-3-jishnu.prakash@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- .../bindings/iio/adc/qcom,spmi-adc5-gen3.yaml | 151 ++++++++++++++++++ .../bindings/iio/adc/qcom,spmi-vadc.yaml | 2 + .../bindings/mfd/qcom,spmi-pmic.yaml | 1 + 3 files changed, 154 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml new file mode 100644 index 0000000000000..149f4af8f4b8b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-adc5-gen3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm's SPMI PMIC ADC5 Gen3 + +maintainers: + - Jishnu Prakash + +description: | + SPMI PMIC5 Gen3 voltage ADC (ADC) provides interface to clients to read + voltage. It is a 16-bit sigma-delta ADC. It also performs the same thermal + monitoring function as the existing ADC_TM devices. + + The interface is implemented on SDAM (Shared Direct Access Memory) peripherals + on the master PMIC rather than a dedicated ADC peripheral. The number of PMIC + SDAM peripherals allocated for ADC is not correlated with the PMIC used, it is + programmed in FW (PBS) and is fixed per SOC, based on the SOC requirements. + All boards using a particular (SOC + master PMIC) combination will have the + same number of ADC SDAMs supported on that PMIC. + +properties: + compatible: + const: qcom,spmi-adc5-gen3 + + reg: + items: + - description: SDAM0 base address in the SPMI PMIC register map + - description: SDAM1 base address + minItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + "#io-channel-cells": + const: 1 + + "#thermal-sensor-cells": + const: 1 + + interrupts: + items: + - description: SDAM0 end of conversion (EOC) interrupt + - description: SDAM1 EOC interrupt + minItems: 1 + +patternProperties: + "^channel@[0-9a-f]+$": + type: object + unevaluatedProperties: false + $ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml + description: + Represents the external channels which are connected to the ADC. + + properties: + qcom,decimation: + enum: [ 85, 340, 1360 ] + default: 1360 + + qcom,hw-settle-time: + enum: [ 15, 100, 200, 300, 400, 500, 600, 700, + 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000 ] + default: 15 + + qcom,avg-samples: + enum: [ 1, 2, 4, 8, 16 ] + default: 1 + + qcom,adc-tm: + description: + ADC_TM is a threshold monitoring feature in HW which can be enabled + on any ADC channel, to trigger an IRQ for threshold violation. In + earlier ADC generations, it was implemented in a separate device + (documented in Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml.) + In Gen3, this feature can be enabled in the same ADC device for any + channel and threshold monitoring and IRQ triggering are handled in FW + (PBS) instead of another dedicated HW block. + This property indicates ADC_TM monitoring is done on this channel. + type: boolean + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - "#io-channel-cells" + - interrupts + +additionalProperties: false + +examples: + - | + #include + + pmic { + #address-cells = <1>; + #size-cells = <0>; + + adc@9000 { + compatible = "qcom,spmi-adc5-gen3"; + reg = <0x9000>, <0x9100>; + interrupts = <0x0 0x90 0x1 IRQ_TYPE_EDGE_RISING>, + <0x0 0x91 0x1 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + #thermal-sensor-cells = <1>; + + /* PMK8550 Channel nodes */ + channel@3 { + reg = <0x3>; + label = "pmk8550_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@44 { + reg = <0x44>; + label = "pmk8550_xo_therm"; + qcom,pre-scaling = <1 1>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,adc-tm; + }; + + /* PM8550 Channel nodes */ + channel@103 { + reg = <0x103>; + label = "pm8550_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + /* PM8550B Channel nodes */ + channel@78f { + reg = <0x78f>; + label = "pm8550b_vbat_sns_qbg"; + qcom,pre-scaling = <1 3>; + }; + + /* PM8550VS_C Channel nodes */ + channel@203 { + reg = <0x203>; + label = "pm8550vs_c_die_temp"; + qcom,pre-scaling = <1 1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index 16c80709a3eed..72188041e8b53 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -15,6 +15,8 @@ description: | voltage. The VADC is a 15-bit sigma-delta ADC. SPMI PMIC5/PMIC7 voltage ADC (ADC) provides interface to clients to read voltage. The VADC is a 16-bit sigma-delta ADC. + Note that PMIC7 ADC is the generation between PMIC5 and PMIC5 Gen3 ADC, + it can be considered like PMIC5 Gen2. properties: compatible: diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index e5931d18d9984..644c42b5e2e57 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -135,6 +135,7 @@ patternProperties: "^adc@[0-9a-f]+$": type: object oneOf: + - $ref: /schemas/iio/adc/qcom,spmi-adc5-gen3.yaml# - $ref: /schemas/iio/adc/qcom,spmi-iadc.yaml# - $ref: /schemas/iio/adc/qcom,spmi-rradc.yaml# - $ref: /schemas/iio/adc/qcom,spmi-vadc.yaml# From 4bf8cd68787ab0f599aeca6ea09111441812d585 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 9 Feb 2026 16:24:37 +0530 Subject: [PATCH 076/438] FROMLIST: iio: adc: Add support for QCOM PMIC5 Gen3 ADC The ADC architecture on PMIC5 Gen3 is similar to that on PMIC5 Gen2, with all SW communication to ADC going through PMK8550 which communicates with other PMICs through PBS. One major difference is that the register interface used here is that of an SDAM (Shared Direct Access Memory) peripheral present on PMK8550. There may be more than one SDAM used for ADC5 Gen3 and each has eight channels, which may be used for either immediate reads (same functionality as previous PMIC5 and PMIC5 Gen2 ADC peripherals) or recurring measurements (same as ADC_TM functionality). By convention, we reserve the first channel of the first SDAM for all immediate reads and use the remaining channels across all SDAMs for ADC_TM monitoring functionality. Add support for PMIC5 Gen3 ADC driver for immediate read functionality. ADC_TM is implemented as an auxiliary thermal driver under this ADC driver. Link: https://lore.kernel.org/all/20260209105438.596339-4-jishnu.prakash@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/iio/adc/Kconfig | 26 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/qcom-spmi-adc5-gen3.c | 860 ++++++++++++++++++ include/linux/iio/adc/qcom-adc5-gen3-common.h | 212 +++++ 4 files changed, 1099 insertions(+) create mode 100644 drivers/iio/adc/qcom-spmi-adc5-gen3.c create mode 100644 include/linux/iio/adc/qcom-adc5-gen3-common.h diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 60038ae8dfc4d..1f5915dd192dd 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1366,6 +1366,32 @@ config QCOM_SPMI_ADC5 To compile this driver as a module, choose M here: the module will be called qcom-spmi-adc5. +config QCOM_SPMI_ADC5_GEN3 + tristate "Qualcomm Technologies Inc. SPMI PMIC5 GEN3 ADC" + depends on SPMI && THERMAL + select REGMAP_SPMI + select QCOM_VADC_COMMON + select AUXILIARY_BUS + help + IIO Voltage PMIC5 Gen3 ADC driver for Qualcomm Technologies Inc. + + The driver supports reading multiple channels. The ADC is a 16-bit + sigma-delta ADC. The hardware supports calibrated results for + conversion requests and clients include reading phone power supply + voltage, on board system thermistors connected to the PMIC ADC, + PMIC die temperature, charger temperature, battery current, USB + voltage input and voltage signals connected to supported PMIC GPIO + pins. The hardware supports internal pull-up for thermistors and can + choose between a 30k, 100k or 400k ohm pull up using the ADC channels. + + In addition, the same driver supports ADC thermal monitoring devices + too. They appear as thermal zones with multiple trip points. A thermal + client sets threshold temperature for both warm and cool trips and + gets updated when a threshold is reached. + + To compile this driver as a module, choose M here: the module will + be called qcom-spmi-adc5-gen3. + config RCAR_GYRO_ADC tristate "Renesas R-Car GyroADC driver" depends on ARCH_RCAR_GEN2 || COMPILE_TEST diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index c76550415ff17..097357d146baf 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -116,6 +116,7 @@ obj-$(CONFIG_PAC1934) += pac1934.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o +obj-$(CONFIG_QCOM_SPMI_ADC5_GEN3) += qcom-spmi-adc5-gen3.o obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o obj-$(CONFIG_QCOM_SPMI_RRADC) += qcom-spmi-rradc.o obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c new file mode 100644 index 0000000000000..76ea9bde61685 --- /dev/null +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -0,0 +1,860 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADC5_GEN3_VADC_SDAM 0x0 + +struct adc5_chip; + +/** + * struct adc5_channel_prop - ADC channel structure + * @common_props: structure with ADC channel properties (common to TM usage). + * @adc_tm: indicates TM type if the channel is used for TM measurements. + * @chip: pointer to top-level ADC device structure. + */ +struct adc5_channel_prop { + struct adc5_channel_common_prop common_props; + int adc_tm; + struct adc5_chip *chip; +}; + +/** + * struct adc5_chip - ADC private structure. + * @dev: SPMI ADC5 Gen3 device. + * @dev_data: Top-level ADC device data. + * @nchannels: number of ADC channels. + * @chan_props: array of ADC channel properties. + * @iio_chans: array of IIO channels specification. + * @complete: ADC result notification after interrupt is received. + * @lock: ADC lock for access to the peripheral, to prevent concurrent + * requests from multiple clients. + * @data: software configuration data. + * @n_tm_channels: number of ADC channels used for TM measurements. + * @handler: TM callback to be called for threshold violation interrupt + * on first SDAM. + * @tm_aux: pointer to auxiliary TM device. + */ +struct adc5_chip { + struct device *dev; + struct adc5_device_data dev_data; + unsigned int nchannels; + struct adc5_channel_prop *chan_props; + struct iio_chan_spec *iio_chans; + struct completion complete; + struct mutex lock; + const struct adc5_data *data; + unsigned int n_tm_channels; + void (*handler)(struct auxiliary_device *tm_aux); + struct auxiliary_device *tm_aux; +}; + +int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index, + u16 offset, u8 *data, int len) +{ + return regmap_bulk_read(adc->regmap, + adc->base[sdam_index].base_addr + offset, + data, len); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_read, "QCOM_SPMI_ADC5_GEN3"); + +int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index, + u16 offset, u8 *data, int len) +{ + return regmap_bulk_write(adc->regmap, + adc->base[sdam_index].base_addr + offset, + data, len); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_write, "QCOM_SPMI_ADC5_GEN3"); + +static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data) +{ + u8 rslt[2]; + int ret; + + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_CH_DATA0(0), rslt, sizeof(rslt)); + if (ret) + return ret; + + *data = get_unaligned_le16(rslt); + + if (*data == ADC5_USR_DATA_CHECK) { + dev_err(adc->dev, "Invalid data:%#x\n", *data); + return -EINVAL; + } + + dev_dbg(adc->dev, "voltage raw code:%#x\n", *data); + + return 0; +} + +void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop, u8 *data) +{ + /* Update calibration select and decimation ratio select */ + *data &= ~(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK | ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK); + *data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK, prop->cal_method); + *data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK, prop->decimation); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_update_dig_param, "QCOM_SPMI_ADC5_GEN3"); + +#define ADC5_GEN3_READ_CONFIG_REGS 7 + +static int adc5_gen3_configure(struct adc5_chip *adc, + struct adc5_channel_common_prop *prop) +{ + u8 buf[ADC5_GEN3_READ_CONFIG_REGS]; + u8 conv_req = 0; + int ret; + + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_SID, + buf, sizeof(buf)); + if (ret) + return ret; + + /* Write SID */ + buf[0] = FIELD_PREP(ADC5_GEN3_SID_MASK, prop->sid); + + /* + * Use channel 0 by default for immediate conversion and to indicate + * there is an actual conversion request + */ + buf[1] = ADC5_GEN3_CHAN_CONV_REQ | 0; + + buf[2] = ADC5_GEN3_TIME_IMMEDIATE; + + /* Digital param selection */ + adc5_gen3_update_dig_param(prop, &buf[3]); + + /* Update fast average sample value */ + buf[4] = FIELD_PREP(ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK, + prop->avg_samples) | ADC5_GEN3_FAST_AVG_CTL_EN; + + /* Select ADC channel */ + buf[5] = prop->channel; + + /* Select HW settle delay for channel */ + buf[6] = FIELD_PREP(ADC5_GEN3_HW_SETTLE_DELAY_MASK, + prop->hw_settle_time_us); + + reinit_completion(&adc->complete); + + ret = adc5_gen3_write(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_SID, + buf, sizeof(buf)); + if (ret) + return ret; + + conv_req = ADC5_GEN3_CONV_REQ_REQ; + return adc5_gen3_write(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_CONV_REQ, &conv_req, sizeof(conv_req)); +} + +/* + * Worst case delay from PBS in readying handshake bit can be up to 15ms, when + * PBS is busy running other simultaneous transactions, while in the best case, + * it is already ready at this point. Assigning polling delay and retry count + * accordingly. + */ + +#define ADC5_GEN3_HS_DELAY_US 100 +#define ADC5_GEN3_HS_RETRY_COUNT 150 + +int adc5_gen3_poll_wait_hs(struct adc5_device_data *adc, + unsigned int sdam_index) +{ + u8 conv_req = ADC5_GEN3_CONV_REQ_REQ; + int ret; + u8 status = 0; + + for (int count = 0; count < ADC5_GEN3_HS_RETRY_COUNT; count++) { + ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_HS, &status, sizeof(status)); + if (ret) + return ret; + + if (status == ADC5_GEN3_HS_READY) { + ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_CONV_REQ, + &conv_req, sizeof(conv_req)); + if (ret) + return ret; + + if (!conv_req) + return 0; + } + + fsleep(ADC5_GEN3_HS_DELAY_US); + } + + pr_err("Setting HS ready bit timed out, sdam_index:%d, status:%#x\n", + sdam_index, status); + return -ETIMEDOUT; +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_poll_wait_hs, "QCOM_SPMI_ADC5_GEN3"); + +int adc5_gen3_status_clear(struct adc5_device_data *adc, + int sdam_index, u16 offset, u8 *val, int len) +{ + u8 value; + int ret; + + ret = adc5_gen3_write(adc, sdam_index, offset, val, len); + if (ret) + return ret; + + /* To indicate conversion request is only to clear a status */ + value = 0; + ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &value, + sizeof(value)); + if (ret) + return ret; + + value = ADC5_GEN3_CONV_REQ_REQ; + return adc5_gen3_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &value, + sizeof(value)); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_status_clear, "QCOM_SPMI_ADC5_GEN3"); + +/* + * Worst case delay from PBS for conversion time can be up to 500ms, when PBS + * has timed out twice, once for the initial attempt and once for a retry of + * the same transaction. + */ + +#define ADC5_GEN3_CONV_TIMEOUT_MS 501 + +static int adc5_gen3_do_conversion(struct adc5_chip *adc, + struct adc5_channel_common_prop *prop, + u16 *data_volt) +{ + unsigned long rc; + int ret; + u8 val; + + guard(mutex)(&adc->lock); + ret = adc5_gen3_poll_wait_hs(&adc->dev_data, ADC5_GEN3_VADC_SDAM); + if (ret) + return ret; + + ret = adc5_gen3_configure(adc, prop); + if (ret) { + dev_err(adc->dev, "ADC configure failed with %d\n", ret); + return ret; + } + + /* No support for polling mode at present */ + rc = wait_for_completion_timeout(&adc->complete, + msecs_to_jiffies(ADC5_GEN3_CONV_TIMEOUT_MS)); + if (!rc) { + dev_err(adc->dev, "Reading ADC channel %s timed out\n", + prop->label); + return -ETIMEDOUT; + } + + ret = adc5_gen3_read_voltage_data(adc, data_volt); + if (ret) + return ret; + + val = BIT(0); + return adc5_gen3_status_clear(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_EOC_CLR, &val, 1); +} + +static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) +{ + struct adc5_chip *adc = dev_id; + struct device *dev = adc->dev; + struct auxiliary_device *adev; + u8 status, eoc_status, val; + u8 tm_status[2]; + int ret; + + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_STATUS1, &status, sizeof(status)); + if (ret) { + dev_err(dev, "adc read status1 failed with %d\n", ret); + return IRQ_HANDLED; + } + + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_EOC_STS, &eoc_status, sizeof(eoc_status)); + if (ret) { + dev_err(dev, "adc read eoc status failed with %d\n", ret); + return IRQ_HANDLED; + } + + if (status & ADC5_GEN3_STATUS1_CONV_FAULT) { + dev_err_ratelimited(dev, + "Unexpected conversion fault, status:%#x, eoc_status:%#x\n", + status, eoc_status); + val = ADC5_GEN3_CONV_ERR_CLR_REQ; + adc5_gen3_status_clear(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_CONV_ERR_CLR, &val, 1); + return IRQ_HANDLED; + } + + /* CHAN0 is the preconfigured channel for immediate conversion */ + if (eoc_status & ADC5_GEN3_EOC_CHAN_0) + complete(&adc->complete); + + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, + ADC5_GEN3_TM_HIGH_STS, tm_status, sizeof(tm_status)); + if (ret) { + dev_err(dev, "adc read TM status failed with %d\n", ret); + return IRQ_HANDLED; + } + + dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x, high:%#x, low:%#x\n", + status, eoc_status, tm_status[0], tm_status[1]); + + if (tm_status[0] || tm_status[1]) { + adev = adc->tm_aux; + if (!adev || !adev->dev.driver) { + dev_err(dev, "adc_tm auxiliary device not initialized\n"); + return IRQ_HANDLED; + } + + adc->handler(adev); + } + + return IRQ_HANDLED; +} + +static int adc5_gen3_fwnode_xlate(struct iio_dev *indio_dev, + const struct fwnode_reference_args *iiospec) +{ + struct adc5_chip *adc = iio_priv(indio_dev); + int v_channel; + + for (int i = 0; i < adc->nchannels; i++) { + v_channel = ADC5_GEN3_V_CHAN(adc->chan_props[i].common_props); + if (v_channel == iiospec->args[0]) + return i; + } + + return -ENOENT; +} + +static int adc5_gen3_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct adc5_chip *adc = iio_priv(indio_dev); + struct adc5_channel_common_prop *prop; + u16 adc_code_volt; + int ret; + + prop = &adc->chan_props[chan->address].common_props; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + ret = adc5_gen3_do_conversion(adc, prop, &adc_code_volt); + if (ret) + return ret; + + ret = qcom_adc5_hw_scale(prop->scale_fn_type, prop->prescale, + adc->data, adc_code_volt, val); + if (ret) + return ret; + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int adc5_gen3_read_label(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, char *label) +{ + struct adc5_chip *adc = iio_priv(indio_dev); + struct adc5_channel_prop *prop; + + prop = &adc->chan_props[chan->address]; + return sprintf(label, "%s\n", prop->common_props.label); +} + +static const struct iio_info adc5_gen3_info = { + .read_raw = adc5_gen3_read_raw, + .read_label = adc5_gen3_read_label, + .fwnode_xlate = adc5_gen3_fwnode_xlate, +}; + +struct adc5_channels { + unsigned int prescale_index; + enum iio_chan_type type; + long info_mask; + enum vadc_scale_fn_type scale_fn_type; +}; + +/* In these definitions, _pre refers to an index into adc5_prescale_ratios. */ +#define ADC5_CHAN(_type, _mask, _pre, _scale) \ + { \ + .prescale_index = _pre, \ + .type = _type, \ + .info_mask = _mask, \ + .scale_fn_type = _scale, \ + }, \ + +#define ADC5_CHAN_TEMP(_pre, _scale) \ + ADC5_CHAN(IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \ + +#define ADC5_CHAN_VOLT(_pre, _scale) \ + ADC5_CHAN(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \ + +#define ADC5_CHAN_CUR(_pre, _scale) \ + ADC5_CHAN(IIO_CURRENT, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \ + +static const struct adc5_channels adc5_gen3_chans_pmic[ADC5_MAX_CHANNEL] = { + [ADC5_GEN3_REF_GND] = ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_1P25VREF] = ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_VPH_PWR] = ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_VBAT_SNS_QBG] = ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_VIN_DIV16_MUX] = ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_PMIC_THERM_PM7) + [ADC5_GEN3_AMUX1_THM_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX2_THM_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX3_THM_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX4_THM_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX5_THM_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX6_THM_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX1_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX2_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX3_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) + [ADC5_GEN3_AMUX4_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, + SCALE_HW_CALIB_THERM_100K_PU_PM7) +}; + +static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc, + struct adc5_channel_prop *prop, + struct fwnode_handle *fwnode) +{ + const char *name = fwnode_get_name(fwnode); + const struct adc5_data *data = adc->data; + struct device *dev = adc->dev; + const char *channel_name; + u32 chan, value, sid; + u32 varr[2]; + int ret; + + ret = fwnode_property_read_u32(fwnode, "reg", &chan); + if (ret < 0) + return dev_err_probe(dev, ret, "invalid channel number %s\n", + name); + + /* + * Value read from "reg" is virtual channel number + * virtual channel number = sid << 8 | channel number + */ + sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan); + chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan); + + if (chan > ADC5_MAX_CHANNEL) + return dev_err_probe(dev, -EINVAL, + "%s invalid channel number %d\n", + name, chan); + + prop->common_props.channel = chan; + prop->common_props.sid = sid; + + if (!adc->data->adc_chans[chan].info_mask) + return dev_err_probe(dev, -EINVAL, "Channel %#x not supported\n", chan); + + channel_name = name; + fwnode_property_read_string(fwnode, "label", &channel_name); + prop->common_props.label = channel_name; + + value = data->decimation[ADC5_DECIMATION_DEFAULT]; + fwnode_property_read_u32(fwnode, "qcom,decimation", &value); + ret = qcom_adc5_decimation_from_dt(value, data->decimation); + if (ret < 0) + return dev_err_probe(dev, ret, "%#x invalid decimation %d\n", + chan, value); + prop->common_props.decimation = ret; + + prop->common_props.prescale = adc->data->adc_chans[chan].prescale_index; + ret = fwnode_property_read_u32_array(fwnode, "qcom,pre-scaling", varr, 2); + if (!ret) { + ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]); + if (ret < 0) + return dev_err_probe(dev, ret, + "%#x invalid pre-scaling <%d %d>\n", + chan, varr[0], varr[1]); + prop->common_props.prescale = ret; + } + + value = data->hw_settle_1[VADC_DEF_HW_SETTLE_TIME]; + fwnode_property_read_u32(fwnode, "qcom,hw-settle-time", &value); + ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_1); + if (ret < 0) + return dev_err_probe(dev, ret, + "%#x invalid hw-settle-time %d us\n", + chan, value); + prop->common_props.hw_settle_time_us = ret; + + value = BIT(VADC_DEF_AVG_SAMPLES); + fwnode_property_read_u32(fwnode, "qcom,avg-samples", &value); + ret = qcom_adc5_avg_samples_from_dt(value); + if (ret < 0) + return dev_err_probe(dev, ret, "%#x invalid avg-samples %d\n", + chan, value); + prop->common_props.avg_samples = ret; + + if (fwnode_property_read_bool(fwnode, "qcom,ratiometric")) + prop->common_props.cal_method = ADC5_RATIOMETRIC_CAL; + else + prop->common_props.cal_method = ADC5_ABSOLUTE_CAL; + + prop->adc_tm = fwnode_property_read_bool(fwnode, "qcom,adc-tm"); + if (prop->adc_tm) { + adc->n_tm_channels++; + if (adc->n_tm_channels > (adc->dev_data.num_sdams * 8 - 1)) + return dev_err_probe(dev, -EINVAL, + "Number of TM nodes %u greater than channels supported:%u\n", + adc->n_tm_channels, + adc->dev_data.num_sdams * 8 - 1); + } + + return 0; +} + +static const struct adc5_data adc5_gen3_data_pmic = { + .full_scale_code_volt = 0x70e4, + .adc_chans = adc5_gen3_chans_pmic, + .info = &adc5_gen3_info, + .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX]) + { 85, 340, 1360 }, + .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) + { 15, 100, 200, 300, + 400, 500, 600, 700, + 1000, 2000, 4000, 8000, + 16000, 32000, 64000, 128000 }, +}; + +static const struct of_device_id adc5_match_table[] = { + { + .compatible = "qcom,spmi-adc5-gen3", + .data = &adc5_gen3_data_pmic, + }, + { } +}; +MODULE_DEVICE_TABLE(of, adc5_match_table); + +static int adc5_get_fw_data(struct adc5_chip *adc) +{ + const struct adc5_channels *adc_chan; + struct adc5_channel_prop *chan_props; + struct iio_chan_spec *iio_chan; + struct device *dev = adc->dev; + unsigned int index = 0; + int ret; + + adc->nchannels = device_get_child_node_count(dev); + if (!adc->nchannels) + return dev_err_probe(dev, -EINVAL, "No ADC channels found\n"); + + adc->iio_chans = devm_kcalloc(dev, adc->nchannels, + sizeof(*adc->iio_chans), GFP_KERNEL); + if (!adc->iio_chans) + return -ENOMEM; + + adc->chan_props = devm_kcalloc(dev, adc->nchannels, + sizeof(*adc->chan_props), GFP_KERNEL); + if (!adc->chan_props) + return -ENOMEM; + + chan_props = adc->chan_props; + adc->n_tm_channels = 0; + iio_chan = adc->iio_chans; + adc->data = device_get_match_data(dev); + + device_for_each_child_node_scoped(dev, child) { + ret = adc5_gen3_get_fw_channel_data(adc, chan_props, child); + if (ret) + return ret; + + chan_props->chip = adc; + adc_chan = &adc->data->adc_chans[chan_props->common_props.channel]; + chan_props->common_props.scale_fn_type = adc_chan->scale_fn_type; + + iio_chan->channel = ADC5_GEN3_V_CHAN(chan_props->common_props); + iio_chan->info_mask_separate = adc_chan->info_mask; + iio_chan->type = adc_chan->type; + iio_chan->address = index; + iio_chan->indexed = 1; + iio_chan++; + chan_props++; + index++; + } + + return 0; +} + +static void adc5_gen3_uninit_aux(void *data) +{ + auxiliary_device_uninit(data); +} + +static void adc5_gen3_delete_aux(void *data) +{ + auxiliary_device_delete(data); +} + +static void adc5_gen3_aux_device_release(struct device *dev) {} + +static int adc5_gen3_add_aux_tm_device(struct adc5_chip *adc) +{ + struct tm5_aux_dev_wrapper *aux_device; + int ret, i_tm = 0; + + aux_device = devm_kzalloc(adc->dev, sizeof(*aux_device), GFP_KERNEL); + if (!aux_device) + return -ENOMEM; + + aux_device->aux_dev.name = "adc5_tm_gen3"; + aux_device->aux_dev.dev.parent = adc->dev; + aux_device->aux_dev.dev.release = adc5_gen3_aux_device_release; + + aux_device->tm_props = devm_kcalloc(adc->dev, adc->n_tm_channels, + sizeof(*aux_device->tm_props), + GFP_KERNEL); + if (!aux_device->tm_props) + return -ENOMEM; + + aux_device->dev_data = &adc->dev_data; + + for (int i = 0; i < adc->nchannels; i++) { + if (!adc->chan_props[i].adc_tm) + continue; + aux_device->tm_props[i_tm] = adc->chan_props[i].common_props; + i_tm++; + } + + device_set_of_node_from_dev(&aux_device->aux_dev.dev, adc->dev); + + aux_device->n_tm_channels = adc->n_tm_channels; + + ret = auxiliary_device_init(&aux_device->aux_dev); + if (ret) + return ret; + + ret = devm_add_action_or_reset(adc->dev, adc5_gen3_uninit_aux, + &aux_device->aux_dev); + if (ret) + return ret; + + ret = auxiliary_device_add(&aux_device->aux_dev); + if (ret) + return ret; + ret = devm_add_action_or_reset(adc->dev, adc5_gen3_delete_aux, + &aux_device->aux_dev); + if (ret) + return ret; + + adc->tm_aux = &aux_device->aux_dev; + + return 0; +} + +void adc5_gen3_mutex_lock(struct device *dev) + __acquires(&adc->lock) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); + struct adc5_chip *adc = iio_priv(indio_dev); + + mutex_lock(&adc->lock); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_mutex_lock, "QCOM_SPMI_ADC5_GEN3"); + +void adc5_gen3_mutex_unlock(struct device *dev) + __releases(&adc->lock) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); + struct adc5_chip *adc = iio_priv(indio_dev); + + mutex_unlock(&adc->lock); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_mutex_unlock, "QCOM_SPMI_ADC5_GEN3"); + +int adc5_gen3_get_scaled_reading(struct device *dev, + struct adc5_channel_common_prop *common_props, + int *val) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); + struct adc5_chip *adc = iio_priv(indio_dev); + u16 adc_code_volt; + int ret; + + ret = adc5_gen3_do_conversion(adc, common_props, &adc_code_volt); + if (ret) + return ret; + + return qcom_adc5_hw_scale(common_props->scale_fn_type, + common_props->prescale, + adc->data, adc_code_volt, val); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_get_scaled_reading, "QCOM_SPMI_ADC5_GEN3"); + +int adc5_gen3_therm_code_to_temp(struct device *dev, + struct adc5_channel_common_prop *common_props, + u16 code, int *val) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); + struct adc5_chip *adc = iio_priv(indio_dev); + + return qcom_adc5_hw_scale(common_props->scale_fn_type, + common_props->prescale, + adc->data, code, val); +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_therm_code_to_temp, "QCOM_SPMI_ADC5_GEN3"); + +void adc5_gen3_register_tm_event_notifier(struct device *dev, + void (*handler)(struct auxiliary_device *)) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); + struct adc5_chip *adc = iio_priv(indio_dev); + + adc->handler = handler; +} +EXPORT_SYMBOL_NS_GPL(adc5_gen3_register_tm_event_notifier, "QCOM_SPMI_ADC5_GEN3"); + +static int adc5_gen3_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct iio_dev *indio_dev; + struct adc5_chip *adc; + struct regmap *regmap; + int ret; + u32 *reg; + + regmap = dev_get_regmap(dev->parent, NULL); + if (!regmap) + return -ENODEV; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); + if (!indio_dev) + return -ENOMEM; + + adc = iio_priv(indio_dev); + adc->dev_data.regmap = regmap; + adc->dev = dev; + + platform_set_drvdata(pdev, indio_dev); + init_completion(&adc->complete); + ret = devm_mutex_init(dev, &adc->lock); + if (ret) + return ret; + + ret = device_property_count_u32(dev, "reg"); + if (ret < 0) + return ret; + + adc->dev_data.num_sdams = ret; + + reg = devm_kcalloc(dev, adc->dev_data.num_sdams, sizeof(u32), + GFP_KERNEL); + if (!reg) + return -ENOMEM; + + ret = device_property_read_u32_array(dev, "reg", reg, + adc->dev_data.num_sdams); + if (ret) + return dev_err_probe(dev, ret, + "Failed to read reg property\n"); + + adc->dev_data.base = devm_kcalloc(dev, adc->dev_data.num_sdams, + sizeof(*adc->dev_data.base), + GFP_KERNEL); + if (!adc->dev_data.base) + return -ENOMEM; + + for (int i = 0; i < adc->dev_data.num_sdams; i++) { + adc->dev_data.base[i].base_addr = reg[i]; + + ret = platform_get_irq(pdev, i); + if (ret < 0) + return dev_err_probe(dev, ret, + "Getting IRQ %d failed\n", i); + + adc->dev_data.base[i].irq = ret; + + adc->dev_data.base[i].irq_name = devm_kasprintf(dev, GFP_KERNEL, + "sdam%d", i); + if (!adc->dev_data.base[i].irq_name) + return -ENOMEM; + } + + ret = devm_request_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq, + adc5_gen3_isr, 0, + adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name, + adc); + if (ret) + return dev_err_probe(dev, ret, + "Failed to request SDAM%d irq\n", + ADC5_GEN3_VADC_SDAM); + + ret = adc5_get_fw_data(adc); + if (ret) + return ret; + + if (adc->n_tm_channels > 0) { + ret = adc5_gen3_add_aux_tm_device(adc); + if (ret) + dev_err_probe(dev, ret, + "Failed to add auxiliary TM device\n"); + } + + indio_dev->name = "spmi-adc5-gen3"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &adc5_gen3_info; + indio_dev->channels = adc->iio_chans; + indio_dev->num_channels = adc->nchannels; + + return devm_iio_device_register(dev, indio_dev); +} + +static struct platform_driver adc5_gen3_driver = { + .driver = { + .name = "qcom-spmi-adc5-gen3", + .of_match_table = adc5_match_table, + }, + .probe = adc5_gen3_probe, +}; +module_platform_driver(adc5_gen3_driver); + +MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 Gen3 ADC driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("QCOM_SPMI_ADC5_GEN3"); diff --git a/include/linux/iio/adc/qcom-adc5-gen3-common.h b/include/linux/iio/adc/qcom-adc5-gen3-common.h new file mode 100644 index 0000000000000..e352733f4a706 --- /dev/null +++ b/include/linux/iio/adc/qcom-adc5-gen3-common.h @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Code used in the main and auxiliary Qualcomm PMIC voltage ADCs + * of type ADC5 Gen3. + */ + +#ifndef QCOM_ADC5_GEN3_COMMON_H +#define QCOM_ADC5_GEN3_COMMON_H + +#include +#include +#include +#include +#include +#include + +#define ADC5_GEN3_HS 0x45 +#define ADC5_GEN3_HS_BUSY BIT(7) +#define ADC5_GEN3_HS_READY BIT(0) + +#define ADC5_GEN3_STATUS1 0x46 +#define ADC5_GEN3_STATUS1_CONV_FAULT BIT(7) +#define ADC5_GEN3_STATUS1_THR_CROSS BIT(6) +#define ADC5_GEN3_STATUS1_EOC BIT(0) + +#define ADC5_GEN3_TM_EN_STS 0x47 +#define ADC5_GEN3_TM_HIGH_STS 0x48 +#define ADC5_GEN3_TM_LOW_STS 0x49 + +#define ADC5_GEN3_EOC_STS 0x4a +#define ADC5_GEN3_EOC_CHAN_0 BIT(0) + +#define ADC5_GEN3_EOC_CLR 0x4b +#define ADC5_GEN3_TM_HIGH_STS_CLR 0x4c +#define ADC5_GEN3_TM_LOW_STS_CLR 0x4d +#define ADC5_GEN3_CONV_ERR_CLR 0x4e +#define ADC5_GEN3_CONV_ERR_CLR_REQ BIT(0) + +#define ADC5_GEN3_SID 0x4f +#define ADC5_GEN3_SID_MASK GENMASK(3, 0) + +#define ADC5_GEN3_PERPH_CH 0x50 +#define ADC5_GEN3_CHAN_CONV_REQ BIT(7) + +#define ADC5_GEN3_TIMER_SEL 0x51 +#define ADC5_GEN3_TIME_IMMEDIATE 0x1 + +#define ADC5_GEN3_DIG_PARAM 0x52 +#define ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK GENMASK(5, 4) +#define ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK GENMASK(3, 2) + +#define ADC5_GEN3_FAST_AVG 0x53 +#define ADC5_GEN3_FAST_AVG_CTL_EN BIT(7) +#define ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK GENMASK(2, 0) + +#define ADC5_GEN3_ADC_CH_SEL_CTL 0x54 +#define ADC5_GEN3_DELAY_CTL 0x55 +#define ADC5_GEN3_HW_SETTLE_DELAY_MASK GENMASK(3, 0) + +#define ADC5_GEN3_CH_EN 0x56 +#define ADC5_GEN3_HIGH_THR_INT_EN BIT(1) +#define ADC5_GEN3_LOW_THR_INT_EN BIT(0) + +#define ADC5_GEN3_LOW_THR0 0x57 +#define ADC5_GEN3_LOW_THR1 0x58 +#define ADC5_GEN3_HIGH_THR0 0x59 +#define ADC5_GEN3_HIGH_THR1 0x5a + +#define ADC5_GEN3_CH_DATA0(channel) (0x5c + (channel) * 2) +#define ADC5_GEN3_CH_DATA1(channel) (0x5d + (channel) * 2) + +#define ADC5_GEN3_CONV_REQ 0xe5 +#define ADC5_GEN3_CONV_REQ_REQ BIT(0) + +#define ADC5_GEN3_VIRTUAL_SID_MASK GENMASK(15, 8) +#define ADC5_GEN3_CHANNEL_MASK GENMASK(7, 0) +#define ADC5_GEN3_V_CHAN(x) \ + (FIELD_PREP(ADC5_GEN3_VIRTUAL_SID_MASK, (x).sid) | (x).channel) + +/* ADC channels for PMIC5 Gen3 */ +#define ADC5_GEN3_REF_GND 0x00 +#define ADC5_GEN3_1P25VREF 0x01 +#define ADC5_GEN3_DIE_TEMP 0x03 +#define ADC5_GEN3_USB_SNS_V_16 0x11 +#define ADC5_GEN3_VIN_DIV16_MUX 0x12 +#define ADC5_GEN3_VPH_PWR 0x8e +#define ADC5_GEN3_VBAT_SNS_QBG 0x8f +/* 100k pull-up channels */ +#define ADC5_GEN3_AMUX1_THM_100K_PU 0x44 +#define ADC5_GEN3_AMUX2_THM_100K_PU 0x45 +#define ADC5_GEN3_AMUX3_THM_100K_PU 0x46 +#define ADC5_GEN3_AMUX4_THM_100K_PU 0x47 +#define ADC5_GEN3_AMUX5_THM_100K_PU 0x48 +#define ADC5_GEN3_AMUX6_THM_100K_PU 0x49 +#define ADC5_GEN3_AMUX1_GPIO_100K_PU 0x4a +#define ADC5_GEN3_AMUX2_GPIO_100K_PU 0x4b +#define ADC5_GEN3_AMUX3_GPIO_100K_PU 0x4c +#define ADC5_GEN3_AMUX4_GPIO_100K_PU 0x4d + +#define ADC5_MAX_CHANNEL 0xc0 + +struct device; + +enum adc5_cal_method { + ADC5_NO_CAL = 0, + ADC5_RATIOMETRIC_CAL, + ADC5_ABSOLUTE_CAL, +}; + +enum adc5_time_select { + MEAS_INT_DISABLE = 0, + MEAS_INT_IMMEDIATE, + MEAS_INT_50MS, + MEAS_INT_100MS, + MEAS_INT_1S, + MEAS_INT_NONE, +}; + +/** + * struct adc5_sdam_data - data per SDAM allocated for adc usage + * @base_addr: base address for the ADC SDAM peripheral. + * @irq_name: ADC IRQ name. + * @irq: ADC IRQ number. + */ +struct adc5_sdam_data { + u16 base_addr; + const char *irq_name; + int irq; +}; + +/** + * struct adc5_device_data - Top-level ADC device data + * @regmap: ADC peripheral register map field. + * @base: array of SDAM data. + * @num_sdams: number of ADC SDAM peripherals. + */ +struct adc5_device_data { + struct regmap *regmap; + struct adc5_sdam_data *base; + int num_sdams; +}; + +/** + * struct adc5_channel_common_prop - ADC channel properties (common to ADC and TM). + * @channel: channel number, refer to the channel list. + * @cal_method: calibration method. + * @decimation: sampling rate supported for the channel. + * @sid: ID of PMIC owning the channel. + * @label: Channel name used in device tree. + * @prescale: channel scaling performed on the input signal. + * @hw_settle_time_us: the time between AMUX being configured and the + * start of conversion in uS. + * @avg_samples: ability to provide single result from the ADC + * that is an average of multiple measurements. + * @scale_fn_type: Represents the scaling function to convert voltage + * physical units desired by the client for the channel. + */ +struct adc5_channel_common_prop { + unsigned int channel; + enum adc5_cal_method cal_method; + unsigned int decimation; + unsigned int sid; + const char *label; + unsigned int prescale; + unsigned int hw_settle_time_us; + unsigned int avg_samples; + enum vadc_scale_fn_type scale_fn_type; +}; + +/** + * struct tm5_aux_dev_wrapper - wrapper structure around TM auxiliary device + * @aux_dev: TM auxiliary device structure. + * @dev_data: Top-level ADC device data. + * @tm_props: Array of common ADC channel properties for TM channels. + * @n_tm_channels: number of TM channels. + */ +struct tm5_aux_dev_wrapper { + struct auxiliary_device aux_dev; + struct adc5_device_data *dev_data; + struct adc5_channel_common_prop *tm_props; + unsigned int n_tm_channels; +}; + +int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index, + u16 offset, u8 *data, int len); + +int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index, + u16 offset, u8 *data, int len); + +int adc5_gen3_poll_wait_hs(struct adc5_device_data *adc, + unsigned int sdam_index); + +void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop, + u8 *data); + +int adc5_gen3_status_clear(struct adc5_device_data *adc, + int sdam_index, u16 offset, u8 *val, int len); + +void adc5_gen3_mutex_lock(struct device *dev); +void adc5_gen3_mutex_unlock(struct device *dev); +int adc5_gen3_get_scaled_reading(struct device *dev, + struct adc5_channel_common_prop *common_props, + int *val); +int adc5_gen3_therm_code_to_temp(struct device *dev, + struct adc5_channel_common_prop *common_props, + u16 code, int *val); +void adc5_gen3_register_tm_event_notifier(struct device *dev, + void (*handler)(struct auxiliary_device *)); + +#endif /* QCOM_ADC5_GEN3_COMMON_H */ From e6525e383cf7a4fe2a6f0b5713045620ef6a9b91 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 9 Feb 2026 16:24:38 +0530 Subject: [PATCH 077/438] FROMLIST: thermal: qcom: add support for PMIC5 Gen3 ADC thermal monitoring Add support for ADC_TM part of PMIC5 Gen3. This is an auxiliary driver under the Gen3 ADC driver, which implements the threshold setting and interrupt generating functionalities of QCOM ADC_TM drivers, used to support thermal trip points. Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/all/20260209105438.596339-5-jishnu.prakash@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/thermal/qcom/Kconfig | 9 + drivers/thermal/qcom/Makefile | 1 + drivers/thermal/qcom/qcom-spmi-adc-tm5-gen3.c | 507 ++++++++++++++++++ 3 files changed, 517 insertions(+) create mode 100644 drivers/thermal/qcom/qcom-spmi-adc-tm5-gen3.c diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig index a6bb01082ec69..1acb11e4ac800 100644 --- a/drivers/thermal/qcom/Kconfig +++ b/drivers/thermal/qcom/Kconfig @@ -21,6 +21,15 @@ config QCOM_SPMI_ADC_TM5 Thermal client sets threshold temperature for both warm and cool and gets updated when a threshold is reached. +config QCOM_SPMI_ADC_TM5_GEN3 + tristate "Qualcomm SPMI PMIC Thermal Monitor ADC5 Gen3" + depends on QCOM_SPMI_ADC5_GEN3 + help + This enables the auxiliary thermal driver for the ADC5 Gen3 thermal + monitoring device. It shows up as a thermal zone with multiple trip points. + Thermal client sets threshold temperature for both warm and cool and + gets updated when a threshold is reached. + config QCOM_SPMI_TEMP_ALARM tristate "Qualcomm SPMI PMIC Temperature Alarm" depends on OF && SPMI && IIO diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile index 0fa2512042e78..828d9e7bc7970 100644 --- a/drivers/thermal/qcom/Makefile +++ b/drivers/thermal/qcom/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o qcom_tsens-y += tsens.o tsens-v2.o tsens-v1.o tsens-v0_1.o \ tsens-8960.o obj-$(CONFIG_QCOM_SPMI_ADC_TM5) += qcom-spmi-adc-tm5.o +obj-$(CONFIG_QCOM_SPMI_ADC_TM5_GEN3) += qcom-spmi-adc-tm5-gen3.o obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o obj-$(CONFIG_QCOM_LMH) += lmh.o diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5-gen3.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5-gen3.c new file mode 100644 index 0000000000000..fde9b073f4826 --- /dev/null +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5-gen3.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../thermal_hwmon.h" + +struct device; +struct adc_tm5_gen3_chip; + +/** + * struct adc_tm5_gen3_channel_props - ADC_TM channel structure + * @timer: time period of recurring TM measurement. + * @tm_chan_index: TM channel number used (ranging from 1-7). + * @sdam_index: SDAM on which this TM channel lies. + * @common_props: structure with common ADC channel properties. + * @high_thr_en: TM high threshold crossing detection enabled. + * @low_thr_en: TM low threshold crossing detection enabled. + * @chip: ADC TM device. + * @tzd: pointer to thermal device corresponding to TM channel. + * @last_temp: last temperature that caused threshold violation, + * or a thermal TM channel. + * @last_temp_set: indicates if last_temp is stored. + */ +struct adc_tm5_gen3_channel_props { + unsigned int timer; + unsigned int tm_chan_index; + unsigned int sdam_index; + struct adc5_channel_common_prop common_props; + bool high_thr_en; + bool low_thr_en; + struct adc_tm5_gen3_chip *chip; + struct thermal_zone_device *tzd; + int last_temp; + bool last_temp_set; +}; + +/** + * struct adc_tm5_gen3_chip - ADC Thermal Monitoring device structure + * @dev_data: Top-level ADC device data. + * @chan_props: Array of ADC_TM channel structures. + * @nchannels: number of TM channels allocated + * @dev: SPMI ADC5 Gen3 device. + * @tm_handler_work: handler for TM interrupt for threshold violation. + */ +struct adc_tm5_gen3_chip { + struct adc5_device_data *dev_data; + struct adc_tm5_gen3_channel_props *chan_props; + unsigned int nchannels; + struct device *dev; + struct work_struct tm_handler_work; +}; + +DEFINE_GUARD(adc5_gen3, struct adc_tm5_gen3_chip *, adc5_gen3_mutex_lock(_T->dev), + adc5_gen3_mutex_unlock(_T->dev)) + +static int get_sdam_from_irq(struct adc_tm5_gen3_chip *adc_tm5, int irq) +{ + for (int i = 0; i < adc_tm5->dev_data->num_sdams; i++) { + if (adc_tm5->dev_data->base[i].irq == irq) + return i; + } + return -ENOENT; +} + +static irqreturn_t adctm5_gen3_isr(int irq, void *dev_id) +{ + struct adc_tm5_gen3_chip *adc_tm5 = dev_id; + int ret, sdam_num; + u8 tm_status[2]; + u8 status, val; + + sdam_num = get_sdam_from_irq(adc_tm5, irq); + if (sdam_num < 0) { + dev_err(adc_tm5->dev, "adc irq %d not associated with an sdam\n", + irq); + return IRQ_HANDLED; + } + + ret = adc5_gen3_read(adc_tm5->dev_data, sdam_num, ADC5_GEN3_STATUS1, + &status, sizeof(status)); + if (ret) { + dev_err(adc_tm5->dev, "adc read status1 failed with %d\n", ret); + return IRQ_HANDLED; + } + + if (status & ADC5_GEN3_STATUS1_CONV_FAULT) { + dev_err_ratelimited(adc_tm5->dev, + "Unexpected conversion fault, status:%#x\n", + status); + val = ADC5_GEN3_CONV_ERR_CLR_REQ; + adc5_gen3_status_clear(adc_tm5->dev_data, sdam_num, + ADC5_GEN3_CONV_ERR_CLR, &val, 1); + return IRQ_HANDLED; + } + + ret = adc5_gen3_read(adc_tm5->dev_data, sdam_num, ADC5_GEN3_TM_HIGH_STS, + tm_status, sizeof(tm_status)); + if (ret) { + dev_err(adc_tm5->dev, "adc read TM status failed with %d\n", ret); + return IRQ_HANDLED; + } + + if (tm_status[0] || tm_status[1]) + schedule_work(&adc_tm5->tm_handler_work); + + dev_dbg(adc_tm5->dev, "Interrupt status:%#x, high:%#x, low:%#x\n", + status, tm_status[0], tm_status[1]); + + return IRQ_HANDLED; +} + +static int adc5_gen3_tm_status_check(struct adc_tm5_gen3_chip *adc_tm5, + int sdam_index, u8 *tm_status, u8 *buf) +{ + int ret; + + ret = adc5_gen3_read(adc_tm5->dev_data, sdam_index, ADC5_GEN3_TM_HIGH_STS, + tm_status, 2); + if (ret) { + dev_err(adc_tm5->dev, "adc read TM status failed with %d\n", ret); + return ret; + } + + ret = adc5_gen3_status_clear(adc_tm5->dev_data, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR, + tm_status, 2); + if (ret) { + dev_err(adc_tm5->dev, "adc status clear conv_req failed with %d\n", + ret); + return ret; + } + + ret = adc5_gen3_read(adc_tm5->dev_data, sdam_index, ADC5_GEN3_CH_DATA0(0), + buf, 16); + if (ret) + dev_err(adc_tm5->dev, "adc read data failed with %d\n", ret); + + return ret; +} + +static void tm_handler_work(struct work_struct *work) +{ + struct adc_tm5_gen3_chip *adc_tm5 = container_of(work, struct adc_tm5_gen3_chip, + tm_handler_work); + int sdam_index = -1; + u8 tm_status[2] = { }; + u8 buf[16] = { }; + + for (int i = 0; i < adc_tm5->nchannels; i++) { + struct adc_tm5_gen3_channel_props *chan_prop = &adc_tm5->chan_props[i]; + int offset = chan_prop->tm_chan_index; + bool upper_set, lower_set; + int ret, temp; + u16 code; + + scoped_guard(adc5_gen3, adc_tm5) { + if (chan_prop->sdam_index != sdam_index) { + sdam_index = chan_prop->sdam_index; + ret = adc5_gen3_tm_status_check(adc_tm5, sdam_index, + tm_status, buf); + if (ret) + return; + } + + upper_set = ((tm_status[0] & BIT(offset)) && chan_prop->high_thr_en); + lower_set = ((tm_status[1] & BIT(offset)) && chan_prop->low_thr_en); + } + + if (!(upper_set || lower_set)) + continue; + + code = get_unaligned_le16(&buf[2 * offset]); + dev_dbg(adc_tm5->dev, "ADC_TM threshold code:%#x\n", code); + + ret = adc5_gen3_therm_code_to_temp(adc_tm5->dev, + &chan_prop->common_props, + code, &temp); + if (ret) { + dev_err(adc_tm5->dev, + "Invalid temperature reading, ret = %d, code=%#x\n", + ret, code); + continue; + } + + chan_prop->last_temp = temp; + chan_prop->last_temp_set = true; + thermal_zone_device_update(chan_prop->tzd, THERMAL_TRIP_VIOLATED); + } +} + +static int adc_tm5_gen3_get_temp(struct thermal_zone_device *tz, int *temp) +{ + struct adc_tm5_gen3_channel_props *prop = thermal_zone_device_priv(tz); + struct adc_tm5_gen3_chip *adc_tm5; + + if (!prop || !prop->chip) + return -EINVAL; + + adc_tm5 = prop->chip; + + if (prop->last_temp_set) { + pr_debug("last_temp: %d\n", prop->last_temp); + prop->last_temp_set = false; + *temp = prop->last_temp; + return 0; + } + + return adc5_gen3_get_scaled_reading(adc_tm5->dev, &prop->common_props, + temp); +} + +static int adc_tm5_gen3_disable_channel(struct adc_tm5_gen3_channel_props *prop) +{ + struct adc_tm5_gen3_chip *adc_tm5 = prop->chip; + int ret; + u8 val; + + prop->high_thr_en = false; + prop->low_thr_en = false; + + ret = adc5_gen3_poll_wait_hs(adc_tm5->dev_data, prop->sdam_index); + if (ret) + return ret; + + val = BIT(prop->tm_chan_index); + ret = adc5_gen3_write(adc_tm5->dev_data, prop->sdam_index, + ADC5_GEN3_TM_HIGH_STS_CLR, &val, sizeof(val)); + if (ret) + return ret; + + val = MEAS_INT_DISABLE; + ret = adc5_gen3_write(adc_tm5->dev_data, prop->sdam_index, + ADC5_GEN3_TIMER_SEL, &val, sizeof(val)); + if (ret) + return ret; + + /* To indicate there is an actual conversion request */ + val = ADC5_GEN3_CHAN_CONV_REQ | prop->tm_chan_index; + ret = adc5_gen3_write(adc_tm5->dev_data, prop->sdam_index, + ADC5_GEN3_PERPH_CH, &val, sizeof(val)); + if (ret) + return ret; + + val = ADC5_GEN3_CONV_REQ_REQ; + return adc5_gen3_write(adc_tm5->dev_data, prop->sdam_index, + ADC5_GEN3_CONV_REQ, &val, sizeof(val)); +} + +#define ADC_TM5_GEN3_CONFIG_REGS 12 + +static int adc_tm5_gen3_configure(struct adc_tm5_gen3_channel_props *prop, + int low_temp, int high_temp) +{ + struct adc_tm5_gen3_chip *adc_tm5 = prop->chip; + u8 buf[ADC_TM5_GEN3_CONFIG_REGS]; + u8 conv_req; + u16 adc_code; + int ret; + + ret = adc5_gen3_poll_wait_hs(adc_tm5->dev_data, prop->sdam_index); + if (ret < 0) + return ret; + + ret = adc5_gen3_read(adc_tm5->dev_data, prop->sdam_index, + ADC5_GEN3_SID, buf, sizeof(buf)); + if (ret < 0) + return ret; + + /* Write SID */ + buf[0] = FIELD_PREP(ADC5_GEN3_SID_MASK, prop->common_props.sid); + + /* Select TM channel and indicate there is an actual conversion request */ + buf[1] = ADC5_GEN3_CHAN_CONV_REQ | prop->tm_chan_index; + + buf[2] = prop->timer; + + /* Digital param selection */ + adc5_gen3_update_dig_param(&prop->common_props, &buf[3]); + + /* Update fast average sample value */ + buf[4] &= ~ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK; + buf[4] |= prop->common_props.avg_samples | ADC5_GEN3_FAST_AVG_CTL_EN; + + /* Select ADC channel */ + buf[5] = prop->common_props.channel; + + /* Select HW settle delay for channel */ + buf[6] = FIELD_PREP(ADC5_GEN3_HW_SETTLE_DELAY_MASK, + prop->common_props.hw_settle_time_us); + + /* High temperature corresponds to low voltage threshold */ + prop->low_thr_en = (high_temp != INT_MAX); + if (prop->low_thr_en) { + adc_code = qcom_adc_tm5_gen2_temp_res_scale(high_temp); + put_unaligned_le16(adc_code, &buf[8]); + } + + /* Low temperature corresponds to high voltage threshold */ + prop->high_thr_en = (low_temp != -INT_MAX); + if (prop->high_thr_en) { + adc_code = qcom_adc_tm5_gen2_temp_res_scale(low_temp); + put_unaligned_le16(adc_code, &buf[10]); + } + + buf[7] = 0; + if (prop->high_thr_en) + buf[7] |= ADC5_GEN3_HIGH_THR_INT_EN; + if (prop->low_thr_en) + buf[7] |= ADC5_GEN3_LOW_THR_INT_EN; + + ret = adc5_gen3_write(adc_tm5->dev_data, prop->sdam_index, ADC5_GEN3_SID, + buf, sizeof(buf)); + if (ret < 0) + return ret; + + conv_req = ADC5_GEN3_CONV_REQ_REQ; + return adc5_gen3_write(adc_tm5->dev_data, prop->sdam_index, + ADC5_GEN3_CONV_REQ, &conv_req, sizeof(conv_req)); +} + +static int adc_tm5_gen3_set_trip_temp(struct thermal_zone_device *tz, + int low_temp, int high_temp) +{ + struct adc_tm5_gen3_channel_props *prop = thermal_zone_device_priv(tz); + struct adc_tm5_gen3_chip *adc_tm5; + + if (!prop || !prop->chip) + return -EINVAL; + + adc_tm5 = prop->chip; + + dev_dbg(adc_tm5->dev, "channel:%s, low_temp(mdegC):%d, high_temp(mdegC):%d\n", + prop->common_props.label, low_temp, high_temp); + + guard(adc5_gen3)(adc_tm5); + if (high_temp == INT_MAX && low_temp == -INT_MAX) + return adc_tm5_gen3_disable_channel(prop); + + return adc_tm5_gen3_configure(prop, low_temp, high_temp); +} + +static const struct thermal_zone_device_ops adc_tm_ops = { + .get_temp = adc_tm5_gen3_get_temp, + .set_trips = adc_tm5_gen3_set_trip_temp, +}; + +static int adc_tm5_register_tzd(struct adc_tm5_gen3_chip *adc_tm5) +{ + struct thermal_zone_device *tzd; + unsigned int channel; + int ret; + + for (int i = 0; i < adc_tm5->nchannels; i++) { + channel = ADC5_GEN3_V_CHAN(adc_tm5->chan_props[i].common_props); + tzd = devm_thermal_of_zone_register(adc_tm5->dev, channel, + &adc_tm5->chan_props[i], + &adc_tm_ops); + if (IS_ERR(tzd)) { + if (PTR_ERR(tzd) == -ENODEV) { + dev_info(adc_tm5->dev, + "thermal sensor on channel %d is not used\n", + channel); + continue; + } + return dev_err_probe(adc_tm5->dev, PTR_ERR(tzd), + "Error registering TZ zone:%ld for channel:%d\n", + PTR_ERR(tzd), channel); + } + adc_tm5->chan_props[i].tzd = tzd; + ret = devm_thermal_add_hwmon_sysfs(adc_tm5->dev, tzd); + if (ret) + return ret; + } + return 0; +} + +static void adc5_gen3_clear_work(void *data) +{ + struct adc_tm5_gen3_chip *adc_tm5 = data; + + cancel_work_sync(&adc_tm5->tm_handler_work); +} + +static void adc5_gen3_disable(void *data) +{ + struct adc_tm5_gen3_chip *adc_tm5 = data; + + guard(adc5_gen3)(adc_tm5); + /* Disable all available TM channels */ + for (int i = 0; i < adc_tm5->nchannels; i++) + adc_tm5_gen3_disable_channel(&adc_tm5->chan_props[i]); +} + +static void adctm_event_handler(struct auxiliary_device *adev) +{ + struct adc_tm5_gen3_chip *adc_tm5 = auxiliary_get_drvdata(adev); + + schedule_work(&adc_tm5->tm_handler_work); +} + +static int adc_tm5_probe(struct auxiliary_device *aux_dev, + const struct auxiliary_device_id *id) +{ + struct adc_tm5_gen3_chip *adc_tm5; + struct tm5_aux_dev_wrapper *aux_dev_wrapper; + struct device *dev = &aux_dev->dev; + int ret; + + adc_tm5 = devm_kzalloc(dev, sizeof(*adc_tm5), GFP_KERNEL); + if (!adc_tm5) + return -ENOMEM; + + aux_dev_wrapper = container_of(aux_dev, struct tm5_aux_dev_wrapper, + aux_dev); + + adc_tm5->dev = dev; + adc_tm5->dev_data = aux_dev_wrapper->dev_data; + adc_tm5->nchannels = aux_dev_wrapper->n_tm_channels; + adc_tm5->chan_props = devm_kcalloc(dev, aux_dev_wrapper->n_tm_channels, + sizeof(*adc_tm5->chan_props), GFP_KERNEL); + if (!adc_tm5->chan_props) + return -ENOMEM; + + for (int i = 0; i < adc_tm5->nchannels; i++) { + adc_tm5->chan_props[i].common_props = aux_dev_wrapper->tm_props[i]; + adc_tm5->chan_props[i].timer = MEAS_INT_1S; + adc_tm5->chan_props[i].sdam_index = (i + 1) / 8; + adc_tm5->chan_props[i].tm_chan_index = (i + 1) % 8; + adc_tm5->chan_props[i].chip = adc_tm5; + } + + INIT_WORK(&adc_tm5->tm_handler_work, tm_handler_work); + + /* + * Skipping first SDAM IRQ as it is requested in parent driver. + * If there is a TM violation on that IRQ, the parent driver calls + * the notifier (adctm_event_handler) exposed from this driver to handle it. + */ + for (int i = 1; i < adc_tm5->dev_data->num_sdams; i++) { + ret = devm_request_threaded_irq(dev, + adc_tm5->dev_data->base[i].irq, + NULL, adctm5_gen3_isr, IRQF_ONESHOT, + adc_tm5->dev_data->base[i].irq_name, + adc_tm5); + if (ret < 0) + return ret; + } + + /* + * This drvdata is only used in the function (adctm_event_handler) + * called by parent ADC driver in case of TM violation on the first SDAM. + */ + auxiliary_set_drvdata(aux_dev, adc_tm5); + + adc5_gen3_register_tm_event_notifier(dev, adctm_event_handler); + + /* + * This is to cancel any instances of tm_handler_work scheduled by + * TM interrupt, at the time of module removal. + */ + ret = devm_add_action(dev, adc5_gen3_clear_work, adc_tm5); + if (ret) + return ret; + + ret = adc_tm5_register_tzd(adc_tm5); + if (ret) + return ret; + + /* This is to disable all ADC_TM channels in case of probe failure. */ + + return devm_add_action(dev, adc5_gen3_disable, adc_tm5); +} + +static const struct auxiliary_device_id adctm5_auxiliary_id_table[] = { + { .name = "qcom_spmi_adc5_gen3.adc5_tm_gen3", }, + { } +}; + +MODULE_DEVICE_TABLE(auxiliary, adctm5_auxiliary_id_table); + +static struct auxiliary_driver adctm5gen3_auxiliary_driver = { + .id_table = adctm5_auxiliary_id_table, + .probe = adc_tm5_probe, +}; + +module_auxiliary_driver(adctm5gen3_auxiliary_driver); + +MODULE_DESCRIPTION("SPMI PMIC Thermal Monitor ADC driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("QCOM_SPMI_ADC5_GEN3"); From 676b90147a9f27b768bae74f8fdc0c2131dfc9fd Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 25 Nov 2025 23:15:12 +0530 Subject: [PATCH 078/438] FROMLIST: clk: qcom: clk-alpha-pll: Add support for controlling Rivian PLL Add clock ops for Rivian ELU and EKO_T PLLs, add the register offsets for the Rivian ELU PLL. Since ELU and EKO_T shared the same offsets and PLL ops, reuse the Rivian EKO_T enum. Signed-off-by: Jingyi Wang Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251125-kaanapali-mmcc-v2-v2-3-fb44e78f300b@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 42d3344921457..302c96b518b98 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -212,6 +212,8 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; extern const struct clk_ops clk_alpha_pll_pongo_elu_ops; #define clk_alpha_pll_pongo_eko_t_ops clk_alpha_pll_pongo_elu_ops extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; +#define clk_alpha_pll_rivian_elu_ops clk_alpha_pll_rivian_evo_ops +#define clk_alpha_pll_rivian_eko_t_ops clk_alpha_pll_rivian_evo_ops #define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops #define clk_alpha_pll_rivian_elu_ops clk_alpha_pll_rivian_evo_ops #define clk_alpha_pll_rivian_eko_t_ops clk_alpha_pll_rivian_evo_ops From 254d6f6d9b674cf039ef5c1682a25b2d14392623 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 24 Jan 2026 23:05:02 +0530 Subject: [PATCH 079/438] FROMLIST: dt-bindings: clock: qcom: Add video clock controller on Glymur SoC Add compatible string for Glymur video clock controller and the bindings for Glymur Qualcomm SoC. Add the clock resets required from the GCC clock controller for Video. Link: https://lore.kernel.org/r/20260124-glymur_videocc-v1-1-668f8b9c63be@oss.qualcomm.com Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sm8450-videocc.yaml | 3 ++ include/dt-bindings/clock/qcom,glymur-gcc.h | 1 + .../dt-bindings/clock/qcom,glymur-videocc.h | 45 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,glymur-videocc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index e6beebd6a36ee..7bbf120d928cc 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -15,6 +15,7 @@ description: | domains on SM8450. See also: + include/dt-bindings/clock/qcom,glymur-videocc.h include/dt-bindings/clock/qcom,kaanapali-videocc.h include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h @@ -23,6 +24,7 @@ description: | properties: compatible: enum: + - qcom,glymur-videocc - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8475-videocc @@ -63,6 +65,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-videocc - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8550-videocc diff --git a/include/dt-bindings/clock/qcom,glymur-gcc.h b/include/dt-bindings/clock/qcom,glymur-gcc.h index 10c12b8c51c34..6907653c79927 100644 --- a/include/dt-bindings/clock/qcom,glymur-gcc.h +++ b/include/dt-bindings/clock/qcom,glymur-gcc.h @@ -574,5 +574,6 @@ #define GCC_VIDEO_AXI0_CLK_ARES 89 #define GCC_VIDEO_AXI1_CLK_ARES 90 #define GCC_VIDEO_BCR 91 +#define GCC_VIDEO_AXI0C_CLK_ARES 92 #endif diff --git a/include/dt-bindings/clock/qcom,glymur-videocc.h b/include/dt-bindings/clock/qcom,glymur-videocc.h new file mode 100644 index 0000000000000..98c0debef8fa9 --- /dev/null +++ b/include/dt-bindings/clock/qcom,glymur-videocc.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_GLYMUR_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_GLYMUR_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_MVS0_CLK 2 +#define VIDEO_CC_MVS0_CLK_SRC 3 +#define VIDEO_CC_MVS0_DIV_CLK_SRC 4 +#define VIDEO_CC_MVS0_FREERUN_CLK 5 +#define VIDEO_CC_MVS0_SHIFT_CLK 6 +#define VIDEO_CC_MVS0C_CLK 7 +#define VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC 8 +#define VIDEO_CC_MVS0C_FREERUN_CLK 9 +#define VIDEO_CC_MVS0C_SHIFT_CLK 10 +#define VIDEO_CC_MVS1_CLK 11 +#define VIDEO_CC_MVS1_DIV_CLK_SRC 12 +#define VIDEO_CC_MVS1_FREERUN_CLK 13 +#define VIDEO_CC_MVS1_SHIFT_CLK 14 +#define VIDEO_CC_PLL0 15 +#define VIDEO_CC_SLEEP_CLK 16 +#define VIDEO_CC_SLEEP_CLK_SRC 17 +#define VIDEO_CC_XO_CLK 18 +#define VIDEO_CC_XO_CLK_SRC 19 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0_GDSC 0 +#define VIDEO_CC_MVS0C_GDSC 1 +#define VIDEO_CC_MVS1_GDSC 2 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_BCR 1 +#define VIDEO_CC_MVS0C_BCR 2 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 3 +#define VIDEO_CC_MVS0_FREERUN_CLK_ARES 4 +#define VIDEO_CC_MVS1_FREERUN_CLK_ARES 5 +#define VIDEO_CC_XO_CLK_ARES 6 +#define VIDEO_CC_MVS1_BCR 7 +#endif From 299338bed0346ccd12d948b20e3b96480fe6f1c3 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 24 Jan 2026 23:05:03 +0530 Subject: [PATCH 080/438] FROMLIST: clk: qcom: videocc-glymur: Add video clock controller driver for Glymur Add support for the video clock controller for video clients to be able to request for videocc clocks on Glymur platform. Link: https://lore.kernel.org/r/20260124-glymur_videocc-v1-2-668f8b9c63be@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-glymur.c | 1 + drivers/clk/qcom/videocc-glymur.c | 526 ++++++++++++++++++++++++++++++ 4 files changed, 537 insertions(+) create mode 100644 drivers/clk/qcom/videocc-glymur.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a8a86ea6bb744..20af4340b08f9 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,15 @@ config CLK_GLYMUR_TCSRCC Support for the TCSR clock controller on GLYMUR devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. +config CLK_GLYMUR_VIDEOCC + tristate "Glymur Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_GLYMUR_GCC + help + Support for the video clock controller on Glymur devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config CLK_KAANAPALI_CAMCC tristate "Kaanapali Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 6b0ad8832b55f..a71dfd0ddf512 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o +obj-$(CONFIG_CLK_GLYMUR_VIDEOCC) += videocc-glymur.o obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index 238e205735ed5..cd11470a75f3f 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -8507,6 +8507,7 @@ static const struct qcom_reset_map gcc_glymur_resets[] = { [GCC_VIDEO_AXI0_CLK_ARES] = { 0x3201c, 2 }, [GCC_VIDEO_AXI1_CLK_ARES] = { 0x32044, 2 }, [GCC_VIDEO_BCR] = { 0x32000 }, + [GCC_VIDEO_AXI0C_CLK_ARES] = { 0x32030, 2 }, }; static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { diff --git a/drivers/clk/qcom/videocc-glymur.c b/drivers/clk/qcom/videocc-glymur.c new file mode 100644 index 0000000000000..a504586698255 --- /dev/null +++ b/drivers/clk/qcom/videocc-glymur.c @@ -0,0 +1,526 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_VIDEO_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x25, + .alpha = 0x8000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1965000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_sleep_clk_src = { + .cmd_rcgr = 0x8120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_sleep_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x80f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0_div_clk_src = { + .reg = 0x809c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { + .reg = 0x8060, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_div2_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs1_div_clk_src = { + .reg = 0x80d8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x807c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_freerun_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x8114, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8114, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8114, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x811c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x811c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x811c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1_freerun_clk = { + .halt_reg = 0x80c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1_shift_clk = { + .halt_reg = 0x8118, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8118, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x8034, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x8068, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &video_cc_mvs0c_gdsc.pd, +}; + +static struct gdsc video_cc_mvs1_gdsc = { + .gdscr = 0x80a4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *video_cc_glymur_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, + [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr, + [VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr, + [VIDEO_CC_MVS1_FREERUN_CLK] = &video_cc_mvs1_freerun_clk.clkr, + [VIDEO_CC_MVS1_SHIFT_CLK] = &video_cc_mvs1_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_glymur_gdscs[] = { + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, + [VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc, +}; + +static const struct qcom_reset_map video_cc_glymur_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x80dc }, + [VIDEO_CC_MVS0_BCR] = { 0x8064 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x805c, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8030 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x808c, 2 }, + [VIDEO_CC_MVS1_FREERUN_CLK_ARES] = { 0x80c8, 2 }, + [VIDEO_CC_MVS1_BCR] = { 0x80a0 }, +}; + +static struct clk_alpha_pll *video_cc_glymur_plls[] = { + &video_cc_pll0, +}; + +static u32 video_cc_glymur_critical_cbcrs[] = { + 0x80e0, /* VIDEO_CC_AHB_CLK */ + 0x8138, /* VIDEO_CC_SLEEP_CLK */ + 0x8110, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9f54, + .fast_io = true, +}; + +static struct qcom_cc_driver_data video_cc_glymur_driver_data = { + .alpha_plls = video_cc_glymur_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_glymur_plls), + .clk_cbcrs = video_cc_glymur_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_glymur_critical_cbcrs), +}; + +static struct qcom_cc_desc video_cc_glymur_desc = { + .config = &video_cc_glymur_regmap_config, + .clks = video_cc_glymur_clocks, + .num_clks = ARRAY_SIZE(video_cc_glymur_clocks), + .resets = video_cc_glymur_resets, + .num_resets = ARRAY_SIZE(video_cc_glymur_resets), + .gdscs = video_cc_glymur_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_glymur_gdscs), + .use_rpm = true, + .driver_data = &video_cc_glymur_driver_data, +}; + +static const struct of_device_id video_cc_glymur_match_table[] = { + { .compatible = "qcom,glymur-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_glymur_match_table); + +static int video_cc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_glymur_desc); +} + +static struct platform_driver video_cc_glymur_driver = { + .probe = video_cc_glymur_probe, + .driver = { + .name = "videocc-glymur", + .of_match_table = video_cc_glymur_match_table, + }, +}; + +module_platform_driver(video_cc_glymur_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Glymur Driver"); +MODULE_LICENSE("GPL"); From a711fff8ae4ccee097f5d2e79728897b392349c7 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 30 Jan 2026 15:15:31 +0530 Subject: [PATCH 081/438] FROMLIST: dt-bindings: clock: qcom: document the Glymur GPU Clock Controller Glymur SoC has Qualcomm GX(graphics) clock controller and also the Graphics clock controller. The GX graphics clock controller helps in the recovery of the Graphics subsystem. Add bindings documentation for the Glymur Graphics Clock and Graphics power domain Controller for Glymur SoC. Link: https://lore.kernel.org/all/20260127-glymur_gpucc-v1-1-547334c81ba2@oss.qualcomm.com/ Signed-off-by: Taniya Das --- .../clock/qcom,kaanapali-gxclkctl.yaml | 1 + .../bindings/clock/qcom,sm8450-gpucc.yaml | 4 +- include/dt-bindings/clock/qcom,glymur-gpucc.h | 51 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,glymur-gpucc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml index 5490a975f3db7..55bf3f8110171 100644 --- a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml @@ -20,6 +20,7 @@ description: | properties: compatible: enum: + - qcom,glymur-gxclkctl - qcom,kaanapali-gxclkctl power-domains: diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 6feaa32569f9a..5993804c91fa5 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -13,7 +13,8 @@ description: | Qualcomm graphics clock control module provides the clocks, resets and power domains on Qualcomm SoCs. - See also:: + See also: + include/dt-bindings/clock/qcom,glymur-gpucc.h include/dt-bindings/clock/qcom,kaanapali-gpucc.h include/dt-bindings/clock/qcom,milos-gpucc.h include/dt-bindings/clock/qcom,sar2130p-gpucc.h @@ -27,6 +28,7 @@ description: | properties: compatible: enum: + - qcom,glymur-gpucc - qcom,kaanapali-gpucc - qcom,milos-gpucc - qcom,sar2130p-gpucc diff --git a/include/dt-bindings/clock/qcom,glymur-gpucc.h b/include/dt-bindings/clock/qcom,glymur-gpucc.h new file mode 100644 index 0000000000000..35f5abb848fd0 --- /dev/null +++ b/include/dt-bindings/clock/qcom,glymur-gpucc.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_GLYMUR_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_GLYMUR_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CB_CLK 1 +#define GPU_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_CC_CX_FF_CLK 3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CXO_AON_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_DEMET_CLK 7 +#define GPU_CC_DPM_CLK 8 +#define GPU_CC_FF_CLK_SRC 9 +#define GPU_CC_FREQ_MEASURE_CLK 10 +#define GPU_CC_GMU_CLK_SRC 11 +#define GPU_CC_GPU_SMMU_VOTE_CLK 12 +#define GPU_CC_GX_ACCU_SHIFT_CLK 13 +#define GPU_CC_GX_ACD_AHB_FF_CLK 14 +#define GPU_CC_GX_AHB_FF_CLK 15 +#define GPU_CC_GX_GMU_CLK 16 +#define GPU_CC_GX_RCG_AHB_FF_CLK 17 +#define GPU_CC_HUB_AON_CLK 18 +#define GPU_CC_HUB_CLK_SRC 19 +#define GPU_CC_HUB_CX_INT_CLK 20 +#define GPU_CC_HUB_DIV_CLK_SRC 21 +#define GPU_CC_MEMNOC_GFX_CLK 22 +#define GPU_CC_PLL0 23 +#define GPU_CC_PLL0_OUT_EVEN 24 +#define GPU_CC_RSCC_HUB_AON_CLK 25 +#define GPU_CC_RSCC_XO_AON_CLK 26 +#define GPU_CC_SLEEP_CLK 27 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 + +/* GPU_CC resets */ +#define GPU_CC_CB_BCR 0 +#define GPU_CC_CX_BCR 1 +#define GPU_CC_FAST_HUB_BCR 2 +#define GPU_CC_FF_BCR 3 +#define GPU_CC_GMU_BCR 4 +#define GPU_CC_GX_BCR 5 +#define GPU_CC_XO_BCR 6 + +#endif From 223c5f2d05d8fec3c46b57ef4b163b72dd4ff706 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 30 Jan 2026 15:17:24 +0530 Subject: [PATCH 082/438] FROMLIST: clk: qcom: Add support for GPUCC and GXCLK for Glymur Support the graphics clock controller for Glymur for Graphics SW driver to use the clocks. GXCLKCTL (Graphics GX Clock Controller) is a block dedicated to managing clocks for the GPU subsystem on GX power domain. The GX clock controller driver manages only the GX GDSC and the rest of the resources of the controller are managed by the firmware. Update the compatible for Graphics GX Clock Controller for Glymur as the GX clock controller is a reuse of the Kaanapali driver. Link: https://lore.kernel.org/all/20260127-glymur_gpucc-v1-2-547334c81ba2@oss.qualcomm.com/ Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-glymur.c | 619 ++++++++++++++++++++++++++ drivers/clk/qcom/gxclkctl-kaanapali.c | 1 + 4 files changed, 630 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-glymur.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 20af4340b08f9..c18434a06eb8c 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -38,6 +38,15 @@ config CLK_GLYMUR_GCC Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config CLK_GLYMUR_GPUCC + tristate "GLYMUR Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_GLYMUR_GCC + help + Support for the graphics clock controller on GLYMUR devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_GLYMUR_TCSRCC tristate "GLYMUR TCSR Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index a71dfd0ddf512..90ea21c3b7cf7 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o +obj-$(CONFIG_CLK_GLYMUR_GPUCC) += gpucc-glymur.o gxclkctl-kaanapali.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_VIDEOCC) += videocc-glymur.o obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o diff --git a/drivers/clk/qcom/gpucc-glymur.c b/drivers/clk/qcom/gpucc-glymur.c new file mode 100644 index 0000000000000..6597ded955363 --- /dev/null +++ b/drivers/clk/qcom/gpucc-glymur.c @@ -0,0 +1,619 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 1150.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x3b, + .alpha = 0xe555, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gpu_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL0_OUT_EVEN, 2 }, + { P_GPU_CC_PLL0_OUT_ODD, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0_out_even.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_ff_clk_src = { + .cmd_rcgr = 0x9474, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_ff_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ff_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(575000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(700000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(725000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(750000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x9318, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x93f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_hub_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_div_clk_src = { + .reg = 0x9430, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x90bc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x90bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_accu_shift_clk = { + .halt_reg = 0x9108, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_ff_clk = { + .halt_reg = 0x90ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x90d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x90e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_demet_clk = { + .halt_reg = 0x9010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_demet_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_dpm_clk = { + .halt_reg = 0x910c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x910c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_dpm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_freq_measure_clk = { + .halt_reg = 0x900c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x900c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_freq_measure_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gpu_smmu_vote_clk = { + .halt_reg = 0x7000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_accu_shift_clk = { + .halt_reg = 0x9070, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_acd_ahb_ff_clk = { + .halt_reg = 0x9068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_acd_ahb_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_ahb_ff_clk = { + .halt_reg = 0x9064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_ahb_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gmu_clk = { + .halt_reg = 0x9060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_rcg_ahb_ff_clk = { + .halt_reg = 0x906c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x906c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_rcg_ahb_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x93ec, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x93ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_cx_int_clk = { + .halt_reg = 0x90e8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_cx_int_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_memnoc_gfx_clk = { + .halt_reg = 0x90f0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_rscc_hub_aon_clk = { + .halt_reg = 0x93e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x93e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_rscc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_sleep_clk = { + .halt_reg = 0x90cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x9080, + .gds_hw_ctrl = 0x9094, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_glymur_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, + [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, + [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr, + [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, + [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GPU_SMMU_VOTE_CLK] = &gpu_cc_gpu_smmu_vote_clk.clkr, + [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr, + [GPU_CC_GX_ACD_AHB_FF_CLK] = &gpu_cc_gx_acd_ahb_ff_clk.clkr, + [GPU_CC_GX_AHB_FF_CLK] = &gpu_cc_gx_ahb_ff_clk.clkr, + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, + [GPU_CC_GX_RCG_AHB_FF_CLK] = &gpu_cc_gx_rcg_ahb_ff_clk.clkr, + [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, + [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, + [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, + [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr, + [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, + [GPU_CC_RSCC_HUB_AON_CLK] = &gpu_cc_rscc_hub_aon_clk.clkr, + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, +}; + +static struct gdsc *gpu_cc_glymur_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_glymur_resets[] = { + [GPU_CC_CB_BCR] = { 0x93a0 }, + [GPU_CC_CX_BCR] = { 0x907c }, + [GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, + [GPU_CC_FF_BCR] = { 0x9470 }, + [GPU_CC_GMU_BCR] = { 0x9314 }, + [GPU_CC_GX_BCR] = { 0x905c }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_cc_glymur_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_glymur_critical_cbcrs[] = { + 0x93a4, /* GPU_CC_CB_CLK */ + 0x9008, /* GPU_CC_CXO_AON_CLK */ + 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ +}; + +static const struct regmap_config gpu_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x95e8, + .fast_io = true, +}; + +static struct qcom_cc_driver_data gpu_cc_glymur_driver_data = { + .alpha_plls = gpu_cc_glymur_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_glymur_plls), + .clk_cbcrs = gpu_cc_glymur_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_glymur_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_glymur_desc = { + .config = &gpu_cc_glymur_regmap_config, + .clks = gpu_cc_glymur_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_glymur_clocks), + .resets = gpu_cc_glymur_resets, + .num_resets = ARRAY_SIZE(gpu_cc_glymur_resets), + .gdscs = gpu_cc_glymur_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_glymur_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_glymur_driver_data, +}; + +static const struct of_device_id gpu_cc_glymur_match_table[] = { + { .compatible = "qcom,glymur-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_glymur_match_table); + +static int gpu_cc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_glymur_desc); +} + +static struct platform_driver gpu_cc_glymur_driver = { + .probe = gpu_cc_glymur_probe, + .driver = { + .name = "gpucc-glymur", + .of_match_table = gpu_cc_glymur_match_table, + }, +}; + +module_platform_driver(gpu_cc_glymur_driver); + +MODULE_DESCRIPTION("QTI GPUCC GLYMUR Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c index c209ce5fe4f00..3ee512f34967f 100644 --- a/drivers/clk/qcom/gxclkctl-kaanapali.c +++ b/drivers/clk/qcom/gxclkctl-kaanapali.c @@ -52,6 +52,7 @@ static const struct qcom_cc_desc gx_clkctl_kaanapali_desc = { }; static const struct of_device_id gx_clkctl_kaanapali_match_table[] = { + { .compatible = "qcom,glymur-gxclkctl" }, { .compatible = "qcom,kaanapali-gxclkctl" }, { } }; From f48f71ccfa7e57d263bc8f187cf03b0df97ceddb Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:32 +0530 Subject: [PATCH 083/438] FROMLIST: dt-bindings: clock: qcom: Add X1P42100 video clock controller X1P42100 video clock controller has most clocks same as SM8650, but it also has few additional clocks and resets. Add device tree bindings for the video clock controller on Qualcomm X1P42100 platform by defining these additional clocks and resets on top of SM8650. Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-1-b23de57df5ba@oss.qualcomm.com --- .../bindings/clock/qcom,sm8450-videocc.yaml | 2 ++ .../dt-bindings/clock/qcom,x1p42100-videocc.h | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,x1p42100-videocc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index 7bbf120d928cc..91538be4543c5 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -32,6 +32,7 @@ properties: - qcom,sm8650-videocc - qcom,sm8750-videocc - qcom,x1e80100-videocc + - qcom,x1p42100-videocc clocks: items: @@ -70,6 +71,7 @@ allOf: - qcom,sm8450-videocc - qcom,sm8550-videocc - qcom,sm8750-videocc + - qcom,x1p42100-videocc then: required: - required-opps diff --git a/include/dt-bindings/clock/qcom,x1p42100-videocc.h b/include/dt-bindings/clock/qcom,x1p42100-videocc.h new file mode 100644 index 0000000000000..eb6c9b7264f8c --- /dev/null +++ b/include/dt-bindings/clock/qcom,x1p42100-videocc.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_X1P42100_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_X1P42100_H + +#include "qcom,sm8650-videocc.h" + +/* X1P42100 introduces below new clocks and resets compared to SM8650 */ + +/* VIDEO_CC clocks */ +#define VIDEO_CC_MVS0_BSE_CLK 17 +#define VIDEO_CC_MVS0_BSE_CLK_SRC 18 +#define VIDEO_CC_MVS0_BSE_DIV4_DIV_CLK_SRC 19 + +/* VIDEO_CC resets */ +#define VIDEO_CC_MVS0_BSE_BCR 8 + +#endif From 8e51954bf1b8b8b63df6c06ab68e02fa6f8d7acc Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:33 +0530 Subject: [PATCH 084/438] FROMLIST: dt-bindings: clock: qcom: Add X1P42100 camera clock controller Add X1P42100 camera clock controller support and clock bindings for camera QDSS debug clocks which are applicable for both X1E80100 and X1P42100 platforms. Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-2-b23de57df5ba@oss.qualcomm.com Signed-off-by: Jagadeesh Kona Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/clock/qcom,x1e80100-camcc.yaml | 1 + include/dt-bindings/clock/qcom,x1e80100-camcc.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml index 938a2f1ff3fca..b28614186cc09 100644 --- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml @@ -23,6 +23,7 @@ properties: compatible: enum: - qcom,x1e80100-camcc + - qcom,x1p42100-camcc reg: maxItems: 1 diff --git a/include/dt-bindings/clock/qcom,x1e80100-camcc.h b/include/dt-bindings/clock/qcom,x1e80100-camcc.h index d72fdfb06a7c7..06c316022fb0d 100644 --- a/include/dt-bindings/clock/qcom,x1e80100-camcc.h +++ b/include/dt-bindings/clock/qcom,x1e80100-camcc.h @@ -115,6 +115,9 @@ #define CAM_CC_SLEEP_CLK_SRC 105 #define CAM_CC_SLOW_AHB_CLK_SRC 106 #define CAM_CC_XO_CLK_SRC 107 +#define CAM_CC_QDSS_DEBUG_CLK 108 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 109 +#define CAM_CC_QDSS_DEBUG_XO_CLK 110 /* CAM_CC power domains */ #define CAM_CC_BPS_GDSC 0 From 1b5e2f0a55abd2a2dd28357b19653198fec0373e Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:34 +0530 Subject: [PATCH 085/438] FROMLIST: clk: qcom: videocc-x1p42100: Add support for video clock controller Add support for the video clock controller for video clients to be able to request for videocc clocks on X1P42100 platform. Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-3-b23de57df5ba@oss.qualcomm.com Signed-off-by: Jagadeesh Kona Reviewed-by: Taniya Das --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-x1p42100.c | 585 ++++++++++++++++++++++++++++ 3 files changed, 596 insertions(+) create mode 100644 drivers/clk/qcom/videocc-x1p42100.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index c18434a06eb8c..26570b18e94f4 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -173,6 +173,16 @@ config CLK_X1P42100_GPUCC Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config CLK_X1P42100_VIDEOCC + tristate "X1P42100 Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_X1E80100_GCC + help + Support for the video clock controller on Qualcomm Technologies, Inc. + X1P42100 devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config CLK_QCM2290_GPUCC tristate "QCM2290 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 90ea21c3b7cf7..0b0b229fe61d0 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o +obj-$(CONFIG_CLK_X1P42100_VIDEOCC) += videocc-x1p42100.o obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o obj-$(CONFIG_IPQ_APSS_5424) += apss-ipq5424.o diff --git a/drivers/clk/qcom/videocc-x1p42100.c b/drivers/clk/qcom/videocc-x1p42100.c new file mode 100644 index 0000000000000..2bb40ac6fcc57 --- /dev/null +++ b/drivers/clk/qcom/videocc-x1p42100.c @@ -0,0 +1,585 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, +}; + +enum { + P_BI_TCXO, + P_VIDEO_CC_PLL0_OUT_MAIN, + P_VIDEO_CC_PLL1_OUT_MAIN, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 420.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x15, + .alpha = 0xe000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 1050.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll1_config = { + .l = 0x36, + .alpha = 0xb000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll video_cc_pll1 = { + .offset = 0x1000, + .config = &video_cc_pll1_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll1.clkr.hw }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_bse_clk_src[] = { + F(420000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(670000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(848000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(920000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_bse_clk_src = { + .cmd_rcgr = 0x8154, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_bse_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_bse_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(210000000, P_VIDEO_CC_PLL0_OUT_MAIN, 2, 0, 0), + F(300000000, P_VIDEO_CC_PLL0_OUT_MAIN, 2, 0, 0), + F(335000000, P_VIDEO_CC_PLL0_OUT_MAIN, 2, 0, 0), + F(424000000, P_VIDEO_CC_PLL0_OUT_MAIN, 2, 0, 0), + F(460000000, P_VIDEO_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = { + F(1050000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs1_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_mvs1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x810c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0_bse_div4_div_clk_src = { + .reg = 0x817c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_bse_div4_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_bse_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs1_div_clk_src = { + .reg = 0x80ec, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = { + .reg = 0x809c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1c_div2_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_bse_clk = { + .halt_reg = 0x8170, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8170, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_bse_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_bse_div4_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x8128, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8128, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x812c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x812c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1_clk = { + .halt_reg = 0x80e0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80e0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1_shift_clk = { + .halt_reg = 0x8130, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8130, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1c_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs1c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs1c_shift_clk = { + .halt_reg = 0x8134, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x804c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x80a4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0c_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs1c_gdsc = { + .gdscr = 0x8078, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs1c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs1_gdsc = { + .gdscr = 0x80cc, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs1c_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *video_cc_x1p42100_clocks[] = { + [VIDEO_CC_MVS0_BSE_CLK] = &video_cc_mvs0_bse_clk.clkr, + [VIDEO_CC_MVS0_BSE_CLK_SRC] = &video_cc_mvs0_bse_clk_src.clkr, + [VIDEO_CC_MVS0_BSE_DIV4_DIV_CLK_SRC] = &video_cc_mvs0_bse_div4_div_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr, + [VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr, + [VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr, + [VIDEO_CC_MVS1_SHIFT_CLK] = &video_cc_mvs1_shift_clk.clkr, + [VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr, + [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, + [VIDEO_CC_MVS1C_SHIFT_CLK] = &video_cc_mvs1c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_x1p42100_gdscs[] = { + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, + [VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc, + [VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc, +}; + +static const struct qcom_reset_map video_cc_x1p42100_resets[] = { + [CVP_VIDEO_CC_INTERFACE_BCR] = { 0x80f0 }, + [CVP_VIDEO_CC_MVS0_BCR] = { 0x80a0 }, + [CVP_VIDEO_CC_MVS0C_BCR] = { 0x8048 }, + [CVP_VIDEO_CC_MVS1_BCR] = { 0x80c8 }, + [CVP_VIDEO_CC_MVS1C_BCR] = { 0x8074 }, + [VIDEO_CC_MVS0_BSE_BCR] = { 0x816c }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8064, 2 }, + [VIDEO_CC_MVS1C_CLK_ARES] = { 0x8090, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x8124, 2 }, +}; + +static struct clk_alpha_pll *video_cc_x1p42100_plls[] = { + &video_cc_pll0, + &video_cc_pll1, +}; + +static u32 video_cc_x1p42100_critical_cbcrs[] = { + 0x80f4, /* VIDEO_CC_AHB_CLK */ + 0x8150, /* VIDEO_CC_SLEEP_CLK */ + 0x8124, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_x1p42100_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9f54, + .fast_io = true, +}; + +static struct qcom_cc_driver_data video_cc_x1p42100_driver_data = { + .alpha_plls = video_cc_x1p42100_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_x1p42100_plls), + .clk_cbcrs = video_cc_x1p42100_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_x1p42100_critical_cbcrs), +}; + +static const struct qcom_cc_desc video_cc_x1p42100_desc = { + .config = &video_cc_x1p42100_regmap_config, + .clks = video_cc_x1p42100_clocks, + .num_clks = ARRAY_SIZE(video_cc_x1p42100_clocks), + .resets = video_cc_x1p42100_resets, + .num_resets = ARRAY_SIZE(video_cc_x1p42100_resets), + .gdscs = video_cc_x1p42100_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_x1p42100_gdscs), + .use_rpm = true, + .driver_data = &video_cc_x1p42100_driver_data, +}; + +static const struct of_device_id video_cc_x1p42100_match_table[] = { + { .compatible = "qcom,x1p42100-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_x1p42100_match_table); + +static int video_cc_x1p42100_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_x1p42100_desc); +} + +static struct platform_driver video_cc_x1p42100_driver = { + .probe = video_cc_x1p42100_probe, + .driver = { + .name = "videocc-x1p42100", + .of_match_table = video_cc_x1p42100_match_table, + }, +}; + +module_platform_driver(video_cc_x1p42100_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC X1P42100 Driver"); +MODULE_LICENSE("GPL"); From 9691dd2ce8708259d0154c298fc08a67f38a35a9 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:35 +0530 Subject: [PATCH 086/438] FROMLIST: clk: qcom: camcc-x1e80100: Add support for camera QDSS debug clocks Add support for camera QDSS debug clocks on X1E80100 platform. Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-4-b23de57df5ba@oss.qualcomm.com Signed-off-by: Jagadeesh Kona Fixes: 76126a5129b5 ("clk: qcom: Add camcc clock driver for x1e80100") Reviewed-by: Konrad Dybcio Reviewed-by: Bryan O'Donoghue --- drivers/clk/qcom/camcc-x1e80100.c | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/clk/qcom/camcc-x1e80100.c b/drivers/clk/qcom/camcc-x1e80100.c index cbcc1c9fcb341..7e3fc7aee854e 100644 --- a/drivers/clk/qcom/camcc-x1e80100.c +++ b/drivers/clk/qcom/camcc-x1e80100.c @@ -1052,6 +1052,31 @@ static struct clk_rcg2 cam_cc_mclk7_clk_src = { }, }; +static const struct freq_tbl ftbl_cam_cc_qdss_debug_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_CAM_CC_PLL8_OUT_EVEN, 8, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x13938, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + static const struct freq_tbl ftbl_cam_cc_sfe_0_clk_src[] = { F(345600000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), F(432000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), @@ -2182,6 +2207,42 @@ static struct clk_branch cam_cc_mclk7_clk = { }, }; +static struct clk_branch cam_cc_qdss_debug_clk = { + .halt_reg = 0x13a64, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13a64, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qdss_debug_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_xo_clk = { + .halt_reg = 0x13a68, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13a68, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch cam_cc_sfe_0_clk = { .halt_reg = 0x133c0, .halt_check = BRANCH_HALT, @@ -2398,6 +2459,9 @@ static struct clk_regmap *cam_cc_x1e80100_clocks[] = { [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, [CAM_CC_PLL8] = &cam_cc_pll8.clkr, [CAM_CC_PLL8_OUT_EVEN] = &cam_cc_pll8_out_even.clkr, + [CAM_CC_QDSS_DEBUG_CLK] = &cam_cc_qdss_debug_clk.clkr, + [CAM_CC_QDSS_DEBUG_CLK_SRC] = &cam_cc_qdss_debug_clk_src.clkr, + [CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr, [CAM_CC_SFE_0_CLK] = &cam_cc_sfe_0_clk.clkr, [CAM_CC_SFE_0_CLK_SRC] = &cam_cc_sfe_0_clk_src.clkr, [CAM_CC_SFE_0_FAST_AHB_CLK] = &cam_cc_sfe_0_fast_ahb_clk.clkr, From 8507a1cfbcd53e466abccdd51ce8cb19acb25948 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:36 +0530 Subject: [PATCH 087/438] FROMLIST: clk: qcom: camcc-x1p42100: Add support for camera clock controller Add support for the camera clock controller for camera clients to be able to request for camcc clocks on X1P42100 platform. Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-5-b23de57df5ba@oss.qualcomm.com Signed-off-by: Jagadeesh Kona Reviewed-by: Konrad Dybcio Reviewed-by: Taniya Das --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/camcc-x1p42100.c | 2223 +++++++++++++++++++++++++++++ 3 files changed, 2234 insertions(+) create mode 100644 drivers/clk/qcom/camcc-x1p42100.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 26570b18e94f4..98bb8fb57709b 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -164,6 +164,16 @@ config CLK_X1E80100_TCSRCC Support for the TCSR clock controller on X1E80100 devices. Say Y if you want to use peripheral devices such as SD/UFS. +config CLK_X1P42100_CAMCC + tristate "X1P42100 Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_X1E80100_GCC + help + Support for the camera clock controller on Qualcomm Technologies, Inc. + X1P42100 devices. + Say Y if you want to support camera devices and camera functionality + such as capturing pictures. + config CLK_X1P42100_GPUCC tristate "X1P42100 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 0b0b229fe61d0..2a08ef4840828 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o +obj-$(CONFIG_CLK_X1P42100_CAMCC) += camcc-x1p42100.o obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o obj-$(CONFIG_CLK_X1P42100_VIDEOCC) += videocc-x1p42100.o obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o diff --git a/drivers/clk/qcom/camcc-x1p42100.c b/drivers/clk/qcom/camcc-x1p42100.c new file mode 100644 index 0000000000000..c1a61c2679199 --- /dev/null +++ b/drivers/clk/qcom/camcc-x1p42100.c @@ -0,0 +1,2223 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_BI_TCXO_AO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL2_OUT_MAIN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_SLEEP_CLK, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +static const struct pll_vco rivian_ole_vco[] = { + { 777000000, 1285000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_cc_pll0_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +/* 728.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x25, + .alpha = 0xeaaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x10000030, + .config_ctl_hi_val = 0x80890263, + .config_ctl_hi1_val = 0x00000217, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00100000, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_config, + .vco_table = rivian_ole_vco, + .num_vco = ARRAY_SIZE(rivian_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_evo_ops, + }, + }, +}; + +/* 864.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x2d, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 3 }, + { P_CAM_CC_PLL2_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2.clkr.hw }, + { .hw = &cam_cc_pll2.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x10278, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_axi_rt_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_axi_rt_clk_src = { + .cmd_rcgr = 0x138f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_axi_rt_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_rt_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x1365c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .cmd_rcgr = 0x1378c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x11164, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cphy_rx_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x150e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x15104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x15124, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x15258, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .cmd_rcgr = 0x1538c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { + .cmd_rcgr = 0x154c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csid_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csid_clk_src = { + .cmd_rcgr = 0x138d4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csid_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x10018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_fast_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_clk_src = { + .cmd_rcgr = 0x13520, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(432000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(727000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_lite_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x13000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_lite_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x1313c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_lite_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_nps_clk_src[] = { + F(364000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(500000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(700000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x103cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk_src", + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_jpeg_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x133dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_jpeg_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_CC_PLL2_OUT_MAIN, 10, 1, 4), + F(68571429, P_CAM_CC_PLL2_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .cmd_rcgr = 0x15000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk0_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .cmd_rcgr = 0x1501c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk1_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .cmd_rcgr = 0x15038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk2_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .cmd_rcgr = 0x15054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk3_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk4_clk_src = { + .cmd_rcgr = 0x15070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk4_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk5_clk_src = { + .cmd_rcgr = 0x1508c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk5_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk6_clk_src = { + .cmd_rcgr = 0x150a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk6_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk7_clk_src = { + .cmd_rcgr = 0x150c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk7_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_qdss_debug_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x13938, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sleep_clk_src = { + .cmd_rcgr = 0x13aa0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sleep_clk_src", + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x10148, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_slow_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x13a84, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_5, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_cc_bps_ahb_clk = { + .halt_reg = 0x10274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_clk = { + .halt_reg = 0x103a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x103a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_fast_ahb_clk = { + .halt_reg = 0x10144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_nrt_clk = { + .halt_reg = 0x13920, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x13920, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x13920, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_nrt_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_axi_rt_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_rt_clk = { + .halt_reg = 0x13910, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13910, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_rt_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_axi_rt_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_dcd_xo_clk = { + .halt_reg = 0x1392c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1392c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_dcd_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_xo_clk = { + .halt_reg = 0x13930, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13930, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_0_clk = { + .halt_reg = 0x13788, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13788, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_1_clk = { + .halt_reg = 0x138b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x138b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_core_ahb_clk = { + .halt_reg = 0x13a80, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x13a80, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ahb_clk = { + .halt_reg = 0x138bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x138bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_bps_clk = { + .halt_reg = 0x103b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x103b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_fast_ahb_clk = { + .halt_reg = 0x138c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x138c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_0_clk = { + .halt_reg = 0x11150, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_lite_clk = { + .halt_reg = 0x13138, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13138, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ipe_nps_clk = { + .halt_reg = 0x10504, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10504, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x150f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x1511c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1511c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x15250, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15250, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x15384, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15384, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi4phytimer_clk = { + .halt_reg = 0x154b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x154b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi4phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi5phytimer_clk = { + .halt_reg = 0x155ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x155ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi5phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_clk = { + .halt_reg = 0x138ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x138ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_csiphy_rx_clk = { + .halt_reg = 0x15100, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15100, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_csiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x150fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x15120, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x15254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x15388, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15388, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy4_clk = { + .halt_reg = 0x154bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x154bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy5_clk = { + .halt_reg = 0x155f0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x155f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_ahb_clk = { + .halt_reg = 0x13658, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13658, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_clk = { + .halt_reg = 0x1364c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1364c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_clk = { + .halt_reg = 0x11144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_dsp_clk = { + .halt_reg = 0x11154, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11154, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_dsp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_fast_ahb_clk = { + .halt_reg = 0x11160, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11160, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_ahb_clk = { + .halt_reg = 0x13278, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13278, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0x1312c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1312c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0x13274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0x13268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13268, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_ahb_clk = { + .halt_reg = 0x1051c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1051c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_clk = { + .halt_reg = 0x104f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x104f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_fast_ahb_clk = { + .halt_reg = 0x10520, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10520, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_clk = { + .halt_reg = 0x10508, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10508, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_fast_ahb_clk = { + .halt_reg = 0x10524, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10524, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0x13508, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13508, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk0_clk = { + .halt_reg = 0x15018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk1_clk = { + .halt_reg = 0x15034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk2_clk = { + .halt_reg = 0x15050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk3_clk = { + .halt_reg = 0x1506c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1506c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk4_clk = { + .halt_reg = 0x15088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk5_clk = { + .halt_reg = 0x150a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk6_clk = { + .halt_reg = 0x150c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk7_clk = { + .halt_reg = 0x150dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_clk = { + .halt_reg = 0x13a64, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13a64, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qdss_debug_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_xo_clk = { + .halt_reg = 0x13a68, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13a68, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x13a6c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_titan_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_bps_gdsc = { + .gdscr = 0x10004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x103b8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_x1p42100_clocks[] = { + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, + [CAM_CC_BPS_FAST_AHB_CLK] = &cam_cc_bps_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_AXI_NRT_CLK] = &cam_cc_camnoc_axi_nrt_clk.clkr, + [CAM_CC_CAMNOC_AXI_RT_CLK] = &cam_cc_camnoc_axi_rt_clk.clkr, + [CAM_CC_CAMNOC_AXI_RT_CLK_SRC] = &cam_cc_camnoc_axi_rt_clk_src.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_XO_CLK] = &cam_cc_camnoc_xo_clk.clkr, + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, + [CAM_CC_CPAS_BPS_CLK] = &cam_cc_cpas_bps_clk.clkr, + [CAM_CC_CPAS_FAST_AHB_CLK] = &cam_cc_cpas_fast_ahb_clk.clkr, + [CAM_CC_CPAS_IFE_0_CLK] = &cam_cc_cpas_ife_0_clk.clkr, + [CAM_CC_CPAS_IFE_LITE_CLK] = &cam_cc_cpas_ife_lite_clk.clkr, + [CAM_CC_CPAS_IPE_NPS_CLK] = &cam_cc_cpas_ipe_nps_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr, + [CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr, + [CAM_CC_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_clk_src.clkr, + [CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr, + [CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr, + [CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr, + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, + [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr, + [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr, + [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr, + [CAM_CC_IFE_0_FAST_AHB_CLK] = &cam_cc_ife_0_fast_ahb_clk.clkr, + [CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_NPS_AHB_CLK] = &cam_cc_ipe_nps_ahb_clk.clkr, + [CAM_CC_IPE_NPS_CLK] = &cam_cc_ipe_nps_clk.clkr, + [CAM_CC_IPE_NPS_CLK_SRC] = &cam_cc_ipe_nps_clk_src.clkr, + [CAM_CC_IPE_NPS_FAST_AHB_CLK] = &cam_cc_ipe_nps_fast_ahb_clk.clkr, + [CAM_CC_IPE_PPS_CLK] = &cam_cc_ipe_pps_clk.clkr, + [CAM_CC_IPE_PPS_FAST_AHB_CLK] = &cam_cc_ipe_pps_fast_ahb_clk.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr, + [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr, + [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr, + [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr, + [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr, + [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr, + [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr, + [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr, + [CAM_CC_MCLK4_CLK] = &cam_cc_mclk4_clk.clkr, + [CAM_CC_MCLK4_CLK_SRC] = &cam_cc_mclk4_clk_src.clkr, + [CAM_CC_MCLK5_CLK] = &cam_cc_mclk5_clk.clkr, + [CAM_CC_MCLK5_CLK_SRC] = &cam_cc_mclk5_clk_src.clkr, + [CAM_CC_MCLK6_CLK] = &cam_cc_mclk6_clk.clkr, + [CAM_CC_MCLK6_CLK_SRC] = &cam_cc_mclk6_clk_src.clkr, + [CAM_CC_MCLK7_CLK] = &cam_cc_mclk7_clk.clkr, + [CAM_CC_MCLK7_CLK_SRC] = &cam_cc_mclk7_clk_src.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_QDSS_DEBUG_CLK] = &cam_cc_qdss_debug_clk.clkr, + [CAM_CC_QDSS_DEBUG_CLK_SRC] = &cam_cc_qdss_debug_clk_src.clkr, + [CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr, + [CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_x1p42100_gdscs[] = { + [CAM_CC_BPS_GDSC] = &cam_cc_bps_gdsc, + [CAM_CC_IFE_0_GDSC] = &cam_cc_ife_0_gdsc, + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_x1p42100_resets[] = { + [CAM_CC_BPS_BCR] = { 0x10000 }, + [CAM_CC_ICP_BCR] = { 0x1351c }, + [CAM_CC_IFE_0_BCR] = { 0x11000 }, + [CAM_CC_IPE_0_BCR] = { 0x103b4 }, +}; + +static struct clk_alpha_pll *cam_cc_x1p42100_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll6, +}; + +static u32 cam_cc_x1p42100_critical_cbcrs[] = { + 0x13a9c, /* CAM_CC_GDSC_CLK */ + 0x13ab8, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_x1p42100_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1603c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_x1p42100_driver_data = { + .alpha_plls = cam_cc_x1p42100_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_x1p42100_plls), + .clk_cbcrs = cam_cc_x1p42100_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_x1p42100_critical_cbcrs), +}; + +static struct qcom_cc_desc cam_cc_x1p42100_desc = { + .config = &cam_cc_x1p42100_regmap_config, + .clks = cam_cc_x1p42100_clocks, + .num_clks = ARRAY_SIZE(cam_cc_x1p42100_clocks), + .resets = cam_cc_x1p42100_resets, + .num_resets = ARRAY_SIZE(cam_cc_x1p42100_resets), + .gdscs = cam_cc_x1p42100_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_x1p42100_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_x1p42100_driver_data, +}; + +static const struct of_device_id cam_cc_x1p42100_match_table[] = { + { .compatible = "qcom,x1p42100-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_x1p42100_match_table); + +static int cam_cc_x1p42100_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_x1p42100_desc); +} + +static struct platform_driver cam_cc_x1p42100_driver = { + .probe = cam_cc_x1p42100_probe, + .driver = { + .name = "camcc-x1p42100", + .of_match_table = cam_cc_x1p42100_match_table, + }, +}; + +module_platform_driver(cam_cc_x1p42100_driver); + +MODULE_DESCRIPTION("QTI CAMCC X1P42100 Driver"); +MODULE_LICENSE("GPL"); From 7936121351ee8b1a8ef35ce0cd75f7e7e99e19b5 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 20 Feb 2026 11:24:20 +0530 Subject: [PATCH 088/438] FROMLIST: dt-bindings: clock: qcom: Add SM8750 GPU clocks The SM8750 features a "traditional" GPU_CC block, much of which is controlled through the GMU microcontroller. Additionally, there's an separate GX_CC block, where the GX GDSC is moved. Update the bindings to accommodate for SM8750 SoC. Signed-off-by: Konrad Dybcio Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20260220-gpucc_sm8750_v2-v3-1-6c5408564c3c@oss.qualcomm.com Signed-off-by: Taniya Das --- .../clock/qcom,kaanapali-gxclkctl.yaml | 1 + .../bindings/clock/qcom,sm8450-gpucc.yaml | 2 + include/dt-bindings/clock/qcom,sm8750-gpucc.h | 50 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,sm8750-gpucc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml index 55bf3f8110171..466c884aa2bab 100644 --- a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml @@ -22,6 +22,7 @@ properties: enum: - qcom,glymur-gxclkctl - qcom,kaanapali-gxclkctl + - qcom,sm8750-gxclkctl power-domains: description: diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 5993804c91fa5..be202ab4f3fcc 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -23,6 +23,7 @@ description: | include/dt-bindings/clock/qcom,sm8550-gpucc.h include/dt-bindings/reset/qcom,sm8450-gpucc.h include/dt-bindings/reset/qcom,sm8650-gpucc.h + include/dt-bindings/reset/qcom,sm8750-gpucc.h include/dt-bindings/reset/qcom,x1e80100-gpucc.h properties: @@ -37,6 +38,7 @@ properties: - qcom,sm8475-gpucc - qcom,sm8550-gpucc - qcom,sm8650-gpucc + - qcom,sm8750-gpucc - qcom,x1e80100-gpucc - qcom,x1p42100-gpucc diff --git a/include/dt-bindings/clock/qcom,sm8750-gpucc.h b/include/dt-bindings/clock/qcom,sm8750-gpucc.h new file mode 100644 index 0000000000000..e2143d905fece --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-gpucc.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8750_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CB_CLK 1 +#define GPU_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_CC_CX_FF_CLK 3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CXO_AON_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_DEMET_CLK 7 +#define GPU_CC_DPM_CLK 8 +#define GPU_CC_FF_CLK_SRC 9 +#define GPU_CC_FREQ_MEASURE_CLK 10 +#define GPU_CC_GMU_CLK_SRC 11 +#define GPU_CC_GX_ACCU_SHIFT_CLK 12 +#define GPU_CC_GX_ACD_AHB_FF_CLK 13 +#define GPU_CC_GX_AHB_FF_CLK 14 +#define GPU_CC_GX_GMU_CLK 15 +#define GPU_CC_GX_RCG_AHB_FF_CLK 16 +#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 17 +#define GPU_CC_HUB_AON_CLK 18 +#define GPU_CC_HUB_CLK_SRC 19 +#define GPU_CC_HUB_CX_INT_CLK 20 +#define GPU_CC_HUB_DIV_CLK_SRC 21 +#define GPU_CC_MEMNOC_GFX_CLK 22 +#define GPU_CC_PLL0 23 +#define GPU_CC_PLL0_OUT_EVEN 24 +#define GPU_CC_RSCC_HUB_AON_CLK 25 +#define GPU_CC_RSCC_XO_AON_CLK 26 +#define GPU_CC_SLEEP_CLK 27 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 + +/* GPU_CC resets */ +#define GPU_CC_GPU_CC_CB_BCR 0 +#define GPU_CC_GPU_CC_CX_BCR 1 +#define GPU_CC_GPU_CC_FAST_HUB_BCR 2 +#define GPU_CC_GPU_CC_FF_BCR 3 +#define GPU_CC_GPU_CC_GMU_BCR 4 +#define GPU_CC_GPU_CC_GX_BCR 5 +#define GPU_CC_GPU_CC_XO_BCR 6 + +#endif From 5da9c61ec2c8bd995da2da70ba85d08a606f7bb6 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 20 Feb 2026 11:24:21 +0530 Subject: [PATCH 089/438] FROMLIST: clk: qcom: Add a driver for SM8750 GPU clocks Support the graphics clock controller for SM8750 for Graphics SW driver to use the clocks. GXCLKCTL (Graphics GX Clock Controller) is a block dedicated to managing clocks for the GPU subsystem on GX power domain. The GX clock controller driver manages only the GX GDSC and the rest of the resources of the controller are managed by the firmware. Update the compatible for Graphics GX Clock Controller for SM8750 as the GX clock controller is a reuse of the Kaanapali driver. Signed-off-by: Konrad Dybcio Co-developed-by: Taniya Das Link: https://lore.kernel.org/r/20260220-gpucc_sm8750_v2-v3-2-6c5408564c3c@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sm8750.c | 472 ++++++++++++++++++++++++++ drivers/clk/qcom/gxclkctl-kaanapali.c | 1 + 4 files changed, 483 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 98bb8fb57709b..99ef623a3c936 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1519,6 +1519,15 @@ config SM_GPUCC_8650 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config SM_GPUCC_8750 + tristate "SM8750 Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8750 + help + Support for the graphics clock controller on SM8750 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SM_LPASSCC_6115 tristate "SM6115 Low Power Audio Subsystem (LPASS) Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 2a08ef4840828..4eb79dec0ddc8 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -184,6 +184,7 @@ obj-$(CONFIG_SM_GPUCC_8350) += gpucc-sm8350.o obj-$(CONFIG_SM_GPUCC_8450) += gpucc-sm8450.o obj-$(CONFIG_SM_GPUCC_8550) += gpucc-sm8550.o obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o +obj-$(CONFIG_SM_GPUCC_8750) += gpucc-sm8750.o gxclkctl-kaanapali.o obj-$(CONFIG_SM_GPUCC_MILOS) += gpucc-milos.o obj-$(CONFIG_SM_LPASSCC_6115) += lpasscc-sm6115.o obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o diff --git a/drivers/clk/qcom/gpucc-sm8750.c b/drivers/clk/qcom/gpucc-sm8750.c new file mode 100644 index 0000000000000..2983683e6fbb0 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sm8750.c @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, +}; + +static const struct pll_vco taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x34, + .alpha = 0x1555, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_cc_pll0_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gpu_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL0_OUT_EVEN, 2 }, + { P_GPU_CC_PLL0_OUT_ODD, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0_out_even.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .fw_name = "gpll0_out_main" }, + { .fw_name = "gpll0_out_main_div" }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(500000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(687500000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x9318, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x93ec, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_hub_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_div_clk_src = { + .reg = 0x942c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x90bc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x90bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_accu_shift_clk = { + .halt_reg = 0x910c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x910c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x90d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x90e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_demet_clk = { + .halt_reg = 0x9010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_demet_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_dpm_clk = { + .halt_reg = 0x9110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9110, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_dpm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_freq_measure_clk = { + .halt_reg = 0x900c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x900c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_freq_measure_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_accu_shift_clk = { + .halt_reg = 0x9070, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gmu_clk = { + .halt_reg = 0x9060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { + .halt_reg = 0x7000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x93e8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x93e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_cx_int_clk = { + .halt_reg = 0x90e8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_cx_int_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_memnoc_gfx_clk = { + .halt_reg = 0x90f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x9080, + .gds_hw_ctrl = 0x9094, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x8, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct clk_regmap *gpu_cc_sm8750_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, + [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr, + [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr, + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, + [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, + [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, + [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, + [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, + [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr, + [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, +}; + +static struct gdsc *gpu_cc_sm8750_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_sm8750_resets[] = { + [GPU_CC_GPU_CC_XO_BCR] = { 0x9000 }, + [GPU_CC_GPU_CC_GX_BCR] = { 0x905c }, + [GPU_CC_GPU_CC_CX_BCR] = { 0x907c }, + [GPU_CC_GPU_CC_GMU_BCR] = { 0x9314 }, + [GPU_CC_GPU_CC_CB_BCR] = { 0x93a0 }, + [GPU_CC_GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, +}; + +static const struct regmap_config gpu_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9800, + .fast_io = true, +}; + +static struct clk_alpha_pll *gpu_cc_alpha_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_sm8750_critical_cbcrs[] = { + 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ + 0x9008, /* GPU_CC_CXO_AON_CLK */ + 0x9064, /* GPU_CC_GX_AHB_FF_CLK */ + 0x90cc, /* GPU_CC_SLEEP_CLK */ + 0x93a4, /* GPU_CC_CB_CLK */ + 0x93a8, /* GPU_CC_RSCC_HUB_AON_CLK */ +}; + +static struct qcom_cc_driver_data gpu_cc_sm8750_driver_data = { + .alpha_plls = gpu_cc_alpha_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_alpha_plls), + .clk_cbcrs = gpu_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sm8750_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_sm8750_desc = { + .config = &gpu_cc_sm8750_regmap_config, + .clks = gpu_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_sm8750_clocks), + .resets = gpu_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(gpu_cc_sm8750_resets), + .gdscs = gpu_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_sm8750_gdscs), + .driver_data = &gpu_cc_sm8750_driver_data, +}; + +static const struct of_device_id gpu_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_sm8750_match_table); + +static int gpu_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_sm8750_desc); +} + +static struct platform_driver gpu_cc_sm8750_driver = { + .probe = gpu_cc_sm8750_probe, + .driver = { + .name = "sm8750-gpucc", + .of_match_table = gpu_cc_sm8750_match_table, + }, +}; +module_platform_driver(gpu_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI GPU_CC SM8750 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c index 3ee512f34967f..b45ab0ac46c77 100644 --- a/drivers/clk/qcom/gxclkctl-kaanapali.c +++ b/drivers/clk/qcom/gxclkctl-kaanapali.c @@ -54,6 +54,7 @@ static const struct qcom_cc_desc gx_clkctl_kaanapali_desc = { static const struct of_device_id gx_clkctl_kaanapali_match_table[] = { { .compatible = "qcom,glymur-gxclkctl" }, { .compatible = "qcom,kaanapali-gxclkctl" }, + { .compatible = "qcom,sm8750-gxclkctl" }, { } }; MODULE_DEVICE_TABLE(of, gx_clkctl_kaanapali_match_table); From 03a818909cc09cf9eed7ff2b3722aea0690796c9 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Wed, 28 Jan 2026 15:22:25 +0530 Subject: [PATCH 090/438] FROMLIST: dt-bindings: phy: qcom-edp: Add reference clock for sa8775p eDP PHY The initial sa8775p eDP PHY binding contribution missed adding support for voting on the eDP reference clock. This went unnoticed because the UFS PHY driver happened to enable the same clock. After commit 77d2fa54a945 ("scsi: ufs: qcom : Refactor phy_power_on/off calls"), the eDP reference clock is no longer kept enabled, which results in the following PHY power-on failure: phy phy-aec2a00.phy.10: phy poweron failed --> -110 To fix this, explicit voting for the eDP reference clock is required. This patch adds the eDP reference clock for sa8775p eDP PHY and updates the corresponding example node. Link: https://lore.kernel.org/all/20260128114853.2543416-2-quic_riteshk@quicinc.com/ Signed-off-by: Ritesh Kumar --- .../devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml | 6 ++++-- Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml index e2730a2f25cfb..6c827cf9692b9 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml @@ -200,9 +200,11 @@ examples: <0x0aec2000 0x1c8>; clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, - <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>; + <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_EDP_REF_CLKREF_EN>; clock-names = "aux", - "cfg_ahb"; + "cfg_ahb", + "ref"; #clock-cells = <1>; #phy-cells = <0>; diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml index 4a1daae3d8d47..0bf8bf4f66acf 100644 --- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml @@ -74,6 +74,7 @@ allOf: compatible: enum: - qcom,glymur-dp-phy + - qcom,sa8775p-edp-phy - qcom,x1e80100-dp-phy then: properties: From 7d98fa5dcefc338f8fbb9fa1d2b375967f005016 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Oct 2025 19:46:22 +0530 Subject: [PATCH 091/438] FROMLIST: media: dt-bindings: qcom-kaanapali-iris: Add kaanapali video codec binding Kaanapali SOC brings in the new generation of video IP i.e iris4. When compared to previous generation, iris3x, it has, - separate power domains for stream and pixel processing hardware blocks (bse and vpp). - additional power domain for apv codec. - power domains for individual pipes (VPPx). - different clocks and reset lines. Iommus include all the different stream-ids which can be possibly generated by vpu4 video hardware in both secure and non secure execution mode. The vpu have reserved iova, i.e some portion of the addressable range is reserved for IO registers. Iris_resv would describe the acceptable address range. Link: https://lore.kernel.org/linux-media/20251017-knp_video-v2-1-f568ce1a4be3@oss.qualcomm.com/ Signed-off-by: Vikash Garodia --- .../bindings/media/qcom,kaanapali-iris.yaml | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml diff --git a/Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml b/Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml new file mode 100644 index 0000000000000..39e9ac9dad221 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml @@ -0,0 +1,231 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,kaanapali-iris.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Kaanapali Iris video encoder and decoder + +maintainers: + - Vikash Garodia + - Dikshita Agarwal + +description: + The iris video processing unit is a video encode and decode accelerator + present on Qualcomm Kaanapali SoC. + +properties: + compatible: + const: qcom,kaanapali-iris + + reg: + maxItems: 1 + + clocks: + maxItems: 10 + + clock-names: + items: + - const: iface + - const: core + - const: vcodec0_core + - const: iface1 + - const: core_freerun + - const: vcodec0_core_freerun + - const: vcodec_bse + - const: vcodec_vpp0 + - const: vcodec_vpp1 + - const: vcodec_apv + + dma-coherent: true + + firmware-name: + maxItems: 1 + + interconnects: + maxItems: 2 + + interconnect-names: + items: + - const: cpu-cfg + - const: video-mem + + interrupts: + maxItems: 1 + + iommus: + minItems: 3 + maxItems: 8 + + memory-region: + minItems: 1 + maxItems: 2 + + operating-points-v2: true + opp-table: + type: object + + power-domains: + maxItems: 7 + + power-domain-names: + items: + - const: venus + - const: vcodec0 + - const: mxc + - const: mmcx + - const: vpp0 + - const: vpp1 + - const: apv + + resets: + maxItems: 4 + + reset-names: + items: + - const: bus0 + - const: bus1 + - const: core_freerun_reset + - const: vcodec0_core_freerun_reset + +required: + - compatible + - reg + - clocks + - clock-names + - dma-coherent + - interconnects + - interconnect-names + - interrupts + - iommus + - power-domains + - power-domain-names + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + #include + #include + + video-codec@2000000 { + compatible = "qcom,kaanapali-iris"; + reg = <0x02000000 0xf0000>; + + clocks = <&gcc_video_axi0_clk>, + <&video_cc_mvs0c_clk>, + <&video_cc_mvs0_clk>, + <&gcc_video_axi1_clk>, + <&video_cc_mvs0c_freerun_clk>, + <&video_cc_mvs0_freerun_clk>, + <&video_cc_mvs0b_clk>, + <&video_cc_mvs0_vpp0_clk>, + <&video_cc_mvs0_vpp1_clk>, + <&video_cc_mvs0a_clk>; + clock-names = "iface", + "core", + "vcodec0_core", + "iface1", + "core_freerun", + "vcodec0_core_freerun", + "vcodec_bse", + "vcodec_vpp0", + "vcodec_vpp1", + "vcodec_apv"; + + dma-coherent; + + interconnects = <&gem_noc_master_appss_proc &config_noc_slave_venus_cfg>, + <&mmss_noc_master_video_mvp &mc_virt_slave_ebi1>; + interconnect-names = "cpu-cfg", + "video-mem"; + + interrupts = ; + + iommus = <&apps_smmu 0x1940 0x0>, + <&apps_smmu 0x1944 0x0>, + <&apps_smmu 0x1a20 0x0>, + <&apps_smmu 0x1943 0x0>; + + operating-points-v2 = <&iris_opp_table>; + + memory-region = <&video_mem>, <&iris_resv>; + + power-domains = <&video_cc_mvs0c_gdsc>, + <&video_cc_mvs0_gdsc>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_MMCX>, + <&video_cc_mvs0_vpp0_gdsc>, + <&video_cc_mvs0_vpp1_gdsc>, + <&video_cc_mvs0a_gdsc>; + power-domain-names = "venus", + "vcodec0", + "mxc", + "mmcx", + "vpp0", + "vpp1", + "apv"; + + resets = <&gcc_video_axi0_clk_ares>, + <&gcc_video_axi1_clk_ares>, + <&video_cc_mvs0c_freerun_clk_ares>, + <&video_cc_mvs0_freerun_clk_ares>; + reset-names = "bus0", + "bus1", + "core_freerun_reset", + "vcodec0_core_freerun_reset"; + + iris_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000 240000000 240000000 360000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>, + <&rpmhpd_opp_low_svs_d1>; + }; + + opp-338000000 { + opp-hz = /bits/ 64 <338000000 338000000 338000000 507000000>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + }; + + opp-420000000 { + opp-hz = /bits/ 64 <420000000 420000000 420000000 630000000>; + required-opps = <&rpmhpd_opp_svs>, + <&rpmhpd_opp_svs>; + }; + + opp-444000000 { + opp-hz = /bits/ 64 <444000000 444000000 444000000 666000000>; + required-opps = <&rpmhpd_opp_svs_l1>, + <&rpmhpd_opp_svs_l1>; + }; + + opp-533000000 { + opp-hz = /bits/ 64 <533000000 533000000 533000000 800000000>; + required-opps = <&rpmhpd_opp_nom>, + <&rpmhpd_opp_nom>; + }; + + opp-630000000 { + opp-hz = /bits/ 64 <630000000 630000000 630000000 1104000000>; + required-opps = <&rpmhpd_opp_turbo>, + <&rpmhpd_opp_turbo>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000 630000000 630000000 1260000000>; + required-opps = <&rpmhpd_opp_turbo_l0>, + <&rpmhpd_opp_turbo_l0>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000 630000000 850000000 1260000000>; + required-opps = <&rpmhpd_opp_turbo_l1>, + <&rpmhpd_opp_turbo_l1>; + }; + }; + }; From 955e6b8c3d8303988fc3c87a1f59b7dc13e66b2d Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Oct 2025 19:46:29 +0530 Subject: [PATCH 092/438] FROMLIST: media: iris: Add platform data for kaanapali Add support for the kaanapali platform by re-using the SM8550 definitions and using the vpu4 ops. Move the configurations that differs in a per-SoC platform header, that will contain SoC specific data. Link: https://lore.kernel.org/all/20251017-knp_video-v2-8-f568ce1a4be3@oss.qualcomm.com/ Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia Reviewed-by: Bryan O'Donoghue --- .../platform/qcom/iris/iris_platform_common.h | 1 + .../platform/qcom/iris/iris_platform_gen2.c | 88 +++++++++++++++++++ .../qcom/iris/iris_platform_kaanapali.h | 63 +++++++++++++ drivers/media/platform/qcom/iris/iris_probe.c | 4 + 4 files changed, 156 insertions(+) create mode 100644 drivers/media/platform/qcom/iris/iris_platform_kaanapali.h diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 5a489917580eb..8c1ad8ae46025 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -41,6 +41,7 @@ enum pipe_type { PIPE_4 = 4, }; +extern const struct iris_platform_data kaanapali_data; extern const struct iris_platform_data qcs8300_data; extern const struct iris_platform_data sc7280_data; extern const struct iris_platform_data sm8250_data; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 5da90d47f9c6e..e0c99d28762cd 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -12,6 +12,7 @@ #include "iris_vpu_buffer.h" #include "iris_vpu_common.h" +#include "iris_platform_kaanapali.h" #include "iris_platform_qcs8300.h" #include "iris_platform_sm8650.h" #include "iris_platform_sm8750.h" @@ -921,6 +922,93 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = { BUF_SCRATCH_2, }; +const struct iris_platform_data kaanapali_data = { + .get_instance = iris_hfi_gen2_get_instance, + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .get_vpu_buffer_size = iris_vpu4x_buf_size, + .vpu_ops = &iris_vpu4x_ops, + .set_preset_registers = iris_set_sm8550_preset_registers, + .icc_tbl = sm8550_icc_table, + .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), + .clk_rst_tbl = kaanapali_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(kaanapali_clk_reset_table), + .bw_tbl_dec = sm8550_bw_table_dec, + .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), + .pmdomain_tbl = kaanapali_pmdomain_table, + .pmdomain_tbl_size = ARRAY_SIZE(kaanapali_pmdomain_table), + .opp_pd_tbl = sm8550_opp_pd_table, + .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), + .clk_tbl = kaanapali_clk_table, + .clk_tbl_size = ARRAY_SIZE(kaanapali_clk_table), + .opp_clk_tbl = kaanapali_opp_clk_table, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu40_p2_s7.mbn", + .pas_id = IRIS_PAS_ID, + .inst_iris_fmts = platform_fmts_sm8550_dec, + .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), + .inst_caps = &platform_inst_cap_sm8550, + .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), + .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), + .tz_cp_config_data = tz_cp_config_kaanapali, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), + .core_arch = VIDEO_ARCH_LX, + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, + .ubwc_config = &ubwc_config_sm8550, + .num_vpp_pipe = 2, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((8192 * 4352) / 256) * 60, + .dec_input_config_params_default = + sm8550_vdec_input_config_params_default, + .dec_input_config_params_default_size = + ARRAY_SIZE(sm8550_vdec_input_config_params_default), + .dec_input_config_params_hevc = + sm8550_vdec_input_config_param_hevc, + .dec_input_config_params_hevc_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), + .dec_input_config_params_vp9 = + sm8550_vdec_input_config_param_vp9, + .dec_input_config_params_vp9_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_output_config_params = + sm8550_vdec_output_config_params, + .dec_output_config_params_size = + ARRAY_SIZE(sm8550_vdec_output_config_params), + + .enc_input_config_params = + sm8550_venc_input_config_params, + .enc_input_config_params_size = + ARRAY_SIZE(sm8550_venc_input_config_params), + .enc_output_config_params = + sm8550_venc_output_config_params, + .enc_output_config_params_size = + ARRAY_SIZE(sm8550_venc_output_config_params), + + .dec_input_prop = sm8550_vdec_subscribe_input_properties, + .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, + .dec_output_prop_avc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, + .dec_output_prop_hevc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, + .dec_output_prop_vp9_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + + .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), + .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), + + .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, + .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), +}; + const struct iris_platform_data sm8550_data = { .get_instance = iris_hfi_gen2_get_instance, .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, diff --git a/drivers/media/platform/qcom/iris/iris_platform_kaanapali.h b/drivers/media/platform/qcom/iris/iris_platform_kaanapali.h new file mode 100644 index 0000000000000..247fb9d7cb632 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_kaanapali.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __IRIS_PLATFORM_KAANAPALI_H__ +#define __IRIS_PLATFORM_KAANAPALI_H__ + +#define VIDEO_REGION_VM0_SECURE_NP_ID 1 +#define VIDEO_REGION_VM0_NONSECURE_NP_ID 5 + +static const char *const kaanapali_clk_reset_table[] = { + "bus0", + "bus1", + "core_freerun_reset", + "vcodec0_core_freerun_reset", +}; + +static const char *const kaanapali_pmdomain_table[] = { + "venus", + "vcodec0", + "vpp0", + "vpp1", + "apv", +}; + +static const struct platform_clk_data kaanapali_clk_table[] = { + { IRIS_AXI_CLK, "iface" }, + { IRIS_CTRL_CLK, "core" }, + { IRIS_HW_CLK, "vcodec0_core" }, + { IRIS_AXI1_CLK, "iface1" }, + { IRIS_CTRL_FREERUN_CLK, "core_freerun" }, + { IRIS_HW_FREERUN_CLK, "vcodec0_core_freerun" }, + { IRIS_BSE_HW_CLK, "vcodec_bse" }, + { IRIS_VPP0_HW_CLK, "vcodec_vpp0" }, + { IRIS_VPP1_HW_CLK, "vcodec_vpp1" }, + { IRIS_APV_HW_CLK, "vcodec_apv" }, +}; + +static const char *const kaanapali_opp_clk_table[] = { + "vcodec0_core", + "vcodec_apv", + "vcodec_bse", + "core", + NULL, +}; + +static struct tz_cp_config tz_cp_config_kaanapali[] = { + { + .cp_start = VIDEO_REGION_VM0_SECURE_NP_ID, + .cp_size = 0, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, + { + .cp_start = VIDEO_REGION_VM0_NONSECURE_NP_ID, + .cp_size = 0, + .cp_nonpixel_start = 0x25800000, + .cp_nonpixel_size = 0xda400000, + }, +}; + +#endif /* __IRIS_PLATFORM_KAANAPALI_H__ */ diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index ddaacda523ecb..a27a23b960bdf 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -348,6 +348,10 @@ static const struct dev_pm_ops iris_pm_ops = { }; static const struct of_device_id iris_dt_match[] = { + { + .compatible = "qcom,kaanapali-iris", + .data = &kaanapali_data, + }, { .compatible = "qcom,qcs8300-iris", .data = &qcs8300_data, From 947c848d2fa9533ce08f51d8825a1972a4110bd4 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Wed, 11 Feb 2026 12:19:16 +0530 Subject: [PATCH 093/438] FROMLIST: media: iris: Enable Secure PAS support with IOMMU managed by Linux Most Qualcomm platforms feature a inhouse hypervisor (such as Gunyah or QHEE), which typically handles IOMMU configuration. This includes mapping memory regions and device memory resources for remote processors by intercepting qcom_scm_pas_auth_and_reset() calls. These mappings are later removed during teardown. Additionally, SHM bridge setup is required to enable memory protection for both remoteproc metadata and its memory regions. When the hypervisor is absent, the operating system must perform these configurations instead. Support for handling IOMMU and SHM setup in the absence of a hypervisor is now in place. Extend the Iris driver to enable this functionality on platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE). Additionally, the Iris driver must map the firmware and its required resources to the firmware SID, which is now specified via the device tree. Link: https://lore.kernel.org/lkml/20250819165447.4149674-12-mukesh.ojha@oss.qualcomm.com/ Signed-off-by: Vikash Garodia Signed-off-by: Mukesh Ojha --- drivers/media/platform/qcom/iris/iris_core.c | 9 +- drivers/media/platform/qcom/iris/iris_core.h | 5 + .../media/platform/qcom/iris/iris_firmware.c | 127 ++++++++++++++++-- .../media/platform/qcom/iris/iris_firmware.h | 2 + 4 files changed, 133 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c index 8406c48d635b6..62a9e15b47372 100644 --- a/drivers/media/platform/qcom/iris/iris_core.c +++ b/drivers/media/platform/qcom/iris/iris_core.c @@ -18,6 +18,7 @@ void iris_core_deinit(struct iris_core *core) if (core->state != IRIS_CORE_DEINIT) { iris_fw_unload(core); iris_vpu_power_off(core); + iris_fw_deinit(core); iris_hfi_queues_deinit(core); core->state = IRIS_CORE_DEINIT; } @@ -67,10 +68,14 @@ int iris_core_init(struct iris_core *core) if (ret) goto error_queue_deinit; - ret = iris_fw_load(core); + ret = iris_fw_init(core); if (ret) goto error_power_off; + ret = iris_fw_load(core); + if (ret) + goto error_firmware_deinit; + ret = iris_vpu_boot_firmware(core); if (ret) goto error_unload_fw; @@ -85,6 +90,8 @@ int iris_core_init(struct iris_core *core) error_unload_fw: iris_fw_unload(core); +error_firmware_deinit: + iris_fw_deinit(core); error_power_off: iris_vpu_power_off(core); error_queue_deinit: diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index fb194c967ad4f..ef081ccc3429d 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -82,6 +82,11 @@ struct iris_core { struct v4l2_device v4l2_dev; struct video_device *vdev_dec; struct video_device *vdev_enc; + struct video_firmware { + struct device *dev; + struct qcom_scm_pas_context *ctx; + struct iommu_domain *iommu_domain; + } fw; const struct v4l2_file_operations *iris_v4l2_file_ops; const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops_dec; const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops_enc; diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index 5f408024e967f..d74a5aed291d7 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -3,10 +3,15 @@ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ +#include #include #include +#include +#include #include +#include #include +#include #include #include "iris_core.h" @@ -17,6 +22,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) { u32 pas_id = core->iris_platform_data->pas_id; + struct qcom_scm_pas_context *ctx; const struct firmware *firmware = NULL; struct device *dev = core->dev; struct resource res; @@ -36,6 +42,14 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) mem_phys = res.start; res_size = resource_size(&res); + dev = core->fw.dev ? : core->dev; + + ctx = devm_qcom_scm_pas_context_alloc(dev, pas_id, mem_phys, res_size); + if (!ctx) + return -ENOMEM; + + ctx->use_tzmem = core->fw.dev; + ret = request_firmware(&firmware, fw_name, dev); if (ret) return ret; @@ -52,9 +66,29 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) goto err_release_fw; } - ret = qcom_mdt_load(dev, firmware, fw_name, - pas_id, mem_virt, mem_phys, res_size, NULL); + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL); + qcom_scm_pas_metadata_release(ctx); + if (ret) + goto err_mem_unmap; + + if (core->fw.iommu_domain) { + ret = iommu_map(core->fw.iommu_domain, 0, mem_phys, res_size, + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL); + if (ret) + goto err_mem_unmap; + } + ret = qcom_scm_pas_prepare_and_auth_reset(ctx); + if (ret) + goto err_iommu_unmap; + + core->fw.ctx = ctx; + + return ret; + +err_iommu_unmap: + iommu_unmap(core->fw.iommu_domain, 0, res_size); +err_mem_unmap: memunmap(mem_virt); err_release_fw: release_firmware(firmware); @@ -79,12 +113,6 @@ int iris_fw_load(struct iris_core *core) return -ENOMEM; } - ret = qcom_scm_pas_auth_and_reset(core->iris_platform_data->pas_id); - if (ret) { - dev_err(core->dev, "auth and reset failed: %d\n", ret); - return ret; - } - for (i = 0; i < core->iris_platform_data->tz_cp_config_data_size; i++) { cp_config = &core->iris_platform_data->tz_cp_config_data[i]; ret = qcom_scm_mem_protect_video_var(cp_config->cp_start, @@ -103,10 +131,91 @@ int iris_fw_load(struct iris_core *core) int iris_fw_unload(struct iris_core *core) { - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); + struct qcom_scm_pas_context *ctx = core->fw.ctx; + int ret; + + if (!ctx) + return -EINVAL; + + ret = qcom_scm_pas_shutdown(ctx->pas_id); + if (core->fw.iommu_domain) + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size); + + core->fw.ctx = NULL; + return ret; } int iris_set_hw_state(struct iris_core *core, bool resume) { return qcom_scm_set_remote_state(resume, 0); } + +int iris_fw_init(struct iris_core *core) +{ + struct platform_device_info info; + struct iommu_domain *iommu_dom; + struct platform_device *pdev; + struct device_node *np; + int ret; + + np = of_get_child_by_name(core->dev->of_node, "video-firmware"); + if (!np) + return 0; + + memset(&info, 0, sizeof(info)); + info.fwnode = &np->fwnode; + info.parent = core->dev; + info.name = np->name; + info.dma_mask = DMA_BIT_MASK(32); + + pdev = platform_device_register_full(&info); + if (IS_ERR(pdev)) { + of_node_put(np); + return PTR_ERR(pdev); + } + + pdev->dev.of_node = np; + + ret = of_dma_configure(&pdev->dev, np, true); + if (ret) + goto err_unregister; + + core->fw.dev = &pdev->dev; + + iommu_dom = iommu_get_domain_for_dev(core->fw.dev); + if (!iommu_dom) { + ret = -EINVAL; + goto err_unset_fw_dev; + } + + ret = iommu_attach_device(iommu_dom, core->fw.dev); + if (ret) + goto err_unset_fw_dev; + + core->fw.iommu_domain = iommu_dom; + + of_node_put(np); + + return 0; + +err_unset_fw_dev: + core->fw.dev = NULL; +err_unregister: + platform_device_unregister(pdev); + of_node_put(np); + return ret; +} + +void iris_fw_deinit(struct iris_core *core) +{ + if (!core->fw.dev) + return; + + if (core->fw.iommu_domain) { + iommu_detach_device(core->fw.iommu_domain, core->fw.dev); + core->fw.iommu_domain = NULL; + } + + platform_device_unregister(to_platform_device(core->fw.dev)); + core->fw.dev = NULL; +} diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/media/platform/qcom/iris/iris_firmware.h index e833ecd348871..adde461099667 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.h +++ b/drivers/media/platform/qcom/iris/iris_firmware.h @@ -11,5 +11,7 @@ struct iris_core; int iris_fw_load(struct iris_core *core); int iris_fw_unload(struct iris_core *core); int iris_set_hw_state(struct iris_core *core, bool resume); +int iris_fw_init(struct iris_core *core); +void iris_fw_deinit(struct iris_core *core); #endif From 05ffb7c93a3c88b7ab8dfd336cb7ecdf69c9d508 Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Fri, 21 Nov 2025 19:12:06 +0530 Subject: [PATCH 094/438] FROMLIST: drm/bridge: lt9611uxc: Increase EDID wait time from 500ms to 1000ms EDID interrupt was coming 600-650 ms after HPD interrupt, resulting into EDID read timeout and default resolution of 1024x768 on display. Signed-off-by: Gopi Botlagunta Link: https://lore.kernel.org/all/20251121-hdmibridge-v1-1-14c63890f362@oss.qualcomm.com/ --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 11aab07d88df6..ed06375c4c6f5 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -381,7 +381,7 @@ lt9611uxc_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connect static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc) { return wait_event_interruptible_timeout(lt9611uxc->wq, lt9611uxc->edid_read, - msecs_to_jiffies(500)); + msecs_to_jiffies(1000)); } static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) From 7030e8e137cc56fd060ab4a4358ebb54569da5dc Mon Sep 17 00:00:00 2001 From: Nilesh Laad Date: Wed, 26 Nov 2025 17:01:18 +0530 Subject: [PATCH 095/438] FROMLIST: drm/bridge: lt9611uxc: extend mode valid checks Currently valid mode checks are only for hdisplay and vdisplay, add htotal and vtotal to filter only specific modes. Link:https://lore.kernel.org/lkml/20251126-lt9611uxc-modes-v2-1-34bf9b351921@oss.qualcomm.com/ Signed-off-by: Nilesh Laad Signed-off-by: Mahadevan P --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index ed06375c4c6f5..cc2c9367f6d9d 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -88,7 +88,9 @@ static const struct regmap_config lt9611uxc_regmap_config = { struct lt9611uxc_mode { u16 hdisplay; + u16 htotal; u16 vdisplay; + u16 vtotal; u8 vrefresh; }; @@ -97,22 +99,22 @@ struct lt9611uxc_mode { * Enumerate them here to check whether the mode is supported. */ static struct lt9611uxc_mode lt9611uxc_modes[] = { - { 1920, 1080, 60 }, - { 1920, 1080, 30 }, - { 1920, 1080, 25 }, - { 1366, 768, 60 }, - { 1360, 768, 60 }, - { 1280, 1024, 60 }, - { 1280, 800, 60 }, - { 1280, 720, 60 }, - { 1280, 720, 50 }, - { 1280, 720, 30 }, - { 1152, 864, 60 }, - { 1024, 768, 60 }, - { 800, 600, 60 }, - { 720, 576, 50 }, - { 720, 480, 60 }, - { 640, 480, 60 }, + { 1920, 2200, 1080, 1125, 60 }, + { 1920, 2200, 1080, 1125, 30 }, + { 1920, 2640, 1080, 1125, 25 }, + { 1366, 1792, 768, 798, 60 }, + { 1360, 1792, 768, 795, 60 }, + { 1280, 1688, 1024, 1066, 60 }, + { 1280, 1680, 800, 831, 60 }, + { 1280, 1650, 720, 750, 60 }, + { 1280, 1980, 720, 750, 50 }, + { 1280, 3300, 720, 750, 30 }, + { 1152, 1600, 864, 900, 60 }, + { 1024, 1344, 768, 806, 60 }, + { 800, 1056, 600, 628, 60 }, + { 720, 864, 576, 625, 50 }, + { 720, 858, 480, 525, 60 }, + { 640, 800, 480, 525, 60 }, }; static struct lt9611uxc *bridge_to_lt9611uxc(struct drm_bridge *bridge) @@ -236,7 +238,9 @@ static struct lt9611uxc_mode *lt9611uxc_find_mode(const struct drm_display_mode for (i = 0; i < ARRAY_SIZE(lt9611uxc_modes); i++) { if (lt9611uxc_modes[i].hdisplay == mode->hdisplay && + lt9611uxc_modes[i].htotal == mode->htotal && lt9611uxc_modes[i].vdisplay == mode->vdisplay && + lt9611uxc_modes[i].vtotal == mode->vtotal && lt9611uxc_modes[i].vrefresh == drm_mode_vrefresh(mode)) { return <9611uxc_modes[i]; } From 674ccad9789e51d7aedc6f06986f78b465ce80d1 Mon Sep 17 00:00:00 2001 From: Nilesh Laad Date: Wed, 26 Nov 2025 18:52:37 +0530 Subject: [PATCH 096/438] FROMLIST: drm/bridge: lt9611uxc: add support for 4K@30 resolution Add 3840x2160@30 mode in lt9611uxc modes to add support for 4K@30 resolution. Link:https://lore.kernel.org/r/20251126-lt9611uxc-4k30-v2-1-3de0ea58c24e@oss.qualcomm.com Signed-off-by: Nilesh Laad Signed-off-by: Mahadevan P --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index cc2c9367f6d9d..cd1a948d18afa 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -99,6 +99,7 @@ struct lt9611uxc_mode { * Enumerate them here to check whether the mode is supported. */ static struct lt9611uxc_mode lt9611uxc_modes[] = { + { 3840, 4400, 2160, 2250, 30 }, { 1920, 2200, 1080, 1125, 60 }, { 1920, 2200, 1080, 1125, 30 }, { 1920, 2640, 1080, 1125, 25 }, From e6accaa5d8cd8f799dd2fe4b9753ff5372fac83a Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sun, 28 Dec 2025 17:10:39 +0530 Subject: [PATCH 097/438] FROMLIST: dt-bindings: bridge: lt8713sx: Add bindings Add bindings for lt8713sx. Co-developed-by: Prahlad Valluru Signed-off-by: Prahlad Valluru Signed-off-by: Vishnu Saini Link: https://lore.kernel.org/all/20251228-lt8713sx-bridge-driver-v3-1-9169fbef0e5b@oss.qualcomm.com/ --- .../display/bridge/lontium,lt8713sx.yaml | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/lontium,lt8713sx.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt8713sx.yaml b/Documentation/devicetree/bindings/display/bridge/lontium,lt8713sx.yaml new file mode 100644 index 0000000000000..0a6dc56e337cb --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt8713sx.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/lontium,lt8713sx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lontium LT8713SX Type-C/DP1.4 to Type-C/DP1.4/HDMI2.0/DP++ bridge-hub + +maintainers: + - Tony + +description: + The Lontium LT8713SX is a Type-C/DP1.4 to Type-C/DP1.4/HDMI2.0 converter + that integrates one DP input and up to three configurable output interfaces + (DP1.4 / HDMI2.0 / DP++), with SST/MST functionality and audio support. + +properties: + compatible: + enum: + - lontium,lt8713sx + + reg: + maxItems: 1 + + vcc-supply: + description: Regulator for 3.3V vcc. + + vdd-supply: + description: Regulator for 1.1V vdd. + + reset-gpios: + description: GPIO connected to active low RESET pin. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: + DP port for DP input from soc to bridge chip + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + DP port for DP output from bridge + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: + Additional DP port for DP output from bridge + + required: + - port@0 + +required: + - compatible + - reg + - ports + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + bridge@4f { + compatible = "lontium,lt8713sx"; + reg = <0x4f>; + reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lt8713sx_dp_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; + }; + }; + + port@1 { + reg = <1>; + lt8713sx_dp0_out: endpoint { + remote-endpoint = <&dp0_connector_in>; + }; + }; + + port@2 { + reg = <2>; + lt8713sx_dp1_out: endpoint { + remote-endpoint = <&dp1_connector_in>; + }; + }; + }; + }; + }; From 8496d6acc5b9180f6a27e4da014200caf8f6fc98 Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sun, 28 Dec 2025 17:10:40 +0530 Subject: [PATCH 098/438] FROMLIST: drm/bridge: add support for lontium lt8713sx bridge driver The lt8713sx is a Type-C/DP1.4 to Type-C/DP1.4/HDMI2.0 converter, with three configurable DP1.4/HDMI2.0/DP++ output interfaces and audio output interface. Driver is required for firmware upgrade in the bridge chip. Co-developed-by: Prahlad Valluru Signed-off-by: Prahlad Valluru Signed-off-by: Vishnu Saini Link: https://lore.kernel.org/all/20251228-lt8713sx-bridge-driver-v3-2-9169fbef0e5b@oss.qualcomm.com/ --- drivers/gpu/drm/bridge/Kconfig | 10 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/lontium-lt8713sx.c | 682 ++++++++++++++++++++++ 3 files changed, 693 insertions(+) create mode 100644 drivers/gpu/drm/bridge/lontium-lt8713sx.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 39385deafc68e..297bdf68dfff7 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -191,6 +191,16 @@ config DRM_LONTIUM_LT9611UXC HDMI signals Please say Y if you have such hardware. +config DRM_LONTIUM_LT8713SX + tristate "Lontium LT8713SX DP MST bridge" + depends on OF + select REGMAP_I2C + help + Driver for Lontium LT8713SX DP MST bridge + chip firmware upgrade, which converts Type-C/DP1.4 + to 3 configurable Type-C/DP1.4/HDMI2.0 outputs + Please say Y if you have such hardware. + config DRM_ITE_IT66121 tristate "ITE IT66121 HDMI bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 909c21cc3acd3..dc2ff31797b36 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT8912B) += lontium-lt8912b.o obj-$(CONFIG_DRM_LONTIUM_LT9211) += lontium-lt9211.o obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o +obj-$(CONFIG_DRM_LONTIUM_LT8713SX) += lontium-lt8713sx.o obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o diff --git a/drivers/gpu/drm/bridge/lontium-lt8713sx.c b/drivers/gpu/drm/bridge/lontium-lt8713sx.c new file mode 100644 index 0000000000000..6ea54ff3733d4 --- /dev/null +++ b/drivers/gpu/drm/bridge/lontium-lt8713sx.c @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define FW_FILE "lt8713sx_fw.bin" + +#define REG_PAGE_CONTROL 0xff + +#define MAX_OUTPUT_PORTS 3 +#define LT8713SX_PAGE_SIZE 256 + +DECLARE_CRC8_TABLE(lt8713sx_crc_table); + +struct lt8713sx { + struct device *dev; + struct drm_bridge bridge; + struct drm_bridge *next_bridge[MAX_OUTPUT_PORTS]; + int num_outputs; + + struct regmap *regmap; + /* Protects all accesses to registers by stopping the on-chip MCU */ + struct mutex ocm_lock; + + struct gpio_desc *reset_gpio; + struct gpio_desc *enable_gpio; + + struct i2c_client *client; + const struct firmware *fw; + + u8 *fw_buffer; + + u32 main_crc_value; + u32 bank_crc_value[17]; + + int bank_num; +}; + +static void lt8713sx_reset(struct lt8713sx *lt8713sx); + +static const struct regmap_range lt8713sx_ranges[] = { + { + .range_min = 0x0000, + .range_max = 0xffff + }, +}; + +static const struct regmap_access_table lt8713sx_table = { + .yes_ranges = lt8713sx_ranges, + .n_yes_ranges = ARRAY_SIZE(lt8713sx_ranges), +}; + +static const struct regmap_range_cfg lt8713sx_range_cfg = { + .name = "lt8713sx", + .range_min = 0x0000, + .range_max = 0xffff, + .selector_reg = REG_PAGE_CONTROL, + .selector_mask = 0xff, + .selector_shift = 0, + .window_start = 0, + .window_len = 0x100, +}; + +static const struct regmap_config lt8713sx_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_table = <8713sx_table, + .ranges = <8713sx_range_cfg, + .num_ranges = 1, + .cache_type = REGCACHE_NONE, + .max_register = 0xffff, +}; + +static void lt8713sx_i2c_enable(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); +} + +static void lt8713sx_i2c_disable(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x00); +} + +static u32 calculate_crc(const u8 *upgrade_data, u64 len, u64 crc_size) +{ + u8 crc = 0x00; + u8 pad = 0xff; + + crc = crc8(lt8713sx_crc_table, upgrade_data, len, crc); + + /* pad remaining bytes */ + crc_size -= len; + while (crc_size--) + crc = crc8(lt8713sx_crc_table, &pad, 1, crc); + + return crc; +} + +static int lt8713sx_prepare_firmware_data(struct lt8713sx *lt8713sx) +{ + int ret = 0; + u64 sz_12k = 12 * SZ_1K; + + ret = request_firmware(<8713sx->fw, FW_FILE, lt8713sx->dev); + if (ret < 0) { + dev_err(lt8713sx->dev, "request firmware failed\n"); + return ret; + } + + dev_dbg(lt8713sx->dev, "Firmware size: %zu bytes\n", lt8713sx->fw->size); + + if (lt8713sx->fw->size > SZ_256K - 1) { + dev_err(lt8713sx->dev, "Firmware size exceeds 256KB limit\n"); + release_firmware(lt8713sx->fw); + return -EINVAL; + } + + lt8713sx->fw_buffer = kvmalloc(SZ_256K, GFP_KERNEL); + if (!lt8713sx->fw_buffer) { + release_firmware(lt8713sx->fw); + return -ENOMEM; + } + + memset(lt8713sx->fw_buffer, 0xff, SZ_256K); + + if (lt8713sx->fw->size < SZ_64K) { + memcpy(lt8713sx->fw_buffer, lt8713sx->fw->data, lt8713sx->fw->size); + lt8713sx->fw_buffer[SZ_64K - 1] = + calculate_crc(lt8713sx->fw->data, lt8713sx->fw->size, SZ_64K - 1); + lt8713sx->main_crc_value = lt8713sx->fw_buffer[SZ_64K - 1]; + dev_dbg(lt8713sx->dev, + "Main Firmware Data Crc=0x%02X\n", lt8713sx->main_crc_value); + + } else { + /* main firmware */ + memcpy(lt8713sx->fw_buffer, lt8713sx->fw->data, SZ_64K - 1); + lt8713sx->fw_buffer[SZ_64K - 1] = + calculate_crc(lt8713sx->fw_buffer, SZ_64K - 1, SZ_64K - 1); + lt8713sx->main_crc_value = lt8713sx->fw_buffer[SZ_64K - 1]; + dev_dbg(lt8713sx->dev, + "Main Firmware Data Crc=0x%02X\n", lt8713sx->main_crc_value); + + /* bank firmware */ + memcpy(lt8713sx->fw_buffer + SZ_64K, + lt8713sx->fw->data + SZ_64K, + lt8713sx->fw->size - SZ_64K); + + lt8713sx->bank_num = (lt8713sx->fw->size - SZ_64K + sz_12k - 1) / sz_12k; + dev_dbg(lt8713sx->dev, "Bank Number Total is %d.\n", lt8713sx->bank_num); + + for (int i = 0; i < lt8713sx->bank_num; i++) { + lt8713sx->bank_crc_value[i] = + calculate_crc(lt8713sx->fw_buffer + SZ_64K + i * sz_12k, + sz_12k, sz_12k); + dev_dbg(lt8713sx->dev, "Bank number:%d; Firmware Data Crc:0x%02X\n", + i, lt8713sx->bank_crc_value[i]); + } + } + return 0; +} + +static void lt8713sx_config_parameters(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe05e, 0xc1); + regmap_write(lt8713sx->regmap, 0xe058, 0x00); + regmap_write(lt8713sx->regmap, 0xe059, 0x50); + regmap_write(lt8713sx->regmap, 0xe05a, 0x10); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); + regmap_write(lt8713sx->regmap, 0xe058, 0x21); +} + +static void lt8713sx_wren(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe103, 0xbf); + regmap_write(lt8713sx->regmap, 0xe103, 0xff); + regmap_write(lt8713sx->regmap, 0xe05a, 0x04); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); +} + +static void lt8713sx_wrdi(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe05a, 0x08); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); +} + +static void lt8713sx_fifo_reset(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe103, 0xbf); + regmap_write(lt8713sx->regmap, 0xe103, 0xff); +} + +static void lt8713sx_disable_sram_write(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe055, 0x00); +} + +static void lt8713sx_sram_to_flash(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe05a, 0x30); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); +} + +static void lt8713sx_i2c_to_sram(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe055, 0x80); + regmap_write(lt8713sx->regmap, 0xe05e, 0xc0); + regmap_write(lt8713sx->regmap, 0xe058, 0x21); +} + +static u8 lt8713sx_read_flash_status(struct lt8713sx *lt8713sx) +{ + u32 flash_status = 0; + + regmap_write(lt8713sx->regmap, 0xe103, 0x3f); + regmap_write(lt8713sx->regmap, 0xe103, 0xff); + + regmap_write(lt8713sx->regmap, 0xe05e, 0x40); + regmap_write(lt8713sx->regmap, 0xe056, 0x05); /* opcode=read status register */ + regmap_write(lt8713sx->regmap, 0xe055, 0x25); + regmap_write(lt8713sx->regmap, 0xe055, 0x01); + regmap_write(lt8713sx->regmap, 0xe058, 0x21); + + regmap_read(lt8713sx->regmap, 0xe05f, &flash_status); + dev_dbg(lt8713sx->dev, "flash_status:%x\n", flash_status); + + return flash_status; +} + +static void lt8713sx_block_erase(struct lt8713sx *lt8713sx) +{ + u32 i = 0; + u8 flash_status = 0; + u8 blocknum = 0x00; + u32 flashaddr = 0x00; + + for (blocknum = 0; blocknum < 8; blocknum++) { + flashaddr = blocknum * SZ_32K; + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe05a, 0x04); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); + regmap_write(lt8713sx->regmap, 0xe05b, flashaddr >> 16); + regmap_write(lt8713sx->regmap, 0xe05c, flashaddr >> 8); + regmap_write(lt8713sx->regmap, 0xe05d, flashaddr); + regmap_write(lt8713sx->regmap, 0xe05a, 0x01); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); + msleep(100); + i = 0; + while (1) { + flash_status = lt8713sx_read_flash_status(lt8713sx); + if ((flash_status & 0x01) == 0) + break; + + if (i > 50) + break; + + i++; + msleep(50); + } + } + dev_dbg(lt8713sx->dev, "erase flash done.\n"); +} + +static void lt8713sx_load_main_fw_to_sram(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe068, 0x00); + regmap_write(lt8713sx->regmap, 0xe069, 0x00); + regmap_write(lt8713sx->regmap, 0xe06a, 0x00); + regmap_write(lt8713sx->regmap, 0xe065, 0x00); + regmap_write(lt8713sx->regmap, 0xe066, 0xff); + regmap_write(lt8713sx->regmap, 0xe067, 0xff); + regmap_write(lt8713sx->regmap, 0xe06b, 0x00); + regmap_write(lt8713sx->regmap, 0xe06c, 0x00); + regmap_write(lt8713sx->regmap, 0xe060, 0x01); + msleep(200); + regmap_write(lt8713sx->regmap, 0xe060, 0x00); +} + +static void lt8713sx_load_bank_fw_to_sram(struct lt8713sx *lt8713sx, u64 addr) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe068, ((addr & 0xff0000) >> 16)); + regmap_write(lt8713sx->regmap, 0xe069, ((addr & 0x00ff00) >> 8)); + regmap_write(lt8713sx->regmap, 0xe06a, (addr & 0x0000ff)); + regmap_write(lt8713sx->regmap, 0xe065, 0x00); + regmap_write(lt8713sx->regmap, 0xe066, 0x30); + regmap_write(lt8713sx->regmap, 0xe067, 0x00); + regmap_write(lt8713sx->regmap, 0xe06b, 0x00); + regmap_write(lt8713sx->regmap, 0xe06c, 0x00); + regmap_write(lt8713sx->regmap, 0xe060, 0x01); + msleep(50); + regmap_write(lt8713sx->regmap, 0xe060, 0x00); +} + +static int lt8713sx_write_data(struct lt8713sx *lt8713sx, const u8 *data, u64 filesize) +{ + int page = 0, num = 0, i = 0, val; + + page = (filesize % LT8713SX_PAGE_SIZE) ? + ((filesize / LT8713SX_PAGE_SIZE) + 1) : (filesize / LT8713SX_PAGE_SIZE); + + dev_dbg(lt8713sx->dev, + "Writing to Sram=%u pages, total size = %llu bytes\n", page, filesize); + + for (num = 0; num < page; num++) { + dev_dbg(lt8713sx->dev, "page[%d]\n", num); + lt8713sx_i2c_to_sram(lt8713sx); + + for (i = 0; i < LT8713SX_PAGE_SIZE; i++) { + if ((num * LT8713SX_PAGE_SIZE + i) < filesize) + val = *(data + (num * LT8713SX_PAGE_SIZE + i)); + else + val = 0xff; + regmap_write(lt8713sx->regmap, 0xe059, val); + } + + lt8713sx_wren(lt8713sx); + lt8713sx_sram_to_flash(lt8713sx); + } + + lt8713sx_wrdi(lt8713sx); + lt8713sx_disable_sram_write(lt8713sx); + + return 0; +} + +static void lt8713sx_main_upgrade_result(struct lt8713sx *lt8713sx) +{ + u32 main_crc_result; + + regmap_read(lt8713sx->regmap, 0xe023, &main_crc_result); + + dev_dbg(lt8713sx->dev, "Main CRC HW: 0x%02X\n", main_crc_result); + dev_dbg(lt8713sx->dev, "Main CRC FW: 0x%02X\n", lt8713sx->main_crc_value); + + if (main_crc_result == lt8713sx->main_crc_value) + dev_dbg(lt8713sx->dev, "Main Firmware Upgrade Success.\n"); + else + dev_err(lt8713sx->dev, "Main Firmware Upgrade Failed.\n"); +} + +static void lt8713sx_bank_upgrade_result(struct lt8713sx *lt8713sx, u8 banknum) +{ + u32 bank_crc_result; + + regmap_read(lt8713sx->regmap, 0xe023, &bank_crc_result); + + dev_dbg(lt8713sx->dev, "Bank %d CRC Result: 0x%02X\n", banknum, bank_crc_result); + + if (bank_crc_result == lt8713sx->bank_crc_value[banknum]) + dev_dbg(lt8713sx->dev, "Bank %d Firmware Upgrade Success.\n", banknum); + else + dev_err(lt8713sx->dev, "Bank %d Firmware Upgrade Failed.\n", banknum); +} + +static void lt8713sx_bank_result_check(struct lt8713sx *lt8713sx) +{ + int i; + u64 addr = 0x010000; + + for (i = 0; i < lt8713sx->bank_num; i++) { + lt8713sx_load_bank_fw_to_sram(lt8713sx, addr); + lt8713sx_bank_upgrade_result(lt8713sx, i); + addr += 0x3000; + } +} + +static int lt8713sx_firmware_upgrade(struct lt8713sx *lt8713sx) +{ + int ret; + + lt8713sx_config_parameters(lt8713sx); + + lt8713sx_block_erase(lt8713sx); + + if (lt8713sx->fw->size < SZ_64K) { + ret = lt8713sx_write_data(lt8713sx, lt8713sx->fw_buffer, SZ_64K); + if (ret < 0) { + dev_err(lt8713sx->dev, "Failed to write firmware data: %d\n", ret); + return ret; + } + } else { + ret = lt8713sx_write_data(lt8713sx, lt8713sx->fw_buffer, lt8713sx->fw->size); + if (ret < 0) { + dev_err(lt8713sx->dev, "Failed to write firmware data: %d\n", ret); + return ret; + } + } + dev_dbg(lt8713sx->dev, "Write Data done.\n"); + + return 0; +} + +static int lt8713sx_firmware_update(struct lt8713sx *lt8713sx) +{ + int ret = 0; + + mutex_lock(<8713sx->ocm_lock); + lt8713sx_i2c_enable(lt8713sx); + + ret = lt8713sx_prepare_firmware_data(lt8713sx); + if (ret < 0) { + dev_err(lt8713sx->dev, "Failed to prepare firmware data: %d\n", ret); + goto error; + } + + ret = lt8713sx_firmware_upgrade(lt8713sx); + if (ret < 0) { + dev_err(lt8713sx->dev, "Upgrade failure.\n"); + goto error; + } else { + /* Validate CRC */ + lt8713sx_load_main_fw_to_sram(lt8713sx); + lt8713sx_main_upgrade_result(lt8713sx); + lt8713sx_wrdi(lt8713sx); + lt8713sx_fifo_reset(lt8713sx); + lt8713sx_bank_result_check(lt8713sx); + lt8713sx_wrdi(lt8713sx); + } + +error: + lt8713sx_i2c_disable(lt8713sx); + if (!ret) + lt8713sx_reset(lt8713sx); + + kvfree(lt8713sx->fw_buffer); + lt8713sx->fw_buffer = NULL; + + if (lt8713sx->fw) { + release_firmware(lt8713sx->fw); + lt8713sx->fw = NULL; + } + mutex_unlock(<8713sx->ocm_lock); + + return ret; +} + +static void lt8713sx_reset(struct lt8713sx *lt8713sx) +{ + dev_dbg(lt8713sx->dev, "reset bridge.\n"); + gpiod_set_value_cansleep(lt8713sx->reset_gpio, 1); + msleep(20); + + gpiod_set_value_cansleep(lt8713sx->reset_gpio, 0); + msleep(20); + + dev_dbg(lt8713sx->dev, "reset done.\n"); +} + +static int lt8713sx_regulator_enable(struct lt8713sx *lt8713sx) +{ + int ret; + + ret = devm_regulator_get_enable(lt8713sx->dev, "vdd"); + if (ret < 0) + return dev_err_probe(lt8713sx->dev, ret, "failed to enable vdd regulator\n"); + + usleep_range(1000, 10000); + + ret = devm_regulator_get_enable(lt8713sx->dev, "vcc"); + if (ret < 0) + return dev_err_probe(lt8713sx->dev, ret, "failed to enable vcc regulator\n"); + return 0; +} + +static int lt8713sx_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, + enum drm_bridge_attach_flags flags) +{ + struct lt8713sx *lt8713sx = container_of(bridge, struct lt8713sx, bridge); + int i, ret; + + for (i = 0; i < lt8713sx->num_outputs; i++) { + if (!lt8713sx->next_bridge[i]) + continue; + + ret = drm_bridge_attach(encoder, + lt8713sx->next_bridge[i], + bridge, flags); + if (ret) + return ret; + } + + return 0; +} + +static int lt8713sx_get_ports(struct lt8713sx *lt8713sx) +{ + struct device *dev = lt8713sx->dev; + struct device_node *port, *ports, *ep, *remote; + int i = 0; + u32 reg; + + ports = of_get_child_by_name(dev->of_node, "ports"); + if (!ports) + return -ENODEV; + + for_each_child_of_node(ports, port) { + if (of_property_read_u32(port, "reg", ®)) + continue; + + if (reg == 0) + continue; + + if (i >= ARRAY_SIZE(lt8713sx->next_bridge)) { + of_node_put(port); + break; + } + + ep = of_graph_get_next_endpoint(port, NULL); + if (!ep) + continue; + + remote = of_graph_get_remote_port_parent(ep); + of_node_put(ep); + + if (!remote) + continue; + + lt8713sx->next_bridge[i] = of_drm_find_bridge(remote); + of_node_put(remote); + if (lt8713sx->next_bridge[i]) + i++; + } + lt8713sx->num_outputs = i; + dev_dbg(dev, "Enabled %d output ports", i); + + of_node_put(ports); + return 0; +}; + +static int lt8713sx_gpio_init(struct lt8713sx *lt8713sx) +{ + struct device *dev = lt8713sx->dev; + + lt8713sx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(lt8713sx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(lt8713sx->reset_gpio), + "failed to acquire reset gpio\n"); + + /* power enable gpio */ + lt8713sx->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(lt8713sx->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(lt8713sx->enable_gpio), + "failed to acquire enable gpio\n"); + return 0; +} + +static ssize_t lt8713sx_firmware_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct lt8713sx *lt8713sx = dev_get_drvdata(dev); + int ret; + + ret = lt8713sx_firmware_update(lt8713sx); + if (ret < 0) + return ret; + return len; +} + +static DEVICE_ATTR_WO(lt8713sx_firmware); + +static struct attribute *lt8713sx_attrs[] = { + &dev_attr_lt8713sx_firmware.attr, + NULL, +}; + +static const struct attribute_group lt8713sx_attr_group = { + .attrs = lt8713sx_attrs, +}; + +static const struct attribute_group *lt8713sx_attr_groups[] = { + <8713sx_attr_group, + NULL, +}; + +static const struct drm_bridge_funcs lt8713sx_bridge_funcs = { + .attach = lt8713sx_bridge_attach, +}; + +static int lt8713sx_probe(struct i2c_client *client) +{ + struct lt8713sx *lt8713sx; + struct device *dev = &client->dev; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return dev_err_probe(dev, -ENODEV, "device doesn't support I2C\n"); + + lt8713sx = devm_drm_bridge_alloc(dev, struct lt8713sx, bridge, <8713sx_bridge_funcs); + if (IS_ERR(lt8713sx)) + return PTR_ERR(lt8713sx); + + lt8713sx->dev = dev; + lt8713sx->client = client; + i2c_set_clientdata(client, lt8713sx); + + ret = devm_mutex_init(lt8713sx->dev, <8713sx->ocm_lock); + if (ret) + return ret; + + lt8713sx->regmap = devm_regmap_init_i2c(client, <8713sx_regmap_config); + if (IS_ERR(lt8713sx->regmap)) + return dev_err_probe(dev, PTR_ERR(lt8713sx->regmap), "regmap i2c init failed\n"); + + ret = lt8713sx_get_ports(lt8713sx); + if (ret < 0) + return ret; + + ret = lt8713sx_gpio_init(lt8713sx); + if (ret < 0) + return ret; + + ret = lt8713sx_regulator_enable(lt8713sx); + if (ret) + return ret; + + lt8713sx_reset(lt8713sx); + + lt8713sx->bridge.funcs = <8713sx_bridge_funcs; + lt8713sx->bridge.of_node = dev->of_node; + lt8713sx->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; + drm_bridge_add(<8713sx->bridge); + + crc8_populate_msb(lt8713sx_crc_table, 0x31); + + return 0; +} + +static void lt8713sx_remove(struct i2c_client *client) +{ + struct lt8713sx *lt8713sx = i2c_get_clientdata(client); + + drm_bridge_remove(<8713sx->bridge); +} + +static struct i2c_device_id lt8713sx_id[] = { + { "lontium,lt8713sx", 0 }, + { /* sentinel */ } +}; + +static const struct of_device_id lt8713sx_match_table[] = { + { .compatible = "lontium,lt8713sx" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lt8713sx_match_table); + +static struct i2c_driver lt8713sx_driver = { + .driver = { + .name = "lt8713sx", + .of_match_table = lt8713sx_match_table, + .dev_groups = lt8713sx_attr_groups, + }, + .probe = lt8713sx_probe, + .remove = lt8713sx_remove, + .id_table = lt8713sx_id, +}; + +module_i2c_driver(lt8713sx_driver); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("lt8713sx drm bridge driver"); +MODULE_AUTHOR("Tony "); +MODULE_FIRMWARE(FW_FILE); From 84c52252e8c0c5f8c37bf8cb08f33a252b3de6f8 Mon Sep 17 00:00:00 2001 From: Prahlad Valluru Date: Tue, 25 Nov 2025 20:55:07 +0530 Subject: [PATCH 099/438] FROMLIST: drm/msm/dsi/phy: fix rounding error in recalc_rate Required vco rate is set by programming decimal and fraction from 64 bit calculation. This programmed rate is not exactly matching the requested rate and corresponding recalc_rate is having rounding error due to this delta. When setting byte_clk and byte_intf_clk from this pll, set_rate on byte_intf_clk resulting in dividers getting reprogrammed, which are already set from byte_clk. Convert this recalc_rate to KHz and back to Hz to round up this delta in calculation. Signed-off-by: Prahlad Valluru Link: https://lore.kernel.org/all/20251125-msm-dsi-phy-7nm-clk-rate-v1-1-17141806e3a0@oss.qualcomm.com/ --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 8cb0db3a98808..1cc4061465cd6 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -595,6 +595,12 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, pll_freq += div_u64(tmp64, multiplier); vco_rate = pll_freq; + /* + * Recalculating the rate from dec and frac doesn't end up the rate + * we originally set. Convert the freq to KHz, round it up and + * convert it back to Hz. + */ + vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000; pll_7nm->vco_current_rate = vco_rate; DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", From d18211fae75ed4a148260bc89521638f3453e8d0 Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Fri, 23 Jan 2026 15:54:56 +0530 Subject: [PATCH 100/438] FROMLIST: dt-bindings: bridge: lt9211: Add bindings Add bindings for lt9211c. Signed-off-by: Gopi Botlagunta Signed-off-by: Yi Zhang Link: https://lore.kernel.org/all/20251224-add-lt9211c-bridge-v4-1-406e73ec28c5@oss.qualcomm.com/ --- .../display/bridge/lontium,lt9211.yaml | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml b/Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml index 9a6e9b25d14a9..98079df61cbb3 100644 --- a/Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml +++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml @@ -4,19 +4,20 @@ $id: http://devicetree.org/schemas/display/bridge/lontium,lt9211.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Lontium LT9211 DSI/LVDS/DPI to DSI/LVDS/DPI bridge. +title: Lontium LT9211/LT9211C DSI/LVDS/DPI to DSI/LVDS/DPI bridge. maintainers: - Marek Vasut description: | - The LT9211 are bridge devices which convert Single/Dual-Link DSI/LVDS + The LT9211 and LT9211C are bridge devices which convert Single/Dual-Link DSI/LVDS or Single DPI to Single/Dual-Link DSI/LVDS or Single DPI. properties: compatible: enum: - lontium,lt9211 + - lontium,lt9211c reg: maxItems: 1 @@ -91,6 +92,43 @@ examples: vccio-supply = <<9211_1v8>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@2 { + reg = <2>; + + endpoint { + remote-endpoint = <&panel_in_lvds>; + }; + }; + }; + }; + }; + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + lvds-bridge@3b { + compatible = "lontium,lt9211c"; + reg = <0x3b>; + + reset-gpios = <&tlmm 128 GPIO_ACTIVE_HIGH>; + + vccio-supply = <<9211c_1v8>; + ports { #address-cells = <1>; #size-cells = <0>; From f11e34338b5c9d6f2df5b61b4cdef2ed32a8d7bf Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Wed, 28 Jan 2026 15:13:23 +0530 Subject: [PATCH 101/438] FROMLIST: drm/bridge: add support for lontium lt9211c bridge LT9211c is a Single/Dual-Link DSI/LVDS or Single DPI input to Single-link/Dual-Link DSI/LVDS or Single DPI output bridge chip. Extend the existing lontium-lt9211 driver to support DSI-to-LVDS bridge configuration. Signed-off-by: Yi Zhang Signed-off-by: Nilesh Laad Signed-off-by: Gopi Botlagunta Link: https://lore.kernel.org/lkml/20251224-add-lt9211c-bridge-v4-2-406e73ec28c5@oss.qualcomm.com/ --- drivers/gpu/drm/bridge/lontium-lt9211.c | 903 ++++++++++++++++++++++-- 1 file changed, 835 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c b/drivers/gpu/drm/bridge/lontium-lt9211.c index 03fc8fd10f20a..95fefab9c0216 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9211.c +++ b/drivers/gpu/drm/bridge/lontium-lt9211.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -28,28 +29,48 @@ #include #include -#define REG_PAGE_CONTROL 0xff -#define REG_CHIPID0 0x8100 -#define REG_CHIPID0_VALUE 0x18 -#define REG_CHIPID1 0x8101 -#define REG_CHIPID1_VALUE 0x01 -#define REG_CHIPID2 0x8102 -#define REG_CHIPID2_VALUE 0xe3 +#define REG_PAGE_CONTROL 0xff +#define REG_CHIPID0 0x8100 +#define REG_CHIPID0_VALUE 0x18 +#define REG_CHIPID1 0x8101 +#define REG_CHIPID1_VALUE 0x01 +#define REG_CHIPID2 0x8102 +#define REG_CHIPID2_VALUE 0xe3 -#define REG_DSI_LANE 0xd000 +/* LT9211C chip ID values */ +#define REG_CHIPID0_LT9211C_VALUE 0x21 +#define REG_CHIPID1_LT9211C_VALUE 0x03 +#define REG_CHIPID2_LT9211C_VALUE 0xe1 + +#define REG_DSI_LANE 0xd000 /* DSI lane count - 0 means 4 lanes ; 1, 2, 3 means 1, 2, 3 lanes. */ -#define REG_DSI_LANE_COUNT(n) ((n) & 3) +#define REG_DSI_LANE_COUNT(n) ((n) & 3) + +/* Chip type enum */ +enum lt9211_chip_type { + LT9211, + LT9211C, +}; struct lt9211 { - struct drm_bridge bridge; - struct device *dev; - struct regmap *regmap; - struct mipi_dsi_device *dsi; - struct drm_bridge *panel_bridge; - struct gpio_desc *reset_gpio; - struct regulator *vccio; - bool lvds_dual_link; - bool lvds_dual_link_even_odd_swap; + struct drm_bridge bridge; + struct device *dev; + struct regmap *regmap; + struct mipi_dsi_device *dsi; + struct drm_bridge *panel_bridge; + struct gpio_desc *reset_gpio; + struct regulator *vccio; + bool lvds_dual_link; + bool lvds_dual_link_even_odd_swap; + + /* LT9211C specific fields */ + enum lt9211_chip_type chip_type; + struct workqueue_struct *wq; + struct delayed_work lt9211_dw; + struct drm_display_mode mode; + bool bpp24; + bool jeida; + bool de; }; static const struct regmap_range lt9211_rw_ranges[] = { @@ -86,13 +107,56 @@ static const struct regmap_config lt9211_regmap_config = { .val_bits = 8, .rd_table = <9211_rw_table, .wr_table = <9211_rw_table, - .volatile_table = <9211_rw_table, + .volatile_table = <9211_rw_table, .ranges = <9211_range, .num_ranges = 1, .cache_type = REGCACHE_MAPLE, .max_register = 0xda00, }; +static const struct regmap_range lt9211c_rw_ranges[] = { + regmap_reg_range(0xff, 0xff), + regmap_reg_range(0x8100, 0x8182), + regmap_reg_range(0x8200, 0x82aa), + regmap_reg_range(0x8500, 0x85ff), + regmap_reg_range(0x8600, 0x86a0), + regmap_reg_range(0x8700, 0x8746), + regmap_reg_range(0xd000, 0xd0a7), + regmap_reg_range(0xd400, 0xd42c), + regmap_reg_range(0xd800, 0xd838), + regmap_reg_range(0xd9c0, 0xd9d5), +}; + +static const struct regmap_access_table lt9211c_rw_table = { + .yes_ranges = lt9211c_rw_ranges, + .n_yes_ranges = ARRAY_SIZE(lt9211c_rw_ranges), +}; + +static const struct regmap_range_cfg lt9211c_range = { + .name = "lt9211c", + .range_min = 0x0000, + .range_max = 0xda00, + .selector_reg = REG_PAGE_CONTROL, + .selector_mask = 0xff, + .selector_shift = 0, + .window_start = 0, + .window_len = 0x100, +}; + +static const struct regmap_config lt9211c_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .rd_table = <9211c_rw_table, + .wr_table = <9211c_rw_table, + .volatile_table = <9211c_rw_table, + .ranges = <9211c_range, + .num_ranges = 1, + .cache_type = REGCACHE_RBTREE, + .max_register = 0xda00, +}; + +static void lt9211_delayed_work_func(struct work_struct *work); + static struct lt9211 *bridge_to_lt9211(struct drm_bridge *bridge) { return container_of(bridge, struct lt9211, bridge); @@ -120,14 +184,24 @@ static int lt9211_read_chipid(struct lt9211 *ctx) return ret; } - /* Test for known Chip ID. */ - if (chipid[0] != REG_CHIPID0_VALUE || chipid[1] != REG_CHIPID1_VALUE) { - dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n", - chipid[0], chipid[1], chipid[2]); - return -EINVAL; + /* Test for LT9211 Chip ID. */ + if (chipid[0] == REG_CHIPID0_VALUE && chipid[1] == REG_CHIPID1_VALUE && + chipid[2] == REG_CHIPID2_VALUE) { + dev_dbg(ctx->dev, "Detected LT9211 chip\n"); + return 0; } - return 0; + /* Test for LT9211C Chip ID. */ + if (chipid[0] == REG_CHIPID0_LT9211C_VALUE && + chipid[1] == REG_CHIPID1_LT9211C_VALUE && + chipid[2] == REG_CHIPID2_LT9211C_VALUE) { + dev_dbg(ctx->dev, "Detected LT9211C chip\n"); + return 0; + } + + dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n", chipid[0], + chipid[1], chipid[2]); + return -EINVAL; } static int lt9211_system_init(struct lt9211 *ctx) @@ -250,9 +324,9 @@ static int lt9211_autodetect_rx(struct lt9211 *ctx, height = (buf[3] << 8) | buf[4]; format = buf[2] & 0xf; - if (format == 0x3) { /* YUV422 16bit */ + if (format == 0x3) { /* YUV422 16bit */ width /= 2; - } else if (format == 0xa) { /* RGB888 24bit */ + } else if (format == 0xa) { /* RGB888 24bit */ width /= 3; } else { dev_err(ctx->dev, "Unsupported DSI pixel format 0x%01x\n", @@ -476,7 +550,7 @@ static void lt9211_atomic_enable(struct drm_bridge *bridge, /* Deassert reset */ gpiod_set_value(ctx->reset_gpio, 1); - usleep_range(20000, 21000); /* Very long post-reset delay. */ + usleep_range(20000, 21000); /* Very long post-reset delay. */ /* Get the LVDS format from the bridge state. */ bridge_state = drm_atomic_get_new_bridge_state(state, bridge); @@ -504,8 +578,8 @@ static void lt9211_atomic_enable(struct drm_bridge *bridge, lvds_format_24bpp = true; lvds_format_jeida = false; dev_warn(ctx->dev, - "Unsupported LVDS bus format 0x%04x, please check output bridge driver. Falling back to SPWG24.\n", - bridge_state->output_bus_cfg.format); + "Unsupported LVDS bus format 0x%04x, please check output bridge driver. Falling back to SPWG24.\n", + bridge_state->output_bus_cfg.format); break; } @@ -518,35 +592,42 @@ static void lt9211_atomic_enable(struct drm_bridge *bridge, crtc = drm_atomic_get_new_connector_state(state, connector)->crtc; crtc_state = drm_atomic_get_new_crtc_state(state, crtc); mode = &crtc_state->adjusted_mode; - ret = lt9211_read_chipid(ctx); if (ret) return; - ret = lt9211_system_init(ctx); - if (ret) + if (ctx->chip_type == LT9211C && ctx->wq) { + drm_mode_copy(&ctx->mode, mode); + /* LT9211C must enable after mipi clock enable */ + queue_delayed_work(ctx->wq, &ctx->lt9211_dw, + msecs_to_jiffies(100)); + dev_dbg(ctx->dev, "LT9211C enabled.\n"); return; + } + ret = lt9211_system_init(ctx); + if (ret) + return; - ret = lt9211_configure_rx(ctx); - if (ret) - return; + ret = lt9211_configure_rx(ctx); + if (ret) + return; - ret = lt9211_autodetect_rx(ctx, mode); - if (ret) - return; + ret = lt9211_autodetect_rx(ctx, mode); + if (ret) + return; - ret = lt9211_configure_timing(ctx, mode); - if (ret) - return; + ret = lt9211_configure_timing(ctx, mode); + if (ret) + return; - ret = lt9211_configure_plls(ctx, mode); - if (ret) - return; + ret = lt9211_configure_plls(ctx, mode); + if (ret) + return; ret = lt9211_configure_tx(ctx, lvds_format_jeida, lvds_format_24bpp, - bus_flags & DRM_BUS_FLAG_DE_HIGH); - if (ret) - return; + bus_flags & DRM_BUS_FLAG_DE_HIGH); + if (ret) + return; dev_dbg(ctx->dev, "LT9211 enabled.\n"); } @@ -562,7 +643,7 @@ static void lt9211_atomic_disable(struct drm_bridge *bridge, * and assure lengthy 10ms reset low timing. */ gpiod_set_value(ctx->reset_gpio, 0); - usleep_range(10000, 11000); /* Very long reset duration. */ + usleep_range(10000, 11000); /* Very long reset duration. */ ret = regulator_disable(ctx->vccio); if (ret) @@ -585,7 +666,7 @@ lt9211_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -#define MAX_INPUT_SEL_FORMATS 1 +#define MAX_INPUT_SEL_FORMATS 1 static u32 * lt9211_atomic_get_input_bus_fmts(struct drm_bridge *bridge, @@ -612,14 +693,14 @@ lt9211_atomic_get_input_bus_fmts(struct drm_bridge *bridge, } static const struct drm_bridge_funcs lt9211_funcs = { - .attach = lt9211_attach, - .mode_valid = lt9211_mode_valid, - .atomic_enable = lt9211_atomic_enable, - .atomic_disable = lt9211_atomic_disable, + .attach = lt9211_attach, + .mode_valid = lt9211_mode_valid, + .atomic_enable = lt9211_atomic_enable, + .atomic_disable = lt9211_atomic_disable, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_get_input_bus_fmts = lt9211_atomic_get_input_bus_fmts, - .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_reset = drm_atomic_helper_bridge_reset, }; static int lt9211_parse_dt(struct lt9211 *ctx) @@ -671,11 +752,6 @@ static int lt9211_parse_dt(struct lt9211 *ctx) static int lt9211_host_attach(struct lt9211 *ctx) { - const struct mipi_dsi_device_info info = { - .type = "lt9211", - .channel = 0, - .node = NULL, - }; struct device *dev = ctx->dev; struct device_node *host_node; struct device_node *endpoint; @@ -684,6 +760,8 @@ static int lt9211_host_attach(struct lt9211 *ctx) int dsi_lanes; int ret; + /* Check if the compatible string matches lt9211c */ + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4); host_node = of_graph_get_remote_port_parent(endpoint); @@ -697,7 +775,22 @@ static int lt9211_host_attach(struct lt9211 *ctx) if (dsi_lanes < 0) return dsi_lanes; - dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + if (ctx->chip_type == LT9211C) { + const struct mipi_dsi_device_info info = { + .type = "lt9211c", + .channel = 0, + .node = NULL, + }; + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + } else { + const struct mipi_dsi_device_info info = { + .type = "lt9211", + .channel = 0, + .node = NULL, + }; + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + } + if (IS_ERR(dsi)) return dev_err_probe(dev, PTR_ERR(dsi), "failed to create dsi device\n"); @@ -706,10 +799,16 @@ static int lt9211_host_attach(struct lt9211 *ctx) dsi->lanes = dsi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA | - MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | - MIPI_DSI_MODE_NO_EOT_PACKET; + + if (ctx->chip_type == LT9211C) { + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + } else { + dsi->mode_flags = + MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA | + MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | + MIPI_DSI_MODE_NO_EOT_PACKET; + } ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { @@ -731,6 +830,7 @@ static int lt9211_probe(struct i2c_client *client) return PTR_ERR(ctx); ctx->dev = dev; + ctx->chip_type = LT9211; /* * Put the chip in reset, pull nRST line low, @@ -741,16 +841,32 @@ static int lt9211_probe(struct i2c_client *client) if (IS_ERR(ctx->reset_gpio)) return PTR_ERR(ctx->reset_gpio); - usleep_range(10000, 11000); /* Very long reset duration. */ + usleep_range(10000, 11000); /* Very long reset duration. */ ret = lt9211_parse_dt(ctx); + if (ret) return ret; - ctx->regmap = devm_regmap_init_i2c(client, <9211_regmap_config); + if (of_device_is_compatible(dev->of_node, "lontium,lt9211c")) { + ctx->chip_type = LT9211C; + ctx->regmap = + devm_regmap_init_i2c(client, <9211c_regmap_config); + } else { + ctx->chip_type = LT9211; + ctx->regmap = + devm_regmap_init_i2c(client, <9211_regmap_config); + } if (IS_ERR(ctx->regmap)) return PTR_ERR(ctx->regmap); + /* Initialize LT9211C-specific fields */ + ctx->wq = create_workqueue("lt9211_work"); + if (!ctx->wq) + return -ENOMEM; + + INIT_DELAYED_WORK(&ctx->lt9211_dw, lt9211_delayed_work_func); + dev_set_drvdata(dev, ctx); i2c_set_clientdata(client, ctx); @@ -768,17 +884,668 @@ static void lt9211_remove(struct i2c_client *client) { struct lt9211 *ctx = i2c_get_clientdata(client); + if (ctx->wq) + destroy_workqueue(ctx->wq); + drm_bridge_remove(&ctx->bridge); } +static int lt9211c_configure_rx(struct lt9211 *ctx) +{ + unsigned int pval; + + const struct reg_sequence lt9211c_rx_phy_seq[] = { + { REG_DSI_LANE, REG_DSI_LANE_COUNT(ctx->dsi->lanes) }, + { 0x8201, 0x11 }, + { 0x8218, 0x48 }, + { 0x8201, 0x91 }, + { 0x8202, 0x00 }, + { 0x8203, 0xee }, + { 0x8209, 0x21 }, + { 0x8204, 0x44 }, + { 0x8205, 0xc4 }, + { 0x8206, 0x44 }, + { 0x8213, 0x0c }, + + { 0xd001, 0x00 }, + { 0xd002, 0x0e }, + { 0xd005, 0x00 }, + { 0xd00a, 0x59 }, + { 0xd00b, 0x20 }, + }; + + const struct reg_sequence lt9211c_rx_phy_reset_seq[] = { + { 0x8109, 0xde }, + { 0x8109, 0xdf }, + }; + + const struct reg_sequence lt9211c_rx_clk_sel_seq[] = { + { 0x85e9, 0x88 }, + { 0x8180, 0x51 }, + { 0x8181, 0x10 }, + { 0x8632, 0x03 }, + }; + + const struct reg_sequence lt9211c_rx_input_sel_seq[] = { + { 0xd004, 0x00 }, + { 0xd021, 0x46 }, + }; + + const struct reg_sequence lt9211c_rx_dig_seq[] = { + { 0x853f, 0x08 }, + { 0x8540, 0x04 }, + { 0x8541, 0x03 }, + { 0x8542, 0x02 }, + { 0x8543, 0x01 }, + { 0x8545, 0x04 }, + { 0x8546, 0x03 }, + { 0x8547, 0x02 }, + { 0x8548, 0x01 }, + { 0x8544, 0x00 }, + { 0x8549, 0x00 }, + }; + + int ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_rx_phy_seq, + ARRAY_SIZE(lt9211c_rx_phy_seq)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_rx_phy_reset_seq, + ARRAY_SIZE(lt9211c_rx_phy_reset_seq)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_rx_clk_sel_seq, + ARRAY_SIZE(lt9211c_rx_clk_sel_seq)); + if (ret) + return ret; + + ret = regmap_read(ctx->regmap, 0x8180, &pval); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x8180, (pval & 0xfc | 0x03)); + if (ret) + return ret; + + ret = regmap_read(ctx->regmap, 0x8680, &pval); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x863f, (pval & 0xf8)); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x863f, 0x05); + if (ret) + return ret; + + ret = regmap_read(ctx->regmap, 0x8530, &pval); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x8530, (pval & 0xf8 | 0x11)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_rx_input_sel_seq, + ARRAY_SIZE(lt9211c_rx_input_sel_seq)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_rx_dig_seq, + ARRAY_SIZE(lt9211c_rx_dig_seq)); + if (ret) + return ret; + + /* Give the chip time to lock onto RX stream. */ + msleep(100); + + return 0; +} + +static int lt9211c_autodetect_rx(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + u16 width, height; + u8 buf[5]; + u8 format; + u8 bc[3]; + u8 sot[8]; + int ret; + + /* Read the SOT from the chip. */ + ret = regmap_bulk_read(ctx->regmap, 0xd088, sot, sizeof(sot)); + if (ret) + return ret; + + dev_dbg(ctx->dev, "Sot Num = 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", sot[0], + sot[2], sot[4], sot[6]); + + dev_dbg(ctx->dev, "Sot Data = 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", sot[1], + sot[3], sot[5], sot[7]); + /* HS Settle Set */ + if (sot[0] > 0x10 && sot[0] < 0x50) + regmap_write(ctx->regmap, 0xd002, sot[0] - 5); + else + regmap_write(ctx->regmap, 0xd002, 0x08); + + /* Width/Height/Format Auto-detection */ + ret = regmap_bulk_read(ctx->regmap, 0xd082, buf, sizeof(buf)); + if (ret) + return ret; + + width = (buf[0] << 8) | buf[1]; + height = (buf[3] << 8) | buf[4]; + format = buf[2] & 0xf; + + if (format == 0x3) { /* YUV422 16bit */ + width /= 2; + } else if (format == 0xa) { /* RGB888 24bit */ + width /= 3; + } else { + dev_err(ctx->dev, "Unsupported DSI format 0x%01x\n", format); + return -EINVAL; + } + + if (width != mode->hdisplay) { + dev_err(ctx->dev, + "RX: Detected DSI width (%d) does not match mode hdisplay (%d)\n", + width, mode->hdisplay); + return -EINVAL; + } + + if (height != mode->vdisplay) { + dev_err(ctx->dev, + "RX: Detected DSI height (%d) does not match mode vdisplay (%d)\n", + height, mode->vdisplay); + return -EINVAL; + } + + dev_dbg(ctx->dev, "RX: %dx%d format=0x%01x\n", width, height, format); + return 0; +} + +static int lt9211c_configure_timing(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + const struct reg_sequence lt9211c_timing[] = { + { 0xd00d, (mode->vtotal >> 8) & 0xff }, + { 0xd00e, mode->vtotal & 0xff }, + { 0xd00f, (mode->vdisplay >> 8) & 0xff }, + { 0xd010, mode->vdisplay & 0xff }, + { 0xd011, (mode->htotal >> 8) & 0xff }, + { 0xd012, mode->htotal & 0xff }, + { 0xd013, (mode->hdisplay >> 8) & 0xff }, + { 0xd014, mode->hdisplay & 0xff }, + { 0xd015, (mode->vsync_end - mode->vsync_start) & 0xff }, + { 0xd04c, ((mode->hsync_end - mode->hsync_start) >> 8) & 0xff }, + { 0xd016, (mode->hsync_end - mode->hsync_start) & 0xff }, + { 0xd017, ((mode->vsync_start - mode->vdisplay) >> 8) & 0xff }, + { 0xd018, (mode->vsync_start - mode->vdisplay) & 0xff }, + { 0xd019, ((mode->hsync_start - mode->hdisplay) >> 8) & 0xff }, + { 0xd01a, (mode->hsync_start - mode->hdisplay) & 0xff }, + }; + + return regmap_multi_reg_write(ctx->regmap, lt9211c_timing, + ARRAY_SIZE(lt9211c_timing)); +} + +static int lt9211c_configure_plls(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + const struct reg_sequence lt9211c_dessc_pll_reset[] = { + { 0x8103, 0xfe, 2000 }, + { 0x8103, 0xff, 0 }, + }; + + const struct reg_sequence lt9211c_pcr_cali_seq[] = { + { 0xd00a, 0x5f }, + { 0xd01e, 0x51 }, + { 0xd023, 0x80 }, + { 0xd024, 0x70 }, + { 0xd025, 0x80 }, + { 0xd02a, 0x10 }, + { 0xd021, 0x4f }, + { 0xd022, 0xf0 }, + { 0xd038, 0x04 }, + { 0xd039, 0x08 }, + { 0xd03a, 0x10 }, + { 0xd03b, 0x20 }, + { 0xd03f, 0x04 }, + { 0xd040, 0x08 }, + { 0xd041, 0x10 }, + { 0xd042, 0x20 }, + { 0xd02b, 0xA0 }, + }; + + const struct reg_sequence lt9211c_pcr_reset_seq[] = { + { 0xd009, 0xdb }, + { 0xd009, 0xdf }, + { 0xd008, 0x80 }, + { 0xd008, 0x00 }, + }; + + unsigned int pval; + int ret; + u8 div; + u32 pcr_m; + u32 pcr_k; + u32 pcr_up; + u32 pcr_down; + + /* DeSSC PLL reference clock is 25 MHz XTal. */ + ret = regmap_write(ctx->regmap, 0x8226, 0x20); + if (ret) + return ret; + + /* Prediv = 0 */ + ret = regmap_write(ctx->regmap, 0x8227, 0x40); + if (ret) + return ret; + + if (mode->clock < 22000) { + ret = regmap_write(ctx->regmap, 0x822f, 0x07); + ret |= regmap_write(ctx->regmap, 0x822c, 0x01); + div = 16; + } else if (mode->clock < 44000) { + ret = regmap_write(ctx->regmap, 0x822f, 0x07); + div = 16; + } else if (mode->clock < 88000) { + ret = regmap_write(ctx->regmap, 0x822f, 0x06); + div = 8; + } else if (mode->clock < 176000) { + ret = regmap_write(ctx->regmap, 0x822f, 0x05); + div = 4; + } else { + ret = regmap_write(ctx->regmap, 0x822f, 0x04); + div = 2; + } + + if (ret) + return ret; + + pcr_m = (mode->clock * div) / 25; + pcr_k = pcr_m % 1000; + pcr_m /= 1000; + + pcr_up = pcr_m + 1; + pcr_down = pcr_m - 1; + + pcr_k <<= 14; + + ret = regmap_write(ctx->regmap, 0xd008, 0x00); + if (ret < 0) + return ret; + + /* 0xd026: pcr_m */ + ret = regmap_write(ctx->regmap, 0xd026, (0x80 | (u8)pcr_m) & 0x7f); + if (ret < 0) + return ret; + + /* 0xd027 0xd028 0xd029: pcr_k */ + ret = regmap_write(ctx->regmap, 0xd027, (pcr_k >> 16) & 0xff); + if (ret < 0) + return ret; + + ret = regmap_write(ctx->regmap, 0xd028, (pcr_k >> 8) & 0xff); + if (ret < 0) + return ret; + + ret = regmap_write(ctx->regmap, 0xd029, pcr_k & 0xff); + if (ret < 0) + return ret; + + /* 0xd02d: pcr_m overflow limit setting */ + ret = regmap_write(ctx->regmap, 0xd02d, pcr_up); + if (ret < 0) + return ret; + + /* 0xd031: pcr_m underflow limit setting */ + ret = regmap_write(ctx->regmap, 0xd031, pcr_down); + if (ret < 0) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_dessc_pll_reset, + ARRAY_SIZE(lt9211c_dessc_pll_reset)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_pcr_cali_seq, + ARRAY_SIZE(lt9211c_pcr_cali_seq)); + if (ret) + return ret; + + if (mode->clock < 44000) { + ret = regmap_write(ctx->regmap, 0xd00c, 0x60); + ret |= regmap_write(ctx->regmap, 0xd01b, 0x00); + ret |= regmap_write(ctx->regmap, 0xd01c, 0x60); + } else { + ret = regmap_write(ctx->regmap, 0xd00c, 0x40); + ret |= regmap_write(ctx->regmap, 0xd01b, 0x00); + ret |= regmap_write(ctx->regmap, 0xd01c, 0x40); + } + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_pcr_reset_seq, + ARRAY_SIZE(lt9211c_pcr_reset_seq)); + if (ret) + return ret; + + /* PCR stability test takes seconds. */ + ret = regmap_read_poll_timeout(ctx->regmap, 0xd087, pval, + ((pval & 0x18) == 0x18), 20000, 3000000); + if (ret) + dev_err(ctx->dev, "PCR unstable, ret=%i\n", ret); + + ret = regmap_write(ctx->regmap, 0x8180, 0x51); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x863f, 0x00); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x863f, 0x01); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(ctx->regmap, 0x8640, pval, + ((pval & 0x01) == 0x01), 50000, 250000); + if (ret) + dev_err(ctx->dev, "Video check not stable, ret=%i\n", ret); + + return ret; +} + +static int lt9211c_configure_tx(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + const struct reg_sequence lt9211c_tx_phy_off_seq[] = { + { 0x8236, 0x00 }, + { 0x8237, 0x00 }, + { 0x8108, 0x6f }, + { 0x8103, 0xbf }, + }; + + const struct reg_sequence lt9211c_tx_phy_seq[] = { + { 0x8236, 0x03 }, + { 0x8237, 0x44 }, + { 0x8238, 0x14 }, + { 0x8239, 0x31 }, + { 0x823a, 0xc8 }, + { 0x823b, 0x00 }, + { 0x823c, 0x0f }, + { 0x8246, 0x40 }, + { 0x8247, 0x40 }, + { 0x8248, 0x40 }, + { 0x8249, 0x40 }, + { 0x824a, 0x40 }, + { 0x824b, 0x40 }, + { 0x824c, 0x40 }, + { 0x824d, 0x40 }, + { 0x824e, 0x40 }, + { 0x824f, 0x40 }, + { 0x8250, 0x40 }, + { 0x8251, 0x40 }, + }; + + const struct reg_sequence lt9211c_tx_mltx_reset[] = { + { 0x8103, 0xbf }, + { 0x8103, 0xff }, + }; + + const struct reg_sequence lt9211c_tx_dig_seq[] = { + { 0x854a, 0x01 }, + { 0x854b, 0x00 }, + { 0x854c, 0x10 }, + { 0x854d, 0x20 }, + { 0x854e, 0x50 }, + { 0x854f, 0x30 }, + { 0x8550, 0x46 }, + { 0x8551, 0x10 }, + { 0x8552, 0x20 }, + { 0x8553, 0x50 }, + { 0x8554, 0x30 }, + { 0x8555, 0x00 }, + { 0x8556, 0x20 }, + + { 0x8568, 0x00 }, + { 0x856e, 0x10 | (ctx->de ? BIT(6) : 0) }, + { 0x856f, 0x81 | (ctx->jeida ? BIT(6) : 0) | + (ctx->lvds_dual_link ? BIT(4) : 0) | + (ctx->bpp24 ? BIT(2) : 0) }, + }; + + const struct reg_sequence lt9211c_tx_ssc_seq[] = { + { 0x8234, 0x00 }, + { 0x856e, 0x10 }, + { 0x8181, 0x15 }, + { 0x871e, 0x00 }, + { 0x8717, 0x02 }, + { 0x8718, 0x04 }, + { 0x8719, 0xd4 }, + { 0x871A, 0x00 }, + { 0x871B, 0x12 }, + { 0x871C, 0x00 }, + { 0x871D, 0x24 }, + { 0x871F, 0x1c }, + { 0x8720, 0x00 }, + { 0x8721, 0x00 }, + { 0x871e, 0x02 }, + }; + + const struct reg_sequence lt9211c_tx_pll_reset_seq[] = { + { 0x810c, 0xfe, 2000 }, + { 0x810c, 0xff, 0 }, + }; + + const struct reg_sequence lt9211c_tx_sw_reset_seq[] = { + { 0x8108, 0x6f, 2000 }, + { 0x8108, 0x7f, 0 }, + }; + + unsigned int pval; + int ret; + u32 phy_clk; + u8 pixclk_div; + u8 pre_div; + u8 div_set; + u8 sericlk_div; + u8 val; + + dev_info(ctx->dev, + "dual_link=%d,even_odd_swap=%d,bpp24=%d,jeida=%d,de=%d\n", + ctx->lvds_dual_link, ctx->lvds_dual_link_even_odd_swap, + ctx->bpp24, ctx->jeida, ctx->de); + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_phy_off_seq, + ARRAY_SIZE(lt9211c_tx_phy_off_seq)); + if (ret) + return ret; + + ret = regmap_read(ctx->regmap, 0x8530, &pval); + if (ret) + return ret; + + ret = regmap_write(ctx->regmap, 0x8530, (pval & 0x3f | 0x40)); + if (ret) + return ret; + + /* [7]0:txpll normal work; txpll ref clk sel pix clk */ + ret = regmap_write(ctx->regmap, 0x8230, 0x00); + if (ret) + return ret; + + if (ctx->lvds_dual_link) + phy_clk = (u32)(mode->clock * 7 / 2); + else + phy_clk = (u32)(mode->clock * 7); + + /* 0x8231: prediv sel */ + if (mode->clock < 20000) { + val = 0x28; + pre_div = 1; + } else if (mode->clock < 40000) { + val = 0x28; + pre_div = 1; + } else if (mode->clock < 80000) { + val = 0x29; + pre_div = 2; + } else if (mode->clock < 160000) { + val = 0x2a; + pre_div = 4; + } else if (mode->clock < 320000) { + val = 0x2b; + pre_div = 8; + } else { + val = 0x2f; + pre_div = 16; + } + ret = regmap_write(ctx->regmap, 0x8231, val); + if (ret < 0) + return ret; + + /* 0x8232: serickdiv sel */ + if (phy_clk < 80000) { + val = 0x32; + sericlk_div = 16; + } else if (phy_clk < 160000) { + val = 0x22; + sericlk_div = 8; + } else if (phy_clk < 320000) { + val = 0x12; + sericlk_div = 4; + } else if (phy_clk < 640000) { + val = 0x02; + sericlk_div = 2; + } else { + val = 0x42; + sericlk_div = 1; + } + ret = regmap_write(ctx->regmap, 0x8232, val); + if (ret < 0) + return ret; + + /* 0x8233: pix_mux sel & pix_div sel + * To avoid floating point operations, The pixclk_div is enlarged by 10 times + */ + if (mode->clock > 150000) { + val = 0x04; + pixclk_div = 35; + } else { + pixclk_div = + (u8)((phy_clk * sericlk_div * 10) / (mode->clock * 7)); + if (pixclk_div <= 10) + val = 0x00; + else if (pixclk_div <= 20) + val = 0x01; + else if (pixclk_div <= 40) + val = 0x02; + else + val = 0x03; + } + ret = regmap_write(ctx->regmap, 0x8233, val); + if (ret < 0) + return ret; + + ret = regmap_write(ctx->regmap, 0x8234, 0x01); + if (ret < 0) + return ret; + + /* 0x8235: div set */ + div_set = (u8)(phy_clk * sericlk_div / mode->clock / pre_div); + ret = regmap_write(ctx->regmap, 0x8235, div_set); + if (ret < 0) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_ssc_seq, + ARRAY_SIZE(lt9211c_tx_ssc_seq)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_pll_reset_seq, + ARRAY_SIZE(lt9211c_tx_pll_reset_seq)); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(ctx->regmap, 0x8739, pval, pval & 0x04, + 10000, 1000000); + if (ret) { + dev_err(ctx->dev, "TX PLL unstable, ret=%i\n", ret); + return ret; + } + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_phy_seq, + ARRAY_SIZE(lt9211c_tx_phy_seq)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_mltx_reset, + ARRAY_SIZE(lt9211c_tx_mltx_reset)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_dig_seq, + ARRAY_SIZE(lt9211c_tx_dig_seq)); + if (ret) + return ret; + + ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_sw_reset_seq, + ARRAY_SIZE(lt9211c_tx_sw_reset_seq)); + if (ret) + return ret; + + return 0; +} + +static void lt9211_delayed_work_func(struct work_struct *work) +{ + struct delayed_work *dw = to_delayed_work(work); + struct lt9211 *ctx = container_of(dw, struct lt9211, lt9211_dw); + int ret; + const struct drm_display_mode *mode = &ctx->mode; + + /* For LT9211C */ + if (ctx->chip_type != LT9211C) { + dev_err(ctx->dev, "LT9211: Delayed work called for non-LT9211C chip\n"); + return; + } + ret = lt9211c_configure_rx(ctx); + if (ret) + return; + + ret = lt9211c_autodetect_rx(ctx, mode); + if (ret) + return; + + ret = lt9211c_configure_timing(ctx, mode); + if (ret) + return; + + ret = lt9211c_configure_plls(ctx, mode); + if (ret) + return; + + ret = lt9211c_configure_tx(ctx, mode); + if (ret) + return; + +} + static const struct i2c_device_id lt9211_id[] = { { "lontium,lt9211" }, + { "lontium,lt9211c" }, {}, }; MODULE_DEVICE_TABLE(i2c, lt9211_id); static const struct of_device_id lt9211_match_table[] = { { .compatible = "lontium,lt9211" }, + { .compatible = "lontium,lt9211c" }, {}, }; MODULE_DEVICE_TABLE(of, lt9211_match_table); From 52fe805b4b2963c064678666a6f8e708336fea37 Mon Sep 17 00:00:00 2001 From: Nilesh Laad Date: Wed, 28 Jan 2026 18:28:20 +0530 Subject: [PATCH 102/438] FROMLIST: drm/bridge: lt9611uxc: reset edid_read on disconnect Currently edid_read has value from previous connect session and resulting in drm using older edid before new edid is available in lt9611uxc. Reset edid_read so that correct status is updated and correct edid is available for drm. Link: https://lore.kernel.org/lkml/20260202-lt9611uxc-reset-edid-v2-1-b1e1d72edc90@oss.qualcomm.com/ Signed-off-by: Ravi Agola Signed-off-by: Nilesh Laad --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index cd1a948d18afa..1c0e97030419e 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -173,6 +173,9 @@ static void lt9611uxc_hpd_work(struct work_struct *work) connected = lt9611uxc->hdmi_connected; mutex_unlock(<9611uxc->ocm_lock); + if (!connected) + lt9611uxc->edid_read = false; + drm_bridge_hpd_notify(<9611uxc->bridge, connected ? connector_status_connected : From 54bffffd0e3d05c00fcb65f915f0926b5b5f1167 Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Wed, 18 Feb 2026 16:41:13 +0530 Subject: [PATCH 103/438] FROMLIST: drm/msm: enable separate_gpu_kms by default On targets with multiple display subsystems, such as SA8775P, the GPU binds to the first display subsystem that probes. This implicit binding prevents subsequent display subsystems from probing successfully, breaking multi-display support. Enable separate_gpu_kms by default to decouple GPU and display subsystem probing. This allows each display subsystem to initialize independently, ensuring that all display subsystems are probed. Link: https://lore.kernel.org/all/20260223-seperate_gpu_kms-v1-1-e8231e7f1685@oss.qualcomm.com/ Signed-off-by: Mahadevan P Signed-off-by: Yash Gupta --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index e5ab1e28851df..6474cd0d46c75 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -54,7 +54,7 @@ static bool modeset = true; MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)"); module_param(modeset, bool, 0600); -static bool separate_gpu_kms; +static bool separate_gpu_kms = true; MODULE_PARM_DESC(separate_gpu_drm, "Use separate DRM device for the GPU (0=single DRM device for both GPU and display (default), 1=two DRM devices)"); module_param(separate_gpu_kms, bool, 0400); From acb8e0c2acd7551f1262b4ae6f896fc8e58dc29f Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:53 +0800 Subject: [PATCH 104/438] FROMLIST: dt-bindings: i2c: qcom-cci: Document sm6150 compatible Add the sm6150 CCI device string compatible. Link: https://lore.kernel.org/all/20260122-sm6150_evk-v5-2-039b170450a3@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu Reviewed-by: Krzysztof Kozlowski Reviewed-by: Loic Poulain --- Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index 399a09409e071..35d3a0685ac44 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -34,6 +34,7 @@ properties: - qcom,sc8280xp-cci - qcom,sdm670-cci - qcom,sdm845-cci + - qcom,sm6150-cci - qcom,sm6350-cci - qcom,sm8250-cci - qcom,sm8450-cci @@ -251,6 +252,7 @@ allOf: contains: enum: - qcom,sa8775p-cci + - qcom,sm6150-cci - qcom,sm8550-cci - qcom,sm8650-cci - qcom,x1e80100-cci From 0f57d5fd1ed2d75ffa1b5c98772af9b246ca85a0 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Fri, 23 Jan 2026 17:19:55 +0800 Subject: [PATCH 105/438] FROMLIST: media: i2c: imx412: Assert reset GPIO during probe Assert the reset GPIO before first power up. This avoids a mismatch where the first power up (when the reset GPIO defaults deasserted) differs from subsequent cycles. Link: https://lore.kernel.org/all/20260123-imx412-v7-1-e58303f2b76b@oss.qualcomm.com/ Signed-off-by: Wenmeng Liu --- drivers/media/i2c/imx412.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c index b3826f8035470..aa63dfc349181 100644 --- a/drivers/media/i2c/imx412.c +++ b/drivers/media/i2c/imx412.c @@ -925,7 +925,7 @@ static int imx412_parse_hw_config(struct imx412 *imx412) /* Request optional reset pin */ imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset", - GPIOD_OUT_LOW); + GPIOD_OUT_HIGH); if (IS_ERR(imx412->reset_gpio)) { dev_err(imx412->dev, "failed to get reset gpio %pe\n", imx412->reset_gpio); From 516d0fa64cdb31d57c2216ed6e3fbb88fc553b9a Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Fri, 23 Jan 2026 17:19:56 +0800 Subject: [PATCH 106/438] FROMLIST: media: i2c: imx412: Extend the power-on waiting time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Arducam IMX577 module requires a longer reset time than the 1000µs configured in the current driver. Increase the wait time after power-on to ensure proper initialization. Link: https://lore.kernel.org/all/20260123-imx412-v7-2-e58303f2b76b@oss.qualcomm.com/ Signed-off-by: Wenmeng Liu --- drivers/media/i2c/imx412.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c index aa63dfc349181..e25e0a9ff65c3 100644 --- a/drivers/media/i2c/imx412.c +++ b/drivers/media/i2c/imx412.c @@ -1037,7 +1037,11 @@ static int imx412_power_on(struct device *dev) goto error_reset; } - usleep_range(1000, 1200); + /* + * Certain Arducam IMX577 module variants require a longer reset settle + * time. Increasing the delay from 1ms to 10ms ensures reliable startup. + */ + usleep_range(10000, 12000); return 0; From 0eadc716e5bcb8bb6507e0c6a71b7a3c278972c6 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 10 Dec 2025 12:21:55 +0530 Subject: [PATCH 107/438] FROMLIST: ASoC: qcom: q6dsp-lpass-ports: Extend q6dsp-lpass-ports driver to support additional sampling rates Expand the existing constraints in the q6dsp-lpass-ports driver to allow a wider range of sampling rates, from 8000 Hz to 192000 Hz. This change improves compatibility with diverse audio hardware and provides greater flexibility for audio stream configurations. Link: https://lore.kernel.org/linux-sound/20251210065157.2775514-2-ravi.hothi@oss.qualcomm.com/ Signed-off-by: Ravi Hothi --- sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 73 +++++++++--------------- 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c index 4eed54b071a5c..76421adb5afa2 100644 --- a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c +++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c @@ -10,16 +10,14 @@ #define Q6AFE_TDM_PB_DAI(pre, num, did) { \ .playback = { \ .stream_name = pre" TDM"#num" Playback", \ - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_176400, \ + .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ .channels_min = 1, \ .channels_max = 8, \ .rate_min = 8000, \ - .rate_max = 176400, \ + .rate_max = 192000, \ }, \ .name = #did, \ .id = did, \ @@ -28,16 +26,14 @@ #define Q6AFE_TDM_CAP_DAI(pre, num, did) { \ .capture = { \ .stream_name = pre" TDM"#num" Capture", \ - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_176400, \ + .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ .channels_min = 1, \ .channels_max = 8, \ .rate_min = 8000, \ - .rate_max = 176400, \ + .rate_max = 192000, \ }, \ .name = #did, \ .id = did, \ @@ -46,16 +42,14 @@ #define Q6AFE_CDC_DMA_RX_DAI(did) { \ .playback = { \ .stream_name = #did" Playback", \ - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_176400, \ + .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ .channels_min = 1, \ .channels_max = 8, \ .rate_min = 8000, \ - .rate_max = 176400, \ + .rate_max = 192000, \ }, \ .name = #did, \ .id = did, \ @@ -64,16 +58,14 @@ #define Q6AFE_CDC_DMA_TX_DAI(did) { \ .capture = { \ .stream_name = #did" Capture", \ - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_176400, \ + .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ .channels_min = 1, \ .channels_max = 8, \ .rate_min = 8000, \ - .rate_max = 176400, \ + .rate_max = 192000, \ }, \ .name = #did, \ .id = did, \ @@ -350,118 +342,108 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { }, { .playback = { .stream_name = "Primary MI2S Playback", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .id = PRIMARY_MI2S_RX, .name = "PRI_MI2S_RX", }, { .capture = { .stream_name = "Primary MI2S Capture", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .id = PRIMARY_MI2S_TX, .name = "PRI_MI2S_TX", }, { .playback = { .stream_name = "Secondary MI2S Playback", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .name = "SEC_MI2S_RX", .id = SECONDARY_MI2S_RX, }, { .capture = { .stream_name = "Secondary MI2S Capture", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .id = SECONDARY_MI2S_TX, .name = "SEC_MI2S_TX", }, { .playback = { .stream_name = "Tertiary MI2S Playback", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .name = "TERT_MI2S_RX", .id = TERTIARY_MI2S_RX, }, { .capture = { .stream_name = "Tertiary MI2S Capture", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .id = TERTIARY_MI2S_TX, .name = "TERT_MI2S_TX", }, { .playback = { .stream_name = "Quaternary MI2S Playback", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .name = "QUAT_MI2S_RX", .id = QUATERNARY_MI2S_RX, }, { .capture = { .stream_name = "Quaternary MI2S Capture", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .id = QUATERNARY_MI2S_TX, .name = "QUAT_MI2S_TX", }, { .playback = { .stream_name = "Quinary MI2S Playback", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_192000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 1, .channels_max = 8, @@ -473,13 +455,12 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { }, { .capture = { .stream_name = "Quinary MI2S Capture", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .id = QUINARY_MI2S_TX, .name = "QUIN_MI2S_TX", From f621c2831805f6d58ffb0988642aafd5e15d5b18 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 10 Dec 2025 12:21:56 +0530 Subject: [PATCH 108/438] FROMLIST: ASoC: qcom: q6dsp-lpass-ports: Update constraints to support 32-bit PCM format Expand the existing constraints by introducing support for the 32-bit PCM format (SNDRV_PCM_FMTBIT_S32_LE) alongside the existing 16-bit and 24-bit formats. This enhancement enables handling of high-resolution audio streams and improves audio quality for supported hardware. Link: https://lore.kernel.org/linux-sound/20251210065157.2775514-2-ravi.hothi@oss.qualcomm.com/ Signed-off-by: Ravi Hothi --- sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 35 +++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c index 76421adb5afa2..8542e620ee02d 100644 --- a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c +++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c @@ -344,7 +344,8 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .stream_name = "Primary MI2S Playback", .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -357,7 +358,8 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .stream_name = "Primary MI2S Capture", .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -369,7 +371,9 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .playback = { .stream_name = "Secondary MI2S Playback", .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -382,7 +386,8 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .stream_name = "Secondary MI2S Capture", .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -394,7 +399,9 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .playback = { .stream_name = "Tertiary MI2S Playback", .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -407,7 +414,8 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .stream_name = "Tertiary MI2S Capture", .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -419,7 +427,9 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .playback = { .stream_name = "Quaternary MI2S Playback", .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -432,7 +442,8 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .stream_name = "Quaternary MI2S Capture", .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -444,7 +455,9 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .playback = { .stream_name = "Quinary MI2S Playback", .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, @@ -456,7 +469,9 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = { .capture = { .stream_name = "Quinary MI2S Capture", .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, .channels_max = 8, .rate_min = 8000, From 7a5a1c53e6a22edf859223a532b40636a694eee0 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Mon, 9 Feb 2026 16:59:46 +0530 Subject: [PATCH 109/438] FROMLIST: soc: qcom: pd-mapper: Add support for SA8775P Add support for the Qualcomm SA8775P SoC to the protection domain mapper. SA8775P share the same protection domain configuration as SC8280XP with an additional gpdsp domain, except for charger_pd. Add an entry to the kernel, to avoid the need for userspace to provide this service. Link: https://lore.kernel.org/all/20260209112947.930853-2-mohammad.rafi.shaik@oss.qualcomm.com/ Signed-off-by: Mohammad Rafi Shaik --- drivers/soc/qcom/qcom_pd_mapper.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index dc10bc859ff41..65e1db12da089 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -305,6 +305,18 @@ static const struct qcom_pdm_domain_data cdsp_root_pd = { .services = { NULL }, }; +static const struct qcom_pdm_domain_data gpdsp_root_pd = { + .domain = "msm/gpdsp/root_pd", + .instance_id = 192, + .services = { NULL }, +}; + +static const struct qcom_pdm_domain_data gpdsp1_root_pd = { + .domain = "msm/gpdsp1/root_pd", + .instance_id = 241, + .services = { NULL }, +}; + static const struct qcom_pdm_domain_data slpi_root_pd = { .domain = "msm/slpi/root_pd", .instance_id = 90, @@ -401,6 +413,15 @@ static const struct qcom_pdm_domain_data *qcs404_domains[] = { NULL, }; +static const struct qcom_pdm_domain_data *sa8775p_domains[] = { + &adsp_audio_pd, + &adsp_root_pd, + &cdsp_root_pd, + &gpdsp_root_pd, + &gpdsp1_root_pd, + NULL, +}; + static const struct qcom_pdm_domain_data *sc7180_domains[] = { &adsp_audio_pd, &adsp_root_pd_pdr, @@ -572,6 +593,7 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = { { .compatible = "qcom,qcm2290", .data = qcm2290_domains, }, { .compatible = "qcom,qcm6490", .data = sc7280_domains, }, { .compatible = "qcom,qcs404", .data = qcs404_domains, }, + { .compatible = "qcom,sa8775p", .data = sa8775p_domains, }, { .compatible = "qcom,sc7180", .data = sc7180_domains, }, { .compatible = "qcom,sc7280", .data = sc7280_domains, }, { .compatible = "qcom,sc8180x", .data = sc8180x_domains, }, From 6548d85b8e38679525e6f90a88aa60b50ddb74b9 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Mon, 9 Feb 2026 16:59:47 +0530 Subject: [PATCH 110/438] FROMLIST: soc: qcom: pd-mapper: Add support for QCS8300 Add support for the Qualcomm QCS8300 SoC to the protection domain mapper. QCS8300 share the same protection domain configuration as SC8280XP, except charger_pd. Add an entry to the kernel, to avoid the need for userspace to provide this service. Link: https://lore.kernel.org/all/20260209112947.930853-3-mohammad.rafi.shaik@oss.qualcomm.com/ Signed-off-by: Mohammad Rafi Shaik --- drivers/soc/qcom/qcom_pd_mapper.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index 65e1db12da089..f6f13d8b885c3 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -413,6 +413,13 @@ static const struct qcom_pdm_domain_data *qcs404_domains[] = { NULL, }; +static const struct qcom_pdm_domain_data *qcs8300_domains[] = { + &adsp_audio_pd, + &adsp_root_pd, + &cdsp_root_pd, + NULL, +}; + static const struct qcom_pdm_domain_data *sa8775p_domains[] = { &adsp_audio_pd, &adsp_root_pd, @@ -593,6 +600,7 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = { { .compatible = "qcom,qcm2290", .data = qcm2290_domains, }, { .compatible = "qcom,qcm6490", .data = sc7280_domains, }, { .compatible = "qcom,qcs404", .data = qcs404_domains, }, + { .compatible = "qcom,qcs8300", .data = qcs8300_domains, }, { .compatible = "qcom,sa8775p", .data = sa8775p_domains, }, { .compatible = "qcom,sc7180", .data = sc7180_domains, }, { .compatible = "qcom,sc7280", .data = sc7280_domains, }, From be5d6ff798ef1ed112388d18f62c018b252bce94 Mon Sep 17 00:00:00 2001 From: Le Qi Date: Fri, 30 Jan 2026 14:12:31 +0800 Subject: [PATCH 111/438] FROMLIST: arm64: qcom: pd-mapper: Add QCS615 power domain mappings Add the QCS615 domain table to the in-kernel pd-mapper so that audio subsystems no longer rely on the userspace pd-mapper daemon. This enables proper initialization of ADSP and CDSP domains directly from the kernel. Link: https://lore.kernel.org/all/20260130061231.310113-1-le.qi@oss.qualcomm.com/ Reviewed-by: Dmitry Baryshkov --- drivers/soc/qcom/qcom_pd_mapper.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index f6f13d8b885c3..98c279386a253 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -429,6 +429,16 @@ static const struct qcom_pdm_domain_data *sa8775p_domains[] = { NULL, }; +static const struct qcom_pdm_domain_data *qcs615_domains[] = { + &adsp_audio_pd, + &adsp_root_pd, + &adsp_sensor_pd, + &cdsp_root_pd, + &mpss_root_pd, + &mpss_wlan_pd, + NULL, +}; + static const struct qcom_pdm_domain_data *sc7180_domains[] = { &adsp_audio_pd, &adsp_root_pd_pdr, @@ -600,6 +610,7 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = { { .compatible = "qcom,qcm2290", .data = qcm2290_domains, }, { .compatible = "qcom,qcm6490", .data = sc7280_domains, }, { .compatible = "qcom,qcs404", .data = qcs404_domains, }, + { .compatible = "qcom,qcs615", .data = qcs615_domains, }, { .compatible = "qcom,qcs8300", .data = qcs8300_domains, }, { .compatible = "qcom,sa8775p", .data = sa8775p_domains, }, { .compatible = "qcom,sc7180", .data = sc7180_domains, }, From 7f9a051a3d6275f8d9dc86b83f2952476788a050 Mon Sep 17 00:00:00 2001 From: Song Xue Date: Mon, 22 Sep 2025 19:10:24 +0530 Subject: [PATCH 112/438] FROMLIST: arm64: dts: qcom: qcs615-ride: Add PSCI SYSTEM_RESET2 types Add support for SYSTEM_RESET2 vendor-specific resets in qcs615-ride as reboot-modes. Describe the resets: "bootloader" will cause device to reboot and stop in the bootloader's fastboot mode. "edl" will cause device to reboot into "emergency download mode", which permits loading images via the Firehose protocol. Link: https://lore.kernel.org/all/20251015-arm-psci-system_reset2-vendor-reboots-v16-14-b98aedaa23ee@oss.qualcomm.com/ Signed-off-by: Song Xue Signed-off-by: Shivendra Pratap --- arch/arm64/boot/dts/qcom/qcs615-ride.dts | 7 +++++++ arch/arm64/boot/dts/qcom/talos.dtsi | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index 5a24c19c415e3..c425dc9c2ef3d 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -516,6 +516,13 @@ status = "okay"; }; +&psci { + reboot-mode { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; +}; + &qupv3_id_0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 75716b4a58d6d..fe8ca29a68b00 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -559,7 +559,7 @@ interrupts = ; }; - psci { + psci: psci { compatible = "arm,psci-1.0"; method = "smc"; From 6dfecb0f58059d3d970d9549e487d3ab9219518b Mon Sep 17 00:00:00 2001 From: Qingqing Zhou Date: Wed, 21 Jan 2026 03:35:52 +0530 Subject: [PATCH 113/438] FROMLIST: arm64: dts: qcom: talos: add the GPU SMMU node Add the Adreno GPU SMMU node for Talos chipset. Signed-off-by: Qingqing Zhou Signed-off-by: Jie Zhang Signed-off-by: Akhil P Oommen Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260121-qcs615-spin-2-v7-1-52419b263e92@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/talos.dtsi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index fe8ca29a68b00..281f61564ba03 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -1843,6 +1843,31 @@ #power-domain-cells = <1>; }; + adreno_smmu: iommu@50a0000 { + compatible = "qcom,qcs615-smmu-500", "qcom,adreno-smmu", + "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x050a0000 0x0 0x40000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = , + , + , + , + , + , + , + , + ; + clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>, + <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>; + clock-names = "mem", + "hlos", + "iface"; + power-domains = <&gpucc CX_GDSC>; + dma-coherent; + }; + stm@6002000 { compatible = "arm,coresight-stm", "arm,primecell"; reg = <0x0 0x06002000 0x0 0x1000>, From a05f9e3126c386cce706c522e8fdd29a1e464a3e Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Wed, 21 Jan 2026 03:35:53 +0530 Subject: [PATCH 114/438] FROMLIST: arm64: dts: qcom: talos: Add gpu and rgmu nodes Add gpu and rgmu nodes for Talos chipset. Signed-off-by: Jie Zhang Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Akhil P Oommen Link: https://lore.kernel.org/r/20260121-qcs615-spin-2-v7-2-52419b263e92@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/talos.dtsi | 110 ++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 281f61564ba03..edb3ce4744fbe 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -651,6 +651,11 @@ reg = <0x0 0x95900000 0x0 0x1e00000>; no-map; }; + + pil_gpu_mem: pil-gpu@97715000 { + reg = <0x0 0x97715000 0x0 0x2000>; + no-map; + }; }; soc: soc@0 { @@ -1830,6 +1835,111 @@ }; }; + gpu: gpu@5000000 { + compatible = "qcom,adreno-612.0", "qcom,adreno"; + reg = <0x0 0x05000000 0x0 0x40000>, + <0x0 0x0509e000 0x0 0x1000>, + <0x0 0x05061000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + + clocks = <&gpucc GPU_CC_GX_GFX3D_CLK>; + clock-names = "core"; + + interrupts = ; + + interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "gfx-mem"; + + iommus = <&adreno_smmu 0x0 0x401>; + + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&rpmhpd RPMHPD_CX>; + + qcom,gmu = <&gmu>; + + #cooling-cells = <2>; + + status = "disabled"; + + gpu_zap_shader: zap-shader { + memory-region = <&pil_gpu_mem>; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-845000000 { + opp-hz = /bits/ 64 <845000000>; + required-opps = <&rpmhpd_opp_turbo>; + opp-peak-kBps = <7050000>; + }; + + opp-745000000 { + opp-hz = /bits/ 64 <745000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + opp-peak-kBps = <6075000>; + }; + + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <5287500>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <3975000>; + }; + + opp-435000000 { + opp-hz = /bits/ 64 <435000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3000000>; + }; + }; + }; + + gmu: gmu@506a000 { + compatible = "qcom,adreno-rgmu-612.0", "qcom,adreno-rgmu"; + reg = <0x0 0x0506d000 0x0 0x2c000>; + + clocks = <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "smmu_vote"; + + power-domains = <&gpucc CX_GDSC>, + <&gpucc GX_GDSC>; + power-domain-names = "cx", + "gx"; + + interrupts = , + ; + interrupt-names = "oob", + "gmu"; + + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + gpucc: clock-controller@5090000 { compatible = "qcom,qcs615-gpucc"; reg = <0 0x05090000 0 0x9000>; From 4221d2ef18be499c8e83b27eb2125e6624452c48 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 21 Jan 2026 03:35:54 +0530 Subject: [PATCH 115/438] FROMLIST: arm64: dts: qcom: talos: Add GPU cooling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike the CPU, the GPU does not throttle its speed automatically when it reaches high temperatures. Set up GPU cooling by throttling the GPU speed when it reaches 105°C. Signed-off-by: Gaurav Kohli Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Akhil P Oommen Link: https://lore.kernel.org/r/20260121-qcs615-spin-2-v7-3-52419b263e92@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/talos.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index edb3ce4744fbe..383c92e822329 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -19,6 +19,7 @@ #include #include #include +#include / { interrupt-parent = <&intc>; @@ -4968,12 +4969,25 @@ thermal-sensors = <&tsens0 9>; trips { + gpu_alert0: trip-point0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpu-critical { temperature = <115000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpu_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; q6-hvx-thermal { From 66d6c76a489ec516d2741616118f0db79d2da3b4 Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Wed, 21 Jan 2026 03:35:55 +0530 Subject: [PATCH 116/438] FROMLIST: arm64: dts: qcom: qcs615-ride: Enable Adreno 612 GPU Enable GPU for qcs615-ride platform and provide path for zap shader. Signed-off-by: Jie Zhang Signed-off-by: Akhil P Oommen Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260121-qcs615-spin-2-v7-4-52419b263e92@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/qcs615-ride.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index c425dc9c2ef3d..f061ae156e0c6 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -372,6 +372,14 @@ }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/qcs615/a612_zap.mbn"; +}; + &i2c2 { clock-frequency = <400000>; status = "okay"; From 64499f258b509c5fa0691844b513a1f0fd16ec68 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:25 +0530 Subject: [PATCH 117/438] FROMLIST: arm64: dts: qcom: Enable cdsp qmi tmd devices for talos Enable cdsp cooling devices and thermal zone cooling map bindings for cdsp. Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251223123227.1317244-7-gaurav.kohli@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/talos.dtsi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 383c92e822329..5ae8a988b5fa6 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -3690,6 +3690,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; pmu@90b6300 { @@ -4994,12 +5002,26 @@ thermal-sensors = <&tsens0 10>; trips { + q6_hvx_alert0: trip-point0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + q6-hvx-critical { temperature = <115000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&q6_hvx_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; mdm-core-thermal { From a9a6a9f52ab792865b548c05076b9972e6940bcb Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 28 Dec 2025 22:50:28 +0530 Subject: [PATCH 118/438] FROMLIST: arm64: dts: qcom: talos: Add psci reboot-modes Add PSCI SYSTEM_RESET2 reboot-modes for talos based boards, for use by the psci_reboot_mode driver. The following modes are defined: - bootloader: reboot into fastboot mode for fastboot flashing. - edl: reboot into emergency download mode for image loading via the Firehose protocol. Support for these modes is firmware dependent. Signed-off-by: Song Xue Signed-off-by: Shivendra Pratap Signed-off-by: Xin Liu Link: https://lore.kernel.org/all/20251228-arm-psci-system_reset2-vendor-reboots-v19-10-ebb956053098@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/talos.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 5ae8a988b5fa6..9ca5e2535355c 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -618,6 +618,11 @@ &cluster_sleep_1 &cluster_sleep_2>; }; + + reboot-mode { + mode-bootloader = <0x80010001 0x2>; + mode-edl = <0x80000000 0x1>; + }; }; reserved-memory { From 54f9e26d47cf53bf851e59899c9f7d445bda1ed5 Mon Sep 17 00:00:00 2001 From: Sudarshan Shetty Date: Wed, 14 Jan 2026 15:30:41 +0530 Subject: [PATCH 119/438] FROMLIST: dt-bindings: arm: qcom: talos-evk: Add QCS615 Talos EVK SMARC platform Add binding support for the Qualcomm Technologies, Inc. Talos EVK SMARC platform based on the QCS615 SoC. Link: https://lore.kernel.org/all/20260217103749.1249718-2-tessolveupstream@gmail.com/ Acked-by: Krzysztof Kozlowski Signed-off-by: Sudarshan Shetty Signed-off-by: Jie Gan --- Documentation/devicetree/bindings/arm/qcom.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index d48c625d3fc42..9732a32a5f59f 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -883,6 +883,7 @@ properties: - items: - enum: - qcom,qcs615-ride + - qcom,talos-evk - const: qcom,qcs615 - const: qcom,sm6150 From 2290203cb025c3d6f252d5e96fffed12cfb7ab45 Mon Sep 17 00:00:00 2001 From: Sudarshan Shetty Date: Tue, 17 Feb 2026 16:07:48 +0530 Subject: [PATCH 120/438] FROMLOST: arm64: dts: qcom: talos/qcs615-ride: Fix inconsistent USB PHY node naming The USB PHY nodes has inconsistent labels as 'usb_1_hsphy' and 'usb_hsphy_2' across talos.dtsi and qcs615-ride.dts. This patch renames them to follow a consistent naming scheme. No functional changes, only label renaming. Link: https://lore.kernel.org/all/20260217103749.1249718-3-tessolveupstream@gmail.com/ Reviewed-by: Dmitry Baryshkov Signed-off-by: Sudarshan Shetty --- arch/arm64/boot/dts/qcom/qcs615-ride.dts | 2 +- arch/arm64/boot/dts/qcom/talos.dtsi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index f061ae156e0c6..e5ce9a4faa9cb 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -677,7 +677,7 @@ dr_mode = "peripheral"; }; -&usb_hsphy_2 { +&usb_2_hsphy { vdd-supply = <&vreg_l5a>; vdda-pll-supply = <&vreg_l12a>; vdda-phy-dpdm-supply = <&vreg_l13a>; diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 9ca5e2535355c..f28621d5a7233 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -4566,7 +4566,7 @@ status = "disabled"; }; - usb_hsphy_2: phy@88e3000 { + usb_2_hsphy: phy@88e3000 { compatible = "qcom,qcs615-qusb2-phy"; reg = <0x0 0x088e3000 0x0 0x180>; @@ -4749,7 +4749,7 @@ iommus = <&apps_smmu 0xe0 0x0>; interrupts = ; - phys = <&usb_hsphy_2>; + phys = <&usb_2_hsphy>; phy-names = "usb2-phy"; snps,dis_u2_susphy_quirk; From e0179f3222f480af8fbc0fa12cc7386edbfdf4b3 Mon Sep 17 00:00:00 2001 From: Sudarshan Shetty Date: Tue, 17 Feb 2026 16:07:49 +0530 Subject: [PATCH 121/438] FROMLIST: arm64: dts: qcom: talos-evk: Add support for QCS615 talos evk board Add the device tree for the QCS615-based Talos EVK platform. The platform is composed of a System-on-Module following the SMARC standard, and a Carrier Board. The Carrier Board supports several display configurations, HDMI and LVDS. Both configurations use the same base hardware, with the display selection controlled by a DIP switch. Use a DTBO file, talos-evk-lvds-auo,g133han01.dtso, which defines an overlay that disables HDMI and adds LVDS. The DTs file talos-evk can describe the HDMI display configurations. According to the hardware design and vendor guidance, the WiFi PA supplies VDD_PA_A and VDD_PA_B only need to be enabled at the same time as asserting WLAN_EN. On this platform, WiFi enablement is controlled via the WLAN_EN GPIO (GPIO84), which also drives the VDD_PA_A and VDD_PA_B power enables. Remove the VDD_PA_A and VDD_PA_B regulator nodes from the device tree and rely on WLAN_EN to enable WiFi functionality. Add talos-evk-usb1-peripheral.dtso overlay to enable USB0 peripheral (EDL) mode. The base DTS will keep USB0 host-only due to hardware routing through the EDL DIP switch, and the overlay switches the configuration for device-mode operation. The initial device tree includes support for: - CPU and memory - UART - GPIOs - Regulators - PMIC - Early console - AT24MAC602 EEPROM - MCP2515 SPI to CAN - ADV7535 DSI-to-HDMI bridge - DisplayPort interface - SN65DSI84ZXHR DSI-to-LVDS bridge - Wi-Fi/BT Link: https://lore.kernel.org/all/20260217103749.1249718-4-tessolveupstream@gmail.com/ Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Sudarshan Shetty --- arch/arm64/boot/dts/qcom/Makefile | 6 + .../qcom/talos-evk-lvds-auo,g133han01.dtso | 131 ++++ arch/arm64/boot/dts/qcom/talos-evk-som.dtsi | 614 ++++++++++++++++++ .../dts/qcom/talos-evk-usb1-peripheral.dtso | 10 + arch/arm64/boot/dts/qcom/talos-evk.dts | 139 ++++ 5 files changed, 900 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/talos-evk-lvds-auo,g133han01.dtso create mode 100644 arch/arm64/boot/dts/qcom/talos-evk-som.dtsi create mode 100644 arch/arm64/boot/dts/qcom/talos-evk-usb1-peripheral.dtso create mode 100644 arch/arm64/boot/dts/qcom/talos-evk.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index f80b5d9cf1e80..4dd34a36dcf59 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -348,6 +348,12 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8650-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8650-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8750-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8750-qrd.dtb +dtb-$(CONFIG_ARCH_QCOM) += talos-evk.dtb +talos-evk-usb1-peripheral-dtbs := talos-evk.dtb talos-evk-usb1-peripheral.dtbo +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-usb1-peripheral.dtb +talos-evk-lvds-auo,g133han01-dtbs := \ + talos-evk.dtb talos-evk-lvds-auo,g133han01.dtbo +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-lvds-auo,g133han01.dtb x1e001de-devkit-el2-dtbs := x1e001de-devkit.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1e001de-devkit.dtb x1e001de-devkit-el2.dtb x1e78100-lenovo-thinkpad-t14s-el2-dtbs := x1e78100-lenovo-thinkpad-t14s.dtb x1-el2.dtbo diff --git a/arch/arm64/boot/dts/qcom/talos-evk-lvds-auo,g133han01.dtso b/arch/arm64/boot/dts/qcom/talos-evk-lvds-auo,g133han01.dtso new file mode 100644 index 0000000000000..fc2296e346b83 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-lvds-auo,g133han01.dtso @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; +/plugin/; + +#include + +&{/} { + backlight: backlight { + compatible = "gpio-backlight"; + gpios = <&tlmm 59 GPIO_ACTIVE_HIGH>, + <&tlmm 115 GPIO_ACTIVE_HIGH>; + default-on; + }; + + panel-lvds { + compatible = "auo,g133han01"; + power-supply = <&vreg_v3p3>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* LVDS A (Odd pixels) */ + port@0 { + reg = <0>; + dual-lvds-odd-pixels; + + lvds_panel_out_a: endpoint { + remote-endpoint = <&sn65dsi84_out_a>; + }; + }; + + /* LVDS B (Even pixels) */ + port@1 { + reg = <1>; + dual-lvds-even-pixels; + + lvds_panel_out_b: endpoint { + remote-endpoint = <&sn65dsi84_out_b>; + }; + }; + }; + }; + + vreg_v3p3: regulator-v3p3 { + compatible = "regulator-fixed"; + regulator-name = "vdd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&hdmi_connector { + status = "disabled"; +}; + +&i2c1 { + clock-frequency = <400000>; + + status = "okay"; + + hdmi_bridge: bridge@3d { + status = "disabled"; + }; + + lvds_bridge: bridge@2c { + compatible = "ti,sn65dsi84"; + reg = <0x2c>; + enable-gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sn65dsi84_in: endpoint { + data-lanes = <1 2 3 4>; + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@2 { + reg = <2>; + + sn65dsi84_out_a: endpoint { + data-lanes = <1 2 3 4>; + remote-endpoint = <&lvds_panel_out_a>; + }; + }; + + port@3 { + reg = <3>; + + sn65dsi84_out_b: endpoint { + data-lanes = <1 2 3 4>; + remote-endpoint = <&lvds_panel_out_b>; + }; + }; + }; + }; +}; + +&mdss_dsi0 { + vdda-supply = <&vreg_l11a>; + + status = "okay"; +}; + +&mdss_dsi0_out { + remote-endpoint = <&sn65dsi84_in>; + data-lanes = <0 1 2 3>; +}; + +&tlmm { + lcd_bklt_en: lcd-bklt-en-state { + pins = "gpio115"; + function = "gpio"; + bias-disable; + }; + + lcd_bklt_pwm: lcd-bklt-pwm-state { + pins = "gpio59"; + function = "gpio"; + bias-disable; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi b/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi new file mode 100644 index 0000000000000..f877a3e5d0b00 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi @@ -0,0 +1,614 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include +#include +#include "talos.dtsi" +#include "pm8150.dtsi" +/ { + aliases { + i2c1 = &i2c1; + i2c5 = &i2c5; + mmc0 = &sdhc_1; + serial0 = &uart0; + serial1 = &uart7; + spi6 = &spi6; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + can_osc: can-oscillator { + compatible = "fixed-clock"; + clock-frequency = <20000000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32764>; + #clock-cells = <0>; + }; + + xo_board_clk: xo-board-clk { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + }; + + regulator-usb2-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB2_VBUS"; + gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&usb2_en>; + pinctrl-names = "default"; + enable-active-high; + regulator-always-on; + }; + + vreg_conn_1p8: regulator-conn-1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p8"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm8150_gpios 1 GPIO_ACTIVE_HIGH>; + }; + + vreg_conn_pa: regulator-conn-pa { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_pa"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm8150_gpios 6 GPIO_ACTIVE_HIGH>; + }; + + vreg_v3p3_can: regulator-v3p3-can { + compatible = "regulator-fixed"; + regulator-name = "vreg-v3p3-can"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + vreg_v5p0_can: regulator-v5p0-can { + compatible = "regulator-fixed"; + regulator-name = "vreg-v5p0-can"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + wcn6855-pmu { + compatible = "qcom,wcn6855-pmu"; + + pinctrl-0 = <&bt_en_state>, <&wlan_en_state>; + pinctrl-names = "default"; + + bt-enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>; + wlan-enable-gpios = <&tlmm 84 GPIO_ACTIVE_HIGH>; + + vddio-supply = <&vreg_conn_pa>; + vddaon-supply = <&vreg_s5a>; + vddpmu-supply = <&vreg_conn_1p8>; + vddpmumx-supply = <&vreg_conn_1p8>; + vddpmucx-supply = <&vreg_conn_pa>; + vddrfa0p95-supply = <&vreg_s5a>; + vddrfa1p3-supply = <&vreg_s6a>; + vddrfa1p9-supply = <&vreg_l15a>; + vddpcie1p3-supply = <&vreg_s6a>; + vddpcie1p9-supply = <&vreg_l15a>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p7: ldo7 { + regulator-name = "vreg_pmu_rfa_1p7"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm8150-rpmh-regulators"; + qcom,pmic-id = "a"; + + vreg_s3a: smps3 { + regulator-name = "vreg_s3a"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <650000>; + regulator-initial-mode = ; + }; + + vreg_s4a: smps4 { + regulator-name = "vreg_s4a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1829000>; + regulator-initial-mode = ; + }; + + vreg_s5a: smps5 { + regulator-name = "vreg_s5a"; + regulator-min-microvolt = <1896000>; + regulator-max-microvolt = <2040000>; + regulator-initial-mode = ; + }; + + vreg_s6a: smps6 { + regulator-name = "vreg_s6a"; + regulator-min-microvolt = <1304000>; + regulator-max-microvolt = <1404000>; + regulator-initial-mode = ; + }; + + vreg_l1a: ldo1 { + regulator-name = "vreg_l1a"; + regulator-min-microvolt = <488000>; + regulator-max-microvolt = <852000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2a: ldo2 { + regulator-name = "vreg_l2a"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <3100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3a: ldo3 { + regulator-name = "vreg_l3a"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1248000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5a: ldo5 { + regulator-name = "vreg_l5a"; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <975000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7a: ldo7 { + regulator-name = "vreg_l7a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8a: ldo8 { + regulator-name = "vreg_l8a"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1350000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l10a: ldo10 { + regulator-name = "vreg_l10a"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l11a: ldo11 { + regulator-name = "vreg_l11a"; + regulator-min-microvolt = <1232000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l12a: ldo12 { + regulator-name = "vreg_l12a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1890000>; + regulator-initial-mode = ; + }; + + vreg_l13a: ldo13 { + regulator-name = "vreg_l13a"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3230000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l15a: ldo15 { + regulator-name = "vreg_l15a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1904000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l16a: ldo16 { + regulator-name = "vreg_l16a"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l17a: ldo17 { + regulator-name = "vreg_l17a"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = ; + }; + }; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&i2c5 { + clock-frequency = <400000>; + status = "okay"; + + eeprom@57 { + compatible = "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; + + eeprom@5f { + compatible = "atmel,24mac602"; + reg = <0x5f>; + pagesize = <16>; + }; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000>; + remote-endpoint = <&dp0_connector_in>; +}; + +&mdss_dsi0 { + vdda-supply = <&vreg_l11a>; + status = "okay"; +}; + +&mdss_dsi0_phy { + vcca-supply = <&vreg_l5a>; + status = "okay"; +}; + +&pcie { + perst-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&pcie_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + status = "okay"; +}; + +&pcie_port0 { + wifi@0 { + compatible = "pci17cb,1103"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + qcom,calibration-variant = "QC_QCS615_Ride"; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pm8150_gpios { + usb2_en: usb2-en-state { + pins = "gpio10"; + function = "normal"; + output-enable; + power-source = <0>; + }; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/qcs615/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/qcs615/cdsp.mbn"; + + status = "okay"; +}; + +&sdhc_1 { + pinctrl-0 = <&sdc1_state_on>; + pinctrl-1 = <&sdc1_state_off>; + pinctrl-names = "default", "sleep"; + + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + vmmc-supply = <&vreg_l17a>; + vqmmc-supply = <&vreg_s4a>; + + non-removable; + no-sd; + no-sdio; + + status = "okay"; +}; + +&spi6 { + status = "okay"; + + can@0 { + compatible = "microchip,mcp2515"; + reg = <0>; + clocks = <&can_osc>; + interrupts-extended = <&tlmm 87 IRQ_TYPE_LEVEL_LOW>; + spi-max-frequency = <10000000>; + vdd-supply = <&vreg_v3p3_can>; + xceiver-supply = <&vreg_v5p0_can>; + }; +}; + +&tlmm { + bt_en_state: bt-en-state { + pins = "gpio85"; + function = "gpio"; + bias-pull-down; + }; + + pcie_default_state: pcie-default-state { + clkreq-pins { + pins = "gpio90"; + function = "pcie_clk_req"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio89"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + wake-pins { + pins = "gpio100"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + wifi_reg_en_pins_state: wifi-reg-en-pins-state { + pins = "gpio91"; + function = "gpio"; + drive-strength = <8>; + output-high; + bias-pull-up; + }; + + wlan_en_state: wlan-en-state { + pins = "gpio84"; + function = "gpio"; + drive-strength = <16>; + bias-pull-up; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart7 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn6855-bt"; + firmware-name = "QCA6698/hpnv21", "QCA6698/hpbtfw21.tlv"; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; + }; +}; + +/* + * USB0 routing and EDL mode: + * + * The USB0 controller’s HS differential pair is switched (manually) + * between the Micro-USB port for EDL/ADB and the on-board USB 3.0 hub. + * + * During EDL (Emergency Download) mode, the HS lines are explicitly + * routed to the Micro-USB port to allow the SoC to enter device mode + * for flashing. + * + * After EDL the switch is normally toggled so the HS lines stay + * connected to the hub’s Type-A downstream ports, leaving no electrical + * path to the Micro-USB connector — therefore USB0 runs host-only in + * normal runtime and device mode must not be advertised. + * + * USB0 is configured host-only in the base device tree; a separate + * device-tree overlay enables the Micro-USB peripheral configuration for + * ADB. For ADB to work during normal runtime the DIP switch SW1 must be + * manually toggled to the off position (reconnecting the HS pair to the + * Micro-USB port). + */ + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "host"; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + vdda-phy-dpdm-supply = <&vreg_l13a>; + + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; + +&usb_2_hsphy { + vdd-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + vdda-phy-dpdm-supply = <&vreg_l13a>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + status = "okay"; +}; + +&usb_qmpphy_2 { + vdda-phy-supply = <&vreg_l11a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 123 GPIO_ACTIVE_LOW>; + vcc-supply = <&vreg_l17a>; + vcc-max-microamp = <600000>; + vccq2-supply = <&vreg_s4a>; + vccq2-max-microamp = <600000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + status = "okay"; +}; + +&venus { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/talos-evk-usb1-peripheral.dtso b/arch/arm64/boot/dts/qcom/talos-evk-usb1-peripheral.dtso new file mode 100644 index 0000000000000..2f4630a6ba66e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-usb1-peripheral.dtso @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; +/plugin/; + +&usb_1_dwc3 { + dr_mode = "peripheral"; +}; diff --git a/arch/arm64/boot/dts/qcom/talos-evk.dts b/arch/arm64/boot/dts/qcom/talos-evk.dts new file mode 100644 index 0000000000000..af100e22beeec --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk.dts @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include "talos-evk-som.dtsi" + +/ { + model = "Qualcomm QCS615 IQ 615 EVK"; + compatible = "qcom,talos-evk", "qcom,qcs615", "qcom,sm6150"; + chassis-type = "embedded"; + + aliases { + mmc1 = &sdhc_2; + }; + + dp0-connector { + compatible = "dp-connector"; + label = "DP0"; + type = "full-size"; + + hpd-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; + + port { + dp0_connector_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; + }; + }; + }; + + hdmi_connector: hdmi-out { + compatible = "hdmi-connector"; + type = "d"; + + port { + hdmi_con_out: endpoint { + remote-endpoint = <&adv7535_out>; + }; + }; + }; + + vreg_v1p8_out: regulator-v1p8-out { + compatible = "regulator-fixed"; + regulator-name = "vreg-v1p8-out"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vreg_v5p0_out>; + regulator-boot-on; + regulator-always-on; + }; + + vreg_v3p3_out: regulator-v3p3-out { + compatible = "regulator-fixed"; + regulator-name = "vreg-v3p3-out"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vreg_v5p0_out>; + regulator-boot-on; + regulator-always-on; + }; + + vreg_v5p0_out: regulator-v5p0-out { + compatible = "regulator-fixed"; + regulator-name = "vreg-v5p0-out"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + /* Powered by system 20V rail (USBC_VBUS_IN) */ + }; +}; + +&i2c1 { + clock-frequency = <400000>; + status = "okay"; + + hdmi_bridge: bridge@3d { + compatible = "adi,adv7535"; + reg = <0x3d>; + avdd-supply = <&vreg_v1p8_out>; + dvdd-supply = <&vreg_v1p8_out>; + pvdd-supply = <&vreg_v1p8_out>; + a2vdd-supply = <&vreg_v1p8_out>; + v3p3-supply = <&vreg_v3p3_out>; + interrupts-extended = <&tlmm 26 IRQ_TYPE_LEVEL_LOW>; + adi,dsi-lanes = <4>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adv7535_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + + adv7535_out: endpoint { + remote-endpoint = <&hdmi_con_out>; + }; + }; + }; + }; +}; + +&mdss_dsi0_out { + remote-endpoint = <&adv7535_in>; + data-lanes = <0 1 2 3>; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = ; + + status = "okay"; +}; + +&sdhc_2 { + pinctrl-0 = <&sdc2_state_on>; + pinctrl-1 = <&sdc2_state_off>; + pinctrl-names = "default", "sleep"; + + bus-width = <4>; + cd-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l10a>; + vqmmc-supply = <&vreg_s4a>; + + status = "okay"; +}; From 3d2fc107f0cef551cd16ee3da3a45b26e16e16ab Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Wed, 28 Jan 2026 09:25:34 +0800 Subject: [PATCH 122/438] FROMLIST: arm64: dts: qcom: talos: add ETR device Add the TMC ETR device to store collected trace data in DDR memory. Link: https://lore.kernel.org/all/20260128-enable-etr-on-talos-v2-1-ba77063d6b62@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/talos.dtsi | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index f28621d5a7233..e777018e887d1 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -2394,6 +2394,14 @@ #address-cells = <1>; #size-cells = <0>; + port@0 { + reg = <0>; + + replicator0_out0: endpoint { + remote-endpoint = <&tmc_etr_in>; + }; + }; + port@1 { reg = <1>; @@ -2428,6 +2436,25 @@ }; }; + tmc@6048000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x06048000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + iommus = <&apps_smmu 0x01e0 0x0>; + arm,scatter-gather; + + in-ports { + port { + tmc_etr_in: endpoint { + remote-endpoint = <&replicator0_out0>; + }; + }; + }; + }; + replicator@604a000 { compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0x0 0x0604a000 0x0 0x1000>; From 88759cab81d59e513b70ce66710a37004e1ab272 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:52 +0800 Subject: [PATCH 123/438] FROMLIST: arm64: dts: qcom: talos: Add camss node Add node for the SM6150 camera subsystem. Link: https://lore.kernel.org/all/20260122-sm6150_evk-v5-1-039b170450a3@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Reviewed-by: Bryan O'Donoghue Signed-off-by: Wenmeng Liu --- arch/arm64/boot/dts/qcom/talos.dtsi | 200 ++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index e777018e887d1..1e8f66f849789 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -3965,6 +3965,206 @@ #power-domain-cells = <1>; }; + camss: isp@acb3000 { + compatible = "qcom,sm6150-camss"; + + reg = <0x0 0x0acb3000 0x0 0x1000>, + <0x0 0x0acba000 0x0 0x1000>, + <0x0 0x0acc8000 0x0 0x1000>, + <0x0 0x0ac65000 0x0 0x1000>, + <0x0 0x0ac66000 0x0 0x1000>, + <0x0 0x0ac67000 0x0 0x1000>, + <0x0 0x0acaf000 0x0 0x4000>, + <0x0 0x0acb6000 0x0 0x4000>, + <0x0 0x0acc4000 0x0 0x4000>, + <0x0 0x0ac6f000 0x0 0x3000>, + <0x0 0x0ac42000 0x0 0x5000>, + <0x0 0x0ac48000 0x0 0x1000>, + <0x0 0x0ac40000 0x0 0x1000>, + <0x0 0x0ac18000 0x0 0x3000>, + <0x0 0x0ac00000 0x0 0x6000>, + <0x0 0x0ac10000 0x0 0x8000>, + <0x0 0x0ac87000 0x0 0x3000>, + <0x0 0x0ac52000 0x0 0x4000>, + <0x0 0x0ac4e000 0x0 0x4000>, + <0x0 0x0ac6b000 0x0 0x0a00>; + reg-names = "csid0", + "csid1", + "csid_lite", + "csiphy0", + "csiphy1", + "csiphy2", + "vfe0", + "vfe1", + "vfe_lite", + "bps", + "camnoc", + "cpas_cdm", + "cpas_top", + "icp_csr", + "icp_qgic", + "icp_sierra", + "ipe0", + "jpeg_dma", + "jpeg_enc", + "lrme"; + + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_AXI_CLK>, + <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_0_CSID_CLK>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_AXI_CLK>, + <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_1_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_BPS_CLK>, + <&camcc CAM_CC_BPS_AHB_CLK>, + <&camcc CAM_CC_BPS_AXI_CLK>, + <&camcc CAM_CC_BPS_AREG_CLK>, + <&camcc CAM_CC_ICP_CLK>, + <&camcc CAM_CC_IPE_0_CLK>, + <&camcc CAM_CC_IPE_0_AHB_CLK>, + <&camcc CAM_CC_IPE_0_AREG_CLK>, + <&camcc CAM_CC_IPE_0_AXI_CLK>, + <&camcc CAM_CC_JPEG_CLK>, + <&camcc CAM_CC_LRME_CLK>; + clock-names = "gcc_ahb", + "gcc_axi_hf", + "camnoc_axi", + "cpas_ahb", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "csiphy2", + "csiphy2_timer", + "soc_ahb", + "vfe0", + "vfe0_axi", + "vfe0_cphy_rx", + "vfe0_csid", + "vfe1", + "vfe1_axi", + "vfe1_cphy_rx", + "vfe1_csid", + "vfe_lite", + "vfe_lite_cphy_rx", + "vfe_lite_csid", + "bps", + "bps_ahb", + "bps_axi", + "bps_areg", + "icp", + "ipe0", + "ipe0_ahb", + "ipe0_areg", + "ipe0_axi", + "jpeg", + "lrme"; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_CAMNOC_HF0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_HF1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "ahb", + "hf_0", + "hf_1", + "sf_mnoc"; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "csid0", + "csid1", + "csid_lite", + "csiphy0", + "csiphy1", + "csiphy2", + "vfe0", + "vfe1", + "vfe_lite", + "camnoc", + "cdm", + "icp", + "jpeg_dma", + "jpeg_enc", + "lrme"; + + iommus = <&apps_smmu 0x0820 0x40>, + <&apps_smmu 0x0840 0x00>, + <&apps_smmu 0x0860 0x40>, + <&apps_smmu 0x0c00 0x00>, + <&apps_smmu 0x0cc0 0x00>, + <&apps_smmu 0x0c80 0x00>, + <&apps_smmu 0x0ca0 0x00>, + <&apps_smmu 0x0d00 0x00>, + <&apps_smmu 0x0d20 0x00>, + <&apps_smmu 0x0d40 0x00>, + <&apps_smmu 0x0d80 0x20>, + <&apps_smmu 0x0da0 0x20>, + <&apps_smmu 0x0de2 0x00>; + + power-domains = <&camcc IFE_0_GDSC>, + <&camcc IFE_1_GDSC>, + <&camcc TITAN_TOP_GDSC>, + <&camcc BPS_GDSC>, + <&camcc IPE_0_GDSC>; + power-domain-names = "ife0", + "ife1", + "top", + "bps", + "ipe"; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + }; + + port@1 { + reg = <1>; + }; + + port@2 { + reg = <2>; + }; + }; + }; + camcc: clock-controller@ad00000 { compatible = "qcom,qcs615-camcc"; reg = <0 0x0ad00000 0 0x10000>; From e9e96b7f091a01e53720531b6677a0124fed64d2 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:54 +0800 Subject: [PATCH 124/438] FROMLIST: arm64: dts: qcom: talos: Add CCI definitions Qualcomm Talos SoC contains single controller, containing 2 I2C hosts. Link: https://lore.kernel.org/all/20260122-sm6150_evk-v5-3-039b170450a3@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu --- arch/arm64/boot/dts/qcom/talos.dtsi | 51 +++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 1e8f66f849789..03631256ebd48 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -1564,6 +1564,22 @@ #interrupt-cells = <2>; wakeup-parent = <&pdc>; + cci_i2c0_default: cci-i2c0-default-state { + /* SDA, SCL */ + pins = "gpio32", "gpio33"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-up; + }; + + cci_i2c1_default: cci-i2c1-default-state { + /* SDA, SCL */ + pins = "gpio34", "gpio35"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-up; + }; + qup_i2c1_data_clk: qup-i2c1-data-clk-state { pins = "gpio4", "gpio5"; function = "qup0"; @@ -3965,6 +3981,41 @@ #power-domain-cells = <1>; }; + cci: cci@ac4a000 { + compatible = "qcom,sm6150-cci", "qcom,msm8996-cci"; + + reg = <0x0 0x0ac4a000 0x0 0x4000>; + interrupts = ; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CCI_CLK>; + clock-names = "camnoc_axi", + "cpas_ahb", + "cci"; + pinctrl-0 = <&cci_i2c0_default &cci_i2c1_default>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + camss: isp@acb3000 { compatible = "qcom,sm6150-camss"; From d766e96344be178eab93f1233946538d43bfe2bb Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:55 +0800 Subject: [PATCH 125/438] FROMLIST: arm64: dts: qcom: talos: Add camera MCLK pinctrl Define pinctrl definitions to enable camera master clocks on Talos. Link: https://lore.kernel.org/all/20260122-sm6150_evk-v5-4-039b170450a3@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu --- arch/arm64/boot/dts/qcom/talos.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 03631256ebd48..918db56e2bf9a 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -1564,6 +1564,34 @@ #interrupt-cells = <2>; wakeup-parent = <&pdc>; + cam0_default: cam0-default-state { + pins = "gpio28"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam1_default: cam1-default-state { + pins = "gpio29"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam2_default: cam2-default-state { + pins = "gpio30"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam3_default: cam3-default-state { + pins = "gpio31"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + cci_i2c0_default: cci-i2c0-default-state { /* SDA, SCL */ pins = "gpio32", "gpio33"; From 58fa69e81de0d8f55a460730a6a587cf507a1d9f Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:53 +0800 Subject: [PATCH 126/438] FROMLIST: dt-bindings: i2c: qcom-cci: Document sm6150 compatible Add the sm6150 CCI device string compatible. Link: https://lore.kernel.org/all/20260122-sm6150_evk-v5-2-039b170450a3@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu --- Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index 399a09409e071..35d3a0685ac44 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -34,6 +34,7 @@ properties: - qcom,sc8280xp-cci - qcom,sdm670-cci - qcom,sdm845-cci + - qcom,sm6150-cci - qcom,sm6350-cci - qcom,sm8250-cci - qcom,sm8450-cci @@ -251,6 +252,7 @@ allOf: contains: enum: - qcom,sa8775p-cci + - qcom,sm6150-cci - qcom,sm8550-cci - qcom,sm8650-cci - qcom,x1e80100-cci From 5e78293275ee180f1bf331c045f223885cb67501 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:56 +0800 Subject: [PATCH 127/438] FROMLIST: arm64: dts: qcom: talos-evk-camera: Add DT overlay Enable IMX577 via CCI on Taloss EVK Core Kit. The Talos EVK board does not include a camera sensor by default, this DTSO has enabled the Arducam 12.3MP IMX577 Mini Camera Module on the CSI-1 interface. Link: https://lore.kernel.org/all/20260122-sm6150_evk-v5-5-039b170450a3@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu --- arch/arm64/boot/dts/qcom/Makefile | 3 + .../dts/qcom/talos-evk-camera-imx577.dtso | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/talos-evk-camera-imx577.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 4dd34a36dcf59..2f4694b2d388f 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -350,9 +350,12 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8750-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8750-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += talos-evk.dtb talos-evk-usb1-peripheral-dtbs := talos-evk.dtb talos-evk-usb1-peripheral.dtbo +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-camera-imx577.dtbo +talos-evk-camera-imx577-dtbs := talos-evk.dtb talos-evk-camera-imx577.dtbo dtb-$(CONFIG_ARCH_QCOM) += talos-evk-usb1-peripheral.dtb talos-evk-lvds-auo,g133han01-dtbs := \ talos-evk.dtb talos-evk-lvds-auo,g133han01.dtbo +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-camera-imx577.dtb dtb-$(CONFIG_ARCH_QCOM) += talos-evk-lvds-auo,g133han01.dtb x1e001de-devkit-el2-dtbs := x1e001de-devkit.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1e001de-devkit.dtb x1e001de-devkit-el2.dtb diff --git a/arch/arm64/boot/dts/qcom/talos-evk-camera-imx577.dtso b/arch/arm64/boot/dts/qcom/talos-evk-camera-imx577.dtso new file mode 100644 index 0000000000000..53006a861878f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-camera-imx577.dtso @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include + +&camss { + vdd-csiphy-1p2-supply = <&vreg_l11a>; + vdd-csiphy-1p8-supply = <&vreg_l12a>; + + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csiphy1_ep: endpoint { + data-lanes = <0 1 2 3>; + remote-endpoint = <&imx577_ep1>; + }; + }; + }; +}; + +&cci { + status = "okay"; +}; + +&cci_i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx577"; + reg = <0x1a>; + + reset-gpios = <&tlmm 29 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam2_default>; + pinctrl-names = "default"; + + clocks = <&camcc CAM_CC_MCLK2_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK2_CLK>; + assigned-clock-rates = <24000000>; + + avdd-supply = <&vreg_s4a>; + + port { + imx577_ep1: endpoint { + link-frequencies = /bits/ 64 <600000000>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&csiphy1_ep>; + }; + }; + }; +}; From 3d862f0c9bdd9534fcc13555f9b847730e5d820f Mon Sep 17 00:00:00 2001 From: Le Qi Date: Tue, 27 Jan 2026 20:26:11 +0800 Subject: [PATCH 128/438] FROMLIST: arm64: dts: qcom: talos: Add GPR node, audio services, and MI2S1 TLMM pins This patch adds the Generic Pack Router (GPR) node together with Audio Process Manager (APM) and Proxy Resource Manager (PRM) audio service nodes to the Talos device tree description. It also introduces MI2S1 pinctrl states for data0, data1, sck, and ws lines, grouped into a single entry at the SoC-level DTSI for better reuse and clarity. Link: https://lore.kernel.org/all/20251204083225.1190017-2-le.qi@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Signed-off-by: Le Qi --- arch/arm64/boot/dts/qcom/talos.dtsi | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 918db56e2bf9a..8857bd51c84e5 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -20,6 +20,7 @@ #include #include #include +#include / { interrupt-parent = <&intc>; @@ -1564,6 +1565,13 @@ #interrupt-cells = <2>; wakeup-parent = <&pdc>; + mi2s1_pins: mi2s1-state { + pins = "gpio108", "gpio109", "gpio110", "gpio111"; + function = "mi2s_1"; + drive-strength = <8>; + bias-disable; + }; + cam0_default: cam0-default-state { pins = "gpio28"; function = "cam_mclk"; @@ -5151,6 +5159,45 @@ dma-coherent; }; }; + + gpr: gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = ; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = ; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1721 0x0>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; }; }; From e2dc0f40b6a29571399942f03ea676589ce335b4 Mon Sep 17 00:00:00 2001 From: Le Qi Date: Tue, 27 Jan 2026 20:30:18 +0800 Subject: [PATCH 129/438] FROMLIST: arm64: dts: qcom: talos-evk: Add sound card support with DA7212 codec Add the sound card node for QCS615 Talos EVK with DA7212 codec connected over the Primary MI2S interface. The configuration enables headphone playback and headset microphone capture, both of which have been tested to work. Link: https://lore.kernel.org/all/20251204083225.1190017-3-le.qi@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Le Qi --- arch/arm64/boot/dts/qcom/talos-evk.dts | 52 ++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos-evk.dts b/arch/arm64/boot/dts/qcom/talos-evk.dts index af100e22beeec..42f8a3944b29b 100644 --- a/arch/arm64/boot/dts/qcom/talos-evk.dts +++ b/arch/arm64/boot/dts/qcom/talos-evk.dts @@ -5,6 +5,7 @@ /dts-v1/; #include "talos-evk-som.dtsi" +#include / { model = "Qualcomm QCS615 IQ 615 EVK"; @@ -40,6 +41,46 @@ }; }; + sound { + compatible = "qcom,qcs615-sndcard"; + model = "TALOS-EVK"; + + pinctrl-0 = <&mi2s1_pins>; + pinctrl-names = "default"; + + pri-mi2s-capture-dai-link { + link-name = "Primary MI2S Capture"; + + codec { + sound-dai = <&codec_da7212>; + }; + + cpu { + sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + pri-mi2s-playback-dai-link { + link-name = "Primary MI2S Playback"; + + codec { + sound-dai = <&codec_da7212>; + }; + + cpu { + sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + vreg_v1p8_out: regulator-v1p8-out { compatible = "regulator-fixed"; regulator-name = "vreg-v1p8-out"; @@ -109,6 +150,17 @@ }; }; +&i2c5 { + codec_da7212: codec@1a { + compatible = "dlg,da7212"; + reg = <0x1a>; + #sound-dai-cells = <0>; + VDDA-supply = <&vreg_v1p8_out>; + VDDIO-supply = <&vreg_v1p8_out>; + VDDMIC-supply = <&vreg_v3p3_out>; + }; +}; + &mdss_dsi0_out { remote-endpoint = <&adv7535_in>; data-lanes = <0 1 2 3>; From 18f326bc094c615894755a14ddbc2ca2198e6561 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 19 Jan 2026 14:24:54 +0530 Subject: [PATCH 130/438] FROMLIST: arm64: dts: qcom: talos: Add EL2 overlay All the existing variants Talos boards are using Gunyah hypervisor which means that, so far, Linux-based OS could only boot in EL1 on those devices. However, it is possible for us to boot Linux at EL2 on these devices [1]. When running under Gunyah, the remote processor firmware IOMMU streams are controlled by Gunyah. However, without Gunyah, the IOMMU is managed by the consumer of this DeviceTree. Therefore, describe the firmware streams for each remote processor. Add a EL2-specific DT overlay and apply it to Talos IOT variant devices to create -el2.dtb for each of them alongside "normal" dtb. [1] https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi Link: https://lore.kernel.org/lkml/20260127-talos-el2-overlay-v2-3-b6a2266532c4@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Signed-off-by: Mukesh Ojha --- arch/arm64/boot/dts/qcom/Makefile | 4 ++++ arch/arm64/boot/dts/qcom/talos-el2.dtso | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/talos-el2.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 2f4694b2d388f..5fdd0395649b3 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -137,6 +137,10 @@ dtb-$(CONFIG_ARCH_QCOM) += qcm6490-shift-otter.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride.dtb + +qcs615-ride-el2-dtbs := qcs615-ride.dtb talos-el2.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-radxa-dragon-q6a.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2.dtb diff --git a/arch/arm64/boot/dts/qcom/talos-el2.dtso b/arch/arm64/boot/dts/qcom/talos-el2.dtso new file mode 100644 index 0000000000000..f6818c058d724 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-el2.dtso @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + + * Talos specific modifications required to boot in EL2. + */ + +/dts-v1/; +/plugin/; + +&gpu_zap_shader { + status = "disabled"; +}; + +&remoteproc_adsp { + iommus = <&apps_smmu 0x1720 0x0>; +}; + +&remoteproc_cdsp { + iommus = <&apps_smmu 0x1080 0x0>; +}; + +&venus { + status = "disabled"; +}; From ee064efa1b6ec200df42add06c281eef3bfc9834 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:41 +0800 Subject: [PATCH 131/438] FROMLIST: coresight: core: Refactoring ctcu_get_active_port and make it generic Remove ctcu_get_active_port from CTCU module and add it to the core framework. The port number is crucial for the CTCU device to identify which ETR it serves. With the port number we can correctly get required parameters of the CTCU device in TMC module. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-1-9cb44178b250@oss.qualcomm.com/ Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- drivers/hwtracing/coresight/coresight-core.c | 24 +++++++++++++++++++ .../hwtracing/coresight/coresight-ctcu-core.c | 19 +-------------- drivers/hwtracing/coresight/coresight-priv.h | 2 ++ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 80e26396ad0a0..1cbaa63aa7215 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -585,6 +585,30 @@ struct coresight_device *coresight_get_sink(struct coresight_path *path) } EXPORT_SYMBOL_GPL(coresight_get_sink); +/** + * coresight_get_in_port: Find the input port number at @remote where the @csdev + * device is connected to. + * + * @csdev: csdev of the device. + * @remote: csdev of the remote device which is connected to @csdev. + * + * Return: port number upon success or -EINVAL for fail. + */ +int coresight_get_in_port(struct coresight_device *csdev, + struct coresight_device *remote) +{ + struct coresight_platform_data *pdata = remote->pdata; + int i; + + for (i = 0; i < pdata->nr_inconns; ++i) { + if (pdata->in_conns[i]->src_dev == csdev) + return pdata->in_conns[i]->dest_port; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(coresight_get_in_port); + u32 coresight_get_sink_id(struct coresight_device *csdev) { if (!csdev->ea) diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c index abed15eb72b4a..78be783b3cb25 100644 --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c @@ -118,23 +118,6 @@ static int __ctcu_set_etr_traceid(struct coresight_device *csdev, u8 traceid, in return 0; } -/* - * Searching the sink device from helper's view in case there are multiple helper devices - * connected to the sink device. - */ -static int ctcu_get_active_port(struct coresight_device *sink, struct coresight_device *helper) -{ - struct coresight_platform_data *pdata = helper->pdata; - int i; - - for (i = 0; i < pdata->nr_inconns; ++i) { - if (pdata->in_conns[i]->src_dev == sink) - return pdata->in_conns[i]->dest_port; - } - - return -EINVAL; -} - static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight_path *path, bool enable) { @@ -147,7 +130,7 @@ static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight return -EINVAL; } - port_num = ctcu_get_active_port(sink, csdev); + port_num = coresight_get_in_port(sink, csdev); if (port_num < 0) return -EINVAL; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index fd896ac07942e..cbf80b83e5ce5 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -155,6 +155,8 @@ void coresight_remove_links(struct coresight_device *orig, u32 coresight_get_sink_id(struct coresight_device *csdev); void coresight_path_assign_trace_id(struct coresight_path *path, enum cs_mode mode); +int coresight_get_in_port(struct coresight_device *csdev, + struct coresight_device *remote); #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM3X) int etm_readl_cp14(u32 off, unsigned int *val); From d4363b04bde221d2852f34c82716a6e5ec247db1 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:42 +0800 Subject: [PATCH 132/438] FROMLIST: coresight: tmc: add create/clean functions for etr_buf_list Introduce functions for creating and inserting or removing the etr_buf_node to/from the etr_buf_list. The byte-cntr functionality requires two etr_buf to receive trace data. The active etr_buf collects the trace data from source device, while the byte-cntr reading function accesses the deactivated etr_buf after is has been filled and synced, transferring data to the userspace. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-2-9cb44178b250@oss.qualcomm.com/ Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- .../hwtracing/coresight/coresight-tmc-core.c | 1 + .../hwtracing/coresight/coresight-tmc-etr.c | 94 +++++++++++++++++++ drivers/hwtracing/coresight/coresight-tmc.h | 19 ++++ 3 files changed, 114 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 36599c431be62..1ea255ffa67cf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -840,6 +840,7 @@ static int __tmc_probe(struct device *dev, struct resource *res) idr_init(&drvdata->idr); mutex_init(&drvdata->idr_mutex); dev_list = &etr_devs; + INIT_LIST_HEAD(&drvdata->etr_buf_list); break; case TMC_CONFIG_TYPE_ETF: desc.groups = coresight_etf_groups; diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 4dc1defe27a5f..15c0874ff6418 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1918,6 +1918,100 @@ const struct coresight_ops tmc_etr_cs_ops = { .panic_ops = &tmc_etr_sync_ops, }; +/** + * tmc_clean_etr_buf_list - clean the etr_buf_list. + * @drvdata: driver data of the TMC device. + * + * Remove the allocated node from the list and free the extra buffer. + */ +void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata) +{ + struct etr_buf_node *nd, *next; + + list_for_each_entry_safe(nd, next, &drvdata->etr_buf_list, node) { + if (nd->sysfs_buf == drvdata->sysfs_buf) { + if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED) { + drvdata->sysfs_buf = NULL; + tmc_free_etr_buf(nd->sysfs_buf); + nd->sysfs_buf = NULL; + } + list_del(&nd->node); + kfree(nd); + } else { + /* Free allocated buffers which are not utilized by ETR */ + list_del(&nd->node); + tmc_free_etr_buf(nd->sysfs_buf); + nd->sysfs_buf = NULL; + kfree(nd); + } + } +} +EXPORT_SYMBOL_GPL(tmc_clean_etr_buf_list); + +/** + * tmc_create_etr_buf_list - create a list to manage the etr_buf_node. + * @drvdata: driver data of the TMC device. + * @num_nodes: number of nodes want to create with the list. + * + * Return 0 upon success and return the error number if fail. + */ +int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes) +{ + struct etr_buf_node *new_node; + struct etr_buf *sysfs_buf; + int i = 0, ret = 0; + + /* We dont need a list if there is only one node */ + if (num_nodes < 2) + return -EINVAL; + + /* We expect that sysfs_buf in drvdata has already been allocated. */ + if (drvdata->sysfs_buf) { + /* Directly insert the allocated sysfs_buf into the list first */ + new_node = kzalloc_obj(*new_node, GFP_KERNEL); + if (IS_ERR(new_node)) + return PTR_ERR(new_node); + + new_node->sysfs_buf = drvdata->sysfs_buf; + new_node->is_free = false; + list_add(&new_node->node, &drvdata->etr_buf_list); + i++; + } + + while (i < num_nodes) { + new_node = kzalloc_obj(*new_node, GFP_KERNEL); + if (IS_ERR(new_node)) { + ret = PTR_ERR(new_node); + break; + } + + sysfs_buf = tmc_alloc_etr_buf(drvdata, drvdata->size, 0, cpu_to_node(0), NULL); + if (IS_ERR(sysfs_buf)) { + kfree(new_node); + ret = PTR_ERR(sysfs_buf); + break; + } + + /* We dont have a available sysfs_buf in drvdata, setup one */ + if (!drvdata->sysfs_buf) { + drvdata->sysfs_buf = sysfs_buf; + new_node->is_free = false; + } else + new_node->is_free = true; + + new_node->sysfs_buf = sysfs_buf; + list_add(&new_node->node, &drvdata->etr_buf_list); + i++; + } + + /* Clean the list if there is an error */ + if (ret) + tmc_clean_etr_buf_list(drvdata); + + return ret; +} +EXPORT_SYMBOL_GPL(tmc_create_etr_buf_list); + int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) { int ret = 0; diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 319a354ede9fc..57d8394d09b75 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -208,6 +208,19 @@ struct tmc_resrv_buf { s64 len; }; +/** + * @sysfs_buf: Allocated sysfs_buf. + * @is_free: Indicates whether the buffer is free to choose. + * @pos: Position of the buffer. + * @node: Node in etr_buf_list. + */ +struct etr_buf_node { + struct etr_buf *sysfs_buf; + bool is_free; + loff_t pos; + struct list_head node; +}; + /** * struct tmc_drvdata - specifics associated to an TMC component * @atclk: optional clock for the core parts of the TMC. @@ -245,6 +258,8 @@ struct tmc_resrv_buf { * (after crash) by default. * @crash_mdata: Reserved memory for storing tmc crash metadata. * Used by ETR/ETF. + * @etr_buf_list: List that is used to manage allocated etr_buf. + * @reading_node: Available buffer_node for byte-cntr reading. */ struct tmc_drvdata { struct clk *atclk; @@ -275,6 +290,8 @@ struct tmc_drvdata { struct etr_buf *perf_buf; struct tmc_resrv_buf resrv_buf; struct tmc_resrv_buf crash_mdata; + struct list_head etr_buf_list; + struct etr_buf_node *reading_node; }; struct etr_buf_operations { @@ -447,5 +464,7 @@ struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, enum cs_mode mode, struct coresight_path *path); extern const struct attribute_group coresight_etr_group; +void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata); +int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes); #endif From e634da5c61ab2fa3585cde2006bf67b430d41649 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:43 +0800 Subject: [PATCH 133/438] FROMLIST: coresight: tmc: Introduce tmc_sysfs_ops to wrap sysfs read operations Introduce tmc_sysfs_ops as a wrapper, wrap sysfs read operations, for reading trace data from the TMC buffer. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-3-9cb44178b250@oss.qualcomm.com/ Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- .../hwtracing/coresight/coresight-tmc-core.c | 51 ++++++++----------- drivers/hwtracing/coresight/coresight-tmc.h | 15 ++++++ 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 1ea255ffa67cf..32ca2ec994deb 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -232,17 +232,10 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata) { int ret = 0; - switch (drvdata->config_type) { - case TMC_CONFIG_TYPE_ETB: - case TMC_CONFIG_TYPE_ETF: - ret = tmc_read_prepare_etb(drvdata); - break; - case TMC_CONFIG_TYPE_ETR: - ret = tmc_read_prepare_etr(drvdata); - break; - default: + if (drvdata->sysfs_ops) + ret = drvdata->sysfs_ops->read_prepare(drvdata); + else ret = -EINVAL; - } if (!ret) dev_dbg(&drvdata->csdev->dev, "TMC read start\n"); @@ -254,17 +247,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata) { int ret = 0; - switch (drvdata->config_type) { - case TMC_CONFIG_TYPE_ETB: - case TMC_CONFIG_TYPE_ETF: - ret = tmc_read_unprepare_etb(drvdata); - break; - case TMC_CONFIG_TYPE_ETR: - ret = tmc_read_unprepare_etr(drvdata); - break; - default: + if (drvdata->sysfs_ops) + ret = drvdata->sysfs_ops->read_unprepare(drvdata); + else ret = -EINVAL; - } if (!ret) dev_dbg(&drvdata->csdev->dev, "TMC read end\n"); @@ -291,15 +277,7 @@ static int tmc_open(struct inode *inode, struct file *file) static ssize_t tmc_get_sysfs_trace(struct tmc_drvdata *drvdata, loff_t pos, size_t len, char **bufpp) { - switch (drvdata->config_type) { - case TMC_CONFIG_TYPE_ETB: - case TMC_CONFIG_TYPE_ETF: - return tmc_etb_get_sysfs_trace(drvdata, pos, len, bufpp); - case TMC_CONFIG_TYPE_ETR: - return tmc_etr_get_sysfs_trace(drvdata, pos, len, bufpp); - } - - return -EINVAL; + return drvdata->sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); } static ssize_t tmc_read(struct file *file, char __user *data, size_t len, @@ -769,6 +747,18 @@ static void register_crash_dev_interface(struct tmc_drvdata *drvdata, "Valid crash tracedata found\n"); } +static const struct tmc_sysfs_ops etb_sysfs_ops = { + .read_prepare = tmc_read_prepare_etb, + .read_unprepare = tmc_read_unprepare_etb, + .get_trace_data = tmc_etb_get_sysfs_trace, +}; + +static const struct tmc_sysfs_ops etr_sysfs_ops = { + .read_prepare = tmc_read_prepare_etr, + .read_unprepare = tmc_read_unprepare_etr, + .get_trace_data = tmc_etr_get_sysfs_trace, +}; + static int __tmc_probe(struct device *dev, struct resource *res) { int ret = 0; @@ -828,6 +818,7 @@ static int __tmc_probe(struct device *dev, struct resource *res) desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etb_cs_ops; dev_list = &etb_devs; + drvdata->sysfs_ops = &etb_sysfs_ops; break; case TMC_CONFIG_TYPE_ETR: desc.groups = coresight_etr_groups; @@ -841,6 +832,7 @@ static int __tmc_probe(struct device *dev, struct resource *res) mutex_init(&drvdata->idr_mutex); dev_list = &etr_devs; INIT_LIST_HEAD(&drvdata->etr_buf_list); + drvdata->sysfs_ops = &etr_sysfs_ops; break; case TMC_CONFIG_TYPE_ETF: desc.groups = coresight_etf_groups; @@ -849,6 +841,7 @@ static int __tmc_probe(struct device *dev, struct resource *res) desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; desc.ops = &tmc_etf_cs_ops; dev_list = &etf_devs; + drvdata->sysfs_ops = &etb_sysfs_ops; break; default: pr_err("%s: Unsupported TMC config\n", desc.name); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 57d8394d09b75..92ffaf771feab 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -260,6 +260,7 @@ struct etr_buf_node { * Used by ETR/ETF. * @etr_buf_list: List that is used to manage allocated etr_buf. * @reading_node: Available buffer_node for byte-cntr reading. + * @sysfs_ops: Read operations for sysfs mode. */ struct tmc_drvdata { struct clk *atclk; @@ -292,6 +293,20 @@ struct tmc_drvdata { struct tmc_resrv_buf crash_mdata; struct list_head etr_buf_list; struct etr_buf_node *reading_node; + const struct tmc_sysfs_ops *sysfs_ops; +}; + +/** + * struct tmc_sysfs_ops - read operations for TMC and its helper devices + * @read_prepare: prepare operation. + * @read_unprepare: unprepare operation. + * @get_trace_data: read operation. + */ +struct tmc_sysfs_ops { + int (*read_prepare)(struct tmc_drvdata *drvdata); + int (*read_unprepare)(struct tmc_drvdata *drvdata); + ssize_t (*get_trace_data)(struct tmc_drvdata *drvdata, loff_t pos, + size_t len, char **bufpp); }; struct etr_buf_operations { From 69f1ace5b2072bac8e29deece5c4963eead4c730 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:44 +0800 Subject: [PATCH 134/438] FROMLIST: coresight: etr: add a new function to retrieve the CTCU device Add tmc_etr_get_ctcu_device function to find the ptr of the coresight_device of the CTCU device if the CTCU device is connected to the TMC ETR device. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-4-9cb44178b250@oss.qualcomm.com/ Signed-off-by: Jie Gan --- .../hwtracing/coresight/coresight-tmc-etr.c | 24 +++++++++++++++++++ drivers/hwtracing/coresight/coresight-tmc.h | 1 + 2 files changed, 25 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 15c0874ff6418..97d9e8384e0e0 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -865,6 +865,30 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) } EXPORT_SYMBOL_GPL(tmc_etr_get_catu_device); +/* + * TMC ETR could be connected to a CTCU device, which can provide ATID filter + * and byte-cntr service. This is represented by the output port of the TMC + * (ETR) connected to the input port of the CTCU. + * + * Retruns : coresight_device ptr for the CTCU device if a CTCU is found. + * : NULL otherwise. + */ +struct coresight_device * +tmc_etr_get_ctcu_device(struct tmc_drvdata *drvdata) +{ + struct coresight_device *etr = drvdata->csdev; + union coresight_dev_subtype ctcu_subtype = { + .helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CTCU + }; + + if (!IS_ENABLED(CONFIG_CORESIGHT_CTCU)) + return NULL; + + return coresight_find_output_type(etr->pdata, CORESIGHT_DEV_TYPE_HELPER, + ctcu_subtype); +} +EXPORT_SYMBOL_GPL(tmc_etr_get_ctcu_device); + static const struct etr_buf_operations *etr_buf_ops[] = { [ETR_MODE_FLAT] = &etr_flat_buf_ops, [ETR_MODE_ETR_SG] = &etr_sg_buf_ops, diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 92ffaf771feab..27dd72065c606 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -472,6 +472,7 @@ static inline uint32_t find_crash_tracedata_crc(struct tmc_drvdata *drvdata, } struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); +struct coresight_device *tmc_etr_get_ctcu_device(struct tmc_drvdata *drvdata); void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu); void tmc_etr_remove_catu_ops(void); From 5f5fc4506dfb981dab73b11cb5d0edb30d53f39e Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:45 +0800 Subject: [PATCH 135/438] FROMLIST: dt-bindings: arm: add an interrupt property for Coresight CTCU Add an interrupt property to CTCU device. The interrupt will be triggered when the data size in the ETR buffer exceeds the threshold of the BYTECNTRVAL register. Programming a threshold in the BYTECNTRVAL register of CTCU device will enable the interrupt. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-5-9cb44178b250@oss.qualcomm.com/ Acked-by: Krzysztof Kozlowski Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- .../devicetree/bindings/arm/qcom,coresight-ctcu.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index e002f87361ad3..2981001a7d7f7 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml @@ -44,6 +44,11 @@ properties: items: - const: apb + interrupts: + items: + - description: Interrupt for the ETR device connected to in-port0. + - description: Interrupt for the ETR device connected to in-port1. + label: description: Description of a coresight device. @@ -65,6 +70,8 @@ additionalProperties: false examples: - | + #include + ctcu@1001000 { compatible = "qcom,sa8775p-ctcu"; reg = <0x1001000 0x1000>; @@ -72,6 +79,9 @@ examples: clocks = <&aoss_qmp>; clock-names = "apb"; + interrupts = , + ; + in-ports { #address-cells = <1>; #size-cells = <0>; From 9e87117152608e54849af485d0af067e3d122060 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:46 +0800 Subject: [PATCH 136/438] FROMLIST: coresight: ctcu: enable byte-cntr for TMC ETR devices The byte-cntr function provided by the CTCU device is used to transfer data from the ETR buffer to the userspace. An interrupt is triggered if the data size exceeds the threshold set in the BYTECNTRVAL register. The interrupt handler counts the number of triggered interruptions and the read function will read the data from the synced ETR buffer. Switching the sysfs_buf when current buffer is full or the timeout is triggered and resets rrp and rwp registers after switched the buffer. The synced buffer will become available for reading after the switch. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-6-9cb44178b250@oss.qualcomm.com/ Signed-off-by: Jie Gan --- .../testing/sysfs-bus-coresight-devices-ctcu | 8 + drivers/hwtracing/coresight/Makefile | 2 +- .../coresight/coresight-ctcu-byte-cntr.c | 367 ++++++++++++++++++ .../hwtracing/coresight/coresight-ctcu-core.c | 103 ++++- drivers/hwtracing/coresight/coresight-ctcu.h | 77 +++- .../hwtracing/coresight/coresight-tmc-etr.c | 18 + drivers/hwtracing/coresight/coresight-tmc.h | 1 + 7 files changed, 563 insertions(+), 13 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu create mode 100644 drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu new file mode 100644 index 0000000000000..a58a05491f7a6 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu @@ -0,0 +1,8 @@ +What: /sys/bus/coresight/devices//irq_threshold[0:1] +Date: February 2026 +KernelVersion: 7.1 +Contact: Tingwei Zhang ; Jinlong Mao ; Jie Gan +Description: + (RW) Configure the byte-cntr IRQ register for the specified ETR device + based on its port number. An interrupt is generated when the data size + exceeds the value set in the IRQ register. diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index ab16d06783a57..821a1b06b20c2 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -55,5 +55,5 @@ coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \ obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o obj-$(CONFIG_CORESIGHT_CTCU) += coresight-ctcu.o -coresight-ctcu-y := coresight-ctcu-core.o +coresight-ctcu-y := coresight-ctcu-core.o coresight-ctcu-byte-cntr.o obj-$(CONFIG_CORESIGHT_KUNIT_TESTS) += coresight-kunit-tests.o diff --git a/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c new file mode 100644 index 0000000000000..bf59e654465b7 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c @@ -0,0 +1,367 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include "coresight-ctcu.h" +#include "coresight-priv.h" +#include "coresight-tmc.h" + +static irqreturn_t byte_cntr_handler(int irq, void *data) +{ + struct ctcu_byte_cntr *byte_cntr_data = (struct ctcu_byte_cntr *)data; + + atomic_inc(&byte_cntr_data->irq_cnt); + wake_up(&byte_cntr_data->wq); + + return IRQ_HANDLED; +} + +static void ctcu_reset_sysfs_buf(struct tmc_drvdata *drvdata) +{ + u32 sts; + + CS_UNLOCK(drvdata->base); + tmc_write_rrp(drvdata, drvdata->sysfs_buf->hwaddr); + tmc_write_rwp(drvdata, drvdata->sysfs_buf->hwaddr); + sts = readl_relaxed(drvdata->base + TMC_STS) & ~TMC_STS_FULL; + writel_relaxed(sts, drvdata->base + TMC_STS); + CS_LOCK(drvdata->base); +} + +static void ctcu_cfg_byte_cntr_reg(struct tmc_drvdata *drvdata, u32 val, u32 offset) +{ + struct ctcu_drvdata *ctcu_drvdata; + struct coresight_device *helper; + + helper = tmc_etr_get_ctcu_device(drvdata); + if (!helper) + return; + + ctcu_drvdata = dev_get_drvdata(helper->dev.parent); + /* A one value for IRQCTRL register represents 8 bytes */ + ctcu_program_register(ctcu_drvdata, val / 8, offset); +} + +static struct ctcu_byte_cntr *ctcu_get_byte_cntr_data(struct tmc_drvdata *drvdata) +{ + struct ctcu_byte_cntr *byte_cntr_data; + struct ctcu_drvdata *ctcu_drvdata; + struct coresight_device *helper; + int port; + + helper = tmc_etr_get_ctcu_device(drvdata); + if (!helper) + return NULL; + + port = coresight_get_in_port(drvdata->csdev, helper); + if (port < 0) + return NULL; + + ctcu_drvdata = dev_get_drvdata(helper->dev.parent); + byte_cntr_data = &ctcu_drvdata->byte_cntr_data[port]; + return byte_cntr_data; +} + +static bool ctcu_byte_cntr_switch_buffer(struct tmc_drvdata *drvdata, + struct ctcu_byte_cntr *byte_cntr_data) +{ + struct etr_buf_node *nd, *next, *curr_node, *picked_node; + struct etr_buf *curr_buf = drvdata->sysfs_buf; + bool found_free_buf = false; + + if (WARN_ON(!drvdata || !byte_cntr_data)) + return found_free_buf; + + /* Stop the ETR before we start the switch */ + if (coresight_get_mode(drvdata->csdev) != CS_MODE_DISABLED) + tmc_etr_enable_disable_hw(drvdata, false); + + list_for_each_entry_safe(nd, next, &drvdata->etr_buf_list, node) { + /* curr_buf is free for next round */ + if (nd->sysfs_buf == curr_buf) { + nd->is_free = true; + curr_node = nd; + } + + if (!found_free_buf && nd->is_free && nd->sysfs_buf != curr_buf) { + picked_node = nd; + found_free_buf = true; + } + } + + if (found_free_buf) { + curr_node->pos = 0; + drvdata->reading_node = curr_node; + drvdata->sysfs_buf = picked_node->sysfs_buf; + drvdata->etr_buf = picked_node->sysfs_buf; + picked_node->is_free = false; + /* Reset irq_cnt for next etr_buf */ + atomic_set(&byte_cntr_data->irq_cnt, 0); + /* Reset rrp and rwp when the system has switched the buffer*/ + ctcu_reset_sysfs_buf(drvdata); + /* Restart the ETR when we find a free buffer */ + if (coresight_get_mode(drvdata->csdev) != CS_MODE_DISABLED) + tmc_etr_enable_disable_hw(drvdata, true); + } + + return found_free_buf; +} + +/* + * ctcu_byte_cntr_get_data() - reads data from the deactivated and filled buffer. + * The byte-cntr reading work reads data from the deactivated and filled buffer. + * The read operation waits for a buffer to become available, either filled or + * upon timeout, and then reads trace data from the synced buffer. + */ +static ssize_t ctcu_byte_cntr_get_data(struct tmc_drvdata *drvdata, loff_t pos, + size_t len, char **bufpp) +{ + struct etr_buf *sysfs_buf = drvdata->sysfs_buf; + struct device *dev = &drvdata->csdev->dev; + ssize_t actual, size = sysfs_buf->size; + struct ctcu_byte_cntr *byte_cntr_data; + size_t thresh_val; + atomic_t *irq_cnt; + int ret; + + byte_cntr_data = ctcu_get_byte_cntr_data(drvdata); + if (!byte_cntr_data) + return -EINVAL; + + thresh_val = byte_cntr_data->thresh_val; + irq_cnt = &byte_cntr_data->irq_cnt; + +wait_buffer: + if (!byte_cntr_data->reading_buf) { + ret = wait_event_interruptible_timeout(byte_cntr_data->wq, + ((atomic_read(irq_cnt) + 1) * thresh_val >= size) || + !byte_cntr_data->enable, + BYTE_CNTR_TIMEOUT); + if (ret < 0) + return ret; + /* + * The current etr_buf is almost full or timeout is triggered, + * so switch the buffer and mark the switched buffer as reading. + */ + if (byte_cntr_data->enable) { + if (!ctcu_byte_cntr_switch_buffer(drvdata, byte_cntr_data)) { + dev_err(dev, "Switch buffer failed for byte-cntr\n"); + return -EINVAL; + } + + byte_cntr_data->reading_buf = true; + } else { + /* + * TMC-ETR has been disabled, so directly reads data from + * the drvdata->sysfs_buf. + */ + actual = drvdata->sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); + if (actual > 0) { + byte_cntr_data->total_size += actual; + return actual; + } + + /* Exit byte-cntr reading */ + return 0; + } + } + + /* Check the status of current etr_buf*/ + if ((atomic_read(irq_cnt) + 1) * thresh_val >= size) + /* + * Unlikely to find a free buffer to switch, so just disable + * the ETR for a while. + */ + if (!ctcu_byte_cntr_switch_buffer(drvdata, byte_cntr_data)) + dev_warn(dev, "No available buffer to store data, disable ETR\n"); + + pos = drvdata->reading_node->pos; + actual = drvdata->sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); + if (actual <= 0) { + /* Reset flags upon reading is finished or failed */ + byte_cntr_data->reading_buf = false; + drvdata->reading_node = NULL; + + /* + * Nothing in the buffer, waiting for the next buffer + * to be filled. + */ + if (actual == 0) + goto wait_buffer; + } else + byte_cntr_data->total_size += actual; + + return actual; +} + +static int ctcu_read_prepare_byte_cntr(struct tmc_drvdata *drvdata) +{ + struct ctcu_byte_cntr *byte_cntr_data; + unsigned long flags; + int ret = 0; + + /* config types are set a boot time and never change */ + if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) + return -EINVAL; + + /* + * Byte counter reading should start only after the TMC-ETR has been + * enabled, which implies that the sysfs_buf has already been setup + * in drvdata. + */ + if (!drvdata->sysfs_buf) + return -EINVAL; + + byte_cntr_data = ctcu_get_byte_cntr_data(drvdata); + if (!byte_cntr_data) + return -EINVAL; + + /* + * The threshold value must not exceed the buffer size. + * A margin should be maintained between the two values to account + * for the time gap between the interrupt and buffer switching. + */ + if (byte_cntr_data->thresh_val + SZ_16K >= drvdata->size) { + dev_err(&drvdata->csdev->dev, "The threshold value is too large\n"); + return -EINVAL; + } + + raw_spin_lock_irqsave(&drvdata->spinlock, flags); + if (byte_cntr_data->reading) { + ret = -EBUSY; + goto out_unlock; + } + + byte_cntr_data->reading = true; + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + /* Setup an available etr_buf_list for byte-cntr */ + ret = tmc_create_etr_buf_list(drvdata, 2); + if (ret) + goto out; + + raw_spin_lock_irqsave(&drvdata->spinlock, flags); + atomic_set(&byte_cntr_data->irq_cnt, 0); + /* Configure the byte-cntr register to enable IRQ */ + ctcu_cfg_byte_cntr_reg(drvdata, byte_cntr_data->thresh_val, + byte_cntr_data->irq_ctrl_offset); + enable_irq_wake(byte_cntr_data->irq); + byte_cntr_data->total_size = 0; + +out_unlock: + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + +out: + return ret; +} + +static int ctcu_read_unprepare_byte_cntr(struct tmc_drvdata *drvdata) +{ + struct device *dev = &drvdata->csdev->dev; + struct ctcu_byte_cntr *byte_cntr_data; + unsigned long flags; + + byte_cntr_data = ctcu_get_byte_cntr_data(drvdata); + if (!byte_cntr_data) + return -EINVAL; + + raw_spin_lock_irqsave(&drvdata->spinlock, flags); + /* Configure the byte-cntr register to disable IRQ */ + ctcu_cfg_byte_cntr_reg(drvdata, 0, byte_cntr_data->irq_ctrl_offset); + disable_irq_wake(byte_cntr_data->irq); + byte_cntr_data->reading = false; + byte_cntr_data->reading_buf = false; + drvdata->reading_node = NULL; + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + dev_dbg(dev, "send data total size:%llu bytes\n", byte_cntr_data->total_size); + tmc_clean_etr_buf_list(drvdata); + + return 0; +} + +static const struct tmc_sysfs_ops byte_cntr_sysfs_ops = { + .read_prepare = ctcu_read_prepare_byte_cntr, + .read_unprepare = ctcu_read_unprepare_byte_cntr, + .get_trace_data = ctcu_byte_cntr_get_data, +}; + +/* Start the byte-cntr function when the path is enabled. */ +void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path) +{ + struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct coresight_device *sink = coresight_get_sink(path); + struct ctcu_byte_cntr *byte_cntr_data; + int port_num; + + if (!sink) + return; + + port_num = coresight_get_in_port(sink, csdev); + if (port_num < 0) + return; + + byte_cntr_data = &drvdata->byte_cntr_data[port_num]; + /* Don't start byte-cntr function when threshold is not set. */ + if (!byte_cntr_data->thresh_val || byte_cntr_data->enable) + return; + + guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock); + byte_cntr_data->enable = true; + byte_cntr_data->reading_buf = false; +} + +/* Stop the byte-cntr function when the path is disabled. */ +void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path) +{ + struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct coresight_device *sink = coresight_get_sink(path); + struct ctcu_byte_cntr *byte_cntr_data; + int port_num; + + if (!sink || coresight_get_mode(sink) == CS_MODE_SYSFS) + return; + + port_num = coresight_get_in_port(sink, csdev); + if (port_num < 0) + return; + + byte_cntr_data = &drvdata->byte_cntr_data[port_num]; + guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock); + byte_cntr_data->enable = false; +} + +void ctcu_byte_cntr_init(struct device *dev, struct ctcu_drvdata *drvdata, int etr_num) +{ + struct ctcu_byte_cntr *byte_cntr_data; + struct device_node *nd = dev->of_node; + int irq_num, ret, i; + + drvdata->byte_cntr_sysfs_ops = &byte_cntr_sysfs_ops; + for (i = 0; i < etr_num; i++) { + byte_cntr_data = &drvdata->byte_cntr_data[i]; + irq_num = of_irq_get(nd, i); + if (irq_num < 0) { + dev_err(dev, "Failed to get IRQ from DT for port%d\n", i); + continue; + } + + ret = devm_request_irq(dev, irq_num, byte_cntr_handler, + IRQF_TRIGGER_RISING | IRQF_SHARED, + dev_name(dev), byte_cntr_data); + if (ret) { + dev_err(dev, "Failed to register IRQ for port%d\n", i); + continue; + } + + byte_cntr_data->irq = irq_num; + init_waitqueue_head(&byte_cntr_data->wq); + raw_spin_lock_init(&drvdata->spin_lock); + } +} diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c index 78be783b3cb25..0e5cadaac3504 100644 --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "coresight-ctcu.h" #include "coresight-priv.h" @@ -45,17 +46,21 @@ DEFINE_CORESIGHT_DEVLIST(ctcu_devs, "ctcu"); #define CTCU_ATID_REG_BIT(traceid) (traceid % 32) #define CTCU_ATID_REG_SIZE 0x10 +#define CTCU_ETR0_IRQCTRL 0x6c +#define CTCU_ETR1_IRQCTRL 0x70 #define CTCU_ETR0_ATID0 0xf8 #define CTCU_ETR1_ATID0 0x108 static const struct ctcu_etr_config sa8775p_etr_cfgs[] = { { - .atid_offset = CTCU_ETR0_ATID0, - .port_num = 0, + .atid_offset = CTCU_ETR0_ATID0, + .irq_ctrl_offset = CTCU_ETR0_IRQCTRL, + .port_num = 0, }, { - .atid_offset = CTCU_ETR1_ATID0, - .port_num = 1, + .atid_offset = CTCU_ETR1_ATID0, + .irq_ctrl_offset = CTCU_ETR1_IRQCTRL, + .port_num = 1, }, }; @@ -64,6 +69,88 @@ static const struct ctcu_config sa8775p_cfgs = { .num_etr_config = ARRAY_SIZE(sa8775p_etr_cfgs), }; +void ctcu_program_register(struct ctcu_drvdata *drvdata, u32 val, u32 offset) +{ + CS_UNLOCK(drvdata->base); + ctcu_writel(drvdata, val, offset); + CS_LOCK(drvdata->base); +} + +static ssize_t irq_threshold_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ctcu_byte_cntr_irq_attribute *irq_attr = + container_of(attr, struct ctcu_byte_cntr_irq_attribute, attr); + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent); + u8 port = irq_attr->port; + + if (!drvdata->byte_cntr_data[port].irq_ctrl_offset) + return -EINVAL; + + return sysfs_emit(buf, "%u\n", + (unsigned int)drvdata->byte_cntr_data[port].thresh_val); +} + +static ssize_t irq_threshold_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct ctcu_byte_cntr_irq_attribute *irq_attr = + container_of(attr, struct ctcu_byte_cntr_irq_attribute, attr); + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent); + u8 port = irq_attr->port; + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + /* Threshold 0 disables the interruption. */ + guard(raw_spinlock_irqsave)(&drvdata->spin_lock); + /* A small threshold will result in a large number of interruptions */ + if (val && val < SZ_4K) + return -EINVAL; + + if (drvdata->byte_cntr_data[port].irq_ctrl_offset) + drvdata->byte_cntr_data[port].thresh_val = val; + + return size; +} + +static umode_t irq_threshold_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device_attribute *dev_attr = + container_of(attr, struct device_attribute, attr); + struct ctcu_byte_cntr_irq_attribute *irq_attr = + container_of(dev_attr, struct ctcu_byte_cntr_irq_attribute, attr); + struct device *dev = kobj_to_dev(kobj); + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent); + u8 port = irq_attr->port; + + if (drvdata && drvdata->byte_cntr_data[port].irq_ctrl_offset) + return attr->mode; + + return 0; +} + +static struct attribute *ctcu_attrs[] = { + ctcu_byte_cntr_irq_rw(0), + ctcu_byte_cntr_irq_rw(1), + NULL, +}; + +static struct attribute_group ctcu_attr_grp = { + .attrs = ctcu_attrs, + .is_visible = irq_threshold_is_visible, +}; + +static const struct attribute_group *ctcu_attr_grps[] = { + &ctcu_attr_grp, + NULL, +}; + static void ctcu_program_atid_register(struct ctcu_drvdata *drvdata, u32 reg_offset, u8 bit, bool enable) { @@ -142,11 +229,15 @@ static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode, struct coresight_path *path) { + ctcu_byte_cntr_start(csdev, path); + return ctcu_set_etr_traceid(csdev, path, true); } static int ctcu_disable(struct coresight_device *csdev, struct coresight_path *path) { + ctcu_byte_cntr_stop(csdev, path); + return ctcu_set_etr_traceid(csdev, path, false); } @@ -197,7 +288,10 @@ static int ctcu_probe(struct platform_device *pdev) for (i = 0; i < cfgs->num_etr_config; i++) { etr_cfg = &cfgs->etr_cfgs[i]; drvdata->atid_offset[i] = etr_cfg->atid_offset; + drvdata->byte_cntr_data[i].irq_ctrl_offset = + etr_cfg->irq_ctrl_offset; } + ctcu_byte_cntr_init(dev, drvdata, cfgs->num_etr_config); } } @@ -209,6 +303,7 @@ static int ctcu_probe(struct platform_device *pdev) desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CTCU; desc.pdata = pdata; desc.dev = dev; + desc.groups = ctcu_attr_grps; desc.ops = &ctcu_ops; desc.access = CSDEV_ACCESS_IOMEM(base); diff --git a/drivers/hwtracing/coresight/coresight-ctcu.h b/drivers/hwtracing/coresight/coresight-ctcu.h index e9594c38dd91c..bc833482c8bcb 100644 --- a/drivers/hwtracing/coresight/coresight-ctcu.h +++ b/drivers/hwtracing/coresight/coresight-ctcu.h @@ -5,19 +5,26 @@ #ifndef _CORESIGHT_CTCU_H #define _CORESIGHT_CTCU_H + +#include #include "coresight-trace-id.h" /* Maximum number of supported ETR devices for a single CTCU. */ #define ETR_MAX_NUM 2 +#define BYTE_CNTR_TIMEOUT (5 * HZ) + /** * struct ctcu_etr_config * @atid_offset: offset to the ATID0 Register. - * @port_num: in-port number of CTCU device that connected to ETR. + * @port_num: in-port number of the CTCU device that connected to ETR. + * @irq_ctrl_offset: offset to the BYTECNTRVAL register. + * @irq_name: IRQ name in dt node. */ struct ctcu_etr_config { const u32 atid_offset; const u32 port_num; + const u32 irq_ctrl_offset; }; struct ctcu_config { @@ -25,15 +32,69 @@ struct ctcu_config { int num_etr_config; }; -struct ctcu_drvdata { - void __iomem *base; - struct clk *apb_clk; - struct device *dev; - struct coresight_device *csdev; +/** + * struct ctcu_byte_cntr + * @enable: indicates that byte_cntr function is enabled or not. + * @reading: indicates that byte-cntr reading is started. + * @reading_buf: indicates that byte-cntr is reading data from the buffer. + * @thresh_val: threshold to trigger a interruption. + * @total_size: total size of transferred data. + * @irq: allocated number of the IRQ. + * @irq_cnt: IRQ count number for triggered interruptions. + * @wq: waitqueue for reading data from ETR buffer. + * @spin_lock: spinlock of byte_cntr_data. + * @irq_ctrl_offset: offset to the BYTECNTVAL Register. + */ +struct ctcu_byte_cntr { + bool enable; + bool reading; + bool reading_buf; + u32 thresh_val; + u64 total_size; + int irq; + atomic_t irq_cnt; + wait_queue_head_t wq; raw_spinlock_t spin_lock; - u32 atid_offset[ETR_MAX_NUM]; + u32 irq_ctrl_offset; +}; + +struct ctcu_drvdata { + void __iomem *base; + struct clk *apb_clk; + struct device *dev; + struct coresight_device *csdev; + struct ctcu_byte_cntr byte_cntr_data[ETR_MAX_NUM]; + raw_spinlock_t spin_lock; + u32 atid_offset[ETR_MAX_NUM]; /* refcnt for each traceid of each sink */ - u8 traceid_refcnt[ETR_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP]; + u8 traceid_refcnt[ETR_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP]; + const struct tmc_sysfs_ops *byte_cntr_sysfs_ops; }; +/** + * struct ctcu_irq_thresh_attribute + * @attr: The device attribute. + * @idx: port number. + */ +struct ctcu_byte_cntr_irq_attribute { + struct device_attribute attr; + u8 port; +}; + +#define ctcu_byte_cntr_irq_rw(port) \ + (&((struct ctcu_byte_cntr_irq_attribute[]) { \ + { \ + __ATTR(irq_threshold##port, 0644, irq_threshold_show, \ + irq_threshold_store), \ + port, \ + } \ + })[0].attr.attr) + +void ctcu_program_register(struct ctcu_drvdata *drvdata, u32 val, u32 offset); + +/* Byte-cntr functions */ +void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path); +void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path); +void ctcu_byte_cntr_init(struct device *dev, struct ctcu_drvdata *drvdata, int port_num); + #endif diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 97d9e8384e0e0..9cac8733d471c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1185,6 +1185,10 @@ ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata, ssize_t actual = len; struct etr_buf *etr_buf = drvdata->sysfs_buf; + /* Reading the buffer from the buf_node if it exists*/ + if (drvdata->reading_node) + etr_buf = drvdata->reading_node->sysfs_buf; + if (pos + actual > etr_buf->len) actual = etr_buf->len - pos; if (actual <= 0) @@ -1248,6 +1252,20 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata) } +/** + * tmc_etr_enable_disable_hw - enable/disable the ETR hw. + * @drvdata: drvdata of the TMC device. + * @enable: indicates enable/disable. + */ +void tmc_etr_enable_disable_hw(struct tmc_drvdata *drvdata, bool enable) +{ + if (enable) + __tmc_etr_enable_hw(drvdata); + else + __tmc_etr_disable_hw(drvdata); +} +EXPORT_SYMBOL_GPL(tmc_etr_enable_disable_hw); + void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) { __tmc_etr_disable_hw(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 27dd72065c606..d60c70530c8a3 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -482,5 +482,6 @@ struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, extern const struct attribute_group coresight_etr_group; void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata); int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes); +void tmc_etr_enable_disable_hw(struct tmc_drvdata *drvdata, bool enable); #endif From 02b188ff1f603ff2fef5f7bdb5d92a615edf877d Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 23 Feb 2026 14:55:47 +0800 Subject: [PATCH 137/438] FROMLIST: coresight: tmc: integrate byte-cntr's sysfs_ops with tmc sysfs file_ops Add code logic to invoke byte-cntr's tmc_sysfs_ops if the byte-cntr is enabled. Link: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-7-9cb44178b250@oss.qualcomm.com/ Signed-off-by: Jie Gan --- .../hwtracing/coresight/coresight-tmc-core.c | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 32ca2ec994deb..6486bdafdddc4 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -31,6 +31,7 @@ #include "coresight-priv.h" #include "coresight-tmc.h" +#include "coresight-ctcu.h" DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb"); DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf"); @@ -228,15 +229,47 @@ static int tmc_prepare_crashdata(struct tmc_drvdata *drvdata) return 0; } +/* Return the byte-cntr's tmc_sysfs_ops if in using */ +static const struct tmc_sysfs_ops *tmc_get_byte_cntr_sysfs_ops(struct tmc_drvdata *drvdata) +{ + struct ctcu_byte_cntr *byte_cntr_data; + struct ctcu_drvdata *ctcu_drvdata; + struct coresight_device *ctcu; + int port; + + ctcu = tmc_etr_get_ctcu_device(drvdata); + if (!ctcu) + return NULL; + + port = coresight_get_in_port(drvdata->csdev, ctcu); + if (port < 0) + return NULL; + + ctcu_drvdata = dev_get_drvdata(ctcu->dev.parent); + byte_cntr_data = &ctcu_drvdata->byte_cntr_data[port]; + if (byte_cntr_data && byte_cntr_data->thresh_val) + return ctcu_drvdata->byte_cntr_sysfs_ops; + + return NULL; +} + static int tmc_read_prepare(struct tmc_drvdata *drvdata) { + const struct tmc_sysfs_ops *byte_cntr_sysfs_ops; int ret = 0; + byte_cntr_sysfs_ops = tmc_get_byte_cntr_sysfs_ops(drvdata); + if (byte_cntr_sysfs_ops) { + ret = byte_cntr_sysfs_ops->read_prepare(drvdata); + goto out; + } + if (drvdata->sysfs_ops) ret = drvdata->sysfs_ops->read_prepare(drvdata); else ret = -EINVAL; +out: if (!ret) dev_dbg(&drvdata->csdev->dev, "TMC read start\n"); @@ -245,13 +278,21 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata) static int tmc_read_unprepare(struct tmc_drvdata *drvdata) { + const struct tmc_sysfs_ops *byte_cntr_sysfs_ops; int ret = 0; + byte_cntr_sysfs_ops = tmc_get_byte_cntr_sysfs_ops(drvdata); + if (byte_cntr_sysfs_ops) { + ret = byte_cntr_sysfs_ops->read_unprepare(drvdata); + goto out; + } + if (drvdata->sysfs_ops) ret = drvdata->sysfs_ops->read_unprepare(drvdata); else ret = -EINVAL; +out: if (!ret) dev_dbg(&drvdata->csdev->dev, "TMC read end\n"); @@ -277,6 +318,12 @@ static int tmc_open(struct inode *inode, struct file *file) static ssize_t tmc_get_sysfs_trace(struct tmc_drvdata *drvdata, loff_t pos, size_t len, char **bufpp) { + const struct tmc_sysfs_ops *byte_cntr_sysfs_ops; + + byte_cntr_sysfs_ops = tmc_get_byte_cntr_sysfs_ops(drvdata); + if (byte_cntr_sysfs_ops) + return byte_cntr_sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); + return drvdata->sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); } @@ -297,7 +344,11 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, return -EFAULT; } - *ppos += actual; + if (drvdata->reading_node) + drvdata->reading_node->pos += actual; + else + *ppos += actual; + dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual); return actual; From 4d9d032ccb952972e8e173bd750d2d55eb636f66 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 19 Feb 2026 22:46:57 +0800 Subject: [PATCH 138/438] FROMLIST: coresight: ctcu: fix the spin_bug Acquiring an uninitialized raw_spin_lock is invalid and may trigger unexpected behavior or spin_bug. Link: https://lore.kernel.org/all/20260219-fix-spin-lock-issue-v1-1-557f7d513d7e@oss.qualcomm.com/ Fixes: f78d206f3d73 ("Coresight: Add Coresight TMC Control Unit driver") Reviewed-by: James Clark Signed-off-by: Jie Gan --- drivers/hwtracing/coresight/coresight-ctcu-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c index 0e5cadaac3504..444b460b82510 100644 --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c @@ -306,6 +306,7 @@ static int ctcu_probe(struct platform_device *pdev) desc.groups = ctcu_attr_grps; desc.ops = &ctcu_ops; desc.access = CSDEV_ACCESS_IOMEM(base); + raw_spin_lock_init(&drvdata->spin_lock); drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) From f8b0871151d5ebf06fe123afb7e95302bfd76191 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:35 -0800 Subject: [PATCH 139/438] FROMLIST: dt-bindings: arm: Add support for Qualcomm TGU trace The Trigger Generation Unit (TGU) is designed to detect patterns or sequences within a specific region of the System on Chip (SoC). Once configured and activated, it monitors sense inputs and can detect a pre-programmed state or sequence across clock cycles, subsequently producing a trigger. TGU configuration space offset table x-------------------------x | | | | | | Step configuration | | space layout | coresight management | x-------------x | registers | |---> | | | | | | reserve | | | | | | |-------------------------| | |-------------| | | | | priority[3] | | step[7] |<-- | |-------------| |-------------------------| | | | priority[2] | | | | | |-------------| | ... | |Steps region | | priority[1] | | | | | |-------------| |-------------------------| | | | priority[0] | | |<-- | |-------------| | step[0] |--------------------> | | |-------------------------| | condition | | | | | | control and status | x-------------x | space | | | x-------------------------x |Timer/Counter| | | x-------------x TGU Configuration in Hardware The TGU provides a step region for user configuration, similar to a flow chart. Each step region consists of three register clusters: 1.Priority Region: Sets the required signals with priority. 2.Condition Region: Defines specific requirements (e.g., signal A reaches three times) and the subsequent action once the requirement is met. 3.Timer/Counter (Optional): Provides timing or counting functionality. Add a new tgu.yaml file to describe the bindings required to define the TGU in the device trees. Link: https://lore.kernel.org/all/20260109021141.3778421-2-songwei.chai@oss.qualcomm.com/ Reviewed-by: Rob Herring (Arm) Signed-off-by: Songwei Chai --- .../devicetree/bindings/arm/qcom,tgu.yaml | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/qcom,tgu.yaml diff --git a/Documentation/devicetree/bindings/arm/qcom,tgu.yaml b/Documentation/devicetree/bindings/arm/qcom,tgu.yaml new file mode 100644 index 0000000000000..5b6a58ebe6911 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/qcom,tgu.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/qcom,tgu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Trigger Generation Unit - TGU + +description: | + The Trigger Generation Unit (TGU) is a Data Engine which can be utilized + to sense a plurality of signals and create a trigger into the CTI or + generate interrupts to processors. The TGU is like the trigger circuit + of a Logic Analyzer. The corresponding trigger logic can be realized by + configuring the conditions for each step after sensing the signal. + Once setup and enabled, it will observe sense inputs and based upon + the activity of those inputs, even over clock cycles, may detect a + preprogrammed state/sequence and then produce a trigger or interrupt. + + The primary use case of the TGU is to detect patterns or sequences on a + given set of signals within some region to identify the issue in time + once there is abnormal behavior in the subsystem. + +maintainers: + - Mao Jinlong + - Songwei Chai + +# Need a custom select here or 'arm,primecell' will match on lots of nodes +select: + properties: + compatible: + contains: + enum: + - qcom,tgu + required: + - compatible + +properties: + compatible: + items: + - const: qcom,tgu + - const: arm,primecell + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: apb_pclk + + in-ports: + $ref: /schemas/graph.yaml#/properties/ports + additionalProperties: false + + properties: + port: + description: + The port mechanism here ensures the relationship between TGU and + TPDM, as TPDM is one of the inputs for TGU. It will allow TGU to + function as TPDM's helper and enable TGU when the connected + TPDM is enabled. + $ref: /schemas/graph.yaml#/properties/port + +required: + - compatible + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + tgu@10b0e000 { + compatible = "qcom,tgu", "arm,primecell"; + reg = <0x10b0e000 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + tgu_in_tpdm_swao: endpoint{ + remote-endpoint = <&tpdm_swao_out_tgu>; + }; + }; + }; + }; +... From b76346134a7aef34b815c44f6656874987457974 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:36 -0800 Subject: [PATCH 140/438] FROMLIST: qcom-tgu: Add TGU driver Add driver to support device TGU (Trigger Generation Unit). TGU is a Data Engine which can be utilized to sense a plurality of signals and create a trigger into the CTI or generate interrupts to processors. Add probe/enable/disable functions for tgu. Link: https://lore.kernel.org/all/20260109021141.3778421-3-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../ABI/testing/sysfs-bus-amba-devices-tgu | 9 + drivers/Makefile | 1 + drivers/hwtracing/Kconfig | 2 + drivers/hwtracing/qcom/Kconfig | 18 ++ drivers/hwtracing/qcom/Makefile | 3 + drivers/hwtracing/qcom/tgu.c | 176 ++++++++++++++++++ drivers/hwtracing/qcom/tgu.h | 51 +++++ 7 files changed, 260 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-amba-devices-tgu create mode 100644 drivers/hwtracing/qcom/Kconfig create mode 100644 drivers/hwtracing/qcom/Makefile create mode 100644 drivers/hwtracing/qcom/tgu.c create mode 100644 drivers/hwtracing/qcom/tgu.h diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu new file mode 100644 index 0000000000000..56ec3f5ab5d65 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu @@ -0,0 +1,9 @@ +What: /sys/bus/amba/devices//enable_tgu +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the enable/disable status of TGU + Accepts only one of the 2 values - 0 or 1. + 0 : disable TGU. + 1 : enable TGU. diff --git a/drivers/Makefile b/drivers/Makefile index 53fbd2e0acdd2..82b712a12a268 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -177,6 +177,7 @@ obj-$(CONFIG_RAS) += ras/ obj-$(CONFIG_USB4) += thunderbolt/ obj-$(CONFIG_CORESIGHT) += hwtracing/coresight/ obj-y += hwtracing/intel_th/ +obj-y += hwtracing/qcom/ obj-$(CONFIG_STM) += hwtracing/stm/ obj-$(CONFIG_HISI_PTT) += hwtracing/ptt/ obj-y += android/ diff --git a/drivers/hwtracing/Kconfig b/drivers/hwtracing/Kconfig index 911ee977103c0..8a640218eed84 100644 --- a/drivers/hwtracing/Kconfig +++ b/drivers/hwtracing/Kconfig @@ -7,4 +7,6 @@ source "drivers/hwtracing/intel_th/Kconfig" source "drivers/hwtracing/ptt/Kconfig" +source "drivers/hwtracing/qcom/Kconfig" + endmenu diff --git a/drivers/hwtracing/qcom/Kconfig b/drivers/hwtracing/qcom/Kconfig new file mode 100644 index 0000000000000..d6f6d4b0f28ed --- /dev/null +++ b/drivers/hwtracing/qcom/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# QCOM specific hwtracing drivers +# +menu "Qualcomm specific hwtracing drivers" + +config QCOM_TGU + tristate "QCOM Trigger Generation Unit driver" + help + This driver provides support for Trigger Generation Unit that is + used to detect patterns or sequences on a given set of signals. + TGU is used to monitor a particular bus within a given region to + detect illegal transaction sequences or slave responses. It is also + used to monitor a data stream to detect protocol violations and to + provide a trigger point for centering data around a specific event + within the trace data buffer. + +endmenu diff --git a/drivers/hwtracing/qcom/Makefile b/drivers/hwtracing/qcom/Makefile new file mode 100644 index 0000000000000..5a0a868c1ea0d --- /dev/null +++ b/drivers/hwtracing/qcom/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_QCOM_TGU) += tgu.o diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c new file mode 100644 index 0000000000000..c5b2b384e6aeb --- /dev/null +++ b/drivers/hwtracing/qcom/tgu.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tgu.h" + +static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) +{ + TGU_UNLOCK(drvdata->base); + /* Enable TGU to program the triggers */ + writel(1, drvdata->base + TGU_CONTROL); + TGU_LOCK(drvdata->base); +} + +static int tgu_enable(struct device *dev) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + + guard(spinlock)(&drvdata->lock); + if (drvdata->enable) + return -EBUSY; + + tgu_write_all_hw_regs(drvdata); + drvdata->enable = true; + + return 0; +} + +static void tgu_disable(struct device *dev) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + + guard(spinlock)(&drvdata->lock); + if (drvdata->enable) { + TGU_UNLOCK(drvdata->base); + writel(0, drvdata->base + TGU_CONTROL); + TGU_LOCK(drvdata->base); + + drvdata->enable = false; + } +} + +static ssize_t enable_tgu_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + bool enabled; + + guard(spinlock)(&drvdata->lock); + enabled = drvdata->enable; + + return sysfs_emit(buf, "%d\n", enabled ? 1 : 0); +} + +/* enable_tgu_store - Configure Trace and Gating Unit (TGU) triggers. */ +static ssize_t enable_tgu_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + unsigned long val; + int ret = 0; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + if (val) { + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + ret = tgu_enable(dev); + if (ret) { + pm_runtime_put(dev); + return ret; + } + } else { + tgu_disable(dev); + pm_runtime_put(dev); + } + + return size; +} +static DEVICE_ATTR_RW(enable_tgu); + +static struct attribute *tgu_common_attrs[] = { + &dev_attr_enable_tgu.attr, + NULL, +}; + +static const struct attribute_group tgu_common_grp = { + .attrs = tgu_common_attrs, + NULL, +}; + +static const struct attribute_group *tgu_attr_groups[] = { + &tgu_common_grp, + NULL, +}; + +static int tgu_probe(struct amba_device *adev, const struct amba_id *id) +{ + struct device *dev = &adev->dev; + struct tgu_drvdata *drvdata; + int ret; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + drvdata->base = devm_ioremap_resource(dev, &adev->res); + if (IS_ERR(drvdata->base)) + return PTR_ERR(drvdata->base); + + spin_lock_init(&drvdata->lock); + + ret = sysfs_create_groups(&dev->kobj, tgu_attr_groups); + if (ret) { + dev_err(dev, "failed to create sysfs groups: %d\n", ret); + return ret; + } + + drvdata->enable = false; + + pm_runtime_put(&adev->dev); + return 0; +} + +static void tgu_remove(struct amba_device *adev) +{ + struct device *dev = &adev->dev; + + sysfs_remove_groups(&dev->kobj, tgu_attr_groups); + + tgu_disable(dev); +} + +static const struct amba_id tgu_ids[] = { + { + .id = 0x000f0e00, + .mask = 0x000fffff, + }, + { 0, 0, NULL }, +}; + +MODULE_DEVICE_TABLE(amba, tgu_ids); + +static struct amba_driver tgu_driver = { + .drv = { + .name = "qcom-tgu", + .suppress_bind_attrs = true, + }, + .probe = tgu_probe, + .remove = tgu_remove, + .id_table = tgu_ids, +}; + +module_amba_driver(tgu_driver); + +MODULE_AUTHOR("Songwei Chai "); +MODULE_AUTHOR("Jinlong Mao "); +MODULE_DESCRIPTION("Qualcomm Trigger Generation Unit driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h new file mode 100644 index 0000000000000..b11cfb28261de --- /dev/null +++ b/drivers/hwtracing/qcom/tgu.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _QCOM_TGU_H +#define _QCOM_TGU_H + +/* Register addresses */ +#define TGU_CONTROL 0x0000 +#define TGU_LAR 0xfb0 +#define TGU_UNLOCK_OFFSET 0xc5acce55 + +static inline void TGU_LOCK(void __iomem *addr) +{ + do { + /* Wait for things to settle */ + mb(); + writel_relaxed(0x0, addr + TGU_LAR); + } while (0); +} + +static inline void TGU_UNLOCK(void __iomem *addr) +{ + do { + writel_relaxed(TGU_UNLOCK_OFFSET, addr + TGU_LAR); + /* Make sure everyone has seen this */ + mb(); + } while (0); +} + +/** + * struct tgu_drvdata - Data structure for a TGU (Trigger Generator Unit) + * @base: Memory-mapped base address of the TGU device + * @dev: Pointer to the associated device structure + * @lock: Spinlock for handling concurrent access + * @enable: Flag indicating whether the TGU device is enabled + * + * This structure defines the data associated with a TGU device, + * including its base address, device pointers, clock, spinlock for + * synchronization, trigger data pointers, maximum limits for various + * trigger-related parameters, and enable status. + */ +struct tgu_drvdata { + void __iomem *base; + struct device *dev; + spinlock_t lock; + bool enable; +}; + +#endif From 2e1075d731555fcdc5cfe99ab047065eeb840ef7 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:37 -0800 Subject: [PATCH 141/438] FROMLIST: qcom-tgu: Add signal priority support Like circuit of a Logic analyzer, in TGU, the requirement could be configured in each step and the trigger will be created once the requirements are met. Add priority functionality here to sort the signals into different priorities. The signal which is wanted could be configured in each step's priority node, the larger number means the higher priority and the signal with higher priority will be sensed more preferentially. Link: https://lore.kernel.org/all/20260109021141.3778421-4-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../ABI/testing/sysfs-bus-amba-devices-tgu | 7 + drivers/hwtracing/qcom/tgu.c | 160 ++++++++++++++++++ drivers/hwtracing/qcom/tgu.h | 113 +++++++++++++ 3 files changed, 280 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu index 56ec3f5ab5d65..ec630e6ff2ee3 100644 --- a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu @@ -7,3 +7,10 @@ Description: Accepts only one of the 2 values - 0 or 1. 0 : disable TGU. 1 : enable TGU. + +What: /sys/bus/amba/devices//step[0:7]_priority[0:3]/reg[0:17] +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the sensed signal with specific step and priority for TGU. diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c index c5b2b384e6aeb..f8870766d624d 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -14,14 +14,120 @@ #include "tgu.h" +static int calculate_array_location(struct tgu_drvdata *drvdata, + int step_index, int operation_index, + int reg_index) +{ + return operation_index * (drvdata->max_step) * (drvdata->max_reg) + + step_index * (drvdata->max_reg) + reg_index; +} + +static ssize_t tgu_dataset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + struct tgu_attribute *tgu_attr = + container_of(attr, struct tgu_attribute, attr); + int index; + + index = calculate_array_location(drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num); + + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->priority[index]); +} + +static ssize_t tgu_dataset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct tgu_drvdata *tgu_drvdata = dev_get_drvdata(dev); + struct tgu_attribute *tgu_attr = + container_of(attr, struct tgu_attribute, attr); + unsigned long val; + int index; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + guard(spinlock)(&tgu_drvdata->lock); + index = calculate_array_location(tgu_drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num); + + tgu_drvdata->value_table->priority[index] = val; + return size; +} + +static umode_t tgu_node_visible(struct kobject *kobject, + struct attribute *attr, + int n) +{ + struct device *dev = kobj_to_dev(kobject); + struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + struct device_attribute *dev_attr = + container_of(attr, struct device_attribute, attr); + struct tgu_attribute *tgu_attr = + container_of(dev_attr, struct tgu_attribute, attr); + int ret = SYSFS_GROUP_INVISIBLE; + + if (tgu_attr->step_index < drvdata->max_step) { + ret = (tgu_attr->reg_num < drvdata->max_reg) ? + attr->mode : 0; + } + return ret; +} + static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) { + int i, j, k, index; + TGU_UNLOCK(drvdata->base); + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < MAX_PRIORITY; j++) { + for (k = 0; k < drvdata->max_reg; k++) { + index = calculate_array_location( + drvdata, i, j, k); + + writel(drvdata->value_table->priority[index], + drvdata->base + + PRIORITY_REG_STEP(i, j, k)); + } + } + } /* Enable TGU to program the triggers */ writel(1, drvdata->base + TGU_CONTROL); TGU_LOCK(drvdata->base); } +static void tgu_set_reg_number(struct tgu_drvdata *drvdata) +{ + int num_sense_input; + int num_reg; + u32 devid; + + devid = readl(drvdata->base + TGU_DEVID); + + num_sense_input = TGU_DEVID_SENSE_INPUT(devid); + if (((num_sense_input * NUMBER_BITS_EACH_SIGNAL) % LENGTH_REGISTER) == 0) + num_reg = (num_sense_input * NUMBER_BITS_EACH_SIGNAL) / LENGTH_REGISTER; + else + num_reg = ((num_sense_input * NUMBER_BITS_EACH_SIGNAL) / LENGTH_REGISTER) + 1; + drvdata->max_reg = num_reg; + +} + +static void tgu_set_steps(struct tgu_drvdata *drvdata) +{ + u32 devid; + + devid = readl(drvdata->base + TGU_DEVID); + + drvdata->max_step = TGU_DEVID_STEPS(devid); +} + static int tgu_enable(struct device *dev) { struct tgu_drvdata *drvdata = dev_get_drvdata(dev); @@ -105,6 +211,38 @@ static const struct attribute_group tgu_common_grp = { static const struct attribute_group *tgu_attr_groups[] = { &tgu_common_grp, + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 3), NULL, }; @@ -112,6 +250,8 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct tgu_drvdata *drvdata; + size_t priority_size; + unsigned int *priority; int ret; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -127,12 +267,32 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->lock); + tgu_set_reg_number(drvdata); + tgu_set_steps(drvdata); + ret = sysfs_create_groups(&dev->kobj, tgu_attr_groups); if (ret) { dev_err(dev, "failed to create sysfs groups: %d\n", ret); return ret; } + drvdata->value_table = + devm_kzalloc(dev, sizeof(*drvdata->value_table), GFP_KERNEL); + if (!drvdata->value_table) + return -ENOMEM; + + priority_size = MAX_PRIORITY * drvdata->max_reg * + drvdata->max_step * + sizeof(*(drvdata->value_table->priority)); + + priority = devm_kzalloc(dev, priority_size, GFP_KERNEL); + + if (!priority) + return -ENOMEM; + + drvdata->value_table->priority = priority; + + drvdata->enable = false; pm_runtime_put(&adev->dev); diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index b11cfb28261de..f54cea01e4275 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -10,6 +10,113 @@ #define TGU_CONTROL 0x0000 #define TGU_LAR 0xfb0 #define TGU_UNLOCK_OFFSET 0xc5acce55 +#define TGU_DEVID 0xfc8 + +#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) +#define TGU_DEVID_SENSE_INPUT(devid_val) ((int) BMVAL(devid_val, 10, 17)) +#define TGU_DEVID_STEPS(devid_val) ((int)BMVAL(devid_val, 3, 6)) +#define NUMBER_BITS_EACH_SIGNAL 4 +#define LENGTH_REGISTER 32 + +/* + * TGU configuration space Step configuration + * offset table space layout + * x-------------------------x$ x-------------x$ + * | |$ | |$ + * | | | reserve |$ + * | | | |$ + * |coresight management | |-------------|base+n*0x1D8+0x1F4$ + * | registe | |---> |prioroty[3] |$ + * | | | |-------------|base+n*0x1D8+0x194$ + * | | | |prioroty[2] |$ + * |-------------------------| | |-------------|base+n*0x1D8+0x134$ + * | | | |prioroty[1] |$ + * | step[7] | | |-------------|base+n*0x1D8+0xD4$ + * |-------------------------|->base+0x40+7*0x1D8 | |prioroty[0] |$ + * | | | |-------------|base+n*0x1D8+0x74$ + * | ... | | | condition |$ + * | | | | select |$ + * |-------------------------|->base+0x40+1*0x1D8 | |-------------|base+n*0x1D8+0x60$ + * | | | | condition |$ + * | step[0] |--------------------> | decode |$ + * |-------------------------|-> base+0x40 |-------------|base+n*0x1D8+0x50$ + * | | | |$ + * | Control and status space| |Timer/Counter|$ + * | space | | |$ + * x-------------------------x->base x-------------x base+n*0x1D8+0x40$ + * + */ +#define STEP_OFFSET 0x1D8 +#define PRIORITY_START_OFFSET 0x0074 +#define PRIORITY_OFFSET 0x60 +#define REG_OFFSET 0x4 + +/* Calculate compare step addresses */ +#define PRIORITY_REG_STEP(step, priority, reg)\ + (PRIORITY_START_OFFSET + PRIORITY_OFFSET * priority +\ + REG_OFFSET * reg + STEP_OFFSET * step) + +#define tgu_dataset_rw(name, step_index, type, reg_num) \ + (&((struct tgu_attribute[]){ { \ + __ATTR(name, 0644, tgu_dataset_show, tgu_dataset_store), \ + step_index, \ + type, \ + reg_num, \ + } })[0].attr.attr) + +#define STEP_PRIORITY(step_index, reg_num, priority) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_PRIORITY##priority, \ + reg_num) + +#define STEP_PRIORITY_LIST(step_index, priority) \ + {STEP_PRIORITY(step_index, 0, priority), \ + STEP_PRIORITY(step_index, 1, priority), \ + STEP_PRIORITY(step_index, 2, priority), \ + STEP_PRIORITY(step_index, 3, priority), \ + STEP_PRIORITY(step_index, 4, priority), \ + STEP_PRIORITY(step_index, 5, priority), \ + STEP_PRIORITY(step_index, 6, priority), \ + STEP_PRIORITY(step_index, 7, priority), \ + STEP_PRIORITY(step_index, 8, priority), \ + STEP_PRIORITY(step_index, 9, priority), \ + STEP_PRIORITY(step_index, 10, priority), \ + STEP_PRIORITY(step_index, 11, priority), \ + STEP_PRIORITY(step_index, 12, priority), \ + STEP_PRIORITY(step_index, 13, priority), \ + STEP_PRIORITY(step_index, 14, priority), \ + STEP_PRIORITY(step_index, 15, priority), \ + STEP_PRIORITY(step_index, 16, priority), \ + STEP_PRIORITY(step_index, 17, priority), \ + NULL \ + } + +#define PRIORITY_ATTRIBUTE_GROUP_INIT(step, priority)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_PRIORITY_LIST(step, priority),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_priority" #priority \ + }) + +enum operation_index { + TGU_PRIORITY0, + TGU_PRIORITY1, + TGU_PRIORITY2, + TGU_PRIORITY3, +}; + +/* Maximum priority that TGU supports */ +#define MAX_PRIORITY 4 + +struct tgu_attribute { + struct device_attribute attr; + u32 step_index; + enum operation_index operation_index; + u32 reg_num; +}; + +struct value_table { + unsigned int *priority; +}; static inline void TGU_LOCK(void __iomem *addr) { @@ -35,6 +142,9 @@ static inline void TGU_UNLOCK(void __iomem *addr) * @dev: Pointer to the associated device structure * @lock: Spinlock for handling concurrent access * @enable: Flag indicating whether the TGU device is enabled + * @value_table: Store given value based on relevant parameters. + * @max_reg: Maximum number of registers + * @max_step: Maximum step size * * This structure defines the data associated with a TGU device, * including its base address, device pointers, clock, spinlock for @@ -46,6 +156,9 @@ struct tgu_drvdata { struct device *dev; spinlock_t lock; bool enable; + struct value_table *value_table; + int max_reg; + int max_step; }; #endif From a37658f93c66ae23e44df96570b7b7314f8580ee Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:38 -0800 Subject: [PATCH 142/438] FROMLIST: qcom-tgu: Add TGU decode support Decoding is when all the potential pieces for creating a trigger are brought together for a given step. Example - there may be a counter keeping track of some occurrences and a priority-group that is being used to detect a pattern on the sense inputs. These 2 inputs to condition_decode must be programmed, for a given step, to establish the condition for the trigger, or movement to another steps. Link: https://lore.kernel.org/all/20260109021141.3778421-5-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../ABI/testing/sysfs-bus-amba-devices-tgu | 7 + drivers/hwtracing/qcom/tgu.c | 162 ++++++++++++++++-- drivers/hwtracing/qcom/tgu.h | 27 +++ 3 files changed, 177 insertions(+), 19 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu index ec630e6ff2ee3..4efa36a11d8ee 100644 --- a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu @@ -14,3 +14,10 @@ KernelVersion 6.19 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the sensed signal with specific step and priority for TGU. + +What: /sys/bus/amba/devices//step[0:7]_condition_decode/reg[0:3] +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the decode mode with specific step for TGU. diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c index f8870766d624d..39301d35ee9df 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -18,8 +18,36 @@ static int calculate_array_location(struct tgu_drvdata *drvdata, int step_index, int operation_index, int reg_index) { - return operation_index * (drvdata->max_step) * (drvdata->max_reg) + - step_index * (drvdata->max_reg) + reg_index; + int ret = -EINVAL; + + switch (operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + ret = operation_index * (drvdata->max_step) * + (drvdata->max_reg) + + step_index * (drvdata->max_reg) + reg_index; + break; + case TGU_CONDITION_DECODE: + ret = step_index * (drvdata->max_condition_decode) + + reg_index; + break; + default: + break; + } + return ret; +} + +static int check_array_location(struct tgu_drvdata *drvdata, int step, + int ops, int reg) +{ + int result = calculate_array_location(drvdata, step, ops, reg); + + if (result == -EINVAL) + dev_err(drvdata->dev, "%s - Fail\n", __func__); + + return result; } static ssize_t tgu_dataset_show(struct device *dev, @@ -30,12 +58,26 @@ static ssize_t tgu_dataset_show(struct device *dev, container_of(attr, struct tgu_attribute, attr); int index; - index = calculate_array_location(drvdata, tgu_attr->step_index, - tgu_attr->operation_index, - tgu_attr->reg_num); - - return sysfs_emit(buf, "0x%x\n", - drvdata->value_table->priority[index]); + index = check_array_location(drvdata, tgu_attr->step_index, + tgu_attr->operation_index, tgu_attr->reg_num); + + if (index == -EINVAL) + return index; + + switch (tgu_attr->operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->priority[index]); + case TGU_CONDITION_DECODE: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->condition_decode[index]); + default: + break; + } + return -EINVAL; } static ssize_t tgu_dataset_store(struct device *dev, @@ -47,18 +89,37 @@ static ssize_t tgu_dataset_store(struct device *dev, container_of(attr, struct tgu_attribute, attr); unsigned long val; int index; + int ret; ret = kstrtoul(buf, 0, &val); if (ret) return ret; guard(spinlock)(&tgu_drvdata->lock); - index = calculate_array_location(tgu_drvdata, tgu_attr->step_index, + index = check_array_location(tgu_drvdata, tgu_attr->step_index, tgu_attr->operation_index, tgu_attr->reg_num); - tgu_drvdata->value_table->priority[index] = val; - return size; + if (index == -EINVAL) + return -EINVAL; + + switch (tgu_attr->operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + tgu_drvdata->value_table->priority[index] = val; + ret = size; + break; + case TGU_CONDITION_DECODE: + tgu_drvdata->value_table->condition_decode[index] = val; + ret = size; + break; + default: + ret = -EINVAL; + break; + } + return ret; } static umode_t tgu_node_visible(struct kobject *kobject, @@ -74,13 +135,27 @@ static umode_t tgu_node_visible(struct kobject *kobject, int ret = SYSFS_GROUP_INVISIBLE; if (tgu_attr->step_index < drvdata->max_step) { - ret = (tgu_attr->reg_num < drvdata->max_reg) ? - attr->mode : 0; + switch (tgu_attr->operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + ret = (tgu_attr->reg_num < drvdata->max_reg) ? + attr->mode : 0; + break; + case TGU_CONDITION_DECODE: + ret = (tgu_attr->reg_num < + drvdata->max_condition_decode) ? + attr->mode : 0; + break; + default: + break; + } } return ret; } -static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) +static ssize_t tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) { int i, j, k, index; @@ -88,8 +163,10 @@ static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) for (i = 0; i < drvdata->max_step; i++) { for (j = 0; j < MAX_PRIORITY; j++) { for (k = 0; k < drvdata->max_reg; k++) { - index = calculate_array_location( + index = check_array_location( drvdata, i, j, k); + if (index == -EINVAL) + goto exit; writel(drvdata->value_table->priority[index], drvdata->base + @@ -97,9 +174,23 @@ static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) } } } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_condition_decode; j++) { + index = check_array_location(drvdata, i, + TGU_CONDITION_DECODE, j); + if (index == -EINVAL) + goto exit; + + writel(drvdata->value_table->condition_decode[index], + drvdata->base + CONDITION_DECODE_STEP(i, j)); + } + } /* Enable TGU to program the triggers */ writel(1, drvdata->base + TGU_CONTROL); +exit: TGU_LOCK(drvdata->base); + return index >= 0 ? 0 : -EINVAL; } static void tgu_set_reg_number(struct tgu_drvdata *drvdata) @@ -128,18 +219,32 @@ static void tgu_set_steps(struct tgu_drvdata *drvdata) drvdata->max_step = TGU_DEVID_STEPS(devid); } +static void tgu_set_conditions(struct tgu_drvdata *drvdata) +{ + u32 devid; + + devid = readl(drvdata->base + TGU_DEVID); + drvdata->max_condition_decode = TGU_DEVID_CONDITIONS(devid); +} + static int tgu_enable(struct device *dev) { struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + int ret = 0; guard(spinlock)(&drvdata->lock); if (drvdata->enable) return -EBUSY; - tgu_write_all_hw_regs(drvdata); + ret = tgu_write_all_hw_regs(drvdata); + + if (ret == -EINVAL) + goto exit; + drvdata->enable = true; - return 0; +exit: + return ret; } static void tgu_disable(struct device *dev) @@ -243,6 +348,14 @@ static const struct attribute_group *tgu_attr_groups[] = { PRIORITY_ATTRIBUTE_GROUP_INIT(7, 1), PRIORITY_ATTRIBUTE_GROUP_INIT(7, 2), PRIORITY_ATTRIBUTE_GROUP_INIT(7, 3), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(0), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(1), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(2), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(3), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(4), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(5), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(6), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(7), NULL, }; @@ -250,8 +363,8 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct tgu_drvdata *drvdata; - size_t priority_size; - unsigned int *priority; + size_t priority_size, condition_size; + unsigned int *priority, *condition; int ret; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -269,6 +382,7 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) tgu_set_reg_number(drvdata); tgu_set_steps(drvdata); + tgu_set_conditions(drvdata); ret = sysfs_create_groups(&dev->kobj, tgu_attr_groups); if (ret) { @@ -292,6 +406,16 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) drvdata->value_table->priority = priority; + condition_size = drvdata->max_condition_decode * + drvdata->max_step * + sizeof(*(drvdata->value_table->condition_decode)); + + condition = devm_kzalloc(dev, condition_size, GFP_KERNEL); + + if (!condition) + return -ENOMEM; + + drvdata->value_table->condition_decode = condition; drvdata->enable = false; diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index f54cea01e4275..0d058663aca50 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -15,6 +15,7 @@ #define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) #define TGU_DEVID_SENSE_INPUT(devid_val) ((int) BMVAL(devid_val, 10, 17)) #define TGU_DEVID_STEPS(devid_val) ((int)BMVAL(devid_val, 3, 6)) +#define TGU_DEVID_CONDITIONS(devid_val) ((int)BMVAL(devid_val, 0, 2)) #define NUMBER_BITS_EACH_SIGNAL 4 #define LENGTH_REGISTER 32 @@ -48,6 +49,7 @@ */ #define STEP_OFFSET 0x1D8 #define PRIORITY_START_OFFSET 0x0074 +#define CONDITION_DECODE_OFFSET 0x0050 #define PRIORITY_OFFSET 0x60 #define REG_OFFSET 0x4 @@ -56,6 +58,9 @@ (PRIORITY_START_OFFSET + PRIORITY_OFFSET * priority +\ REG_OFFSET * reg + STEP_OFFSET * step) +#define CONDITION_DECODE_STEP(step, decode) \ + (CONDITION_DECODE_OFFSET + REG_OFFSET * decode + STEP_OFFSET * step) + #define tgu_dataset_rw(name, step_index, type, reg_num) \ (&((struct tgu_attribute[]){ { \ __ATTR(name, 0644, tgu_dataset_show, tgu_dataset_store), \ @@ -68,6 +73,9 @@ tgu_dataset_rw(reg##reg_num, step_index, TGU_PRIORITY##priority, \ reg_num) +#define STEP_DECODE(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_CONDITION_DECODE, reg_num) + #define STEP_PRIORITY_LIST(step_index, priority) \ {STEP_PRIORITY(step_index, 0, priority), \ STEP_PRIORITY(step_index, 1, priority), \ @@ -90,6 +98,14 @@ NULL \ } +#define STEP_DECODE_LIST(n) \ + {STEP_DECODE(n, 0), \ + STEP_DECODE(n, 1), \ + STEP_DECODE(n, 2), \ + STEP_DECODE(n, 3), \ + NULL \ + } + #define PRIORITY_ATTRIBUTE_GROUP_INIT(step, priority)\ (&(const struct attribute_group){\ .attrs = (struct attribute*[])STEP_PRIORITY_LIST(step, priority),\ @@ -97,11 +113,19 @@ .name = "step" #step "_priority" #priority \ }) +#define CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_DECODE_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_condition_decode" \ + }) + enum operation_index { TGU_PRIORITY0, TGU_PRIORITY1, TGU_PRIORITY2, TGU_PRIORITY3, + TGU_CONDITION_DECODE, }; /* Maximum priority that TGU supports */ @@ -116,6 +140,7 @@ struct tgu_attribute { struct value_table { unsigned int *priority; + unsigned int *condition_decode; }; static inline void TGU_LOCK(void __iomem *addr) @@ -145,6 +170,7 @@ static inline void TGU_UNLOCK(void __iomem *addr) * @value_table: Store given value based on relevant parameters. * @max_reg: Maximum number of registers * @max_step: Maximum step size + * @max_condition_decode: Maximum number of condition_decode * * This structure defines the data associated with a TGU device, * including its base address, device pointers, clock, spinlock for @@ -159,6 +185,7 @@ struct tgu_drvdata { struct value_table *value_table; int max_reg; int max_step; + int max_condition_decode; }; #endif From 14dd529fd0b72f8a6fc3871c7c4bef84fff72383 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:39 -0800 Subject: [PATCH 143/438] FROMLIST: qcom-tgu: Add support to configure next action Add "select" node for each step to determine if another step is taken, trigger(s) are generated, counters/timers incremented/decremented, etc. Link: https://lore.kernel.org/all/20260109021141.3778421-6-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../ABI/testing/sysfs-bus-amba-devices-tgu | 7 +++ drivers/hwtracing/qcom/tgu.c | 57 ++++++++++++++++++- drivers/hwtracing/qcom/tgu.h | 27 +++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu index 4efa36a11d8ee..fffe65d3c0db5 100644 --- a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu @@ -21,3 +21,10 @@ KernelVersion 6.19 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the decode mode with specific step for TGU. + +What: /sys/bus/amba/devices//step[0:7]_condition_select/reg[0:3] +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the next action with specific step for TGU. diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c index 39301d35ee9df..e1a1f0f423bab 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -33,6 +33,10 @@ static int calculate_array_location(struct tgu_drvdata *drvdata, ret = step_index * (drvdata->max_condition_decode) + reg_index; break; + case TGU_CONDITION_SELECT: + ret = step_index * (drvdata->max_condition_select) + + reg_index; + break; default: break; } @@ -74,6 +78,9 @@ static ssize_t tgu_dataset_show(struct device *dev, case TGU_CONDITION_DECODE: return sysfs_emit(buf, "0x%x\n", drvdata->value_table->condition_decode[index]); + case TGU_CONDITION_SELECT: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->condition_select[index]); default: break; } @@ -115,6 +122,10 @@ static ssize_t tgu_dataset_store(struct device *dev, tgu_drvdata->value_table->condition_decode[index] = val; ret = size; break; + case TGU_CONDITION_SELECT: + tgu_drvdata->value_table->condition_select[index] = val; + ret = size; + break; default: ret = -EINVAL; break; @@ -148,6 +159,15 @@ static umode_t tgu_node_visible(struct kobject *kobject, drvdata->max_condition_decode) ? attr->mode : 0; break; + case TGU_CONDITION_SELECT: + /* 'default' register is at the end of 'select' region */ + if (tgu_attr->reg_num == + drvdata->max_condition_select - 1) + attr->name = "default"; + ret = (tgu_attr->reg_num < + drvdata->max_condition_select) ? + attr->mode : 0; + break; default: break; } @@ -186,6 +206,19 @@ static ssize_t tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) drvdata->base + CONDITION_DECODE_STEP(i, j)); } } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_condition_select; j++) { + index = check_array_location(drvdata, i, + TGU_CONDITION_SELECT, j); + + if (index == -EINVAL) + goto exit; + + writel(drvdata->value_table->condition_select[index], + drvdata->base + CONDITION_SELECT_STEP(i, j)); + } + } /* Enable TGU to program the triggers */ writel(1, drvdata->base + TGU_CONTROL); exit: @@ -225,6 +258,8 @@ static void tgu_set_conditions(struct tgu_drvdata *drvdata) devid = readl(drvdata->base + TGU_DEVID); drvdata->max_condition_decode = TGU_DEVID_CONDITIONS(devid); + /* select region has an additional 'default' register */ + drvdata->max_condition_select = TGU_DEVID_CONDITIONS(devid) + 1; } static int tgu_enable(struct device *dev) @@ -356,6 +391,14 @@ static const struct attribute_group *tgu_attr_groups[] = { CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(5), CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(6), CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(7), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(0), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(1), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(2), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(3), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(4), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(5), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(6), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(7), NULL, }; @@ -363,8 +406,8 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct tgu_drvdata *drvdata; - size_t priority_size, condition_size; - unsigned int *priority, *condition; + size_t priority_size, condition_size, select_size; + unsigned int *priority, *condition, *select; int ret; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -417,6 +460,16 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) drvdata->value_table->condition_decode = condition; + select_size = drvdata->max_condition_select * drvdata->max_step * + sizeof(*(drvdata->value_table->condition_select)); + + select = devm_kzalloc(dev, select_size, GFP_KERNEL); + + if (!select) + return -ENOMEM; + + drvdata->value_table->condition_select = select; + drvdata->enable = false; pm_runtime_put(&adev->dev); diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index 0d058663aca50..8c92e88d7e2c9 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -50,6 +50,7 @@ #define STEP_OFFSET 0x1D8 #define PRIORITY_START_OFFSET 0x0074 #define CONDITION_DECODE_OFFSET 0x0050 +#define CONDITION_SELECT_OFFSET 0x0060 #define PRIORITY_OFFSET 0x60 #define REG_OFFSET 0x4 @@ -61,6 +62,9 @@ #define CONDITION_DECODE_STEP(step, decode) \ (CONDITION_DECODE_OFFSET + REG_OFFSET * decode + STEP_OFFSET * step) +#define CONDITION_SELECT_STEP(step, select) \ + (CONDITION_SELECT_OFFSET + REG_OFFSET * select + STEP_OFFSET * step) + #define tgu_dataset_rw(name, step_index, type, reg_num) \ (&((struct tgu_attribute[]){ { \ __ATTR(name, 0644, tgu_dataset_show, tgu_dataset_store), \ @@ -76,6 +80,9 @@ #define STEP_DECODE(step_index, reg_num) \ tgu_dataset_rw(reg##reg_num, step_index, TGU_CONDITION_DECODE, reg_num) +#define STEP_SELECT(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_CONDITION_SELECT, reg_num) + #define STEP_PRIORITY_LIST(step_index, priority) \ {STEP_PRIORITY(step_index, 0, priority), \ STEP_PRIORITY(step_index, 1, priority), \ @@ -106,6 +113,15 @@ NULL \ } +#define STEP_SELECT_LIST(n) \ + {STEP_SELECT(n, 0), \ + STEP_SELECT(n, 1), \ + STEP_SELECT(n, 2), \ + STEP_SELECT(n, 3), \ + STEP_SELECT(n, 4), \ + NULL \ + } + #define PRIORITY_ATTRIBUTE_GROUP_INIT(step, priority)\ (&(const struct attribute_group){\ .attrs = (struct attribute*[])STEP_PRIORITY_LIST(step, priority),\ @@ -120,12 +136,20 @@ .name = "step" #step "_condition_decode" \ }) +#define CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_SELECT_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_condition_select" \ + }) + enum operation_index { TGU_PRIORITY0, TGU_PRIORITY1, TGU_PRIORITY2, TGU_PRIORITY3, TGU_CONDITION_DECODE, + TGU_CONDITION_SELECT, }; /* Maximum priority that TGU supports */ @@ -141,6 +165,7 @@ struct tgu_attribute { struct value_table { unsigned int *priority; unsigned int *condition_decode; + unsigned int *condition_select; }; static inline void TGU_LOCK(void __iomem *addr) @@ -171,6 +196,7 @@ static inline void TGU_UNLOCK(void __iomem *addr) * @max_reg: Maximum number of registers * @max_step: Maximum step size * @max_condition_decode: Maximum number of condition_decode + * @max_condition_select: Maximum number of condition_select * * This structure defines the data associated with a TGU device, * including its base address, device pointers, clock, spinlock for @@ -186,6 +212,7 @@ struct tgu_drvdata { int max_reg; int max_step; int max_condition_decode; + int max_condition_select; }; #endif From 800dd3e52a9597a4f77402954e22ce374756e160 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:40 -0800 Subject: [PATCH 144/438] FROMLIST: qcom-tgu: Add timer/counter functionality for TGU Add counter and timer node for each step which could be programed if they are to be utilized in trigger event/sequence. Link: https://lore.kernel.org/all/20260109021141.3778421-7-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../ABI/testing/sysfs-bus-amba-devices-tgu | 14 ++ drivers/hwtracing/qcom/tgu.c | 126 +++++++++++++++++- drivers/hwtracing/qcom/tgu.h | 54 ++++++++ 3 files changed, 192 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu index fffe65d3c0db5..61b5a08bdee17 100644 --- a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu @@ -28,3 +28,17 @@ KernelVersion 6.19 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the next action with specific step for TGU. + +What: /sys/bus/amba/devices//step[0:7]_timer/reg[0:1] +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the timer value with specific step for TGU. + +What: /sys/bus/amba/devices//step[0:7]_counter/reg[0:1] +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the counter value with specific step for TGU. diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c index e1a1f0f423bab..a3d9c3c4e28a9 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -37,6 +37,12 @@ static int calculate_array_location(struct tgu_drvdata *drvdata, ret = step_index * (drvdata->max_condition_select) + reg_index; break; + case TGU_COUNTER: + ret = step_index * (drvdata->max_counter) + reg_index; + break; + case TGU_TIMER: + ret = step_index * (drvdata->max_timer) + reg_index; + break; default: break; } @@ -81,6 +87,12 @@ static ssize_t tgu_dataset_show(struct device *dev, case TGU_CONDITION_SELECT: return sysfs_emit(buf, "0x%x\n", drvdata->value_table->condition_select[index]); + case TGU_TIMER: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->timer[index]); + case TGU_COUNTER: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->counter[index]); default: break; } @@ -126,6 +138,14 @@ static ssize_t tgu_dataset_store(struct device *dev, tgu_drvdata->value_table->condition_select[index] = val; ret = size; break; + case TGU_TIMER: + tgu_drvdata->value_table->timer[index] = val; + ret = size; + break; + case TGU_COUNTER: + tgu_drvdata->value_table->counter[index] = val; + ret = size; + break; default: ret = -EINVAL; break; @@ -168,6 +188,22 @@ static umode_t tgu_node_visible(struct kobject *kobject, drvdata->max_condition_select) ? attr->mode : 0; break; + case TGU_COUNTER: + if (drvdata->max_counter == 0) + ret = SYSFS_GROUP_INVISIBLE; + else + ret = (tgu_attr->reg_num < + drvdata->max_counter) ? + attr->mode : 0; + break; + case TGU_TIMER: + if (drvdata->max_timer == 0) + ret = SYSFS_GROUP_INVISIBLE; + else + ret = (tgu_attr->reg_num < + drvdata->max_timer) ? + attr->mode : 0; + break; default: break; } @@ -219,6 +255,30 @@ static ssize_t tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) drvdata->base + CONDITION_SELECT_STEP(i, j)); } } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_timer; j++) { + index = check_array_location(drvdata, i, TGU_TIMER, j); + + if (index == -EINVAL) + goto exit; + + writel(drvdata->value_table->timer[index], + drvdata->base + TIMER_COMPARE_STEP(i, j)); + } + } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_counter; j++) { + index = check_array_location(drvdata, i, TGU_COUNTER, j); + + if (index == -EINVAL) + goto exit; + + writel(drvdata->value_table->counter[index], + drvdata->base + COUNTER_COMPARE_STEP(i, j)); + } + } /* Enable TGU to program the triggers */ writel(1, drvdata->base + TGU_CONTROL); exit: @@ -262,6 +322,31 @@ static void tgu_set_conditions(struct tgu_drvdata *drvdata) drvdata->max_condition_select = TGU_DEVID_CONDITIONS(devid) + 1; } +static void tgu_set_timer_counter(struct tgu_drvdata *drvdata) +{ + int num_timers, num_counters; + u32 devid2; + + devid2 = readl(drvdata->base + CORESIGHT_DEVID2); + + if (TGU_DEVID2_TIMER0(devid2) && TGU_DEVID2_TIMER1(devid2)) + num_timers = 2; + else if (TGU_DEVID2_TIMER0(devid2) || TGU_DEVID2_TIMER1(devid2)) + num_timers = 1; + else + num_timers = 0; + + if (TGU_DEVID2_COUNTER0(devid2) && TGU_DEVID2_COUNTER1(devid2)) + num_counters = 2; + else if (TGU_DEVID2_COUNTER0(devid2) || TGU_DEVID2_COUNTER1(devid2)) + num_counters = 1; + else + num_counters = 0; + + drvdata->max_timer = num_timers; + drvdata->max_counter = num_counters; +} + static int tgu_enable(struct device *dev) { struct tgu_drvdata *drvdata = dev_get_drvdata(dev); @@ -399,6 +484,22 @@ static const struct attribute_group *tgu_attr_groups[] = { CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(5), CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(6), CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(7), + TIMER_ATTRIBUTE_GROUP_INIT(0), + TIMER_ATTRIBUTE_GROUP_INIT(1), + TIMER_ATTRIBUTE_GROUP_INIT(2), + TIMER_ATTRIBUTE_GROUP_INIT(3), + TIMER_ATTRIBUTE_GROUP_INIT(4), + TIMER_ATTRIBUTE_GROUP_INIT(5), + TIMER_ATTRIBUTE_GROUP_INIT(6), + TIMER_ATTRIBUTE_GROUP_INIT(7), + COUNTER_ATTRIBUTE_GROUP_INIT(0), + COUNTER_ATTRIBUTE_GROUP_INIT(1), + COUNTER_ATTRIBUTE_GROUP_INIT(2), + COUNTER_ATTRIBUTE_GROUP_INIT(3), + COUNTER_ATTRIBUTE_GROUP_INIT(4), + COUNTER_ATTRIBUTE_GROUP_INIT(5), + COUNTER_ATTRIBUTE_GROUP_INIT(6), + COUNTER_ATTRIBUTE_GROUP_INIT(7), NULL, }; @@ -406,8 +507,8 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct tgu_drvdata *drvdata; - size_t priority_size, condition_size, select_size; - unsigned int *priority, *condition, *select; + size_t priority_size, condition_size, select_size, timer_size, counter_size; + unsigned int *priority, *condition, *select, *timer, *counter; int ret; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -426,6 +527,7 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) tgu_set_reg_number(drvdata); tgu_set_steps(drvdata); tgu_set_conditions(drvdata); + tgu_set_timer_counter(drvdata); ret = sysfs_create_groups(&dev->kobj, tgu_attr_groups); if (ret) { @@ -470,6 +572,26 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) drvdata->value_table->condition_select = select; + timer_size = drvdata->max_step * drvdata->max_timer * + sizeof(*(drvdata->value_table->timer)); + + timer = devm_kzalloc(dev, timer_size, GFP_KERNEL); + + if (!timer) + return -ENOMEM; + + drvdata->value_table->timer = timer; + + counter_size = drvdata->max_step * drvdata->max_counter * + sizeof(*(drvdata->value_table->counter)); + + counter = devm_kzalloc(dev, counter_size, GFP_KERNEL); + + if (!counter) + return -ENOMEM; + + drvdata->value_table->counter = counter; + drvdata->enable = false; pm_runtime_put(&adev->dev); diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index 8c92e88d7e2c9..94708750b02dd 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -11,11 +11,17 @@ #define TGU_LAR 0xfb0 #define TGU_UNLOCK_OFFSET 0xc5acce55 #define TGU_DEVID 0xfc8 +#define CORESIGHT_DEVID2 0xfc0 #define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) #define TGU_DEVID_SENSE_INPUT(devid_val) ((int) BMVAL(devid_val, 10, 17)) #define TGU_DEVID_STEPS(devid_val) ((int)BMVAL(devid_val, 3, 6)) #define TGU_DEVID_CONDITIONS(devid_val) ((int)BMVAL(devid_val, 0, 2)) +#define TGU_DEVID2_TIMER0(devid_val) ((int)BMVAL(devid_val, 18, 23)) +#define TGU_DEVID2_TIMER1(devid_val) ((int)BMVAL(devid_val, 13, 17)) +#define TGU_DEVID2_COUNTER0(devid_val) ((int)BMVAL(devid_val, 6, 11)) +#define TGU_DEVID2_COUNTER1(devid_val) ((int)BMVAL(devid_val, 0, 5)) + #define NUMBER_BITS_EACH_SIGNAL 4 #define LENGTH_REGISTER 32 @@ -51,6 +57,8 @@ #define PRIORITY_START_OFFSET 0x0074 #define CONDITION_DECODE_OFFSET 0x0050 #define CONDITION_SELECT_OFFSET 0x0060 +#define TIMER_START_OFFSET 0x0040 +#define COUNTER_START_OFFSET 0x0048 #define PRIORITY_OFFSET 0x60 #define REG_OFFSET 0x4 @@ -62,6 +70,12 @@ #define CONDITION_DECODE_STEP(step, decode) \ (CONDITION_DECODE_OFFSET + REG_OFFSET * decode + STEP_OFFSET * step) +#define TIMER_COMPARE_STEP(step, timer) \ + (TIMER_START_OFFSET + REG_OFFSET * timer + STEP_OFFSET * step) + +#define COUNTER_COMPARE_STEP(step, counter) \ + (COUNTER_START_OFFSET + REG_OFFSET * counter + STEP_OFFSET * step) + #define CONDITION_SELECT_STEP(step, select) \ (CONDITION_SELECT_OFFSET + REG_OFFSET * select + STEP_OFFSET * step) @@ -83,6 +97,12 @@ #define STEP_SELECT(step_index, reg_num) \ tgu_dataset_rw(reg##reg_num, step_index, TGU_CONDITION_SELECT, reg_num) +#define STEP_TIMER(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_TIMER, reg_num) + +#define STEP_COUNTER(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_COUNTER, reg_num) + #define STEP_PRIORITY_LIST(step_index, priority) \ {STEP_PRIORITY(step_index, 0, priority), \ STEP_PRIORITY(step_index, 1, priority), \ @@ -122,6 +142,18 @@ NULL \ } +#define STEP_TIMER_LIST(n) \ + {STEP_TIMER(n, 0), \ + STEP_TIMER(n, 1), \ + NULL \ + } + +#define STEP_COUNTER_LIST(n) \ + {STEP_COUNTER(n, 0), \ + STEP_COUNTER(n, 1), \ + NULL \ + } + #define PRIORITY_ATTRIBUTE_GROUP_INIT(step, priority)\ (&(const struct attribute_group){\ .attrs = (struct attribute*[])STEP_PRIORITY_LIST(step, priority),\ @@ -143,6 +175,20 @@ .name = "step" #step "_condition_select" \ }) +#define TIMER_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_TIMER_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_timer" \ + }) + +#define COUNTER_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_COUNTER_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_counter" \ + }) + enum operation_index { TGU_PRIORITY0, TGU_PRIORITY1, @@ -150,6 +196,8 @@ enum operation_index { TGU_PRIORITY3, TGU_CONDITION_DECODE, TGU_CONDITION_SELECT, + TGU_TIMER, + TGU_COUNTER }; /* Maximum priority that TGU supports */ @@ -166,6 +214,8 @@ struct value_table { unsigned int *priority; unsigned int *condition_decode; unsigned int *condition_select; + unsigned int *timer; + unsigned int *counter; }; static inline void TGU_LOCK(void __iomem *addr) @@ -197,6 +247,8 @@ static inline void TGU_UNLOCK(void __iomem *addr) * @max_step: Maximum step size * @max_condition_decode: Maximum number of condition_decode * @max_condition_select: Maximum number of condition_select + * @max_timer: Maximum number of timers + * @max_counter: Maximum number of counters * * This structure defines the data associated with a TGU device, * including its base address, device pointers, clock, spinlock for @@ -213,6 +265,8 @@ struct tgu_drvdata { int max_step; int max_condition_decode; int max_condition_select; + int max_timer; + int max_counter; }; #endif From 5e0f8da27b532c5a0b59ca72161e6ada069c8104 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Thu, 8 Jan 2026 18:11:41 -0800 Subject: [PATCH 145/438] FROMLIST: qcom-tgu: Add reset node to initialize Add reset node to initialize the value of priority/condition_decode/condition_select/timer/counter nodes. Link: https://lore.kernel.org/all/20260109021141.3778421-8-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../ABI/testing/sysfs-bus-amba-devices-tgu | 7 ++ drivers/hwtracing/qcom/tgu.c | 74 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu index 61b5a08bdee17..fa2618b31ab97 100644 --- a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu @@ -42,3 +42,10 @@ KernelVersion 6.19 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the counter value with specific step for TGU. + +What: /sys/bus/amba/devices//reset_tgu +Date: January 2026 +KernelVersion 6.19 +Contact: Jinlong Mao , Songwei Chai +Description: + (Write) Write 1 to reset the dataset for TGU. diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c index a3d9c3c4e28a9..0a45ff78858b8 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -424,8 +424,82 @@ static ssize_t enable_tgu_store(struct device *dev, } static DEVICE_ATTR_RW(enable_tgu); +/* reset_tgu_store - Reset Trace and Gating Unit (TGU) configuration. */ +static ssize_t reset_tgu_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(dev); + unsigned long value; + int i, j, ret; + + if (kstrtoul(buf, 0, &value) || value == 0) + return -EINVAL; + + if (!drvdata->enable) { + ret = pm_runtime_get_sync(drvdata->dev); + if (ret < 0) { + pm_runtime_put(drvdata->dev); + return ret; + } + } + + guard(spinlock)(&drvdata->lock); + TGU_UNLOCK(drvdata->base); + + writel(0, drvdata->base + TGU_CONTROL); + + TGU_LOCK(drvdata->base); + + if (drvdata->value_table->priority) + memset(drvdata->value_table->priority, 0, + MAX_PRIORITY * drvdata->max_step * + drvdata->max_reg * sizeof(unsigned int)); + + if (drvdata->value_table->condition_decode) + memset(drvdata->value_table->condition_decode, 0, + drvdata->max_condition_decode * drvdata->max_step * + sizeof(unsigned int)); + + /* Initialize all condition registers to NOT(value=0x1000000) */ + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_condition_decode; j++) { + drvdata->value_table + ->condition_decode[calculate_array_location( + drvdata, i, TGU_CONDITION_DECODE, j)] = + 0x1000000; + } + } + + if (drvdata->value_table->condition_select) + memset(drvdata->value_table->condition_select, 0, + drvdata->max_condition_select * drvdata->max_step * + sizeof(unsigned int)); + + if (drvdata->value_table->timer) + memset(drvdata->value_table->timer, 0, + (drvdata->max_step) * + (drvdata->max_timer) * + sizeof(unsigned int)); + + if (drvdata->value_table->counter) + memset(drvdata->value_table->counter, 0, + (drvdata->max_step) * + (drvdata->max_counter) * + sizeof(unsigned int)); + + dev_dbg(dev, "Qualcomm-TGU reset complete\n"); + + drvdata->enable = false; + pm_runtime_put(drvdata->dev); + + return size; +} +static DEVICE_ATTR_WO(reset_tgu); + static struct attribute *tgu_common_attrs[] = { &dev_attr_enable_tgu.attr, + &dev_attr_reset_tgu.attr, NULL, }; From 858a109e621cd5a5fe727175c546580d97f596c1 Mon Sep 17 00:00:00 2001 From: Yingchao Deng Date: Tue, 2 Dec 2025 14:42:20 +0800 Subject: [PATCH 146/438] FROMLIST: coresight: cti: Convert trigger usage fields to dynamic bitmaps and arrays Replace the fixed-size u32 fields in the cti_config and cti_trig_grp structure with dynamically allocated bitmaps and arrays. This allows memory to be allocated based on the actual number of triggers during probe time, reducing memory footprint and improving scalability for platforms with varying trigger counts. Additionally, repack struct cti_config to reduce its size from 80 bytes to 72 bytes. Link: https://lore.kernel.org/all/20251202-extended_cti-v6-1-ab68bb15c4f5@oss.qualcomm.com/ Signed-off-by: Yingchao Deng --- .../hwtracing/coresight/coresight-cti-core.c | 58 ++++++++++++++----- .../coresight/coresight-cti-platform.c | 16 ++--- .../hwtracing/coresight/coresight-cti-sysfs.c | 10 +--- drivers/hwtracing/coresight/coresight-cti.h | 17 +++--- 4 files changed, 65 insertions(+), 36 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index bfbc365bb2ef2..f9970e40dd592 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -214,8 +214,8 @@ void cti_write_intack(struct device *dev, u32 ackval) /* DEVID[19:16] - number of CTM channels */ #define CTI_DEVID_CTMCHANNELS(devid_val) ((int) BMVAL(devid_val, 16, 19)) -static void cti_set_default_config(struct device *dev, - struct cti_drvdata *drvdata) +static int cti_set_default_config(struct device *dev, + struct cti_drvdata *drvdata) { struct cti_config *config = &drvdata->config; u32 devid; @@ -234,12 +234,33 @@ static void cti_set_default_config(struct device *dev, config->nr_trig_max = CTIINOUTEN_MAX; } + config->trig_in_use = devm_bitmap_zalloc(dev, config->nr_trig_max, GFP_KERNEL); + if (!config->trig_in_use) + return -ENOMEM; + + config->trig_out_use = devm_bitmap_zalloc(dev, config->nr_trig_max, GFP_KERNEL); + if (!config->trig_out_use) + return -ENOMEM; + + config->trig_out_filter = devm_bitmap_zalloc(dev, config->nr_trig_max, GFP_KERNEL); + if (!config->trig_out_filter) + return -ENOMEM; + + config->ctiinen = devm_kcalloc(dev, config->nr_trig_max, sizeof(u32), GFP_KERNEL); + if (!config->ctiinen) + return -ENOMEM; + + config->ctiouten = devm_kcalloc(dev, config->nr_trig_max, sizeof(u32), GFP_KERNEL); + if (!config->ctiouten) + return -ENOMEM; + config->nr_ctm_channels = CTI_DEVID_CTMCHANNELS(devid); /* Most regs default to 0 as zalloc'ed except...*/ config->trig_filter_enable = true; config->ctigate = GENMASK(config->nr_ctm_channels - 1, 0); config->enable_req_count = 0; + return 0; } /* @@ -270,8 +291,10 @@ int cti_add_connection_entry(struct device *dev, struct cti_drvdata *drvdata, cti_dev->nr_trig_con++; /* add connection usage bit info to overall info */ - drvdata->config.trig_in_use |= tc->con_in->used_mask; - drvdata->config.trig_out_use |= tc->con_out->used_mask; + bitmap_or(drvdata->config.trig_in_use, drvdata->config.trig_in_use, + tc->con_in->used_mask, drvdata->config.nr_trig_max); + bitmap_or(drvdata->config.trig_out_use, drvdata->config.trig_out_use, + tc->con_out->used_mask, drvdata->config.nr_trig_max); return 0; } @@ -293,12 +316,20 @@ struct cti_trig_con *cti_allocate_trig_con(struct device *dev, int in_sigs, if (!in) return NULL; + in->used_mask = devm_bitmap_alloc(dev, in_sigs, GFP_KERNEL); + if (!in->used_mask) + return NULL; + out = devm_kzalloc(dev, offsetof(struct cti_trig_grp, sig_types[out_sigs]), GFP_KERNEL); if (!out) return NULL; + out->used_mask = devm_bitmap_alloc(dev, out_sigs, GFP_KERNEL); + if (!out->used_mask) + return NULL; + tc->con_in = in; tc->con_out = out; tc->con_in->nr_sigs = in_sigs; @@ -314,7 +345,6 @@ int cti_add_default_connection(struct device *dev, struct cti_drvdata *drvdata) { int ret = 0; int n_trigs = drvdata->config.nr_trig_max; - u32 n_trig_mask = GENMASK(n_trigs - 1, 0); struct cti_trig_con *tc = NULL; /* @@ -325,8 +355,9 @@ int cti_add_default_connection(struct device *dev, struct cti_drvdata *drvdata) if (!tc) return -ENOMEM; - tc->con_in->used_mask = n_trig_mask; - tc->con_out->used_mask = n_trig_mask; + bitmap_fill(tc->con_in->used_mask, n_trigs); + bitmap_fill(tc->con_out->used_mask, n_trigs); + ret = cti_add_connection_entry(dev, drvdata, tc, NULL, "default"); return ret; } @@ -339,7 +370,6 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, { struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; - u32 trig_bitmask; u32 chan_bitmask; u32 reg_value; int reg_offset; @@ -349,18 +379,16 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, (trigger_idx >= config->nr_trig_max)) return -EINVAL; - trig_bitmask = BIT(trigger_idx); - /* ensure registered triggers and not out filtered */ if (direction == CTI_TRIG_IN) { - if (!(trig_bitmask & config->trig_in_use)) + if (!(test_bit(trigger_idx, config->trig_in_use))) return -EINVAL; } else { - if (!(trig_bitmask & config->trig_out_use)) + if (!(test_bit(trigger_idx, config->trig_out_use))) return -EINVAL; if ((config->trig_filter_enable) && - (config->trig_out_filter & trig_bitmask)) + test_bit(trigger_idx, config->trig_out_filter)) return -EINVAL; } @@ -892,7 +920,9 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) raw_spin_lock_init(&drvdata->spinlock); /* initialise CTI driver config values */ - cti_set_default_config(dev, drvdata); + ret = cti_set_default_config(dev, drvdata); + if (ret) + return ret; pdata = coresight_cti_get_platform_data(dev); if (IS_ERR(pdata)) { diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c b/drivers/hwtracing/coresight/coresight-cti-platform.c index 4eff96f48594e..af5f45c6fcf0f 100644 --- a/drivers/hwtracing/coresight/coresight-cti-platform.c +++ b/drivers/hwtracing/coresight/coresight-cti-platform.c @@ -136,8 +136,8 @@ static int cti_plat_create_v8_etm_connection(struct device *dev, goto create_v8_etm_out; /* build connection data */ - tc->con_in->used_mask = 0xF0; /* sigs <4,5,6,7> */ - tc->con_out->used_mask = 0xF0; /* sigs <4,5,6,7> */ + bitmap_set(tc->con_in->used_mask, 4, 4); /* sigs <4,5,6,7> */ + bitmap_set(tc->con_out->used_mask, 4, 4); /* sigs <4,5,6,7> */ /* * The EXTOUT type signals from the ETM are connected to a set of input @@ -194,10 +194,10 @@ static int cti_plat_create_v8_connections(struct device *dev, goto of_create_v8_out; /* Set the v8 PE CTI connection data */ - tc->con_in->used_mask = 0x3; /* sigs <0 1> */ + bitmap_set(tc->con_in->used_mask, 0, 2); /* sigs <0 1> */ tc->con_in->sig_types[0] = PE_DBGTRIGGER; tc->con_in->sig_types[1] = PE_PMUIRQ; - tc->con_out->used_mask = 0x7; /* sigs <0 1 2 > */ + bitmap_set(tc->con_out->used_mask, 0, 3); /* sigs <0 1 2 > */ tc->con_out->sig_types[0] = PE_EDBGREQ; tc->con_out->sig_types[1] = PE_DBGRESTART; tc->con_out->sig_types[2] = PE_CTIIRQ; @@ -213,7 +213,7 @@ static int cti_plat_create_v8_connections(struct device *dev, goto of_create_v8_out; /* filter pe_edbgreq - PE trigout sig <0> */ - drvdata->config.trig_out_filter |= 0x1; + set_bit(0, drvdata->config.trig_out_filter); of_create_v8_out: return ret; @@ -257,7 +257,7 @@ static int cti_plat_read_trig_group(struct cti_trig_grp *tgrp, if (!err) { /* set the signal usage mask */ for (idx = 0; idx < tgrp->nr_sigs; idx++) - tgrp->used_mask |= BIT(values[idx]); + set_bit(values[idx], tgrp->used_mask); } kfree(values); @@ -331,7 +331,9 @@ static int cti_plat_process_filter_sigs(struct cti_drvdata *drvdata, err = cti_plat_read_trig_group(tg, fwnode, CTI_DT_FILTER_OUT_SIGS); if (!err) - drvdata->config.trig_out_filter |= tg->used_mask; + bitmap_or(drvdata->config.trig_out_filter, + drvdata->config.trig_out_filter, + tg->used_mask, drvdata->config.nr_trig_max); kfree(tg); return err; diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c index 572b80ee96fbf..a9df772151412 100644 --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c @@ -711,10 +711,8 @@ static ssize_t trigout_filtered_show(struct device *dev, struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *cfg = &drvdata->config; int size = 0, nr_trig_max = cfg->nr_trig_max; - unsigned long mask = cfg->trig_out_filter; - if (mask) - size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max); + size = bitmap_print_to_pagebuf(true, buf, cfg->trig_out_filter, nr_trig_max); return size; } static DEVICE_ATTR_RO(trigout_filtered); @@ -926,9 +924,8 @@ static ssize_t trigin_sig_show(struct device *dev, struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *cfg = &drvdata->config; - unsigned long mask = con->con_in->used_mask; - return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max); + return bitmap_print_to_pagebuf(true, buf, con->con_in->used_mask, cfg->nr_trig_max); } static ssize_t trigout_sig_show(struct device *dev, @@ -940,9 +937,8 @@ static ssize_t trigout_sig_show(struct device *dev, struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *cfg = &drvdata->config; - unsigned long mask = con->con_out->used_mask; - return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max); + return bitmap_print_to_pagebuf(true, buf, con->con_out->used_mask, cfg->nr_trig_max); } /* convert a sig type id to a name */ diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index 4f89091ee93f5..e7b88b07cffec 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -68,7 +68,7 @@ struct fwnode_handle; */ struct cti_trig_grp { int nr_sigs; - u32 used_mask; + unsigned long *used_mask; int sig_types[]; }; @@ -146,20 +146,21 @@ struct cti_config { bool hw_enabled; bool hw_powered; - /* registered triggers and filtering */ - u32 trig_in_use; - u32 trig_out_use; - u32 trig_out_filter; bool trig_filter_enable; u8 xtrig_rchan_sel; /* cti cross trig programmable regs */ - u32 ctiappset; u8 ctiinout_sel; - u32 ctiinen[CTIINOUTEN_MAX]; - u32 ctiouten[CTIINOUTEN_MAX]; + u32 ctiappset; u32 ctigate; u32 asicctl; + u32 *ctiinen; + u32 *ctiouten; + + /* registered triggers and filtering */ + unsigned long *trig_in_use; + unsigned long *trig_out_use; + unsigned long *trig_out_filter; }; /** From f0f4bdb9f97d0bed16104e8b0b854c9478a2a1f3 Mon Sep 17 00:00:00 2001 From: Yingchao Deng Date: Tue, 2 Dec 2025 14:42:21 +0800 Subject: [PATCH 147/438] FROMLIST: coresight: cti: Add Qualcomm extended CTI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QCOM extended CTI is a heavily parameterized version of ARM’s CSCTI. It allows a debugger to send to trigger events to a processor or to send a trigger event to one or more processors when a trigger event occurs on another processor on the same SoC, or even between SoCs. Qualcomm CTI implementation differs from the standard CTI in the following aspects: 1. The number of supported triggers is extended to 128. 2. Several register offsets differ from the CoreSight specification. Link: https://lore.kernel.org/all/20251202-extended_cti-v6-2-ab68bb15c4f5@oss.qualcomm.com/ Co-developed-by: Jinlong Mao Signed-off-by: Jinlong Mao Signed-off-by: Yingchao Deng --- .../testing/sysfs-bus-coresight-devices-cti | 11 ++ .../hwtracing/coresight/coresight-cti-core.c | 95 ++++++++-- .../hwtracing/coresight/coresight-cti-sysfs.c | 177 ++++++++++++++---- drivers/hwtracing/coresight/coresight-cti.h | 43 ++++- drivers/hwtracing/coresight/qcom-cti.h | 29 +++ 5 files changed, 304 insertions(+), 51 deletions(-) create mode 100644 drivers/hwtracing/coresight/qcom-cti.h diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti index a2aef7f5a6d74..9478dfcee03b6 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti @@ -245,3 +245,14 @@ Date: Aug 2025 KernelVersion 6.18 Contact: Mao Jinlong Description: (Read) Show hardware context information of device. + +What: /sys/bus/coresight/devices//regs/ext_reg_sel +Date: Dec 2025 +KernelVersion: 6.19 +Contact: Mao Jinlong +Description: (RW) Select the index for extended registers. + QCOM CTI supports up to 128 triggers, there are 6 registers + need to be expanded to up to 4 instances: + CTITRIGINSTATUS, CTITRIGOUTSTATUS, + ITTRIGIN, ITTRIGOUT, + ITTRIGINACK, ITTRIGOUTACK. diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index f9970e40dd592..51b3644e97c4a 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -21,6 +21,55 @@ #include "coresight-priv.h" #include "coresight-cti.h" +#include "qcom-cti.h" + +static const u32 cti_normal_offset[] = { + [INDEX_CTIINTACK] = CTIINTACK, + [INDEX_CTIAPPSET] = CTIAPPSET, + [INDEX_CTIAPPCLEAR] = CTIAPPCLEAR, + [INDEX_CTIAPPPULSE] = CTIAPPPULSE, + [INDEX_CTIINEN] = CTIINEN(0), + [INDEX_CTIOUTEN] = CTIOUTEN(0), + [INDEX_CTITRIGINSTATUS] = CTITRIGINSTATUS, + [INDEX_CTITRIGOUTSTATUS] = CTITRIGOUTSTATUS, + [INDEX_CTICHINSTATUS] = CTICHINSTATUS, + [INDEX_CTICHOUTSTATUS] = CTICHOUTSTATUS, + [INDEX_CTIGATE] = CTIGATE, + [INDEX_ASICCTL] = ASICCTL, + [INDEX_ITCHINACK] = ITCHINACK, + [INDEX_ITTRIGINACK] = ITTRIGINACK, + [INDEX_ITCHOUT] = ITCHOUT, + [INDEX_ITTRIGOUT] = ITTRIGOUT, + [INDEX_ITCHOUTACK] = ITCHOUTACK, + [INDEX_ITTRIGOUTACK] = ITTRIGOUTACK, + [INDEX_ITCHIN] = ITCHIN, + [INDEX_ITTRIGIN] = ITTRIGIN, + [INDEX_ITCTRL] = CORESIGHT_ITCTRL, +}; + +static const u32 cti_extended_offset[] = { + [INDEX_CTIINTACK] = QCOM_CTIINTACK, + [INDEX_CTIAPPSET] = QCOM_CTIAPPSET, + [INDEX_CTIAPPCLEAR] = QCOM_CTIAPPCLEAR, + [INDEX_CTIAPPPULSE] = QCOM_CTIAPPPULSE, + [INDEX_CTIINEN] = QCOM_CTIINEN, + [INDEX_CTIOUTEN] = QCOM_CTIOUTEN, + [INDEX_CTITRIGINSTATUS] = QCOM_CTITRIGINSTATUS, + [INDEX_CTITRIGOUTSTATUS] = QCOM_CTITRIGOUTSTATUS, + [INDEX_CTICHINSTATUS] = QCOM_CTICHINSTATUS, + [INDEX_CTICHOUTSTATUS] = QCOM_CTICHOUTSTATUS, + [INDEX_CTIGATE] = QCOM_CTIGATE, + [INDEX_ASICCTL] = QCOM_ASICCTL, + [INDEX_ITCHINACK] = QCOM_ITCHINACK, + [INDEX_ITTRIGINACK] = QCOM_ITTRIGINACK, + [INDEX_ITCHOUT] = QCOM_ITCHOUT, + [INDEX_ITTRIGOUT] = QCOM_ITTRIGOUT, + [INDEX_ITCHOUTACK] = QCOM_ITCHOUTACK, + [INDEX_ITTRIGOUTACK] = QCOM_ITTRIGOUTACK, + [INDEX_ITCHIN] = QCOM_ITCHIN, + [INDEX_ITTRIGIN] = QCOM_ITTRIGIN, + [INDEX_ITCTRL] = CORESIGHT_ITCTRL, +}; /* * CTI devices can be associated with a PE, or be connected to CoreSight @@ -70,15 +119,16 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata) /* write the CTI trigger registers */ for (i = 0; i < config->nr_trig_max; i++) { - writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i)); + writel_relaxed(config->ctiinen[i], + drvdata->base + cti_offset(drvdata, INDEX_CTIINEN, i)); writel_relaxed(config->ctiouten[i], - drvdata->base + CTIOUTEN(i)); + drvdata->base + cti_offset(drvdata, INDEX_CTIOUTEN, i)); } /* other regs */ - writel_relaxed(config->ctigate, drvdata->base + CTIGATE); - writel_relaxed(config->asicctl, drvdata->base + ASICCTL); - writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET); + writel_relaxed(config->ctigate, drvdata->base + cti_offset(drvdata, INDEX_CTIGATE, 0)); + writel_relaxed(config->asicctl, drvdata->base + cti_offset(drvdata, INDEX_ASICCTL, 0)); + writel_relaxed(config->ctiappset, drvdata->base + cti_offset(drvdata, INDEX_CTIAPPSET, 0)); /* re-enable CTI */ writel_relaxed(1, drvdata->base + CTICONTROL); @@ -214,6 +264,9 @@ void cti_write_intack(struct device *dev, u32 ackval) /* DEVID[19:16] - number of CTM channels */ #define CTI_DEVID_CTMCHANNELS(devid_val) ((int) BMVAL(devid_val, 16, 19)) +/* DEVARCH[31:21] - ARCHITECT */ +#define CTI_DEVARCH_ARCHITECT(devarch_val) ((int)BMVAL(devarch_val, 21, 31)) + static int cti_set_default_config(struct device *dev, struct cti_drvdata *drvdata) { @@ -394,8 +447,8 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, /* update the local register values */ chan_bitmask = BIT(channel_idx); - reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) : - CTIOUTEN(trigger_idx)); + reg_offset = (direction == CTI_TRIG_IN ? cti_offset(drvdata, INDEX_CTIINEN, trigger_idx) : + cti_offset(drvdata, INDEX_CTIOUTEN, trigger_idx)); raw_spin_lock(&drvdata->spinlock); @@ -479,19 +532,19 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, case CTI_CHAN_SET: config->ctiappset |= chan_bitmask; reg_value = config->ctiappset; - reg_offset = CTIAPPSET; + reg_offset = cti_offset(drvdata, INDEX_CTIAPPSET, 0); break; case CTI_CHAN_CLR: config->ctiappset &= ~chan_bitmask; reg_value = chan_bitmask; - reg_offset = CTIAPPCLEAR; + reg_offset = cti_offset(drvdata, INDEX_CTIAPPCLEAR, 0); break; case CTI_CHAN_PULSE: config->ctiappset &= ~chan_bitmask; reg_value = chan_bitmask; - reg_offset = CTIAPPPULSE; + reg_offset = cti_offset(drvdata, INDEX_CTIAPPPULSE, 0); break; default: @@ -895,6 +948,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_desc cti_desc; struct coresight_platform_data *pdata = NULL; struct resource *res = &adev->res; + u32 devarch; /* driver data*/ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -981,9 +1035,28 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) drvdata->csdev_release = drvdata->csdev->dev.release; drvdata->csdev->dev.release = cti_device_release; + /* check architect value*/ + devarch = readl_relaxed(drvdata->base + CORESIGHT_DEVARCH); + if (CTI_DEVARCH_ARCHITECT(devarch) == ARCHITECT_QCOM) { + drvdata->subtype = QCOM_CTI; + drvdata->offsets = cti_extended_offset; + /* + * QCOM CTI does not implement Claimtag functionality as + * per CoreSight specification, but its CLAIMSET register + * is incorrectly initialized to 0xF. This can mislead + * tools or drivers into thinking the component is claimed. + * + * Reset CLAIMSET to 0 to reflect that no claims are active. + */ + writel_relaxed(0, drvdata->base + CORESIGHT_CLAIMSET); + } else { + drvdata->subtype = ARM_STD_CTI; + drvdata->offsets = cti_normal_offset; + } + /* all done - dec pm refcount */ pm_runtime_put(&adev->dev); - dev_info(&drvdata->csdev->dev, "CTI initialized\n"); + dev_info(&drvdata->csdev->dev, "CTI initialized; subtype=%d\n", drvdata->subtype); return 0; pm_release: diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c index a9df772151412..12a4953829994 100644 --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c @@ -172,9 +172,8 @@ static struct attribute *coresight_cti_attrs[] = { /* register based attributes */ -/* Read registers with power check only (no enable check). */ -static ssize_t coresight_cti_reg_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t coresight_cti_mgmt_reg_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr); @@ -189,6 +188,40 @@ static ssize_t coresight_cti_reg_show(struct device *dev, return sysfs_emit(buf, "0x%x\n", val); } +/* Read registers with power check only (no enable check). */ +static ssize_t coresight_cti_reg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr); + u32 idx, val = 0; + + pm_runtime_get_sync(dev->parent); + raw_spin_lock(&drvdata->spinlock); + idx = drvdata->config.ext_reg_sel; + if (drvdata->config.hw_powered) { + switch (cti_attr->off) { + case INDEX_CTITRIGINSTATUS: + case INDEX_CTITRIGOUTSTATUS: + case INDEX_ITTRIGINACK: + case INDEX_ITTRIGOUT: + case INDEX_ITTRIGOUTACK: + case INDEX_ITTRIGIN: + val = readl_relaxed(drvdata->base + + cti_offset(drvdata, cti_attr->off, idx)); + break; + + default: + val = readl_relaxed(drvdata->base + cti_offset(drvdata, cti_attr->off, 0)); + break; + } + } + + raw_spin_unlock(&drvdata->spinlock); + pm_runtime_put_sync(dev->parent); + return sysfs_emit(buf, "0x%x\n", val); +} + /* Write registers with power check only (no enable check). */ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, struct device_attribute *attr, @@ -197,19 +230,39 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr); unsigned long val = 0; + u32 idx; if (kstrtoul(buf, 0, &val)) return -EINVAL; pm_runtime_get_sync(dev->parent); raw_spin_lock(&drvdata->spinlock); - if (drvdata->config.hw_powered) - cti_write_single_reg(drvdata, cti_attr->off, val); + idx = drvdata->config.ext_reg_sel; + if (drvdata->config.hw_powered) { + switch (cti_attr->off) { + case INDEX_ITTRIGINACK: + case INDEX_ITTRIGOUT: + cti_write_single_reg(drvdata, cti_offset(drvdata, cti_attr->off, idx), val); + break; + + default: + cti_write_single_reg(drvdata, cti_offset(drvdata, cti_attr->off, 0), val); + break; + } + } raw_spin_unlock(&drvdata->spinlock); pm_runtime_put_sync(dev->parent); return size; } +#define coresight_cti_mgmt_reg(name, offset) \ + (&((struct cs_off_attribute[]) { \ + { \ + __ATTR(name, 0444, coresight_cti_mgmt_reg_show, NULL), \ + offset \ + } \ + })[0].attr.attr) + #define coresight_cti_reg(name, offset) \ (&((struct cs_off_attribute[]) { \ { \ @@ -237,17 +290,17 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, /* coresight management registers */ static struct attribute *coresight_cti_mgmt_attrs[] = { - coresight_cti_reg(devaff0, CTIDEVAFF0), - coresight_cti_reg(devaff1, CTIDEVAFF1), - coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS), - coresight_cti_reg(devarch, CORESIGHT_DEVARCH), - coresight_cti_reg(devid, CORESIGHT_DEVID), - coresight_cti_reg(devtype, CORESIGHT_DEVTYPE), - coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0), - coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1), - coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2), - coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3), - coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4), + coresight_cti_mgmt_reg(devaff0, CTIDEVAFF0), + coresight_cti_mgmt_reg(devaff1, CTIDEVAFF1), + coresight_cti_mgmt_reg(authstatus, CORESIGHT_AUTHSTATUS), + coresight_cti_mgmt_reg(devarch, CORESIGHT_DEVARCH), + coresight_cti_mgmt_reg(devid, CORESIGHT_DEVID), + coresight_cti_mgmt_reg(devtype, CORESIGHT_DEVTYPE), + coresight_cti_mgmt_reg(pidr0, CORESIGHT_PERIPHIDR0), + coresight_cti_mgmt_reg(pidr1, CORESIGHT_PERIPHIDR1), + coresight_cti_mgmt_reg(pidr2, CORESIGHT_PERIPHIDR2), + coresight_cti_mgmt_reg(pidr3, CORESIGHT_PERIPHIDR3), + coresight_cti_mgmt_reg(pidr4, CORESIGHT_PERIPHIDR4), NULL, }; @@ -258,13 +311,15 @@ static struct attribute *coresight_cti_mgmt_attrs[] = { * If inaccessible & pcached_val not NULL then show cached value. */ static ssize_t cti_reg32_show(struct device *dev, char *buf, - u32 *pcached_val, int reg_offset) + u32 *pcached_val, int index) { u32 val = 0; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; + int reg_offset; raw_spin_lock(&drvdata->spinlock); + reg_offset = cti_offset(drvdata, index, 0); if ((reg_offset >= 0) && cti_active(config)) { CS_UNLOCK(drvdata->base); val = readl_relaxed(drvdata->base + reg_offset); @@ -284,11 +339,12 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf, * if reg_offset >= 0 then write through if enabled. */ static ssize_t cti_reg32_store(struct device *dev, const char *buf, - size_t size, u32 *pcached_val, int reg_offset) + size_t size, u32 *pcached_val, int index) { unsigned long val; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; + int reg_offset; if (kstrtoul(buf, 0, &val)) return -EINVAL; @@ -298,6 +354,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, if (pcached_val) *pcached_val = (u32)val; + reg_offset = cti_offset(drvdata, index, 0); /* write through if offset and enabled */ if ((reg_offset >= 0) && cti_active(config)) cti_write_single_reg(drvdata, reg_offset, val); @@ -306,14 +363,14 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, } /* Standard macro for simple rw cti config registers */ -#define cti_config_reg32_rw(name, cfgname, offset) \ +#define cti_config_reg32_rw(name, cfgname, index) \ static ssize_t name##_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \ return cti_reg32_show(dev, buf, \ - &drvdata->config.cfgname, offset); \ + &drvdata->config.cfgname, index); \ } \ \ static ssize_t name##_store(struct device *dev, \ @@ -322,7 +379,7 @@ static ssize_t name##_store(struct device *dev, \ { \ struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \ return cti_reg32_store(dev, buf, size, \ - &drvdata->config.cfgname, offset); \ + &drvdata->config.cfgname, index); \ } \ static DEVICE_ATTR_RW(name) @@ -356,6 +413,46 @@ static ssize_t inout_sel_store(struct device *dev, } static DEVICE_ATTR_RW(inout_sel); +/* + * QCOM CTI supports up to 128 triggers, there are 6 registers need to be + * expanded to up to 4 instances, and ext_reg_sel can be used to indicate + * which one is in use. + * CTITRIGINSTATUS, CTITRIGOUTSTATUS, + * ITTRIGIN, ITTRIGOUT, + * ITTRIGINACK, ITTRIGOUTACK. + */ +static ssize_t ext_reg_sel_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 val; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + + raw_spin_lock(&drvdata->spinlock); + val = drvdata->config.ext_reg_sel; + raw_spin_unlock(&drvdata->spinlock); + return sprintf(buf, "%d\n", val); +} + +static ssize_t ext_reg_sel_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + if (val > ((drvdata->config.nr_trig_max + 31) / 32 - 1)) + return -EINVAL; + + raw_spin_lock(&drvdata->spinlock); + drvdata->config.ext_reg_sel = val; + raw_spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(ext_reg_sel); + static ssize_t inen_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -389,7 +486,7 @@ static ssize_t inen_store(struct device *dev, /* write through if enabled */ if (cti_active(config)) - cti_write_single_reg(drvdata, CTIINEN(index), val); + cti_write_single_reg(drvdata, cti_offset(drvdata, INDEX_CTIINEN, index), val); raw_spin_unlock(&drvdata->spinlock); return size; } @@ -428,7 +525,7 @@ static ssize_t outen_store(struct device *dev, /* write through if enabled */ if (cti_active(config)) - cti_write_single_reg(drvdata, CTIOUTEN(index), val); + cti_write_single_reg(drvdata, cti_offset(drvdata, INDEX_CTIOUTEN, index), val); raw_spin_unlock(&drvdata->spinlock); return size; } @@ -448,9 +545,9 @@ static ssize_t intack_store(struct device *dev, } static DEVICE_ATTR_WO(intack); -cti_config_reg32_rw(gate, ctigate, CTIGATE); -cti_config_reg32_rw(asicctl, asicctl, ASICCTL); -cti_config_reg32_rw(appset, ctiappset, CTIAPPSET); +cti_config_reg32_rw(gate, ctigate, INDEX_CTIGATE); +cti_config_reg32_rw(asicctl, asicctl, INDEX_ASICCTL); +cti_config_reg32_rw(appset, ctiappset, INDEX_CTIAPPSET); static ssize_t appclear_store(struct device *dev, struct device_attribute *attr, @@ -504,6 +601,7 @@ static DEVICE_ATTR_WO(apppulse); */ static struct attribute *coresight_cti_regs_attrs[] = { &dev_attr_inout_sel.attr, + &dev_attr_ext_reg_sel.attr, &dev_attr_inen.attr, &dev_attr_outen.attr, &dev_attr_gate.attr, @@ -512,20 +610,20 @@ static struct attribute *coresight_cti_regs_attrs[] = { &dev_attr_appset.attr, &dev_attr_appclear.attr, &dev_attr_apppulse.attr, - coresight_cti_reg(triginstatus, CTITRIGINSTATUS), - coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS), - coresight_cti_reg(chinstatus, CTICHINSTATUS), - coresight_cti_reg(choutstatus, CTICHOUTSTATUS), + coresight_cti_reg(triginstatus, INDEX_CTITRIGINSTATUS), + coresight_cti_reg(trigoutstatus, INDEX_CTITRIGOUTSTATUS), + coresight_cti_reg(chinstatus, INDEX_CTICHINSTATUS), + coresight_cti_reg(choutstatus, INDEX_CTICHOUTSTATUS), #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS - coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL), - coresight_cti_reg(ittrigin, ITTRIGIN), - coresight_cti_reg(itchin, ITCHIN), - coresight_cti_reg_rw(ittrigout, ITTRIGOUT), - coresight_cti_reg_rw(itchout, ITCHOUT), - coresight_cti_reg(itchoutack, ITCHOUTACK), - coresight_cti_reg(ittrigoutack, ITTRIGOUTACK), - coresight_cti_reg_wo(ittriginack, ITTRIGINACK), - coresight_cti_reg_wo(itchinack, ITCHINACK), + coresight_cti_reg_rw(itctrl, INDEX_ITCTRL), + coresight_cti_reg(ittrigin, INDEX_ITTRIGIN), + coresight_cti_reg(itchin, INDEX_ITCHIN), + coresight_cti_reg_rw(ittrigout, INDEX_ITTRIGOUT), + coresight_cti_reg_rw(itchout, INDEX_ITCHOUT), + coresight_cti_reg(itchoutack, INDEX_ITCHOUTACK), + coresight_cti_reg(ittrigoutack, INDEX_ITTRIGOUTACK), + coresight_cti_reg_wo(ittriginack, INDEX_ITTRIGINACK), + coresight_cti_reg_wo(itchinack, INDEX_ITCHINACK), #endif NULL, }; @@ -740,6 +838,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev, config->ctiappset = 0; config->ctiinout_sel = 0; config->xtrig_rchan_sel = 0; + config->ext_reg_sel = 0; /* if enabled then write through */ if (cti_active(config)) diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index e7b88b07cffec..fdd6d8892a95a 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -57,7 +57,38 @@ struct fwnode_handle; * Max of in and out defined in the DEVID register. * - pick up actual number used from .dts parameters if present. */ -#define CTIINOUTEN_MAX 32 +#define CTIINOUTEN_MAX 128 + +/* Qcom CTI supports up to 128 triggers*/ +enum cti_subtype { + ARM_STD_CTI, + QCOM_CTI, +}; + +/* These registers are remapped in Qcom CTI*/ +enum cti_offset_index { + INDEX_CTIINTACK, + INDEX_CTIAPPSET, + INDEX_CTIAPPCLEAR, + INDEX_CTIAPPPULSE, + INDEX_CTIINEN, + INDEX_CTIOUTEN, + INDEX_CTITRIGINSTATUS, + INDEX_CTITRIGOUTSTATUS, + INDEX_CTICHINSTATUS, + INDEX_CTICHOUTSTATUS, + INDEX_CTIGATE, + INDEX_ASICCTL, + INDEX_ITCHINACK, + INDEX_ITTRIGINACK, + INDEX_ITCHOUT, + INDEX_ITTRIGOUT, + INDEX_ITCHOUTACK, + INDEX_ITTRIGOUTACK, + INDEX_ITCHIN, + INDEX_ITTRIGIN, + INDEX_ITCTRL, +}; /** * Group of related trigger signals @@ -149,6 +180,9 @@ struct cti_config { bool trig_filter_enable; u8 xtrig_rchan_sel; + /* qcom_cti regs' index */ + u8 ext_reg_sel; + /* cti cross trig programmable regs */ u8 ctiinout_sel; u32 ctiappset; @@ -181,6 +215,8 @@ struct cti_drvdata { struct cti_config config; struct list_head node; void (*csdev_release)(struct device *dev); + enum cti_subtype subtype; + const u32 *offsets; }; /* @@ -235,6 +271,11 @@ struct coresight_platform_data * coresight_cti_get_platform_data(struct device *dev); const char *cti_plat_get_node_name(struct fwnode_handle *fwnode); +static inline u32 cti_offset(struct cti_drvdata *drvdata, int index, int num) +{ + return drvdata->offsets[index] + 4 * num; +} + /* cti powered and enabled */ static inline bool cti_active(struct cti_config *cfg) { diff --git a/drivers/hwtracing/coresight/qcom-cti.h b/drivers/hwtracing/coresight/qcom-cti.h new file mode 100644 index 0000000000000..3c46317dd81f5 --- /dev/null +++ b/drivers/hwtracing/coresight/qcom-cti.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#define ARCHITECT_QCOM 0x477 + +/* CTI programming registers */ +#define QCOM_CTIINTACK 0x020 +#define QCOM_CTIAPPSET 0x004 +#define QCOM_CTIAPPCLEAR 0x008 +#define QCOM_CTIAPPPULSE 0x00C +#define QCOM_CTIINEN 0x400 +#define QCOM_CTIOUTEN 0x800 +#define QCOM_CTITRIGINSTATUS 0x040 +#define QCOM_CTITRIGOUTSTATUS 0x060 +#define QCOM_CTICHINSTATUS 0x080 +#define QCOM_CTICHOUTSTATUS 0x084 +#define QCOM_CTIGATE 0x088 +#define QCOM_ASICCTL 0x08c +/* Integration test registers */ +#define QCOM_ITCHINACK 0xE70 +#define QCOM_ITTRIGINACK 0xE80 +#define QCOM_ITCHOUT 0xE74 +#define QCOM_ITTRIGOUT 0xEA0 +#define QCOM_ITCHOUTACK 0xE78 +#define QCOM_ITTRIGOUTACK 0xEC0 +#define QCOM_ITCHIN 0xE7C +#define QCOM_ITTRIGIN 0xEE0 From 6c32633a8b5ad265a808aafaa20f9830d67ff941 Mon Sep 17 00:00:00 2001 From: Yingchao Deng Date: Thu, 29 Jan 2026 22:25:07 +0800 Subject: [PATCH 148/438] FROMLIST: stm: class: Add MIPI OST protocol support Add MIPI OST(Open System Trace) protocol support for stm to format the traces. The OST Protocol abstracts the underlying layers from the sending and receiving applications, thus removing dependencies on the connection media and platform implementation. OST over STP packet consists of Header/Payload/End. Header is designed to include the information required by all OST packets. Information that is not shared by all packets is left to the higher layer protocols. Thus, the OST Protocol Header can be regarded as the first part of a complete OST Packet Header, while a higher layer header can be regarded as an extension designed for a specific purpose. +--------+--------+--------+--------+ | start |version |entity |protocol| +--------+--------+--------+--------+ | stm version | magic | +-----------------------------------+ | cpu | +-----------------------------------+ | timestamp | | | +-----------------------------------+ | tgid | | | +-----------------------------------+ | payload | +-----------------------------------+ | ... | end | +-----------------------------------+ In header, there will be STARTSIMPLE/VERSION/ENTITY/PROTOCOL. STARTSIMPLE is used to signal the beginning of a simplified OST protocol. The Version field is a one byte, unsigned number identifying the version of the OST Protocol. The Entity ID field is a one byte unsigned number that identifies the source. The Protocol ID field is a one byte unsigned number identifying the higher layer protocol of the OST Packet, i.e. identifying the format of the data after the OST Protocol Header. OST Control Protocol ID value represents the common control protocol, the remaining Protocol ID values may be used by any higher layer protocols capable of being transported by the OST Protocol. Link: https://lore.kernel.org/all/20260129-p_ost-v5-1-2b14fff39428@oss.qualcomm.com/ Co-developed-by: Tingwei Zhang Signed-off-by: Tingwei Zhang Co-developed-by: Yuanfang Zhang Signed-off-by: Yuanfang Zhang Co-developed-by: Jinlong Mao Signed-off-by: Jinlong Mao Signed-off-by: Yingchao Deng --- .../ABI/testing/configfs-stp-policy-p_ost | 6 + Documentation/trace/p_ost.rst | 36 +++ drivers/hwtracing/stm/Kconfig | 14 ++ drivers/hwtracing/stm/Makefile | 2 + drivers/hwtracing/stm/p_ost.c | 236 ++++++++++++++++++ 5 files changed, 294 insertions(+) create mode 100644 Documentation/ABI/testing/configfs-stp-policy-p_ost create mode 100644 Documentation/trace/p_ost.rst create mode 100644 drivers/hwtracing/stm/p_ost.c diff --git a/Documentation/ABI/testing/configfs-stp-policy-p_ost b/Documentation/ABI/testing/configfs-stp-policy-p_ost new file mode 100644 index 0000000000000..3cc4b38b456ef --- /dev/null +++ b/Documentation/ABI/testing/configfs-stp-policy-p_ost @@ -0,0 +1,6 @@ +What: /config/stp-policy/:p_ost.//entity +Date: Jan 2026 +KernelVersion: 6.20 +Description: + Set the entity which is to identify the source, RW. + diff --git a/Documentation/trace/p_ost.rst b/Documentation/trace/p_ost.rst new file mode 100644 index 0000000000000..df93b889eb4ce --- /dev/null +++ b/Documentation/trace/p_ost.rst @@ -0,0 +1,36 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=================== +MIPI OST over STP +=================== + +The OST(Open System Trace) driver is used with STM class devices to +generate standardized trace stream. Trace sources can be identified +by different entity ids. + +CONFIG_STM_PROTO_OST is for p_ost driver enablement. Once this config +is enabled, you can select the p_ost protocol by command below: + +# mkdir /sys/kernel/config/stp-policy/stm0:p_ost.policy + +The policy name format is extended like this: + :. + +With coresight-stm device, it will be look like "stm0:p_ost.policy". + +With MIPI OST protocol driver, the attributes for each protocol node is: +# mkdir /sys/kernel/config/stp-policy/stm0:p_ost.policy/default +# ls /sys/kernel/config/stp-policy/stm0:p_ost.policy/default +channels entity masters + +The entity here is the set the entity that p_ost supports. Currently +p_ost supports ftrace, console and diag entity. + +Set entity: +# echo 'ftrace' > /sys/kernel/config/stp-policy/stm0:p_ost.policy/default/entity + +Get available and currently selected (shown in square brackets) entity that p_ost supports: +# cat /sys/kernel/config/stp-policy/stm0:p_ost.policy/default/entity +[ftrace] console diag + +See Documentation/ABI/testing/configfs-stp-policy-p_ost for more details. diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig index cd7f0b0f3fbeb..91700ef69add2 100644 --- a/drivers/hwtracing/stm/Kconfig +++ b/drivers/hwtracing/stm/Kconfig @@ -40,6 +40,20 @@ config STM_PROTO_SYS_T If you don't know what this is, say N. +config STM_PROTO_OST + tristate "MIPI OST STM framing protocol driver" + default CONFIG_STM + help + This is an implementation of MIPI OST protocol to be used + over the STP transport. In addition to the data payload, it + also carries additional metadata for entity, better + means of trace source identification, etc. + + The receiving side must be able to decode this protocol in + addition to the MIPI STP, in order to extract the data. + + If you don't know what this is, say N. + config STM_DUMMY tristate "Dummy STM driver" help diff --git a/drivers/hwtracing/stm/Makefile b/drivers/hwtracing/stm/Makefile index 1692fcd292779..d9c8615849b95 100644 --- a/drivers/hwtracing/stm/Makefile +++ b/drivers/hwtracing/stm/Makefile @@ -5,9 +5,11 @@ stm_core-y := core.o policy.o obj-$(CONFIG_STM_PROTO_BASIC) += stm_p_basic.o obj-$(CONFIG_STM_PROTO_SYS_T) += stm_p_sys-t.o +obj-$(CONFIG_STM_PROTO_OST) += stm_p_ost.o stm_p_basic-y := p_basic.o stm_p_sys-t-y := p_sys-t.o +stm_p_ost-y := p_ost.o obj-$(CONFIG_STM_DUMMY) += dummy_stm.o diff --git a/drivers/hwtracing/stm/p_ost.c b/drivers/hwtracing/stm/p_ost.c new file mode 100644 index 0000000000000..51fffa9429597 --- /dev/null +++ b/drivers/hwtracing/stm/p_ost.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * MIPI OST framing protocol for STM devices. + */ + +#include +#include +#include +#include +#include "stm.h" + +/* + * OST Base Protocol Header + * + * Position Bits Field Name + * 0 8 STARTSIMPLE + * 1 8 Version + * 2 8 Entity ID + * 3 8 protocol ID + */ +#define OST_FIELD_STARTSIMPLE 0 +#define OST_FIELD_VERSION 8 +#define OST_FIELD_ENTITY 16 +#define OST_FIELD_PROTOCOL 24 + +#define OST_TOKEN_STARTSIMPLE 0x10 +#define OST_VERSION_MIPI1 0x10 + +/* entity id to identify the source*/ +#define OST_ENTITY_FTRACE 0x01 +#define OST_ENTITY_CONSOLE 0x02 +#define OST_ENTITY_DIAG 0xEE + +#define OST_CONTROL_PROTOCOL 0x0 + +#define DATA_HEADER ((OST_TOKEN_STARTSIMPLE << OST_FIELD_STARTSIMPLE) | \ + (OST_VERSION_MIPI1 << OST_FIELD_PROTOCOL) | \ + (OST_CONTROL_PROTOCOL << OST_FIELD_PROTOCOL)) + +#define STM_MAKE_VERSION(ma, mi) (((ma) << 8) | (mi)) +#define STM_HEADER_MAGIC (0x5953) + +enum ost_entity_type { + OST_ENTITY_TYPE_NONE, + OST_ENTITY_TYPE_FTRACE, + OST_ENTITY_TYPE_CONSOLE, + OST_ENTITY_TYPE_DIAG, +}; + +static const char * const str_ost_entity_type[] = { + [OST_ENTITY_TYPE_NONE] = "none", + [OST_ENTITY_TYPE_FTRACE] = "ftrace", + [OST_ENTITY_TYPE_CONSOLE] = "console", + [OST_ENTITY_TYPE_DIAG] = "diag", +}; + +static const u32 ost_entity_value[] = { + [OST_ENTITY_TYPE_NONE] = 0, + [OST_ENTITY_TYPE_FTRACE] = OST_ENTITY_FTRACE, + [OST_ENTITY_TYPE_CONSOLE] = OST_ENTITY_CONSOLE, + [OST_ENTITY_TYPE_DIAG] = OST_ENTITY_DIAG, +}; + +struct ost_policy_node { + enum ost_entity_type entity_type; +}; + +struct ost_output { + struct ost_policy_node node; +}; + +/* Set default entity type as none */ +static void ost_policy_node_init(void *priv) +{ + struct ost_policy_node *pn = priv; + + pn->entity_type = OST_ENTITY_TYPE_NONE; +} + +static int ost_output_open(void *priv, struct stm_output *output) +{ + struct ost_policy_node *pn = priv; + struct ost_output *opriv; + + opriv = kzalloc(sizeof(*opriv), GFP_ATOMIC); + if (!opriv) + return -ENOMEM; + + memcpy(&opriv->node, pn, sizeof(opriv->node)); + output->pdrv_private = opriv; + return 0; +} + +static void ost_output_close(struct stm_output *output) +{ + kfree(output->pdrv_private); +} + +static ssize_t ost_t_policy_entity_show(struct config_item *item, + char *page) +{ + struct ost_policy_node *pn = to_pdrv_policy_node(item); + ssize_t sz = 0; + int i; + + for (i = 1; i < ARRAY_SIZE(str_ost_entity_type); i++) { + if (i == pn->entity_type) + sz += sysfs_emit_at(page, sz, "[%s] ", str_ost_entity_type[i]); + else + sz += sysfs_emit_at(page, sz, "%s ", str_ost_entity_type[i]); + } + + sz += sysfs_emit_at(page, sz, "\n"); + return sz; +} + +static int entity_index(const char *str) +{ + int i; + + for (i = 1; i < ARRAY_SIZE(str_ost_entity_type); i++) { + if (sysfs_streq(str, str_ost_entity_type[i])) + return i; + } + + return 0; +} + +static ssize_t +ost_t_policy_entity_store(struct config_item *item, const char *page, + size_t count) +{ + struct ost_policy_node *pn = to_pdrv_policy_node(item); + int i; + + i = entity_index(page); + if (i) + pn->entity_type = i; + else + return -EINVAL; + + return count; +} +CONFIGFS_ATTR(ost_t_policy_, entity); + +static struct configfs_attribute *ost_t_policy_attrs[] = { + &ost_t_policy_attr_entity, + NULL, +}; + +static ssize_t +notrace ost_write(struct stm_data *data, struct stm_output *output, + unsigned int chan, const char *buf, size_t count, + struct stm_source_data *source) +{ + struct ost_output *op = output->pdrv_private; + unsigned int c = output->channel + chan; + unsigned int m = output->master; + const unsigned char nil = 0; + u32 header = DATA_HEADER; + struct trc_hdr { + u16 version; + u16 magic; + u32 cpu; + u64 timestamp; + u64 tgid; + } hdr; + ssize_t sz; + + /* + * Identify the source by entity type. + * If entity type is not set, return error value. + */ + if (op->node.entity_type) + header |= ost_entity_value[op->node.entity_type]; + else + return -EINVAL; + + /* + * STP framing rules for OST frames: + * * the first packet of the OST frame is marked; + * * the last packet is a FLAG with timestamped tag. + */ + /* Message layout: HEADER / DATA / TAIL */ + /* HEADER */ + sz = data->packet(data, m, c, STP_PACKET_DATA, STP_PACKET_MARKED, + 4, (u8 *)&header); + if (sz <= 0) + return sz; + + /* DATA */ + hdr.version = STM_MAKE_VERSION(0, 3); + hdr.magic = STM_HEADER_MAGIC; + hdr.cpu = raw_smp_processor_id(); + hdr.timestamp = sched_clock(); + hdr.tgid = task_tgid_nr(current); + sz = stm_data_write(data, m, c, false, &hdr, sizeof(hdr)); + if (sz <= 0) + return sz; + + sz = stm_data_write(data, m, c, false, buf, count); + + /* TAIL */ + if (sz > 0) + data->packet(data, m, c, STP_PACKET_FLAG, + STP_PACKET_TIMESTAMPED, 0, &nil); + + return sz; +} + +static const struct stm_protocol_driver ost_pdrv = { + .owner = THIS_MODULE, + .name = "p_ost", + .write = ost_write, + .policy_attr = ost_t_policy_attrs, + .output_open = ost_output_open, + .output_close = ost_output_close, + .policy_node_init = ost_policy_node_init, +}; + +static int ost_stm_init(void) +{ + return stm_register_protocol(&ost_pdrv); +} +module_init(ost_stm_init); + +static void ost_stm_exit(void) +{ + stm_unregister_protocol(&ost_pdrv); +} +module_exit(ost_stm_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MIPI Open System Trace STM framing protocol driver"); From 35f70a3a092c913380c29a488f055eaa72734023 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:41 -0800 Subject: [PATCH 149/438] FROMLIST: dt-bindings: arm: coresight: Add 'qcom,cpu-bound-components' property Introduce the `qcom,cpu-bound-components` boolean property for CoreSight components (TMC, Funnel, and Replicator). This property indicates that the component is physically located within a CPU cluster power domain. Such components share the power state of the cluster and may require special handling (e.g., cross-CPU register access) compared to system-wide components. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-1-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../bindings/arm/arm,coresight-dynamic-funnel.yaml | 5 +++++ .../bindings/arm/arm,coresight-dynamic-replicator.yaml | 5 +++++ Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml index b74db15e5f8af..a4c7333e8359d 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml @@ -57,6 +57,11 @@ properties: power-domains: maxItems: 1 + qcom,cpu-bound-components: + type: boolean + description: + Indicates whether the funnel is located physically within cpu cluster. + label: description: Description of a coresight device. diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml index 17ea936b796fd..2c6e78f02ed84 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml @@ -67,6 +67,11 @@ properties: Indicates that the replicator will lose register context when AMBA clock is removed which is observed in some replicator designs. + qcom,cpu-bound-components: + type: boolean + description: + Indicates whether the replicator is located physically within cpu cluster. + in-ports: $ref: /schemas/graph.yaml#/properties/ports additionalProperties: false diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml index 96dd5b5f771a3..8c4f2244a5c74 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml @@ -86,6 +86,11 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 maximum: 15 + qcom,cpu-bound-components: + type: boolean + description: + indicates whether the TMC-ETF is located physically within cpu cluster. + in-ports: $ref: /schemas/graph.yaml#/properties/ports additionalProperties: false From 3853fd2b6efc498ee43d47cbe7be9e31b6567088 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:42 -0800 Subject: [PATCH 150/438] FROMLIST: coresight-funnel: Support CPU cluster funnel initialization Funnels associated with CPU clusters reside in the cluster's power domain. Unlike dynamic funnels (which are typically system-wide), these per-cluster funnels are only accessible when the cluster is powered on. Standard runtime PM may not suffice to wake up a cluster from low-power states, making direct register access unreliable. Enhance the funnel driver to support these per-cluster devices: 1. Safe Initialization: - Identify CPU cluster funnels via "qcom,cpu-bound-components". - Use smp_call_function_single() to perform hardware initialization (claim tag clearing) on a CPU within the cluster. - Refactor the probe flow to encapsulate device registration in funnel_add_coresight_dev(). 2. Cross-CPU Enablement: - Update funnel_enable() to use smp_call_function_single() when enabling the hardware on a cluster-bound funnel. 3. Debug Interface Support: - Update funnel_ctrl_show() to safely read the control register via cross-CPU calls when necessary. This ensures that funnel operations remain safe and functional even when the associated CPU cluster is in aggressive low-power states. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-2-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-funnel.c | 183 +++++++++++++++--- 1 file changed, 152 insertions(+), 31 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 3b248e54471a3..a1264df84ab4c 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); * @csdev: component vitals needed by the framework. * @priority: port selection order. * @spinlock: serialize enable/disable operations. + * @supported_cpus: Represent the CPUs related to this funnel. */ struct funnel_drvdata { void __iomem *base; @@ -48,6 +50,13 @@ struct funnel_drvdata { struct coresight_device *csdev; unsigned long priority; raw_spinlock_t spinlock; + struct cpumask *supported_cpus; +}; + +struct funnel_smp_arg { + struct funnel_drvdata *drvdata; + int port; + int rc; }; static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port) @@ -76,6 +85,33 @@ static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port) return rc; } +static void funnel_enable_hw_smp_call(void *info) +{ + struct funnel_smp_arg *arg = info; + + arg->rc = dynamic_funnel_enable_hw(arg->drvdata, arg->port); +} + +static int funnel_enable_hw(struct funnel_drvdata *drvdata, int port) +{ + int cpu, ret; + struct funnel_smp_arg arg = { 0 }; + + if (!drvdata->supported_cpus) + return dynamic_funnel_enable_hw(drvdata, port); + + arg.drvdata = drvdata; + arg.port = port; + + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + funnel_enable_hw_smp_call, &arg, 1); + if (!ret) + return arg.rc; + } + return ret; +} + static int funnel_enable(struct coresight_device *csdev, struct coresight_connection *in, struct coresight_connection *out) @@ -86,19 +122,24 @@ static int funnel_enable(struct coresight_device *csdev, bool first_enable = false; raw_spin_lock_irqsave(&drvdata->spinlock, flags); - if (in->dest_refcnt == 0) { - if (drvdata->base) - rc = dynamic_funnel_enable_hw(drvdata, in->dest_port); - if (!rc) - first_enable = true; - } - if (!rc) + + if (in->dest_refcnt == 0) + first_enable = true; + else in->dest_refcnt++; + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); - if (first_enable) - dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", - in->dest_port); + if (first_enable) { + if (drvdata->base) + rc = funnel_enable_hw(drvdata, in->dest_port); + if (!rc) { + in->dest_refcnt++; + dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", + in->dest_port); + } + } + return rc; } @@ -188,15 +229,39 @@ static u32 get_funnel_ctrl_hw(struct funnel_drvdata *drvdata) return functl; } +static void get_funnel_ctrl_smp_call(void *info) +{ + struct funnel_smp_arg *arg = info; + + arg->rc = get_funnel_ctrl_hw(arg->drvdata); +} + static ssize_t funnel_ctrl_show(struct device *dev, struct device_attribute *attr, char *buf) { u32 val; + int cpu, ret; struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct funnel_smp_arg arg = { 0 }; pm_runtime_get_sync(dev->parent); - - val = get_funnel_ctrl_hw(drvdata); + if (!drvdata->supported_cpus) { + val = get_funnel_ctrl_hw(drvdata); + } else { + arg.drvdata = drvdata; + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + get_funnel_ctrl_smp_call, &arg, 1); + if (!ret) + break; + } + if (!ret) { + val = arg.rc; + } else { + pm_runtime_put(dev->parent); + return ret; + } + } pm_runtime_put(dev->parent); @@ -211,22 +276,68 @@ static struct attribute *coresight_funnel_attrs[] = { }; ATTRIBUTE_GROUPS(coresight_funnel); +static void funnel_clear_self_claim_tag(struct funnel_drvdata *drvdata) +{ + struct csdev_access access = CSDEV_ACCESS_IOMEM(drvdata->base); + + coresight_clear_self_claim_tag(&access); +} + +static void funnel_init_on_cpu(void *info) +{ + struct funnel_drvdata *drvdata = info; + + funnel_clear_self_claim_tag(drvdata); +} + +static int funnel_add_coresight_dev(struct device *dev) +{ + struct coresight_desc desc = { 0 }; + struct funnel_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata->base) { + desc.groups = coresight_funnel_groups; + desc.access = CSDEV_ACCESS_IOMEM(drvdata->base); + } + + desc.name = coresight_alloc_device_name(&funnel_devs, dev); + if (!desc.name) + return -ENOMEM; + + desc.type = CORESIGHT_DEV_TYPE_LINK; + desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; + desc.ops = &funnel_cs_ops; + desc.pdata = dev->platform_data; + desc.dev = dev; + + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + return 0; +} + +static struct cpumask *funnel_get_supported_cpus(struct device *dev) +{ + struct generic_pm_domain *pd; + + pd = pd_to_genpd(dev->pm_domain); + if (pd) + return pd->cpus; + + return NULL; +} + static int funnel_probe(struct device *dev, struct resource *res) { void __iomem *base; struct coresight_platform_data *pdata = NULL; struct funnel_drvdata *drvdata; - struct coresight_desc desc = { 0 }; - int ret; + int cpu, ret; if (is_of_node(dev_fwnode(dev)) && of_device_is_compatible(dev->of_node, "arm,coresight-funnel")) dev_warn_once(dev, "Uses OBSOLETE CoreSight funnel binding\n"); - desc.name = coresight_alloc_device_name(&funnel_devs, dev); - if (!desc.name) - return -ENOMEM; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -244,9 +355,6 @@ static int funnel_probe(struct device *dev, struct resource *res) if (IS_ERR(base)) return PTR_ERR(base); drvdata->base = base; - desc.groups = coresight_funnel_groups; - desc.access = CSDEV_ACCESS_IOMEM(base); - coresight_clear_self_claim_tag(&desc.access); } dev_set_drvdata(dev, drvdata); @@ -258,23 +366,36 @@ static int funnel_probe(struct device *dev, struct resource *res) dev->platform_data = pdata; raw_spin_lock_init(&drvdata->spinlock); - desc.type = CORESIGHT_DEV_TYPE_LINK; - desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; - desc.ops = &funnel_cs_ops; - desc.pdata = pdata; - desc.dev = dev; - drvdata->csdev = coresight_register(&desc); - if (IS_ERR(drvdata->csdev)) - return PTR_ERR(drvdata->csdev); - return 0; + if (fwnode_property_present(dev_fwnode(dev), "qcom,cpu-bound-components")) { + drvdata->supported_cpus = funnel_get_supported_cpus(dev); + if (!drvdata->supported_cpus) + return -EINVAL; + + cpus_read_lock(); + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + funnel_init_on_cpu, drvdata, 1); + if (!ret) + break; + } + cpus_read_unlock(); + + if (ret) + return 0; + } else if (res) { + funnel_clear_self_claim_tag(drvdata); + } + + return funnel_add_coresight_dev(dev); } static int funnel_remove(struct device *dev) { struct funnel_drvdata *drvdata = dev_get_drvdata(dev); - coresight_unregister(drvdata->csdev); + if (drvdata->csdev) + coresight_unregister(drvdata->csdev); return 0; } From bbcd05a748c2894b6f43d3c22a782a089ee78fac Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:43 -0800 Subject: [PATCH 151/438] FROMLIST: coresight-funnel: Defer probe when associated CPUs are offline Per-cluster funnels rely on the associated CPU cluster being online to securely access registers during initialization. If all CPUs in the cluster are offline during probe, these operations fail. Support deferred initialization for these devices: 1. Track funnels that fail to probe due to offline CPUs in a global list. 2. Register a CPU hotplug notifier (funnel_online_cpu) to detect when a relevant CPU comes online. 3. Upon CPU online, retry the hardware initialization and registration with the CoreSight framework. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-3-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-funnel.c | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index a1264df84ab4c..5d114ce1109f4 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -32,6 +32,9 @@ #define FUNNEL_ENSx_MASK 0xff DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); +static LIST_HEAD(funnel_delay_probe); +static enum cpuhp_state hp_online; +static DEFINE_SPINLOCK(delay_lock); /** * struct funnel_drvdata - specifics associated to a funnel component @@ -42,6 +45,8 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); * @priority: port selection order. * @spinlock: serialize enable/disable operations. * @supported_cpus: Represent the CPUs related to this funnel. + * @dev: pointer to the device associated with this funnel. + * @link: list node for adding this funnel to the delayed probe list. */ struct funnel_drvdata { void __iomem *base; @@ -51,6 +56,8 @@ struct funnel_drvdata { unsigned long priority; raw_spinlock_t spinlock; struct cpumask *supported_cpus; + struct device *dev; + struct list_head link; }; struct funnel_smp_arg { @@ -371,7 +378,7 @@ static int funnel_probe(struct device *dev, struct resource *res) drvdata->supported_cpus = funnel_get_supported_cpus(dev); if (!drvdata->supported_cpus) return -EINVAL; - + drvdata->dev = dev; cpus_read_lock(); for_each_cpu(cpu, drvdata->supported_cpus) { ret = smp_call_function_single(cpu, @@ -379,10 +386,15 @@ static int funnel_probe(struct device *dev, struct resource *res) if (!ret) break; } - cpus_read_unlock(); - if (ret) + if (ret) { + scoped_guard(spinlock, &delay_lock) + list_add(&drvdata->link, &funnel_delay_probe); + cpus_read_unlock(); return 0; + } + + cpus_read_unlock(); } else if (res) { funnel_clear_self_claim_tag(drvdata); } @@ -394,9 +406,12 @@ static int funnel_remove(struct device *dev) { struct funnel_drvdata *drvdata = dev_get_drvdata(dev); - if (drvdata->csdev) + if (drvdata->csdev) { coresight_unregister(drvdata->csdev); - + } else { + scoped_guard(spinlock, &delay_lock) + list_del(&drvdata->link); + } return 0; } @@ -533,8 +548,41 @@ static struct amba_driver dynamic_funnel_driver = { .id_table = dynamic_funnel_ids, }; +static int funnel_online_cpu(unsigned int cpu) +{ + struct funnel_drvdata *drvdata, *tmp; + int ret; + + list_for_each_entry_safe(drvdata, tmp, &funnel_delay_probe, link) { + if (cpumask_test_cpu(cpu, drvdata->supported_cpus)) { + scoped_guard(spinlock, &delay_lock) + list_del(&drvdata->link); + + ret = pm_runtime_resume_and_get(drvdata->dev); + if (ret < 0) + return 0; + + funnel_clear_self_claim_tag(drvdata); + funnel_add_coresight_dev(drvdata->dev); + pm_runtime_put(drvdata->dev); + } + } + return 0; +} + static int __init funnel_init(void) { + int ret; + + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "arm/coresight-funnel:online", + funnel_online_cpu, NULL); + + if (ret > 0) + hp_online = ret; + else + return ret; + return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver, THIS_MODULE); } @@ -542,6 +590,10 @@ static int __init funnel_init(void) static void __exit funnel_exit(void) { coresight_remove_driver(&dynamic_funnel_driver, &funnel_driver); + if (hp_online) { + cpuhp_remove_state_nocalls(hp_online); + hp_online = 0; + } } module_init(funnel_init); From 83e65e98207f133429dc29bb782877ff6973c626 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:44 -0800 Subject: [PATCH 152/438] FROMLIST: coresight-replicator: Support CPU cluster replicator initialization Replicators associated with CPU clusters reside in the cluster's power domain. Unlike system-wide replicators, their registers are only accessible when the cluster is powered on. Standard runtime PM may not suffice to wake up a cluster from low-power states, making direct register access unreliable during initialization or operation. Enhance the replicator driver to support these per-cluster devices: 1. Safe Initialization: - Identify per-cluster replicators via device properties. - Use smp_call_function_single() to perform hardware initialization (reset and claim tag clearing) on a CPU within the cluster. - Refactor the probe flow to encapsulate device registration in replicator_add_coresight_dev(). 2. Cross-CPU Enablement: - Update replicator_enable() to use smp_call_function_single() when enabling the hardware on a cluster-bound replicator. 3. Claim/Disclaim Handling: - Introduce replicator_claim/disclaim_device_unlocked() to manage device access safely before full framework registration. This ensures that replicator operations remain robust even when the associated CPU cluster is in low-power states, while maintaining compatibility with existing system-level replicators. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-4-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../coresight/coresight-replicator.c | 200 +++++++++++++++--- 1 file changed, 167 insertions(+), 33 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index e6472658235dc..c11da452559c7 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); * @csdev: component vitals needed by the framework * @spinlock: serialize enable/disable operations. * @check_idfilter_val: check if the context is lost upon clock removal. + * @supported_cpus: Represent the CPUs related to this funnel. */ struct replicator_drvdata { void __iomem *base; @@ -43,18 +45,61 @@ struct replicator_drvdata { struct coresight_device *csdev; raw_spinlock_t spinlock; bool check_idfilter_val; + struct cpumask *supported_cpus; }; -static void dynamic_replicator_reset(struct replicator_drvdata *drvdata) +struct replicator_smp_arg { + struct replicator_drvdata *drvdata; + int outport; + int rc; +}; + +static void replicator_clear_self_claim_tag(struct replicator_drvdata *drvdata) +{ + struct csdev_access access = CSDEV_ACCESS_IOMEM(drvdata->base); + + coresight_clear_self_claim_tag(&access); +} + +static int replicator_claim_device_unlocked(struct replicator_drvdata *drvdata) +{ + struct coresight_device *csdev = drvdata->csdev; + struct csdev_access access = CSDEV_ACCESS_IOMEM(drvdata->base); + u32 claim_tag; + + if (csdev) + return coresight_claim_device_unlocked(csdev); + + writel_relaxed(CORESIGHT_CLAIM_SELF_HOSTED, drvdata->base + CORESIGHT_CLAIMSET); + + claim_tag = readl_relaxed(drvdata->base + CORESIGHT_CLAIMCLR); + if (claim_tag != CORESIGHT_CLAIM_SELF_HOSTED) { + coresight_clear_self_claim_tag_unlocked(&access); + return -EBUSY; + } + + return 0; +} + +static void replicator_disclaim_device_unlocked(struct replicator_drvdata *drvdata) { struct coresight_device *csdev = drvdata->csdev; + struct csdev_access access = CSDEV_ACCESS_IOMEM(drvdata->base); + + if (csdev) + return coresight_disclaim_device_unlocked(csdev); + coresight_clear_self_claim_tag_unlocked(&access); +} + +static void dynamic_replicator_reset(struct replicator_drvdata *drvdata) +{ CS_UNLOCK(drvdata->base); - if (!coresight_claim_device_unlocked(csdev)) { + if (!replicator_claim_device_unlocked(drvdata)) { writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0); writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1); - coresight_disclaim_device_unlocked(csdev); + replicator_disclaim_device_unlocked(drvdata); } CS_LOCK(drvdata->base); @@ -116,6 +161,34 @@ static int dynamic_replicator_enable(struct replicator_drvdata *drvdata, return rc; } +static void replicator_enable_hw_smp_call(void *info) +{ + struct replicator_smp_arg *arg = info; + + arg->rc = dynamic_replicator_enable(arg->drvdata, 0, arg->outport); +} + +static int replicator_enable_hw(struct replicator_drvdata *drvdata, + int inport, int outport) +{ + int cpu, ret; + struct replicator_smp_arg arg = { 0 }; + + if (!drvdata->supported_cpus) + return dynamic_replicator_enable(drvdata, 0, outport); + + arg.drvdata = drvdata; + arg.outport = outport; + + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, replicator_enable_hw_smp_call, &arg, 1); + if (!ret) + return arg.rc; + } + + return ret; +} + static int replicator_enable(struct coresight_device *csdev, struct coresight_connection *in, struct coresight_connection *out) @@ -126,19 +199,24 @@ static int replicator_enable(struct coresight_device *csdev, bool first_enable = false; raw_spin_lock_irqsave(&drvdata->spinlock, flags); - if (out->src_refcnt == 0) { - if (drvdata->base) - rc = dynamic_replicator_enable(drvdata, in->dest_port, - out->src_port); - if (!rc) - first_enable = true; - } - if (!rc) + + if (out->src_refcnt == 0) + first_enable = true; + else out->src_refcnt++; raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); - if (first_enable) - dev_dbg(&csdev->dev, "REPLICATOR enabled\n"); + if (first_enable) { + if (drvdata->base) + rc = replicator_enable_hw(drvdata, in->dest_port, + out->src_port); + if (!rc) { + out->src_refcnt++; + dev_dbg(&csdev->dev, "REPLICATOR enabled\n"); + return rc; + } + } + return rc; } @@ -217,23 +295,69 @@ static const struct attribute_group *replicator_groups[] = { NULL, }; +static int replicator_add_coresight_dev(struct device *dev) +{ + struct coresight_desc desc = { 0 }; + struct replicator_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata->base) { + desc.groups = replicator_groups; + desc.access = CSDEV_ACCESS_IOMEM(drvdata->base); + } + + desc.name = coresight_alloc_device_name(&replicator_devs, dev); + if (!desc.name) + return -ENOMEM; + + desc.type = CORESIGHT_DEV_TYPE_LINK; + desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; + desc.ops = &replicator_cs_ops; + desc.pdata = dev->platform_data; + desc.dev = dev; + + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + return 0; +} + +static void replicator_init_hw(struct replicator_drvdata *drvdata) +{ + replicator_clear_self_claim_tag(drvdata); + replicator_reset(drvdata); +} + +static void replicator_init_on_cpu(void *info) +{ + struct replicator_drvdata *drvdata = info; + + replicator_init_hw(drvdata); +} + +static struct cpumask *replicator_get_supported_cpus(struct device *dev) +{ + struct generic_pm_domain *pd; + + pd = pd_to_genpd(dev->pm_domain); + if (pd) + return pd->cpus; + + return NULL; +} + static int replicator_probe(struct device *dev, struct resource *res) { struct coresight_platform_data *pdata = NULL; struct replicator_drvdata *drvdata; - struct coresight_desc desc = { 0 }; void __iomem *base; - int ret; + int cpu, ret; if (is_of_node(dev_fwnode(dev)) && of_device_is_compatible(dev->of_node, "arm,coresight-replicator")) dev_warn_once(dev, "Uses OBSOLETE CoreSight replicator binding\n"); - desc.name = coresight_alloc_device_name(&replicator_devs, dev); - if (!desc.name) - return -ENOMEM; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -251,9 +375,6 @@ static int replicator_probe(struct device *dev, struct resource *res) if (IS_ERR(base)) return PTR_ERR(base); drvdata->base = base; - desc.groups = replicator_groups; - desc.access = CSDEV_ACCESS_IOMEM(base); - coresight_clear_self_claim_tag(&desc.access); } if (fwnode_property_present(dev_fwnode(dev), @@ -268,25 +389,38 @@ static int replicator_probe(struct device *dev, struct resource *res) dev->platform_data = pdata; raw_spin_lock_init(&drvdata->spinlock); - desc.type = CORESIGHT_DEV_TYPE_LINK; - desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; - desc.ops = &replicator_cs_ops; - desc.pdata = dev->platform_data; - desc.dev = dev; - drvdata->csdev = coresight_register(&desc); - if (IS_ERR(drvdata->csdev)) - return PTR_ERR(drvdata->csdev); + if (fwnode_property_present(dev_fwnode(dev), "qcom,cpu-bound-components")) { + drvdata->supported_cpus = replicator_get_supported_cpus(dev); + if (!drvdata->supported_cpus) + return -EINVAL; + + cpus_read_lock(); + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + replicator_init_on_cpu, drvdata, 1); + if (!ret) + break; + } + cpus_read_unlock(); - replicator_reset(drvdata); - return 0; + if (ret) + return 0; + } else if (res) { + replicator_init_hw(drvdata); + } + + ret = replicator_add_coresight_dev(dev); + + return ret; } static int replicator_remove(struct device *dev) { struct replicator_drvdata *drvdata = dev_get_drvdata(dev); - coresight_unregister(drvdata->csdev); + if (drvdata->csdev) + coresight_unregister(drvdata->csdev); return 0; } From 7a15dbad17de6a5c554417f14be097ba068c1151 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:45 -0800 Subject: [PATCH 153/438] FROMLIST: coresight-replicator: Defer probe when associated CPUs are offline Per-cluster replicators rely on the associated CPU cluster being online to securely access registers during initialization. If all CPUs in the cluster are offline during probe, these operations fail. Support deferred initialization for these devices: 1. Track replicators that fail to probe due to offline CPUs in a global list. 2. Register a CPU hotplug notifier (`replicator_online_cpu`) to detect when a relevant CPU comes online. 3. Upon CPU online, retry the hardware initialization and registration with the CoreSight framework. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-5-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../coresight/coresight-replicator.c | 65 +++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index c11da452559c7..f8d13894098f1 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -26,6 +26,9 @@ #define REPLICATOR_IDFILTER1 0x004 DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); +static LIST_HEAD(replicator_delay_probe); +static enum cpuhp_state hp_online; +static DEFINE_SPINLOCK(delay_lock); /** * struct replicator_drvdata - specifics associated to a replicator component @@ -37,6 +40,8 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); * @spinlock: serialize enable/disable operations. * @check_idfilter_val: check if the context is lost upon clock removal. * @supported_cpus: Represent the CPUs related to this funnel. + * @dev: pointer to the device associated with this replicator. + * @link: link to the delay_probed list. */ struct replicator_drvdata { void __iomem *base; @@ -46,6 +51,8 @@ struct replicator_drvdata { raw_spinlock_t spinlock; bool check_idfilter_val; struct cpumask *supported_cpus; + struct device *dev; + struct list_head link; }; struct replicator_smp_arg { @@ -394,7 +401,7 @@ static int replicator_probe(struct device *dev, struct resource *res) drvdata->supported_cpus = replicator_get_supported_cpus(dev); if (!drvdata->supported_cpus) return -EINVAL; - + drvdata->dev = dev; cpus_read_lock(); for_each_cpu(cpu, drvdata->supported_cpus) { ret = smp_call_function_single(cpu, @@ -402,10 +409,15 @@ static int replicator_probe(struct device *dev, struct resource *res) if (!ret) break; } - cpus_read_unlock(); - if (ret) + if (ret) { + scoped_guard(spinlock, &delay_lock) + list_add(&drvdata->link, &replicator_delay_probe); + cpus_read_unlock(); return 0; + } + + cpus_read_unlock(); } else if (res) { replicator_init_hw(drvdata); } @@ -419,8 +431,13 @@ static int replicator_remove(struct device *dev) { struct replicator_drvdata *drvdata = dev_get_drvdata(dev); - if (drvdata->csdev) + if (drvdata->csdev) { coresight_unregister(drvdata->csdev); + } else { + scoped_guard(spinlock, &delay_lock) + list_del(&drvdata->link); + } + return 0; } @@ -552,8 +569,44 @@ static struct amba_driver dynamic_replicator_driver = { .id_table = dynamic_replicator_ids, }; +static int replicator_online_cpu(unsigned int cpu) +{ + struct replicator_drvdata *drvdata, *tmp; + int ret; + + spin_lock(&delay_lock); + list_for_each_entry_safe(drvdata, tmp, &replicator_delay_probe, link) { + if (cpumask_test_cpu(cpu, drvdata->supported_cpus)) { + list_del(&drvdata->link); + spin_unlock(&delay_lock); + ret = pm_runtime_resume_and_get(drvdata->dev); + if (ret < 0) + return 0; + + replicator_clear_self_claim_tag(drvdata); + replicator_reset(drvdata); + replicator_add_coresight_dev(drvdata->dev); + pm_runtime_put(drvdata->dev); + spin_lock(&delay_lock); + } + } + spin_unlock(&delay_lock); + return 0; +} + static int __init replicator_init(void) { + int ret; + + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "arm/coresight-replicator:online", + replicator_online_cpu, NULL); + + if (ret > 0) + hp_online = ret; + else + return ret; + return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver, THIS_MODULE); } @@ -561,6 +614,10 @@ static int __init replicator_init(void) static void __exit replicator_exit(void) { coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver); + if (hp_online) { + cpuhp_remove_state_nocalls(hp_online); + hp_online = 0; + } } module_init(replicator_init); From 8ec3ae69fc89725fa679e34d048423779971edf7 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:46 -0800 Subject: [PATCH 154/438] FROMLIST: coresight-replicator: Update management interface for CPU-bound devices Standard system replicators allow direct register access from any CPU. However, replicators associated with specific CPU clusters share the cluster's power domain and require access via a CPU within that domain. Replace the standard `coresight_simple_reg*` accessors with custom handlers (`coresight_replicator_reg*`) to support these devices: - For cluster-bound replicators (indicated by `supported_cpus`), use `smp_call_function_single()` to read registers on an associated CPU. - For standard replicators, retain the direct access behavior. This ensures correct operation for per-cluster replicators while maintaining compatibility for existing system-level devices. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-6-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../coresight/coresight-replicator.c | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index f8d13894098f1..a9f22d0e15de2 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -58,6 +58,7 @@ struct replicator_drvdata { struct replicator_smp_arg { struct replicator_drvdata *drvdata; int outport; + u32 offset; int rc; }; @@ -286,9 +287,65 @@ static const struct coresight_ops replicator_cs_ops = { .link_ops = &replicator_link_ops, }; +static void replicator_read_register_smp_call(void *info) +{ + struct replicator_smp_arg *arg = info; + + arg->rc = readl_relaxed(arg->drvdata->base + arg->offset); +} + +static ssize_t coresight_replicator_reg32_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct replicator_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cs_off_attribute *cs_attr = container_of(attr, struct cs_off_attribute, attr); + unsigned long flags; + struct replicator_smp_arg arg = { 0 }; + u32 val; + int ret, cpu; + + pm_runtime_get_sync(dev->parent); + + if (!drvdata->supported_cpus) { + raw_spin_lock_irqsave(&drvdata->spinlock, flags); + val = readl_relaxed(drvdata->base + cs_attr->off); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + + } else { + arg.drvdata = drvdata; + arg.offset = cs_attr->off; + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + replicator_read_register_smp_call, + &arg, 1); + if (!ret) + break; + } + if (!ret) { + val = arg.rc; + } else { + pm_runtime_put_sync(dev->parent); + return ret; + } + } + + pm_runtime_put_sync(dev->parent); + + return sysfs_emit(buf, "0x%x\n", val); +} + +#define coresight_replicator_reg32(name, offset) \ + (&((struct cs_off_attribute[]) { \ + { \ + __ATTR(name, 0444, coresight_replicator_reg32_show, NULL), \ + offset \ + } \ + })[0].attr.attr) + static struct attribute *replicator_mgmt_attrs[] = { - coresight_simple_reg32(idfilter0, REPLICATOR_IDFILTER0), - coresight_simple_reg32(idfilter1, REPLICATOR_IDFILTER1), + coresight_replicator_reg32(idfilter0, REPLICATOR_IDFILTER0), + coresight_replicator_reg32(idfilter1, REPLICATOR_IDFILTER1), NULL, }; From c28d68840ea08033a2e0dc3108a2f5a79cd913e9 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:47 -0800 Subject: [PATCH 155/438] FROMLIST: coresight-tmc: Support probe and initialization for CPU cluster TMCs TMC instances associated with CPU clusters reside in the cluster's power domain. Unlike system-level TMCs, their registers are only accessible when the cluster is powered on. Standard runtime PM may not suffice to wake up a cluster from low-power states during probe, making direct register access unreliable. Refactor the probe sequence to handle these per-cluster devices safely: 1. Identify per-cluster TMCs using the "qcom,cpu-bound-components" property. 2. For such devices, use `smp_call_function_single()` to perform hardware initialization (`tmc_init_hw_config`) on a CPU within the cluster. This ensures the domain is powered during access. 3. Factor out the device registration logic into `tmc_add_coresight_dev()`. This allows common registration code to be shared between the standard probe path and the deferred probe path (used when the associated CPUs are initially offline). This change ensures reliable initialization for per-cluster TMCs while maintaining backward compatibility for standard system-level TMCs. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-7-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-tmc-core.c | 195 +++++++++++------- drivers/hwtracing/coresight/coresight-tmc.h | 6 + 2 files changed, 132 insertions(+), 69 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 6486bdafdddc4..d9d366f9d219d 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -810,56 +811,14 @@ static const struct tmc_sysfs_ops etr_sysfs_ops = { .get_trace_data = tmc_etr_get_sysfs_trace, }; -static int __tmc_probe(struct device *dev, struct resource *res) +static int tmc_add_coresight_dev(struct device *dev) { - int ret = 0; - u32 devid; - void __iomem *base; - struct coresight_platform_data *pdata = NULL; - struct tmc_drvdata *drvdata; + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); struct coresight_desc desc = { 0 }; struct coresight_dev_list *dev_list = NULL; + int ret = 0; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - - dev_set_drvdata(dev, drvdata); - - ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); - if (ret) - return ret; - - ret = -ENOMEM; - - /* Validity for the resource is already checked by the AMBA core */ - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) { - ret = PTR_ERR(base); - goto out; - } - - drvdata->base = base; - desc.access = CSDEV_ACCESS_IOMEM(base); - - raw_spin_lock_init(&drvdata->spinlock); - - devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); - drvdata->config_type = BMVAL(devid, 6, 7); - drvdata->memwidth = tmc_get_memwidth(devid); - /* This device is not associated with a session */ - drvdata->pid = -1; - drvdata->etr_mode = ETR_MODE_AUTO; - - if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { - drvdata->size = tmc_etr_get_default_buffer_size(dev); - drvdata->max_burst_size = tmc_etr_get_max_burst_size(dev); - } else { - drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; - } - - tmc_get_reserved_region(dev); - + desc.access = CSDEV_ACCESS_IOMEM(drvdata->base); desc.dev = dev; switch (drvdata->config_type) { @@ -876,9 +835,9 @@ static int __tmc_probe(struct device *dev, struct resource *res) desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM; desc.ops = &tmc_etr_cs_ops; - ret = tmc_etr_setup_caps(dev, devid, &desc.access); + ret = tmc_etr_setup_caps(dev, drvdata->devid, &desc.access); if (ret) - goto out; + return ret; idr_init(&drvdata->idr); mutex_init(&drvdata->idr_mutex); dev_list = &etr_devs; @@ -896,44 +855,141 @@ static int __tmc_probe(struct device *dev, struct resource *res) break; default: pr_err("%s: Unsupported TMC config\n", desc.name); - ret = -EINVAL; - goto out; + return -EINVAL; } desc.name = coresight_alloc_device_name(dev_list, dev); - if (!desc.name) { - ret = -ENOMEM; + if (!desc.name) + return -ENOMEM; + + drvdata->desc_name = desc.name; + + desc.pdata = dev->platform_data; + + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + drvdata->miscdev.name = desc.name; + drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; + drvdata->miscdev.fops = &tmc_fops; + ret = misc_register(&drvdata->miscdev); + if (ret) + coresight_unregister(drvdata->csdev); + + return ret; +} + +static void tmc_clear_self_claim_tag(struct tmc_drvdata *drvdata) +{ + struct csdev_access access = CSDEV_ACCESS_IOMEM(drvdata->base); + + coresight_clear_self_claim_tag(&access); +} + +static void tmc_init_hw_config(struct tmc_drvdata *drvdata) +{ + u32 devid; + + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); + drvdata->config_type = BMVAL(devid, 6, 7); + drvdata->memwidth = tmc_get_memwidth(devid); + drvdata->devid = devid; + drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; + tmc_clear_self_claim_tag(drvdata); +} + +static void tmc_init_on_cpu(void *info) +{ + struct tmc_drvdata *drvdata = info; + + tmc_init_hw_config(drvdata); +} + +static struct cpumask *tmc_get_supported_cpus(struct device *dev) +{ + struct generic_pm_domain *pd; + + pd = pd_to_genpd(dev->pm_domain); + if (pd) + return pd->cpus; + + return NULL; +} + +static int __tmc_probe(struct device *dev, struct resource *res) +{ + int cpu, ret = 0; + void __iomem *base; + struct coresight_platform_data *pdata = NULL; + struct tmc_drvdata *drvdata; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + dev_set_drvdata(dev, drvdata); + + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); + if (ret) + return ret; + + ret = -ENOMEM; + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) { + ret = PTR_ERR(base); goto out; } + drvdata->base = base; + + raw_spin_lock_init(&drvdata->spinlock); + /* This device is not associated with a session */ + drvdata->pid = -1; + drvdata->etr_mode = ETR_MODE_AUTO; + tmc_get_reserved_region(dev); + pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) { ret = PTR_ERR(pdata); goto out; } dev->platform_data = pdata; - desc.pdata = pdata; - coresight_clear_self_claim_tag(&desc.access); - drvdata->csdev = coresight_register(&desc); - if (IS_ERR(drvdata->csdev)) { - ret = PTR_ERR(drvdata->csdev); - goto out; + if (fwnode_property_present(dev_fwnode(dev), "qcom,cpu-bound-components")) { + drvdata->supported_cpus = tmc_get_supported_cpus(dev); + if (!drvdata->supported_cpus) + return -EINVAL; + + cpus_read_lock(); + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + tmc_init_on_cpu, drvdata, 1); + if (!ret) + break; + } + cpus_read_unlock(); + if (ret) { + ret = 0; + goto out; + } + } else { + tmc_init_hw_config(drvdata); } - drvdata->miscdev.name = desc.name; - drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; - drvdata->miscdev.fops = &tmc_fops; - ret = misc_register(&drvdata->miscdev); - if (ret) { - coresight_unregister(drvdata->csdev); - goto out; + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + drvdata->size = tmc_etr_get_default_buffer_size(dev); + drvdata->max_burst_size = tmc_etr_get_max_burst_size(dev); } + ret = tmc_add_coresight_dev(dev); + out: if (is_tmc_crashdata_valid(drvdata) && !tmc_prepare_crashdata(drvdata)) - register_crash_dev_interface(drvdata, desc.name); + register_crash_dev_interface(drvdata, drvdata->desc_name); return ret; } @@ -979,10 +1035,12 @@ static void __tmc_remove(struct device *dev) * etb fops in this case, device is there until last file * handler to this device is closed. */ - misc_deregister(&drvdata->miscdev); + if (!drvdata->supported_cpus) + misc_deregister(&drvdata->miscdev); if (drvdata->crashdev.fops) misc_deregister(&drvdata->crashdev); - coresight_unregister(drvdata->csdev); + if (drvdata->csdev) + coresight_unregister(drvdata->csdev); } static void tmc_remove(struct amba_device *adev) @@ -1037,7 +1095,6 @@ static void tmc_platform_remove(struct platform_device *pdev) if (WARN_ON(!drvdata)) return; - __tmc_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); } diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index d60c70530c8a3..42fa61ee0ad2d 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -261,6 +261,9 @@ struct etr_buf_node { * @etr_buf_list: List that is used to manage allocated etr_buf. * @reading_node: Available buffer_node for byte-cntr reading. * @sysfs_ops: Read operations for sysfs mode. + * @supported_cpus: Represent the CPUs related to this TMC. + * @devid: TMC variant ID inferred from the device configuration register. + * @desc_name: Name to be used while creating crash interface. */ struct tmc_drvdata { struct clk *atclk; @@ -294,6 +297,9 @@ struct tmc_drvdata { struct list_head etr_buf_list; struct etr_buf_node *reading_node; const struct tmc_sysfs_ops *sysfs_ops; + struct cpumask *supported_cpus; + u32 devid; + const char *desc_name; }; /** From d5eecaa78200fd214109af1a8529e27a565e9016 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:48 -0800 Subject: [PATCH 156/438] FROMLIST: coresight-tmc-etf: Refactor enable function for CPU cluster ETF support TMC-ETF devices associated with specific CPU clusters share the cluster's power domain. Accessing their registers requires the cluster to be powered on, which can only be guaranteed by running code on a CPU within that cluster. Refactor the enablement logic to support this requirement: 1. Split `tmc_etf_enable_hw` and `tmc_etb_enable_hw` into local and SMP-aware variants: - `*_local`: Performs the actual register access. - `*_smp_call`: Wrapper for `smp_call_function_single`. - The main entry point now detects if the device is CPU-bound and uses `smp_call_function_single` to execute the local variant on an appropriate CPU if necessary. 2. Adjust locking in `tmc_enable_etf_sink_sysfs` and `tmc_enable_etf_link`: - Drop the spinlock before calling `tmc_etf_enable_hw`. This is necessary because `smp_call_function_single` (used for cross-CPU calls) may require interrupts enabled or might sleep/wait, which is unsafe under a spinlock. - Re-acquire the lock afterwards to update driver state. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-8-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-tmc-etf.c | 87 ++++++++++++++++--- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 8882b1c4cdc05..11357788e9d93 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -47,7 +47,7 @@ static int __tmc_etb_enable_hw(struct tmc_drvdata *drvdata) return rc; } -static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata) +static int tmc_etb_enable_hw_local(struct tmc_drvdata *drvdata) { int rc = coresight_claim_device(drvdata->csdev); @@ -60,6 +60,36 @@ static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata) return rc; } +struct tmc_smp_arg { + struct tmc_drvdata *drvdata; + int rc; +}; + +static void tmc_etb_enable_hw_smp_call(void *info) +{ + struct tmc_smp_arg *arg = info; + + arg->rc = tmc_etb_enable_hw_local(arg->drvdata); +} + +static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata) +{ + int cpu, ret; + struct tmc_smp_arg arg = { 0 }; + + if (!drvdata->supported_cpus) + return tmc_etb_enable_hw_local(drvdata); + + arg.drvdata = drvdata; + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + tmc_etb_enable_hw_smp_call, &arg, 1); + if (!ret) + return arg.rc; + } + return ret; +} + static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata) { char *bufp; @@ -130,7 +160,7 @@ static int __tmc_etf_enable_hw(struct tmc_drvdata *drvdata) return rc; } -static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata) +static int tmc_etf_enable_hw_local(struct tmc_drvdata *drvdata) { int rc = coresight_claim_device(drvdata->csdev); @@ -143,6 +173,32 @@ static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata) return rc; } +static void tmc_etf_enable_hw_smp_call(void *info) +{ + struct tmc_smp_arg *arg = info; + + arg->rc = tmc_etf_enable_hw_local(arg->drvdata); +} + +static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata) +{ + int cpu, ret; + struct tmc_smp_arg arg = { 0 }; + + if (!drvdata->supported_cpus) + return tmc_etf_enable_hw_local(drvdata); + + arg.drvdata = drvdata; + + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + tmc_etf_enable_hw_smp_call, &arg, 1); + if (!ret) + return arg.rc; + } + return ret; +} + static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata) { struct coresight_device *csdev = drvdata->csdev; @@ -228,7 +284,11 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) used = true; drvdata->buf = buf; } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + ret = tmc_etb_enable_hw(drvdata); + + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (!ret) { coresight_set_mode(csdev, CS_MODE_SYSFS); csdev->refcnt++; @@ -291,7 +351,11 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, break; } - ret = tmc_etb_enable_hw(drvdata); + if (drvdata->supported_cpus && + !cpumask_test_cpu(smp_processor_id(), drvdata->supported_cpus)) + break; + + ret = tmc_etb_enable_hw_local(drvdata); if (!ret) { /* Associate with monitored process. */ drvdata->pid = pid; @@ -376,19 +440,22 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, return -EBUSY; } - if (csdev->refcnt == 0) { + if (csdev->refcnt == 0) + first_enable = true; + + if (!first_enable) + csdev->refcnt++; + + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + if (first_enable) { ret = tmc_etf_enable_hw(drvdata); if (!ret) { coresight_set_mode(csdev, CS_MODE_SYSFS); - first_enable = true; + csdev->refcnt++; + dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); } } - if (!ret) - csdev->refcnt++; - raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); - if (first_enable) - dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); return ret; } From d14f078f5631cbebfa0bdf12d9440f17dd34d733 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:49 -0800 Subject: [PATCH 157/438] FROMLIST: coresight-tmc: Update management interface for CPU-bound TMCs The current TMC management interface (sysfs attributes) assumes that device registers can be accessed directly from any CPU. However, for TMCs associated with specific CPU clusters, registers must be accessed from a CPU within that cluster. Replace the standard `coresight_simple_reg*` handlers with custom accessors (`coresight_tmc_reg*`). These new handlers check if the TMC is bound to a specific set of CPUs: - If bound, they use `smp_call_function_single()` to read the register on an appropriate CPU. - If not bound (global TMC), they fall back to direct access. This ensures correct register reads for per-cluster TMC devices while maintaining backward compatibility for global TMCs. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-9-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-tmc-core.c | 137 ++++++++++++++++-- 1 file changed, 123 insertions(+), 14 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index d9d366f9d219d..232f8f6be2dc4 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -487,21 +487,130 @@ static enum tmc_mem_intf_width tmc_get_memwidth(u32 devid) return memwidth; } +struct tmc_smp_arg { + struct tmc_drvdata *drvdata; + u32 offset; + int rc; +}; + +static void tmc_read_reg_smp_call(void *info) +{ + struct tmc_smp_arg *arg = info; + + arg->rc = readl_relaxed(arg->drvdata->base + arg->offset); +} + +static u32 cpu_tmc_read_reg(struct tmc_drvdata *drvdata, u32 offset) +{ + struct tmc_smp_arg arg = { + .drvdata = drvdata, + .offset = offset, + }; + int cpu, ret = 0; + + for_each_cpu(cpu, drvdata->supported_cpus) { + ret = smp_call_function_single(cpu, + tmc_read_reg_smp_call, &arg, 1); + if (!ret) + return arg.rc; + } + + return ret; +} + +static ssize_t coresight_tmc_reg32_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cs_off_attribute *cs_attr = container_of(attr, struct cs_off_attribute, attr); + int ret; + u32 val; + + ret = pm_runtime_resume_and_get(dev->parent); + if (ret < 0) + return ret; + + if (!drvdata->supported_cpus) + val = readl_relaxed(drvdata->base + cs_attr->off); + else + val = cpu_tmc_read_reg(drvdata, cs_attr->off); + + pm_runtime_put(dev->parent); + + if (ret < 0) + return ret; + else + return sysfs_emit(buf, "0x%x\n", val); +} + +static ssize_t coresight_tmc_reg64_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cs_pair_attribute *cs_attr = container_of(attr, struct cs_pair_attribute, attr); + int ret; + u64 val; + + ret = pm_runtime_resume_and_get(dev->parent); + if (ret < 0) + return ret; + if (!drvdata->supported_cpus) { + val = readl_relaxed(drvdata->base + cs_attr->lo_off) | + ((u64)readl_relaxed(drvdata->base + cs_attr->hi_off) << 32); + } else { + ret = cpu_tmc_read_reg(drvdata, cs_attr->lo_off); + + if (ret < 0) + goto out; + + val = ret; + + ret = cpu_tmc_read_reg(drvdata, cs_attr->hi_off); + if (ret < 0) + goto out; + + val |= ((u64)ret << 32); + } + +out: + pm_runtime_put_sync(dev->parent); + if (ret < 0) + return ret; + else + return sysfs_emit(buf, "0x%llx\n", val); +} + +#define coresight_tmc_reg32(name, offset) \ + (&((struct cs_off_attribute[]) { \ + { \ + __ATTR(name, 0444, coresight_tmc_reg32_show, NULL), \ + offset \ + } \ + })[0].attr.attr) +#define coresight_tmc_reg64(name, lo_off, hi_off) \ + (&((struct cs_pair_attribute[]) { \ + { \ + __ATTR(name, 0444, coresight_tmc_reg64_show, NULL), \ + lo_off, hi_off \ + } \ + })[0].attr.attr) static struct attribute *coresight_tmc_mgmt_attrs[] = { - coresight_simple_reg32(rsz, TMC_RSZ), - coresight_simple_reg32(sts, TMC_STS), - coresight_simple_reg64(rrp, TMC_RRP, TMC_RRPHI), - coresight_simple_reg64(rwp, TMC_RWP, TMC_RWPHI), - coresight_simple_reg32(trg, TMC_TRG), - coresight_simple_reg32(ctl, TMC_CTL), - coresight_simple_reg32(ffsr, TMC_FFSR), - coresight_simple_reg32(ffcr, TMC_FFCR), - coresight_simple_reg32(mode, TMC_MODE), - coresight_simple_reg32(pscr, TMC_PSCR), - coresight_simple_reg32(devid, CORESIGHT_DEVID), - coresight_simple_reg64(dba, TMC_DBALO, TMC_DBAHI), - coresight_simple_reg32(axictl, TMC_AXICTL), - coresight_simple_reg32(authstatus, TMC_AUTHSTATUS), + coresight_tmc_reg32(rsz, TMC_RSZ), + coresight_tmc_reg32(sts, TMC_STS), + coresight_tmc_reg64(rrp, TMC_RRP, TMC_RRPHI), + coresight_tmc_reg64(rwp, TMC_RWP, TMC_RWPHI), + coresight_tmc_reg32(trg, TMC_TRG), + coresight_tmc_reg32(ctl, TMC_CTL), + coresight_tmc_reg32(ffsr, TMC_FFSR), + coresight_tmc_reg32(ffcr, TMC_FFCR), + coresight_tmc_reg32(mode, TMC_MODE), + coresight_tmc_reg32(pscr, TMC_PSCR), + coresight_tmc_reg32(devid, CORESIGHT_DEVID), + coresight_tmc_reg64(dba, TMC_DBALO, TMC_DBAHI), + coresight_tmc_reg32(axictl, TMC_AXICTL), + coresight_tmc_reg32(authstatus, TMC_AUTHSTATUS), NULL, }; From 9d4389c79cd5477f3af57f599c9abeefe0060332 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:50 -0800 Subject: [PATCH 158/438] FROMLIST: coresight-tmc: Defer probe when associated CPUs are offline On some platforms, the TMC driver may probe before the associated CPUs are online. This prevents the driver from securely accessing the hardware or configuring it via smp_call_function_single(), which requires the target CPU to be available. To address this, defer the hardware initialization if the associated CPUs are offline: 1. Track such deferred devices in a global list. 2. Register a CPU hotplug callback (`tmc_online_cpu`) to detect when a relevant CPU comes online. 3. Upon CPU online, retry the hardware initialization and registration for the waiting TMC devices. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-10-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-tmc-core.c | 59 ++++++++++++++++++- drivers/hwtracing/coresight/coresight-tmc.h | 4 ++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 232f8f6be2dc4..5e873bdcf7bb3 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -37,6 +37,9 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb"); DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf"); DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr"); +static LIST_HEAD(tmc_delay_probe); +static enum cpuhp_state hp_online; +static DEFINE_SPINLOCK(delay_lock); int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata) { @@ -1072,6 +1075,8 @@ static int __tmc_probe(struct device *dev, struct resource *res) if (!drvdata->supported_cpus) return -EINVAL; + drvdata->dev = dev; + cpus_read_lock(); for_each_cpu(cpu, drvdata->supported_cpus) { ret = smp_call_function_single(cpu, @@ -1079,11 +1084,16 @@ static int __tmc_probe(struct device *dev, struct resource *res) if (!ret) break; } - cpus_read_unlock(); + if (ret) { + scoped_guard(spinlock, &delay_lock) + list_add(&drvdata->link, &tmc_delay_probe); + cpus_read_unlock(); ret = 0; goto out; } + + cpus_read_unlock(); } else { tmc_init_hw_config(drvdata); } @@ -1148,8 +1158,12 @@ static void __tmc_remove(struct device *dev) misc_deregister(&drvdata->miscdev); if (drvdata->crashdev.fops) misc_deregister(&drvdata->crashdev); - if (drvdata->csdev) + if (drvdata->csdev) { coresight_unregister(drvdata->csdev); + } else { + scoped_guard(spinlock, &delay_lock) + list_del(&drvdata->link); + } } static void tmc_remove(struct amba_device *adev) @@ -1260,14 +1274,55 @@ static struct platform_driver tmc_platform_driver = { }, }; +static int tmc_online_cpu(unsigned int cpu) +{ + struct tmc_drvdata *drvdata, *tmp; + int ret; + + spin_lock(&delay_lock); + list_for_each_entry_safe(drvdata, tmp, &tmc_delay_probe, link) { + if (cpumask_test_cpu(cpu, drvdata->supported_cpus)) { + list_del(&drvdata->link); + + spin_unlock(&delay_lock); + ret = pm_runtime_resume_and_get(drvdata->dev); + if (ret < 0) + return 0; + + tmc_init_hw_config(drvdata); + tmc_clear_self_claim_tag(drvdata); + tmc_add_coresight_dev(drvdata->dev); + pm_runtime_put(drvdata->dev); + spin_lock(&delay_lock); + } + } + spin_unlock(&delay_lock); + return 0; +} + static int __init tmc_init(void) { + int ret; + + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "arm/coresight-tmc:online", + tmc_online_cpu, NULL); + + if (ret > 0) + hp_online = ret; + else + return ret; + return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver, THIS_MODULE); } static void __exit tmc_exit(void) { coresight_remove_driver(&tmc_driver, &tmc_platform_driver); + if (hp_online) { + cpuhp_remove_state_nocalls(hp_online); + hp_online = 0; + } } module_init(tmc_init); module_exit(tmc_exit); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 42fa61ee0ad2d..9d1a2b462285b 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -264,6 +264,8 @@ struct etr_buf_node { * @supported_cpus: Represent the CPUs related to this TMC. * @devid: TMC variant ID inferred from the device configuration register. * @desc_name: Name to be used while creating crash interface. + * @dev: pointer to the device associated with this TMC. + * @link: link to the delay_probed list. */ struct tmc_drvdata { struct clk *atclk; @@ -300,6 +302,8 @@ struct tmc_drvdata { struct cpumask *supported_cpus; u32 devid; const char *desc_name; + struct device *dev; + struct list_head link; }; /** From e0380ed719f972d8c190c74414ca3341bd649ce8 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 18 Dec 2025 00:09:51 -0800 Subject: [PATCH 159/438] FROMLIST: coresight: Pass trace mode to link enable callback Currently, the link enable callback does not receive the CoreSight mode (enum cs_mode). This prevents link drivers from knowing whether they are being enabled for SysFS or Perf. This distinction is crucial because Perf mode runs in atomic context, where certain operations (like smp_call_function_single()) are unsafe. Without knowing the mode, drivers cannot conditionally avoid these unsafe calls. Update the `enable` callback in `struct coresight_ops_link` to accept `enum cs_mode`. This allows drivers to implement mode-specific logic, such as using atomic-safe enablement sequences when running in Perf mode. Update all call sites and driver implementations accordingly. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-11-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- drivers/hwtracing/coresight/coresight-core.c | 7 +++--- .../hwtracing/coresight/coresight-funnel.c | 21 ++++++++++++++++- .../coresight/coresight-replicator.c | 23 ++++++++++++++++++- .../hwtracing/coresight/coresight-tmc-etf.c | 19 ++++++++++++++- drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++- drivers/hwtracing/coresight/coresight-tpda.c | 3 ++- include/linux/coresight.h | 3 ++- 7 files changed, 70 insertions(+), 9 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 1cbaa63aa7215..8dc5291ca892e 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -314,7 +314,8 @@ static void coresight_disable_sink(struct coresight_device *csdev) static int coresight_enable_link(struct coresight_device *csdev, struct coresight_device *parent, struct coresight_device *child, - struct coresight_device *source) + struct coresight_device *source, + enum cs_mode mode) { int link_subtype; struct coresight_connection *inconn, *outconn; @@ -331,7 +332,7 @@ static int coresight_enable_link(struct coresight_device *csdev, if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && IS_ERR(outconn)) return PTR_ERR(outconn); - return link_ops(csdev)->enable(csdev, inconn, outconn); + return link_ops(csdev)->enable(csdev, inconn, outconn, mode); } static void coresight_disable_link(struct coresight_device *csdev, @@ -550,7 +551,7 @@ int coresight_enable_path(struct coresight_path *path, enum cs_mode mode) case CORESIGHT_DEV_TYPE_LINK: parent = list_prev_entry(nd, link)->csdev; child = list_next_entry(nd, link)->csdev; - ret = coresight_enable_link(csdev, parent, child, source); + ret = coresight_enable_link(csdev, parent, child, source, mode); if (ret) goto err_disable_helpers; break; diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 5d114ce1109f4..c50522c2854c7 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -121,7 +121,8 @@ static int funnel_enable_hw(struct funnel_drvdata *drvdata, int port) static int funnel_enable(struct coresight_device *csdev, struct coresight_connection *in, - struct coresight_connection *out) + struct coresight_connection *out, + enum cs_mode mode) { int rc = 0; struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); @@ -135,6 +136,23 @@ static int funnel_enable(struct coresight_device *csdev, else in->dest_refcnt++; + if (mode == CS_MODE_PERF) { + if (first_enable) { + if (drvdata->supported_cpus && + !cpumask_test_cpu(smp_processor_id(), drvdata->supported_cpus)) { + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + return -EINVAL; + } + + if (drvdata->base) + rc = dynamic_funnel_enable_hw(drvdata, in->dest_port); + if (!rc) + in->dest_refcnt++; + } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + return rc; + } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) { @@ -183,6 +201,7 @@ static void funnel_disable(struct coresight_device *csdev, dynamic_funnel_disable_hw(drvdata, in->dest_port); last_disable = true; } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (last_disable) diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index a9f22d0e15de2..cc7d3916b8b9d 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -199,7 +199,8 @@ static int replicator_enable_hw(struct replicator_drvdata *drvdata, static int replicator_enable(struct coresight_device *csdev, struct coresight_connection *in, - struct coresight_connection *out) + struct coresight_connection *out, + enum cs_mode mode) { int rc = 0; struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); @@ -212,6 +213,25 @@ static int replicator_enable(struct coresight_device *csdev, first_enable = true; else out->src_refcnt++; + + if (mode == CS_MODE_PERF) { + if (first_enable) { + if (drvdata->supported_cpus && + !cpumask_test_cpu(smp_processor_id(), drvdata->supported_cpus)) { + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + return -EINVAL; + } + + if (drvdata->base) + rc = dynamic_replicator_enable(drvdata, in->dest_port, + out->src_port); + if (!rc) + out->src_refcnt++; + } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + return rc; + } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) { @@ -272,6 +292,7 @@ static void replicator_disable(struct coresight_device *csdev, out->src_port); last_disable = true; } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (last_disable) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 11357788e9d93..f1b8264b4e5c8 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -427,7 +427,8 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) static int tmc_enable_etf_link(struct coresight_device *csdev, struct coresight_connection *in, - struct coresight_connection *out) + struct coresight_connection *out, + enum cs_mode mode) { int ret = 0; unsigned long flags; @@ -446,6 +447,22 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, if (!first_enable) csdev->refcnt++; + if (mode == CS_MODE_PERF) { + if (first_enable) { + if (drvdata->supported_cpus && + !cpumask_test_cpu(smp_processor_id(), drvdata->supported_cpus)) { + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + return -EINVAL; + } + + ret = tmc_etf_enable_hw_local(drvdata); + if (!ret) + csdev->refcnt++; + } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + return ret; + } + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) { ret = tmc_etf_enable_hw(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c index 1128612e70a73..9873b017abbd9 100644 --- a/drivers/hwtracing/coresight/coresight-tnoc.c +++ b/drivers/hwtracing/coresight/coresight-tnoc.c @@ -81,7 +81,8 @@ static void trace_noc_enable_hw(struct trace_noc_drvdata *drvdata) } static int trace_noc_enable(struct coresight_device *csdev, struct coresight_connection *inport, - struct coresight_connection *outport) + struct coresight_connection *outport, + enum cs_mode mode) { struct trace_noc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index 7055f8f134278..9d0a015e164ce 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -224,7 +224,8 @@ static int __tpda_enable(struct tpda_drvdata *drvdata, int port) static int tpda_enable(struct coresight_device *csdev, struct coresight_connection *in, - struct coresight_connection *out) + struct coresight_connection *out, + enum cs_mode mode) { struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); int ret = 0; diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 2b48be97fcd0d..218eb1d1dcef6 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -383,7 +383,8 @@ struct coresight_ops_sink { struct coresight_ops_link { int (*enable)(struct coresight_device *csdev, struct coresight_connection *in, - struct coresight_connection *out); + struct coresight_connection *out, + enum cs_mode mode); void (*disable)(struct coresight_device *csdev, struct coresight_connection *in, struct coresight_connection *out); From ef3b67a0f6fb192bc3a1145fb1f420f12562a69f Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Tue, 3 Feb 2026 14:39:38 +0800 Subject: [PATCH 160/438] FROMLIST: dt-binding: document QCOM platforms for CTCU device Document the platforms that fallback to using the qcom,sa8775p-ctcu compatible for probing. Link: https://lore.kernel.org/all/20260204-enable-ctcu-and-etr-v3-1-0bb95c590ae1@oss.qualcomm.com/ Signed-off-by: Jie Gan --- .../devicetree/bindings/arm/qcom,coresight-ctcu.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index 2981001a7d7f7..468da6439bbf9 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml @@ -29,7 +29,11 @@ properties: oneOf: - items: - enum: + - qcom,glymur-ctcu + - qcom,kaanapali-ctcu - qcom,qcs8300-ctcu + - qcom,sm8750-ctcu + - qcom,x1e80100-ctcu - const: qcom,sa8775p-ctcu - enum: - qcom,sa8775p-ctcu From a9a98c7d793be8cbe24cfb3d64af8cd015a9e37f Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 18 Dec 2025 00:09:52 -0800 Subject: [PATCH 161/438] FROMLIST: arm64: dts: qcom: hamoa: Add CoreSight nodes for APSS debug block The APSS debug block is built with CoreSight devices like ETM, replicator, funnel and TMC ETF. Add dt nodes for these devices to enable ETM trace. Link: https://lore.kernel.org/all/20251218-cpu_cluster_component_pm-v2-12-2335a6ae62a0@oss.qualcomm.com/ Signed-off-by: Jie Gan Co-developed-by: Yuanfang Zhang Signed-off-by: Yuanfang Zhang --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 926 ++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/purwa.dtsi | 12 + 2 files changed, 938 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index db65c392e6189..48d5725c4aae5 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -305,6 +305,210 @@ }; }; + etm-0 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu0>; + qcom,skip-power-up; + + out-ports { + port { + etm0_out: endpoint { + remote-endpoint = <&ncc0_0_rep_in>; + }; + }; + }; + }; + + etm-1 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu1>; + qcom,skip-power-up; + + out-ports { + port { + etm1_out: endpoint { + remote-endpoint = <&ncc0_1_rep_in>; + }; + }; + }; + }; + + etm-2 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu2>; + qcom,skip-power-up; + + out-ports { + port { + etm2_out: endpoint { + remote-endpoint = <&ncc0_2_rep_in>; + }; + }; + }; + }; + + etm-3 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu3>; + qcom,skip-power-up; + + out-ports { + port { + etm3_out: endpoint { + remote-endpoint = <&ncc0_3_rep_in>; + }; + }; + }; + }; + + etm-4 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu4>; + qcom,skip-power-up; + + out-ports { + port { + etm4_out: endpoint { + remote-endpoint = <&ncc1_0_rep_in>; + }; + }; + }; + }; + + etm-5 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu5>; + qcom,skip-power-up; + + out-ports { + port { + etm5_out: endpoint { + remote-endpoint = <&ncc1_1_rep_in>; + }; + }; + }; + }; + + etm-6 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu6>; + qcom,skip-power-up; + + out-ports { + port { + etm6_out: endpoint { + remote-endpoint = <&ncc1_2_rep_in>; + }; + }; + }; + }; + + etm-7 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu7>; + qcom,skip-power-up; + + out-ports { + port { + etm7_out: endpoint { + remote-endpoint = <&ncc1_3_rep_in>; + }; + }; + }; + }; + + etm8: etm-8 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu8>; + qcom,skip-power-up; + + out-ports { + port { + etm8_out: endpoint { + remote-endpoint = <&ncc2_0_rep_in>; + }; + }; + }; + }; + + etm9: etm-9 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu9>; + qcom,skip-power-up; + + out-ports { + port { + etm9_out: endpoint { + remote-endpoint = <&ncc2_1_rep_in>; + }; + }; + }; + }; + + etm10: etm-10 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu10>; + qcom,skip-power-up; + + out-ports { + port { + etm10_out: endpoint { + remote-endpoint = <&ncc2_2_rep_in>; + }; + }; + }; + }; + + etm11: etm-11 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + cpu = <&cpu11>; + qcom,skip-power-up; + + out-ports { + port { + etm11_out: endpoint { + remote-endpoint = <&ncc2_3_rep_in>; + }; + }; + }; + }; + firmware { scm: scm { compatible = "qcom,scm-x1e80100", "qcom,scm"; @@ -6922,6 +7126,14 @@ }; }; + port@4 { + reg = <4>; + + funnel1_in4: endpoint { + remote-endpoint = <&apss_funnel_out>; + }; + }; + port@5 { reg = <5>; @@ -8212,6 +8424,720 @@ }; }; + apss_funnel: funnel@12080000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x12080000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + apss_funnel_in0: endpoint { + remote-endpoint = <&ncc0_etf_out>; + }; + }; + + port@1 { + reg = <1>; + + apss_funnel_in1: endpoint { + remote-endpoint = <&ncc1_etf_out>; + }; + }; + + port@2 { + reg = <2>; + + apss_funnel_in2: endpoint { + remote-endpoint = <&ncc2_etf_out>; + }; + }; + }; + + out-ports { + port { + apss_funnel_out: endpoint { + remote-endpoint = <&funnel1_in4>; + }; + }; + }; + }; + + funnel@13401000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb908>; + reg = <0x0 0x13401000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + + ncc0_2_funnel_in2: endpoint { + remote-endpoint = <&ncc0_1_funnel_out>; + }; + }; + }; + + out-ports { + port { + ncc0_2_funnel_out: endpoint { + remote-endpoint = <&ncc0_etf_in>; + }; + }; + }; + }; + + tmc@13409000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb961>; + reg = <0x0 0x13409000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc0_etf_in: endpoint { + remote-endpoint = <&ncc0_2_funnel_out>; + }; + }; + }; + + out-ports { + port { + ncc0_etf_out: endpoint { + remote-endpoint = <&apss_funnel_in0>; + }; + }; + }; + }; + + replicator@13490000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x13490000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc0_0_rep_in: endpoint { + remote-endpoint = <&etm0_out>; + }; + }; + }; + + out-ports { + port { + ncc0_0_rep_out: endpoint { + remote-endpoint = <&ncc0_1_funnel_in0>; + }; + }; + }; + }; + + replicator@134a0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x134a0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc0_1_rep_in: endpoint { + remote-endpoint = <&etm1_out>; + }; + }; + }; + + out-ports { + port { + ncc0_1_rep_out: endpoint { + remote-endpoint = <&ncc0_1_funnel_in1>; + }; + }; + }; + }; + + replicator@134b0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x134b0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc0_2_rep_in: endpoint { + remote-endpoint = <&etm2_out>; + }; + }; + }; + + out-ports { + port { + ncc0_2_rep_out: endpoint { + remote-endpoint = <&ncc0_1_funnel_in2>; + }; + }; + }; + }; + + replicator@134c0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x134c0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc0_3_rep_in: endpoint { + remote-endpoint = <&etm3_out>; + }; + }; + }; + + out-ports { + port { + ncc0_3_rep_out: endpoint { + remote-endpoint = <&ncc0_1_funnel_in3>; + }; + }; + }; + }; + + funnel@134d0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb908>; + reg = <0x0 0x134d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + qcom,cpu-bound-components; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ncc0_1_funnel_in0: endpoint { + remote-endpoint = <&ncc0_0_rep_out>; + }; + }; + + port@1 { + reg = <1>; + + ncc0_1_funnel_in1: endpoint { + remote-endpoint = <&ncc0_1_rep_out>; + }; + }; + + port@2 { + reg = <2>; + + ncc0_1_funnel_in2: endpoint { + remote-endpoint = <&ncc0_2_rep_out>; + }; + }; + + port@3 { + reg = <3>; + + ncc0_1_funnel_in3: endpoint { + remote-endpoint = <&ncc0_3_rep_out>; + }; + }; + }; + + out-ports { + port { + ncc0_1_funnel_out: endpoint { + remote-endpoint = <&ncc0_2_funnel_in2>; + }; + }; + }; + }; + + funnel@13901000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb908>; + reg = <0x0 0x13901000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + + ncc1_2_funnel_in2: endpoint { + remote-endpoint = <&ncc1_1_funnel_out>; + }; + }; + }; + + out-ports { + port { + ncc1_2_funnel_out: endpoint { + remote-endpoint = <&ncc1_etf_in>; + }; + }; + }; + }; + + tmc@13909000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb961>; + reg = <0x0 0x13909000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc1_etf_in: endpoint { + remote-endpoint = <&ncc1_2_funnel_out>; + }; + }; + }; + + out-ports { + port { + ncc1_etf_out: endpoint { + remote-endpoint = <&apss_funnel_in1>; + }; + }; + }; + }; + + replicator@13990000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x13990000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc1_0_rep_in: endpoint { + remote-endpoint = <&etm4_out>; + }; + }; + }; + + out-ports { + port { + ncc1_0_rep_out: endpoint { + remote-endpoint = <&ncc1_1_funnel_in0>; + }; + }; + }; + }; + + replicator@139a0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x139a0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc1_1_rep_in: endpoint { + remote-endpoint = <&etm5_out>; + }; + }; + }; + + out-ports { + port { + ncc1_1_rep_out: endpoint { + remote-endpoint = <&ncc1_1_funnel_in1>; + }; + }; + }; + }; + + replicator@139b0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x139b0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc1_2_rep_in: endpoint { + remote-endpoint = <&etm6_out>; + }; + }; + }; + + out-ports { + port { + ncc1_2_rep_out: endpoint { + remote-endpoint = <&ncc1_1_funnel_in2>; + }; + }; + }; + }; + + replicator@139c0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x139c0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc1_3_rep_in: endpoint { + remote-endpoint = <&etm7_out>; + }; + }; + }; + + out-ports { + port { + ncc1_3_rep_out: endpoint { + remote-endpoint = <&ncc1_1_funnel_in3>; + }; + }; + }; + }; + + funnel@139d0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb908>; + reg = <0x0 0x139d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + qcom,cpu-bound-components; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ncc1_1_funnel_in0: endpoint { + remote-endpoint = <&ncc1_0_rep_out>; + }; + }; + + port@1 { + reg = <1>; + + ncc1_1_funnel_in1: endpoint { + remote-endpoint = <&ncc1_1_rep_out>; + }; + }; + + port@2 { + reg = <2>; + + ncc1_1_funnel_in2: endpoint { + remote-endpoint = <&ncc1_2_rep_out>; + }; + }; + + port@3 { + reg = <3>; + + ncc1_1_funnel_in3: endpoint { + remote-endpoint = <&ncc1_3_rep_out>; + }; + }; + }; + + out-ports { + port { + ncc1_1_funnel_out: endpoint { + remote-endpoint = <&ncc1_2_funnel_in2>; + }; + }; + }; + }; + + cluster2_funnel_l2: funnel@13e01000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb908>; + reg = <0x0 0x13e01000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + + ncc2_2_funnel_in2: endpoint { + remote-endpoint = <&ncc2_1_funnel_out>; + }; + }; + }; + + out-ports { + port { + ncc2_2_funnel_out: endpoint { + remote-endpoint = <&ncc2_etf_in>; + }; + }; + }; + }; + + cluster2_etf: tmc@13e09000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb961>; + reg = <0x0 0x13e09000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc2_etf_in: endpoint { + remote-endpoint = <&ncc2_2_funnel_out>; + }; + }; + }; + + out-ports { + port { + ncc2_etf_out: endpoint { + remote-endpoint = <&apss_funnel_in2>; + }; + }; + }; + }; + + cluster2_rep_2_0: replicator@13e90000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x13e90000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc2_0_rep_in: endpoint { + remote-endpoint = <&etm8_out>; + }; + }; + }; + + out-ports { + port { + ncc2_0_rep_out: endpoint { + remote-endpoint = <&ncc2_1_funnel_in0>; + }; + }; + }; + }; + + cluster2_rep_2_1: replicator@13ea0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x13ea0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc2_1_rep_in: endpoint { + remote-endpoint = <&etm9_out>; + }; + }; + }; + + out-ports { + port { + ncc2_1_rep_out: endpoint { + remote-endpoint = <&ncc2_1_funnel_in1>; + }; + }; + }; + }; + + cluster2_rep_2_2: replicator@13eb0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x13eb0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc2_2_rep_in: endpoint { + remote-endpoint = <&etm10_out>; + }; + }; + }; + + out-ports { + port { + ncc2_2_rep_out: endpoint { + remote-endpoint = <&ncc2_1_funnel_in2>; + }; + }; + }; + }; + + cluster2_rep_2_3: replicator@13ec0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb909>; + reg = <0x0 0x13ec0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + port { + ncc2_3_rep_in: endpoint { + remote-endpoint = <&etm11_out>; + }; + }; + }; + + out-ports { + port { + ncc2_3_rep_out: endpoint { + remote-endpoint = <&ncc2_1_funnel_in3>; + }; + }; + }; + }; + + cluster2_funnel_l1: funnel@13ed0000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x000bb908>; + reg = <0x0 0x13ed0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + qcom,cpu-bound-components; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ncc2_1_funnel_in0: endpoint { + remote-endpoint = <&ncc2_0_rep_out>; + }; + }; + + port@1 { + reg = <1>; + + ncc2_1_funnel_in1: endpoint { + remote-endpoint = <&ncc2_1_rep_out>; + }; + }; + + port@2 { + reg = <2>; + + ncc2_1_funnel_in2: endpoint { + remote-endpoint = <&ncc2_2_rep_out>; + }; + }; + + port@3 { + reg = <3>; + + ncc2_1_funnel_in3: endpoint { + remote-endpoint = <&ncc2_3_rep_out>; + }; + }; + }; + + out-ports { + port { + ncc2_1_funnel_out: endpoint { + remote-endpoint = <&ncc2_2_funnel_in2>; + }; + }; + }; + }; + apps_smmu: iommu@15000000 { compatible = "qcom,x1e80100-smmu-500", "qcom,smmu-500", "arm,mmu-500"; reg = <0 0x15000000 0 0x100000>; diff --git a/arch/arm64/boot/dts/qcom/purwa.dtsi b/arch/arm64/boot/dts/qcom/purwa.dtsi index 2cecd2dd0de8c..38f2df9e42b60 100644 --- a/arch/arm64/boot/dts/qcom/purwa.dtsi +++ b/arch/arm64/boot/dts/qcom/purwa.dtsi @@ -21,6 +21,18 @@ /delete-node/ &gpu_speed_bin; /delete-node/ &pcie3_phy; /delete-node/ &thermal_zones; +/delete-node/ &etm8; +/delete-node/ &etm9; +/delete-node/ &etm10; +/delete-node/ &etm11; +/delete-node/ &cluster2_funnel_l1; +/delete-node/ &cluster2_funnel_l2; +/delete-node/ &cluster2_etf; +/delete-node/ &cluster2_rep_2_0; +/delete-node/ &cluster2_rep_2_1; +/delete-node/ &cluster2_rep_2_2; +/delete-node/ &cluster2_rep_2_3; +/delete-node/ &apss_funnel_in2; &gcc { compatible = "qcom,x1p42100-gcc", "qcom,x1e80100-gcc"; From 8bf01dba08932f26150acd6250ff4f557f485123 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Wed, 4 Feb 2026 10:22:02 +0800 Subject: [PATCH 162/438] FROMLIST: arm64: dts: qcom: hamoa: enable ETR and CTCU devices Embedded Trace Router(ETR) is working as a DDR memory sink to collect tracing data from source device. The CTCU serves as the control unit for the ETR device, managing its behavior to determine how trace data is collected. Link: https://lore.kernel.org/all/20260204-enable-ctcu-and-etr-v3-2-0bb95c590ae1@oss.qualcomm.com/ Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 160 +++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 48d5725c4aae5..5a29a1bd9a9b4 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -6975,6 +6975,35 @@ }; }; + ctcu@10001000 { + compatible = "qcom,x1e80100-ctcu", "qcom,sa8775p-ctcu"; + reg = <0x0 0x10001000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ctcu_in0: endpoint { + remote-endpoint = <&etr0_out>; + }; + }; + + port@1 { + reg = <1>; + + ctcu_in1: endpoint { + remote-endpoint = <&etr1_out>; + }; + }; + }; + }; + stm@10002000 { compatible = "arm,coresight-stm", "arm,primecell"; reg = <0x0 0x10002000 0x0 0x1000>, @@ -7197,6 +7226,122 @@ }; }; + replicator@10046000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x10046000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + qdss_rep_in: endpoint { + remote-endpoint = <&swao_rep_out0>; + }; + }; + }; + + out-ports { + port { + qdss_rep_out0: endpoint { + remote-endpoint = <&etr_rep_in>; + }; + }; + }; + }; + + tmc_etr: tmc@10048000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x10048000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + iommus = <&apps_smmu 0x04e0 0x0>; + + arm,scatter-gather; + + in-ports { + port { + etr0_in: endpoint { + remote-endpoint = <&etr_rep_out0>; + }; + }; + }; + + out-ports { + port { + etr0_out: endpoint { + remote-endpoint = <&ctcu_in0>; + }; + }; + }; + }; + + replicator@1004e000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x1004e000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + etr_rep_in: endpoint { + remote-endpoint = <&qdss_rep_out0>; + }; + }; + }; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + etr_rep_out0: endpoint { + remote-endpoint = <&etr0_in>; + }; + }; + + port@1 { + reg = <1>; + + etr_rep_out1: endpoint { + remote-endpoint = <&etr1_in>; + }; + }; + }; + }; + + tmc_etr1: tmc@1004f000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x1004f000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + iommus = <&apps_smmu 0x0500 0x0>; + + arm,scatter-gather; + arm,buffer-size = <0x400000>; + + in-ports { + port { + etr1_in: endpoint { + remote-endpoint = <&etr_rep_out1>; + }; + }; + }; + + out-ports { + port { + etr1_out: endpoint { + remote-endpoint = <&ctcu_in1>; + }; + }; + }; + }; + tpdm@10800000 { compatible = "qcom,coresight-tpdm", "arm,primecell"; reg = <0x0 0x10800000 0x0 0x1000>; @@ -7510,7 +7655,20 @@ }; out-ports { - port { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + swao_rep_out0: endpoint { + remote-endpoint = <&qdss_rep_in>; + }; + }; + + port@1 { + reg = <1>; + swao_rep_out1: endpoint { remote-endpoint = <&eud_in>; }; From 382859ab8b44e37017ef182ddabf4e5c0cff12e3 Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:45 +0800 Subject: [PATCH 163/438] FROMLIST: dt-bindings: arm: qcom: Document PURWA-IOT-EVK board Document the device tree bindings for the PURWA-IOT-EVK board, which uses the Qualcomm X1P42100 SoC. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20260202073555.1345260-1-yijie.yang@oss.qualcomm.com/ --- Documentation/devicetree/bindings/arm/qcom.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index d48c625d3fc42..c339a4348bab4 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -1074,6 +1074,12 @@ properties: - const: qcom,x1e001de - const: qcom,x1e80100 + - items: + - enum: + - qcom,purwa-iot-evk + - const: qcom,purwa-iot-som + - const: qcom,x1p42100 + - items: - enum: - lenovo,thinkpad-t14s-lcd From e6106346ca6e70215c9a748d4dd048708143065b Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:46 +0800 Subject: [PATCH 164/438] FROMLIST: firmware: qcom: scm: Allow QSEECOM on PURWA-IOT-EVK Add the Purwa-IoT-EVK board to the list to enable access to EFI variables. Guarantee that subsystems relying on SCM services can access secure-world features. This change improves reliability and prevents missing functionality or boot-time issues by making service availability explicit. Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20260202073555.1345260-2-yijie.yang@oss.qualcomm.com/ --- drivers/firmware/qcom/qcom_scm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 8fbc96693a55f..58d9911624b67 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2310,6 +2310,7 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "microsoft,romulus13", }, { .compatible = "microsoft,romulus15", }, { .compatible = "qcom,hamoa-iot-evk" }, + { .compatible = "qcom,purwa-iot-evk" }, { .compatible = "qcom,sc8180x-primus" }, { .compatible = "qcom,x1e001de-devkit" }, { .compatible = "qcom,x1e80100-crd" }, From f972374e50bd172b8230274b7a32e0b5ac2f48cb Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:47 +0800 Subject: [PATCH 165/438] FROMLIST: arm64: dts: qcom: Add PURWA-IOT-SOM platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PURWA-IOT-SOM is a compact computing module that integrates a System on Chip (SoC) — specifically the x1p42100 — along with essential components optimized for IoT applications. It is designed to be mounted on carrier boards, enabling the development of complete embedded systems. Purwa uses a slightly different Iris HW revision (8.1.2 on Hamoa, 8.1.11 on Purwa). Support will be added later. Make the following peripherals on the SOM enabled: - Regulators on the SOM - Reserved memory regions - PCIe3, PCIe4, PCIe5, PCIe6a - USB0 through USB6 and their PHYs - ADSP, CDSP - Graphic Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20260202073555.1345260-3-yijie.yang@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi | 696 ++++++++++++++++++++ 1 file changed, 696 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi new file mode 100644 index 0000000000000..71770a8504cf3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi @@ -0,0 +1,696 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "purwa.dtsi" +#include "hamoa-pmics.dtsi" +#include +#include + +/delete-node/ &pmc8380_6; +/delete-node/ &pmc8380_6_thermal; + +/ { + reserved-memory { + linux,cma { + compatible = "shared-dma-pool"; + size = <0x0 0x8000000>; + reusable; + linux,cma-default; + }; + }; +}; + +&apps_rsc { + /* PMC8380C_B */ + regulators-0 { + compatible = "qcom,pm8550-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-bob1-supply = <&vph_pwr>; + vdd-bob2-supply = <&vph_pwr>; + vdd-l1-l4-l10-supply = <&vreg_s4c_1p8>; + vdd-l2-l13-l14-supply = <&vreg_bob1>; + vdd-l5-l16-supply = <&vreg_bob1>; + vdd-l6-l7-supply = <&vreg_bob2>; + vdd-l8-l9-supply = <&vreg_bob1>; + vdd-l12-supply = <&vreg_s5j_1p2>; + vdd-l15-supply = <&vreg_s4c_1p8>; + vdd-l17-supply = <&vreg_bob2>; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = ; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + }; + + vreg_l1b_1p8: ldo1 { + regulator-name = "vreg_l1b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3100000>; + regulator-initial-mode = ; + }; + + vreg_l4b_1p8: ldo4 { + regulator-name = "vreg_l4b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l5b_3p0: ldo5 { + regulator-name = "vreg_l5b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = ; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = ; + }; + + vreg_l7b_2p8: ldo7 { + regulator-name = "vreg_l7b_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l8b_3p0: ldo8 { + regulator-name = "vreg_l8b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = ; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l12b_1p2: ldo12 { + regulator-name = "vreg_l12b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3100000>; + regulator-initial-mode = ; + }; + + vreg_l14b_3p0: ldo14 { + regulator-name = "vreg_l14b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vreg_l16b_2p9: ldo16 { + regulator-name = "vreg_l16b_2p9"; + regulator-min-microvolt = <2912000>; + regulator-max-microvolt = <2912000>; + regulator-initial-mode = ; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = ; + }; + }; + + /* PMC8380VE_C */ + regulators-1 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-l1-supply = <&vreg_s5j_1p2>; + vdd-l2-supply = <&vreg_s1f_0p7>; + vdd-l3-supply = <&vreg_s1f_0p7>; + vdd-s4-supply = <&vph_pwr>; + + vreg_s4c_1p8: smps4 { + regulator-name = "vreg_s4c_1p8"; + regulator-min-microvolt = <1856000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + }; + + vreg_l1c_1p2: ldo1 { + regulator-name = "vreg_l1c_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + + vreg_l2c_0p8: ldo2 { + regulator-name = "vreg_l2c_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + + vreg_l3c_0p8: ldo3 { + regulator-name = "vreg_l3c_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + }; + + /* PMC8380_D */ + regulators-2 { + compatible = "qcom,pmc8380-rpmh-regulators"; + qcom,pmic-id = "d"; + + vdd-l1-supply = <&vreg_s1f_0p7>; + vdd-l2-supply = <&vreg_s1f_0p7>; + vdd-l3-supply = <&vreg_s4c_1p8>; + vdd-s1-supply = <&vph_pwr>; + + vreg_l1d_0p8: ldo1 { + regulator-name = "vreg_l1d_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + + vreg_l2d_0p9: ldo2 { + regulator-name = "vreg_l2d_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + + vreg_l3d_1p8: ldo3 { + regulator-name = "vreg_l3d_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + }; + + /* PMC8380_E */ + regulators-3 { + compatible = "qcom,pmc8380-rpmh-regulators"; + qcom,pmic-id = "e"; + + vdd-l2-supply = <&vreg_s1f_0p7>; + vdd-l3-supply = <&vreg_s5j_1p2>; + + vreg_l2e_0p8: ldo2 { + regulator-name = "vreg_l2e_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + + vreg_l3e_1p2: ldo3 { + regulator-name = "vreg_l3e_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + }; + + /* PMC8380_F */ + regulators-4 { + compatible = "qcom,pmc8380-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-l1-supply = <&vreg_s5j_1p2>; + vdd-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-supply = <&vreg_s5j_1p2>; + vdd-s1-supply = <&vph_pwr>; + + vreg_s1f_0p7: smps1 { + regulator-name = "vreg_s1f_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_l1f_1p0: ldo1 { + regulator-name = "vreg_l1f_1p0"; + regulator-min-microvolt = <1024000>; + regulator-max-microvolt = <1024000>; + regulator-initial-mode = ; + }; + + vreg_l2f_1p0: ldo2 { + regulator-name = "vreg_l2f_1p0"; + regulator-min-microvolt = <1024000>; + regulator-max-microvolt = <1024000>; + regulator-initial-mode = ; + }; + + vreg_l3f_1p0: ldo3 { + regulator-name = "vreg_l3f_1p0"; + regulator-min-microvolt = <1024000>; + regulator-max-microvolt = <1024000>; + regulator-initial-mode = ; + }; + }; + + /* PMC8380VE_I */ + regulators-6 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "i"; + + vdd-l1-supply = <&vreg_s4c_1p8>; + vdd-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-supply = <&vreg_s1f_0p7>; + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + + vreg_s1i_0p9: smps1 { + regulator-name = "vreg_s1i_0p9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + + vreg_s2i_1p0: smps2 { + regulator-name = "vreg_s2i_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_l1i_1p8: ldo1 { + regulator-name = "vreg_l1i_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l2i_1p2: ldo2 { + regulator-name = "vreg_l2i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + + vreg_l3i_0p8: ldo3 { + regulator-name = "vreg_l3i_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + }; + + /* PMC8380VE_J */ + regulators-7 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "j"; + + vdd-l1-supply = <&vreg_s1f_0p7>; + vdd-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-supply = <&vreg_s1f_0p7>; + vdd-s5-supply = <&vph_pwr>; + + vreg_s5j_1p2: smps5 { + regulator-name = "vreg_s5j_1p2"; + regulator-min-microvolt = <1256000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = ; + }; + + vreg_l1j_0p8: ldo1 { + regulator-name = "vreg_l1j_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + + vreg_l2j_1p2: ldo2 { + regulator-name = "vreg_l2j_1p2"; + regulator-min-microvolt = <1256000>; + regulator-max-microvolt = <1256000>; + regulator-initial-mode = ; + }; + + vreg_l3j_0p8: ldo3 { + regulator-name = "vreg_l3j_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + }; + }; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/x1p42100/gen71500_zap.mbn"; +}; + +&pcie3 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie3_default>; + perst-gpios = <&tlmm 143 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>; + + status = "okay"; +}; + +&pcie3_phy { + vdda-phy-supply = <&vreg_l3c_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie4 { + perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie5 { + perst-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie6a { + perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie6a_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie6a_phy { + vdda-phy-supply = <&vreg_l1d_0p8>; + vdda-pll-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&qupv3_0 { + status = "okay"; +}; + +&qupv3_1 { + status = "okay"; +}; + +&qupv3_2 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/x1e80100/adsp.mbn", + "qcom/x1e80100/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/x1e80100/cdsp.mbn", + "qcom/x1e80100/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <34 2>; /* TPM LP & INT */ + + pcie3_default: pcie3-default-state { + clkreq-n-pins { + pins = "gpio144"; + function = "pcie3_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio143"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio145"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio150"; + function = "pcie5_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio149"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio151"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie6a_default: pcie6a-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie6a_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + + }; + }; +}; + +&usb_1_ss0 { + status = "okay"; +}; + +&usb_1_ss0_dwc3 { + dr_mode = "otg"; + usb-role-switch; +}; + +&usb_1_ss0_hsphy { + vdd-supply = <&vreg_l3j_0p8>; + vdda12-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&usb_1_ss0_qmpphy { + vdda-phy-supply = <&vreg_l2j_1p2>; + vdda-pll-supply = <&vreg_l1j_0p8>; + + status = "okay"; +}; + +&usb_1_ss1 { + status = "okay"; +}; + +&usb_1_ss1_dwc3 { + dr_mode = "otg"; + usb-role-switch; +}; + +&usb_1_ss1_hsphy { + vdd-supply = <&vreg_l3j_0p8>; + vdda12-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&usb_1_ss1_qmpphy { + vdda-phy-supply = <&vreg_l2j_1p2>; + vdda-pll-supply = <&vreg_l2d_0p9>; + + status = "okay"; +}; + +&usb_1_ss2 { + status = "okay"; +}; + +&usb_1_ss2_dwc3 { + dr_mode = "otg"; + usb-role-switch; +}; + +&usb_1_ss2_hsphy { + vdd-supply = <&vreg_l3j_0p8>; + vdda12-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&usb_1_ss2_qmpphy { + vdda-phy-supply = <&vreg_l2j_1p2>; + vdda-pll-supply = <&vreg_l2d_0p9>; + + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; + +&usb_2_hsphy { + vdd-supply = <&vreg_l2e_0p8>; + vdda12-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_mp { + status = "okay"; +}; + +&usb_mp_hsphy0 { + vdd-supply = <&vreg_l2e_0p8>; + vdda12-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_mp_hsphy1 { + vdd-supply = <&vreg_l2e_0p8>; + vdda12-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_mp_qmpphy0 { + vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-pll-supply = <&vreg_l3c_0p8>; + + status = "okay"; +}; + +&usb_mp_qmpphy1 { + vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-pll-supply = <&vreg_l3c_0p8>; + + status = "okay"; +}; From 6065d882aaff75d2a4b145bfe7a391dda4661bc7 Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:48 +0800 Subject: [PATCH 166/438] FROMLIST: arm64: dts: qcom: Add base PURWA-IOT-EVK board The PURWA-IOT-EVK is an evaluation platform for IoT products, composed of the Purwa IoT SoM and a carrier board. Together, they form a complete embedded system capable of booting to UART. PURWA-IOT-EVK uses the PS8833 as a retimer for USB0, unlike HAMOA-IOT-EVK. Meanwhile, USB0 bypasses the SBU selector FSUSB42. Make the following peripherals on the carrier board enabled: - UART - On-board regulators - USB Type-C mux - Pinctrl - Embedded USB (EUSB) repeaters - NVMe - pmic-glink - USB DisplayPorts - Bluetooth - WLAN - Audio - PCIe ports for PCIe3 through PCIe6a - TPM Link: https://lore.kernel.org/all/ulnt5ivsedctjy6shyj6sjlaa7ig5b44jsvvrzm5horzl2zkuk@37upvv5uaybx/ Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Signed-off-by: Yijie Yang --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/purwa-iot-evk.dts | 1549 ++++++++++++++++++++ 2 files changed, 1550 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/purwa-iot-evk.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index f80b5d9cf1e80..d42296ed302e7 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -130,6 +130,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-lilac.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-maple.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-poplar.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-xiaomi-sagit.dtb +dtb-$(CONFIG_ARCH_QCOM) += purwa-iot-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += qcm6490-fairphone-fp5.dtb dtb-$(CONFIG_ARCH_QCOM) += qcm6490-idp.dtb dtb-$(CONFIG_ARCH_QCOM) += qcm6490-particle-tachyon.dtb diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts new file mode 100644 index 0000000000000..fe539b1f45677 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts @@ -0,0 +1,1549 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include +#include "purwa-iot-som.dtsi" +#include + +/ { + model = "Qualcomm Technologies, Inc. Purwa IoT EVK"; + compatible = "qcom,purwa-iot-evk", "qcom,purwa-iot-som", "qcom,x1p42100"; + chassis-type = "embedded"; + + aliases { + serial0 = &uart21; + serial1 = &uart14; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pmk8550_pwm 0 5000000>; + enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_bl>; + + pinctrl-0 = <&edp_bl_en>, <&edp_bl_pwm>; + pinctrl-names = "default"; + }; + + wcd938x: audio-codec { + compatible = "qcom,wcd9385-codec"; + + pinctrl-0 = <&wcd_default>; + pinctrl-names = "default"; + + reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>; + + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 + 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; + qcom,rx-device = <&wcd_rx>; + qcom,tx-device = <&wcd_tx>; + + vdd-buck-supply = <&vreg_l15b_1p8>; + vdd-rxtx-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l15b_1p8>; + vdd-mic-bias-supply = <&vreg_bob1>; + + #sound-dai-cells = <1>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + connector3 { + compatible = "usb-a-connector"; + label = "USB-3-Type-A"; + power-role = "source"; + + vbus-supply = <®ulator_usb3_vbus>; + + port { + connector_3_in: endpoint { + }; + }; + }; + + connector6 { + compatible = "usb-a-connector"; + label = "USB-6-Type-A"; + power-role = "source"; + + vbus-supply = <®ulator_usb6_vbus>; + + port { + connector_4_in: endpoint { + }; + }; + }; + + pmic-glink { + compatible = "qcom,x1e80100-pmic-glink", + "qcom,sm8550-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>, + <&tlmm 123 GPIO_ACTIVE_HIGH>, + <&tlmm 125 GPIO_ACTIVE_HIGH>; + + 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>; + + pmic_glink_ss0_hs_in: endpoint { + remote-endpoint = <&usb_1_ss0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss0_ss_in: endpoint { + remote-endpoint = <&retimer_ss0_ss_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_ss0_con_sbu_in: endpoint { + remote-endpoint = <&retimer_ss0_con_sbu_out>; + }; + }; + }; + }; + + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_ss1_hs_in: endpoint { + remote-endpoint = <&usb_1_ss1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss1_ss_in: endpoint { + remote-endpoint = <&retimer_ss1_ss_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_ss1_con_sbu_in: endpoint { + remote-endpoint = <&retimer_ss1_con_sbu_out>; + }; + }; + }; + }; + + connector@2 { + compatible = "usb-c-connector"; + reg = <2>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_ss2_hs_in: endpoint { + remote-endpoint = <&usb_1_ss2_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss2_ss_in: endpoint { + remote-endpoint = <&retimer_ss2_ss_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_ss2_con_sbu_in: endpoint { + remote-endpoint = <&retimer_ss2_con_sbu_out>; + }; + }; + }; + }; + }; + + vreg_edp_3p3: regulator-edp-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_edp_bl: regulator-edp-bl { + compatible = "regulator-fixed"; + + regulator-name = "VBL9"; + regulator-min-microvolt = <3600000>; + regulator-max-microvolt = <3600000>; + + gpio = <&pmc8380_3_gpios 10 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_bl_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_pcie_12v: regulator-pcie-12v { + compatible = "regulator-fixed"; + + regulator-name = "VREG_PCIE_12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + + gpio = <&pm8550ve_8_gpios 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&pcie_x8_12v>; + pinctrl-names = "default"; + }; + + vreg_pcie_3v3: regulator-pcie-3v3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_PCIE_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmc8380_3_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&pm_sde7_main_3p3_en>; + pinctrl-names = "default"; + }; + + vreg_pcie_3v3_aux: regulator-pcie-3v3-aux { + compatible = "regulator-fixed"; + + regulator-name = "VREG_PCIE_3P3_AUX"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmc8380_3_gpios 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&pm_sde7_aux_3p3_en>; + pinctrl-names = "default"; + }; + + /* Left unused as the retimer is not used on this board. */ + vreg_rtmr0_1p15: regulator-rtmr0-1p15 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR0_1P15"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + + gpio = <&pmc8380_5_gpios 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb0_pwr_1p15_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr0_1p8: regulator-rtmr0-1p8 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR0_1P8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&pm8550ve_9_gpios 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb0_1p8_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr0_3p3: regulator-rtmr0-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR0_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb0_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr1_1p15: regulator-rtmr1-1p15 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR1_1P15"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + + gpio = <&tlmm 188 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb1_pwr_1p15_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr1_1p8: regulator-rtmr1-1p8 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR1_1P8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 175 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb1_pwr_1p8_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr1_3p3: regulator-rtmr1-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR1_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 186 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb1_pwr_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr2_1p15: regulator-rtmr2-1p15 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR2_1P15"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + + gpio = <&tlmm 189 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb2_pwr_1p15_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr2_1p8: regulator-rtmr2-1p8 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR2_1P8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 126 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb2_pwr_1p8_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_rtmr2_3p3: regulator-rtmr2-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_RTMR2_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 187 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&usb2_pwr_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + regulator_usb3_vbus: regulator-usb3-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB3_VBUS"; + gpio = <&pm8550ve_9_gpios 4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&usb3_en>; + pinctrl-names = "default"; + enable-active-high; + regulator-always-on; + }; + + regulator_usb6_vbus: regulator-usb6-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB6_VBUS"; + gpio = <&pm8550ve_9_gpios 5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&usb6_en>; + pinctrl-names = "default"; + enable-active-high; + regulator-always-on; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + regulator-boot-on; + }; + + /* + * TODO: These two regulators are actually part of the removable M.2 + * card and not the EVK mainboard. Need to describe this differently. + * Functionally it works correctly, because all we need to do is to + * turn on the actual 3.3V supply above. + */ + vreg_wcn_0p95: regulator-wcn-0p95 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_0P95"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + vin-supply = <&vreg_wcn_3p3>; + }; + + vreg_wcn_1p9: regulator-wcn-1p9 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_1P9"; + regulator-min-microvolt = <1900000>; + regulator-max-microvolt = <1900000>; + + vin-supply = <&vreg_wcn_3p3>; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 214 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_sw_en>; + pinctrl-names = "default"; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_wwan: regulator-wwan { + compatible = "regulator-fixed"; + + regulator-name = "SDX_VPH_PWR"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 221 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wwan_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + sound { + compatible = "qcom,x1e80100-sndcard"; + model = "X1E80100-EVK"; + audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT", + "TweeterLeft IN", "WSA WSA_SPK2 OUT", + "WooferRight IN", "WSA2 WSA_SPK2 OUT", + "TweeterRight IN", "WSA2 WSA_SPK2 OUT", + "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2", + "VA DMIC0", "MIC BIAS3", + "VA DMIC1", "MIC BIAS3", + "VA DMIC2", "MIC BIAS1", + "VA DMIC3", "MIC BIAS1", + "TX SWR_INPUT1", "ADC2_OUTPUT"; + + wcd-playback-dai-link { + link-name = "WCD Playback"; + + codec { + sound-dai = <&wcd938x 0>, <&swr1 0>, <&lpass_rxmacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-capture-dai-link { + link-name = "WCD Capture"; + + codec { + sound-dai = <&wcd938x 1>, <&swr2 1>, <&lpass_txmacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&left_woofer>, + <&left_tweeter>, + <&swr0 0>, + <&lpass_wsamacro 0>, + <&right_woofer>, + <&right_tweeter>, + <&swr3 0>, + <&lpass_wsa2macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + vdd-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_l15b_1p8>; + vddaon-supply = <&vreg_wcn_0p95>; + vdddig-supply = <&vreg_wcn_0p95>; + vddrfa1p2-supply = <&vreg_wcn_1p9>; + vddrfa1p8-supply = <&vreg_wcn_1p9>; + + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + status = "okay"; + + typec-mux@8 { + compatible = "parade,ps8830"; + reg = <0x08>; + + clocks = <&rpmhcc RPMH_RF_CLK5>; + + vdd-supply = <&vreg_rtmr2_1p15>; + vdd33-supply = <&vreg_rtmr2_3p3>; + vdd33-cap-supply = <&vreg_rtmr2_3p3>; + vddar-supply = <&vreg_rtmr2_1p15>; + vddat-supply = <&vreg_rtmr2_1p15>; + vddio-supply = <&vreg_rtmr2_1p8>; + + reset-gpios = <&tlmm 185 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&rtmr2_default>; + pinctrl-names = "default"; + + orientation-switch; + retimer-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + retimer_ss2_ss_out: endpoint { + remote-endpoint = <&pmic_glink_ss2_ss_in>; + }; + }; + + port@1 { + reg = <1>; + + retimer_ss2_ss_in: endpoint { + remote-endpoint = <&usb_1_ss2_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + retimer_ss2_con_sbu_out: endpoint { + remote-endpoint = <&pmic_glink_ss2_con_sbu_in>; + }; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + + status = "okay"; + + typec-mux@8 { + compatible = "parade,ps8830"; + reg = <0x8>; + + clocks = <&rpmhcc RPMH_RF_CLK4>; + + vdd-supply = <&vreg_rtmr0_1p15>; + vdd33-supply = <&vreg_rtmr0_3p3>; + vdd33-cap-supply = <&vreg_rtmr0_3p3>; + vddar-supply = <&vreg_rtmr0_1p15>; + vddat-supply = <&vreg_rtmr0_1p15>; + vddio-supply = <&vreg_rtmr0_1p8>; + + reset-gpios = <&pm8550_gpios 10 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&rtmr0_default>; + pinctrl-names = "default"; + + retimer-switch; + orientation-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + retimer_ss0_ss_out: endpoint { + remote-endpoint = <&pmic_glink_ss0_ss_in>; + }; + }; + + port@1 { + reg = <1>; + + retimer_ss0_ss_in: endpoint { + remote-endpoint = <&usb_1_ss0_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + retimer_ss0_con_sbu_out: endpoint { + remote-endpoint = <&pmic_glink_ss0_con_sbu_in>; + }; + }; + }; + }; +}; + +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; + + eusb3_repeater: redriver@47 { + compatible = "nxp,ptn3222"; + reg = <0x47>; + #phy-cells = <0>; + + vdd3v3-supply = <&vreg_l13b_3p0>; + vdd1v8-supply = <&vreg_l4b_1p8>; + + reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&eusb3_reset_n>; + pinctrl-names = "default"; + }; + + eusb5_repeater: redriver@43 { + compatible = "nxp,ptn3222"; + reg = <0x43>; + #phy-cells = <0>; + + vdd3v3-supply = <&vreg_l13b_3p0>; + vdd1v8-supply = <&vreg_l4b_1p8>; + + reset-gpios = <&tlmm 7 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&eusb5_reset_n>; + pinctrl-names = "default"; + }; + + eusb6_repeater: redriver@4f { + compatible = "nxp,ptn3222"; + reg = <0x4f>; + #phy-cells = <0>; + + vdd3v3-supply = <&vreg_l13b_3p0>; + vdd1v8-supply = <&vreg_l4b_1p8>; + + reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&eusb6_reset_n>; + pinctrl-names = "default"; + }; +}; + +&i2c7 { + clock-frequency = <400000>; + + status = "okay"; + + typec-mux@8 { + compatible = "parade,ps8830"; + reg = <0x8>; + + clocks = <&rpmhcc RPMH_RF_CLK4>; + + vdd-supply = <&vreg_rtmr1_1p15>; + vdd33-supply = <&vreg_rtmr1_3p3>; + vdd33-cap-supply = <&vreg_rtmr1_3p3>; + vddar-supply = <&vreg_rtmr1_1p15>; + vddat-supply = <&vreg_rtmr1_1p15>; + vddio-supply = <&vreg_rtmr1_1p8>; + + reset-gpios = <&tlmm 176 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&rtmr1_default>; + pinctrl-names = "default"; + + retimer-switch; + orientation-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + retimer_ss1_ss_out: endpoint { + remote-endpoint = <&pmic_glink_ss1_ss_in>; + }; + }; + + port@1 { + reg = <1>; + + retimer_ss1_ss_in: endpoint { + remote-endpoint = <&usb_1_ss1_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + retimer_ss1_con_sbu_out: endpoint { + remote-endpoint = <&pmic_glink_ss1_con_sbu_in>; + }; + }; + }; + }; +}; + +&lpass_tlmm { + spkr_0_sd_n_active: spkr-0-sd-n-active-state { + pins = "gpio12"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + spkr_1_sd_n_active: spkr-1-sd-n-active-state { + pins = "gpio13"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + spkr_2_sd_n_active: spkr-2-sd-n-active-state { + pins = "gpio17"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + spkr_3_sd_n_active: spkr-3-sd-n-active-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; +}; + +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + + vdd-micb-supply = <&vreg_l1b_1p8>; + qcom,dmic-sample-rate = <4800000>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp1 { + status = "okay"; +}; + +&mdss_dp1_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp2 { + status = "okay"; +}; + +&mdss_dp2_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp3 { + /delete-property/ #sound-dai-cells; + + pinctrl-0 = <&edp0_hpd_default>; + pinctrl-names = "default"; + + status = "okay"; + + aux-bus { + panel { + compatible = "edp-panel"; + + backlight = <&backlight>; + power-supply = <&vreg_edp_3p3>; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; +}; + +&mdss_dp3_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l3j_0p8>; + vdda-pll-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&pcie3_port0 { + vpcie12v-supply = <&vreg_pcie_12v>; + vpcie3v3-supply = <&vreg_pcie_3v3>; + vpcie3v3aux-supply = <&vreg_pcie_3v3_aux>; + + reset-gpios = <&tlmm 143 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie5 { + vddpe-3v3-supply = <&vreg_wwan>; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; +}; + +&pcie6a { + vddpe-3v3-supply = <&vreg_nvme>; +}; + +&pcie6a_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; +}; + +&pm8550_gpios { + rtmr0_default: rtmr0-reset-n-active-state { + pins = "gpio10"; + function = "normal"; + power-source = <1>; /* 1.8V */ + bias-disable; + input-disable; + output-enable; + }; + + usb0_3p3_reg_en: usb0-3p3-reg-en-state { + pins = "gpio11"; + function = "normal"; + power-source = <1>; /* 1.8V */ + bias-disable; + input-disable; + output-enable; + }; +}; + +&pm8550ve_8_gpios { + pcie_x8_12v: pcie-12v-default-state { + pins = "gpio8"; + function = "normal"; + output-enable; + output-high; + bias-pull-down; + power-source = <0>; + }; +}; + +&pm8550ve_9_gpios { + usb0_1p8_reg_en: usb0-1p8-reg-en-state { + pins = "gpio8"; + function = "normal"; + power-source = <1>; /* 1.8V */ + bias-disable; + input-disable; + output-enable; + }; + + usb3_en: usb3-en-state { + pins = "gpio4"; + function = "normal"; + qcom,drive-strength = ; + output-enable; + power-source = <0>; + }; + + usb6_en: usb6-en-state { + pins = "gpio5"; + function = "normal"; + qcom,drive-strength = ; + output-enable; + power-source = <0>; + }; +}; + +&pm8550_pwm { + status = "okay"; + + multi-led { + color = ; + function = LED_FUNCTION_STATUS; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + }; + + led@2 { + reg = <2>; + color = ; + }; + }; +}; + +&pmc8380_3_gpios { + edp_bl_en: edp-bl-en-state { + pins = "gpio4"; + function = "normal"; + power-source = <1>; + input-disable; + output-enable; + }; + + edp_bl_reg_en: edp-bl-reg-en-state { + pins = "gpio10"; + function = "normal"; + }; + + pm_sde7_aux_3p3_en: pcie-aux-3p3-default-state { + pins = "gpio8"; + function = "normal"; + output-enable; + bias-pull-down; + power-source = <0>; + }; + + pm_sde7_main_3p3_en: pcie-main-3p3-default-state { + pins = "gpio6"; + function = "normal"; + output-enable; + bias-pull-down; + power-source = <0>; + }; +}; + +&pmc8380_5_gpios { + usb0_pwr_1p15_reg_en: usb0-pwr-1p15-reg-en-state { + pins = "gpio8"; + function = "normal"; + power-source = <1>; /* 1.8V */ + bias-disable; + input-disable; + output-enable; + }; +}; + +&pmk8550_gpios { + edp_bl_pwm: edp-bl-pwm-state { + pins = "gpio5"; + function = "func3"; + }; +}; + +&pmk8550_pwm { + status = "okay"; +}; + +&smb2360_0 { + status = "okay"; +}; + +&smb2360_0_eusb2_repeater { + vdd18-supply = <&vreg_l3d_1p8>; + vdd3-supply = <&vreg_l2b_3p0>; +}; + +&smb2360_1 { + status = "okay"; +}; + +&smb2360_1_eusb2_repeater { + vdd18-supply = <&vreg_l3d_1p8>; + vdd3-supply = <&vreg_l14b_3p0>; +}; + +&smb2360_2 { + status = "okay"; +}; + +&smb2360_2_eusb2_repeater { + vdd18-supply = <&vreg_l3d_1p8>; + vdd3-supply = <&vreg_l8b_3p0>; +}; + +&spi11 { + status = "okay"; + + tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +}; + +&swr0 { + status = "okay"; + + pinctrl-0 = <&wsa_swr_active>; + pinctrl-names = "default"; + + /* WSA8845, Left Woofer */ + left_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_0_sd_n_active>; + pinctrl-names = "default"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferLeft"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <1 2 3 7 10 13>; + }; + + /* WSA8845, Left Tweeter */ + left_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_1_sd_n_active>; + pinctrl-names = "default"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterLeft"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <4 5 6 7 11 13>; + }; +}; + +&swr1 { + status = "okay"; + + /* WCD9385 RX */ + wcd_rx: codec@0,4 { + compatible = "sdw20217010d00"; + reg = <0 4>; + qcom,rx-port-mapping = <1 2 3 4 5>; + }; +}; + +&swr2 { + status = "okay"; + + /* WCD9385 TX */ + wcd_tx: codec@0,3 { + compatible = "sdw20217010d00"; + reg = <0 3>; + qcom,tx-port-mapping = <2 2 3 4>; + }; +}; + +&swr3 { + status = "okay"; + + pinctrl-0 = <&wsa2_swr_active>; + pinctrl-names = "default"; + + /* WSA8845, Right Woofer */ + right_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_2_sd_n_active>; + pinctrl-names = "default"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 17 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferRight"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <1 2 3 7 10 13>; + }; + + /* WSA8845, Right Tweeter */ + right_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_3_sd_n_active>; + pinctrl-names = "default"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 18 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterRight"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <4 5 6 7 11 13>; + }; +}; + +&tlmm { + edp_reg_en: edp-reg-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + eusb3_reset_n: eusb3-reset-n-state { + pins = "gpio6"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + output-low; + }; + + eusb5_reset_n: eusb5-reset-n-state { + pins = "gpio7"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + output-low; + }; + + eusb6_reset_n: eusb6-reset-n-state { + pins = "gpio184"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + output-low; + }; + + nvme_reg_en: nvme-reg-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + rtmr1_default: rtmr1-reset-n-active-state { + pins = "gpio176"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + rtmr2_default: rtmr2-reset-n-active-state { + pins = "gpio185"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb1_pwr_1p15_reg_en: usb1-pwr-1p15-reg-en-state { + pins = "gpio188"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb1_pwr_1p8_reg_en: usb1-pwr-1p8-reg-en-state { + pins = "gpio175"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb1_pwr_3p3_reg_en: usb1-pwr-3p3-reg-en-state { + pins = "gpio186"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb2_pwr_1p15_reg_en: usb2-pwr-1p15-reg-en-state { + pins = "gpio189"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb2_pwr_1p8_reg_en: usb2-pwr-1p8-reg-en-state { + pins = "gpio126"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb2_pwr_3p3_reg_en: usb2-pwr-3p3-reg-en-state { + pins = "gpio187"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb_1_ss0_sbu_default: usb-1-ss0-sbu-state { + mode-pins { + pins = "gpio166"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + output-high; + }; + + oe-n-pins { + pins = "gpio168"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + }; + + sel-pins { + pins = "gpio167"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + }; + }; + + wcd_default: wcd-reset-n-active-state { + pins = "gpio191"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + output-low; + }; + + wcn_bt_en: wcn-bt-en-state { + pins = "gpio116"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wcn_wlan_en: wcn-wlan-en-state { + pins = "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wwan_sw_en: wwan-sw-en-state { + pins = "gpio221"; + function = "gpio"; + drive-strength = <4>; + bias-disable; + }; + + wcn_sw_en: wcn-sw-en-state { + pins = "gpio214"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + /* Switches USB signal routing between the USB connector and the Wi-Fi card. */ + wcn_usb_sw_n: wcn-usb-sw-n-state { + pins = "gpio225"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + output-high; + }; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + max-speed = <3200000>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +}; + +&uart21 { + compatible = "qcom,geni-debug-uart"; + + status = "okay"; +}; + +&usb_1_ss0_dwc3_hs { + remote-endpoint = <&pmic_glink_ss0_hs_in>; +}; + +&usb_1_ss0_hsphy { + phys = <&smb2360_0_eusb2_repeater>; +}; + +&usb_1_ss0_qmpphy_out { + remote-endpoint = <&retimer_ss0_ss_in>; +}; + +&usb_1_ss1_dwc3_hs { + remote-endpoint = <&pmic_glink_ss1_hs_in>; +}; + +&usb_1_ss1_hsphy { + phys = <&smb2360_1_eusb2_repeater>; +}; + +&usb_1_ss1_qmpphy_out { + remote-endpoint = <&retimer_ss1_ss_in>; +}; + +&usb_1_ss2_dwc3_hs { + remote-endpoint = <&pmic_glink_ss2_hs_in>; +}; + +&usb_1_ss2_hsphy { + phys = <&smb2360_2_eusb2_repeater>; +}; + +&usb_1_ss2_qmpphy_out { + remote-endpoint = <&retimer_ss2_ss_in>; +}; + +&usb_2_hsphy { + phys = <&eusb5_repeater>; + + pinctrl-0 = <&wcn_usb_sw_n>; + pinctrl-names = "default"; +}; + +&usb_mp_hsphy0 { + phys = <&eusb3_repeater>; +}; + +&usb_mp_hsphy1 { + phys = <&eusb6_repeater>; +}; From 9262a3c0a427758bfb616b15a519eb999d870cba Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Wed, 11 Feb 2026 18:59:25 +0530 Subject: [PATCH 167/438] FROMLIST: arm64: dts: qcom: hamoa: Add UFS nodes for x1e80100 SoC Add UFS host controller and PHY nodes for x1e80100 SoC. Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Reviewed-by: Taniya Das Reviewed-by: Manivannan Sadhasivam Signed-off-by: Pradeep P V K Link: https://lore.kernel.org/all/20260211132926.3716716-1-pradeep.pragallapati@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 122 +++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 5a29a1bd9a9b4..cda308fee5659 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -1039,9 +1039,9 @@ <0>, <0>, <0>, - <0>, - <0>, - <0>; + <&ufs_mem_phy 0>, + <&ufs_mem_phy 1>, + <&ufs_mem_phy 2>; power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; @@ -4073,6 +4073,122 @@ status = "disabled"; }; + ufs_mem_phy: phy@1d80000 { + compatible = "qcom,x1e80100-qmp-ufs-phy", + "qcom,sm8550-qmp-ufs-phy"; + reg = <0x0 0x01d80000 0x0 0x2000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>, + <&tcsr TCSR_UFS_PHY_CLKREF_EN>; + + clock-names = "ref", + "ref_aux", + "qref"; + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + + power-domains = <&gcc GCC_UFS_MEM_PHY_GDSC>; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + ufs_mem_hc: ufshc@1d84000 { + compatible = "qcom,x1e80100-ufshc", + "qcom,sm8550-ufshc", + "qcom,ufshc"; + reg = <0x0 0x01d84000 0x0 0x3000>; + + interrupts = ; + + clocks = <&gcc GCC_UFS_PHY_AXI_CLK>, + <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>, + <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>, + <&rpmhcc RPMH_LN_BB_CLK3>, + <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, + <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>; + clock-names = "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk", + "rx_lane1_sync_clk"; + + operating-points-v2 = <&ufs_opp_table>; + + resets = <&gcc GCC_UFS_PHY_BCR>; + reset-names = "rst"; + + interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "ufs-ddr", + "cpu-ufs"; + + power-domains = <&gcc GCC_UFS_PHY_GDSC>; + required-opps = <&rpmhpd_opp_nom>; + + iommus = <&apps_smmu 0x1a0 0>; + dma-coherent; + + lanes-per-direction = <2>; + + phys = <&ufs_mem_phy>; + phy-names = "ufsphy"; + + #reset-cells = <1>; + + status = "disabled"; + + ufs_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-75000000 { + opp-hz = /bits/ 64 <75000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <75000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-150000000 { + opp-hz = /bits/ 64 <150000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <150000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <300000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + cryptobam: dma-controller@1dc4000 { compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0"; reg = <0x0 0x01dc4000 0x0 0x28000>; From bc1881a1abab70ea066d9117fd88ec9d52f10316 Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Wed, 11 Feb 2026 18:59:26 +0530 Subject: [PATCH 168/438] FROMLIST: arm64: dts: qcom: hamoa-iot-evk: Enable UFS Enable UFS for HAMOA-IOT-EVK board. Reviewed-by: Konrad Dybcio Reviewed-by: Manivannan Sadhasivam Signed-off-by: Pradeep P V K Link: https://lore.kernel.org/all/20260211132926.3716716-1-pradeep.pragallapati@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 2390648a248f7..fccf1d1bdc606 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -1461,6 +1461,24 @@ status = "okay"; }; +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 238 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l2i_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + &usb_1_ss0_dwc3_hs { remote-endpoint = <&pmic_glink_ss0_hs_in>; }; From b15eb81d1be317a6695853df1f0594301681d8d7 Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Wed, 11 Feb 2026 15:00:45 +0530 Subject: [PATCH 169/438] FROMLIST: arm64: dts: qcom: hamoa-iot-evk: Add SDC2 node for hamoa iot evk board Enable SD Card host controller for hamoa iot evk board. Link: https://lore.kernel.org/all/20260211093045.2595126-1-sarthak.garg@oss.qualcomm.com/ Signed-off-by: Sarthak Garg Signed-off-by: Pradeep P V K --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index fccf1d1bdc606..1427e342e9047 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -1144,6 +1144,22 @@ status = "okay"; }; +&sdhc_2 { + cd-gpios = <&tlmm 71 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l9b_2p9>; + vqmmc-supply = <&vreg_l6b_1p8>; + + no-sdio; + no-mmc; + + pinctrl-0 = <&sdc2_default &sdc2_card_det_n>; + pinctrl-1 = <&sdc2_sleep &sdc2_card_det_n>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + &smb2360_0 { status = "okay"; }; @@ -1326,6 +1342,13 @@ bias-disable; }; + sdc2_card_det_n: sd-card-det-n-state { + pins = "gpio71"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + usb1_pwr_1p15_reg_en: usb1-pwr-1p15-reg-en-state { pins = "gpio188"; function = "gpio"; From fb682ce7cc62a5b197f62e27438d0b123d131c37 Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Mon, 2 Feb 2026 14:30:57 +0800 Subject: [PATCH 170/438] FROMLIST: wifi: ath12k: fix incorrect channel survey index A wrong channel survey index was introduced in ath12k_mac_op_get_survey by [1], which can cause ACS to fail. The index is decremented before being used, resulting in an incorrect value when accessing the channel survey data. Fix the index handling to ensure the correct survey entry is used and avoid ACS failures. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: 4f242b1d6996 ("wifi: ath12k: support get_survey mac op for single wiphy") # [1] Signed-off-by: Yingying Tang --- drivers/net/wireless/ath/ath12k/mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index c6b88909b6b78..8fa2722dbf48b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13326,6 +13326,7 @@ int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, struct ath12k *ar; struct ieee80211_supported_band *sband; struct survey_info *ar_survey; + int orig_idx = idx; lockdep_assert_wiphy(hw->wiphy); @@ -13360,7 +13361,7 @@ int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, return -ENOENT; } - ar_survey = &ar->survey[idx]; + ar_survey = &ar->survey[orig_idx]; ath12k_mac_update_bss_chan_survey(ar, &sband->channels[idx]); From 41856302b25c0b1bb43db7d16ee43cb7011558cf Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Wed, 25 Feb 2026 14:25:40 +0800 Subject: [PATCH 171/438] FROMLIST: wifi: ath12k: prepare REO update element only for primary link Commit [1] introduces dp->reo_cmd_update_rx_queue_list for the purpose of tracking all pending REO queue flush commands. The helper ath12k_dp_prepare_reo_update_elem() allocates an element and populates it with REO queue information, then add it to the list. The element would be helpful during clean up stage to finally unmap/free the corresponding REO queue buffer. In MLO scenarios with more than one links, for non dp_primary_link_only chips like WCN7850, that helper is called for each link peer. This results in multiple elements added to the list but all of them pointing to the same REO queue buffer. Consequently the same buffer gets unmap/freed multiple times: BUG kmalloc-2k (Tainted: G B W O ): Object already free ----------------------------------------------------------------------------- Allocated in ath12k_wifi7_dp_rx_assign_reoq+0xce/0x280 [ath12k_wifi7] age=7436 cpu=10 pid=16130 __kmalloc_noprof ath12k_wifi7_dp_rx_assign_reoq ath12k_dp_rx_peer_tid_setup ath12k_dp_peer_setup ath12k_mac_station_add ath12k_mac_op_sta_state [...] Freed in ath12k_dp_rx_tid_cleanup.part.0+0x25/0x40 [ath12k] age=1 cpu=27 pid=16137 kfree ath12k_dp_rx_tid_cleanup.part.0 ath12k_dp_rx_reo_cmd_list_cleanup ath12k_dp_cmn_device_deinit ath12k_core_stop ath12k_core_hw_group_cleanup ath12k_pci_remove Fix this by allowing list addition for primary link only. Note dp_primary_link_only chips like QCN9274 are not affected by this change, because that's what they were doing in the first place. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: 3bf2e57e7d6c ("wifi: ath12k: Add Retry Mechanism for REO RX Queue Update Failures") # [1] Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221011 Signed-off-by: Baochen Qiang Signed-off-by: Yingying Tang --- drivers/net/wireless/ath/ath12k/dp_rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 5a82ede65dd3d..33d6c916ca053 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -565,6 +565,9 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, lockdep_assert_held(&dp->dp_lock); + if (!peer->primary_link) + return 0; + elem = kzalloc_obj(*elem, GFP_ATOMIC); if (!elem) return -ENOMEM; From 49b156fb09e0950aab5d3b4d6f1a92a3a78766d1 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:22 +0530 Subject: [PATCH 172/438] FROMLIST: phy: qcom: sgmii-eth: add second regulator support The Qualcomm SGMII SerDes PHY requires two regulators to function properly. If both of these are not enabled, the following error is observed: [ 77.105651] qcom-dwmac-sgmii-phy 8909000.phy: QSERDES_COM_C_READY_STATUS timed-out [ 77.113447] qcom-ethqos 23040000.ethernet eth0: __stmmac_open: Serdes powerup failed Therefore, add support for handling the additional regulator in the driver. Link: https://lore.kernel.org/linux-arm-msm/20251124-sgmiieth_serdes_regulator-v1-0-73ae8f9cbe2a@oss.qualcomm.com/T/#m44fe996d0f2a26c428b315959cd0623a0271ac3d Fixes: 601d06277007 ("phy: qcom: add the SGMII SerDes PHY driver") Signed-off-by: Mohd Ayaan Anwar --- drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c index 5b1c82459c126..5044f244762f4 100644 --- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c +++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "phy-qcom-qmp-pcs-sgmii.h" #include "phy-qcom-qmp-qserdes-com-v5.h" @@ -26,6 +27,7 @@ #define QSERDES_COM_C_PLL_LOCKED BIT(1) struct qcom_dwmac_sgmii_phy_data { + struct regulator *vdda_0p9; struct regmap *regmap; struct clk *refclk; int speed; @@ -266,9 +268,23 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy) static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy) { + int ret; struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); - return clk_prepare_enable(data->refclk); + ret = regulator_enable(data->vdda_0p9); + if (ret) + goto out_ret; + + ret = clk_prepare_enable(data->refclk); + if (ret) + goto out_reg_disable; + + return 0; + +out_reg_disable: + regulator_disable(data->vdda_0p9); +out_ret: + return ret; } static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy) @@ -283,6 +299,8 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy) clk_disable_unprepare(data->refclk); + regulator_disable(data->vdda_0p9); + return 0; } @@ -343,6 +361,10 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev) if (IS_ERR(data->refclk)) return PTR_ERR(data->refclk); + data->vdda_0p9 = devm_regulator_get(dev, "vdda-0p9"); + if (IS_ERR(data->vdda_0p9)) + return PTR_ERR(data->vdda_0p9); + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(provider)) return PTR_ERR(provider); From a3602e9cbd3dd4519ddc446ddba1261fe4e156bd Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Sun, 14 Sep 2025 20:36:48 +0530 Subject: [PATCH 173/438] FROMLIST: net: phy: qcom: qca808x: Add .get_rate_matching support Add support for rate matching to the QCA8081 PHY driver to correctly report its capabilities. Some boards[0][1] with this PHY currently report support only for 2.5G. Implement the .get_rate_matching callback to allow phylink to determine the actual PHY capabilities and report them accurately. Before: # ethtool eth0 Settings for eth0: Supported ports: [ ] Supported link modes: 2500baseT/Full Supported pause frame use: Symmetric Receive-only ... After: # ethtool eth0 Settings for eth0: Supported ports: [ ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full 2500baseT/Full Supported pause frame use: Symmetric Receive-only ... [0] https://lore.kernel.org/all/20250905192350.1223812-3-umang.chheda@oss.qualcomm.com/ [1] https://lore.kernel.org/all/20250908-lemans-evk-bu-v4-12-5c319c696a7d@oss.qualcomm.com/ Link: https://lore.kernel.org/netdev/20250914-qca808x_rate_match-v1-1-0f9e6a331c3b@oss.qualcomm.com/ Signed-off-by: Mohd Ayaan Anwar --- drivers/net/phy/qcom/qca808x.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c index 8eb51b1a006c4..f22ebb1ac3328 100644 --- a/drivers/net/phy/qcom/qca808x.c +++ b/drivers/net/phy/qcom/qca808x.c @@ -643,6 +643,15 @@ static void qca808x_get_phy_stats(struct phy_device *phydev, qcom_phy_get_stats(stats, priv->hw_stats); } +static int qca808x_get_rate_matching(struct phy_device *phydev, + phy_interface_t iface) +{ + if (iface == PHY_INTERFACE_MODE_2500BASEX) + return RATE_MATCH_PAUSE; + + return RATE_MATCH_NONE; +} + static struct phy_driver qca808x_driver[] = { { /* Qualcomm QCA8081 */ @@ -674,6 +683,7 @@ static struct phy_driver qca808x_driver[] = { .led_polarity_set = qca808x_led_polarity_set, .update_stats = qca808x_update_stats, .get_phy_stats = qca808x_get_phy_stats, + .get_rate_matching = qca808x_get_rate_matching, }, }; module_phy_driver(qca808x_driver); From 63016b83c739789c3f4d0c4d2ec5625d3a42f8c5 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:14 +0530 Subject: [PATCH 174/438] power: reset: reboot-mode: Remove devres based allocations Devres APIs are intended for use in drivers, and they should be avoided in shared subsystem code which is being used by multiple drivers. Avoid using devres based allocations in the reboot-mode subsystem and manually free the resources. Replace devm_kzalloc with kzalloc and handle memory cleanup explicitly. Fixes: 4fcd504edbf7 ("power: reset: add reboot mode driver") Signed-off-by: Shivendra Pratap Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-1-46e085bca4cc@oss.qualcomm.com --- drivers/power/reset/reboot-mode.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index fba53f638da04..ac4223794083f 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -3,6 +3,8 @@ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd */ +#define pr_fmt(fmt) "reboot-mode: " fmt + #include #include #include @@ -71,6 +73,7 @@ static int reboot_mode_notify(struct notifier_block *this, int reboot_mode_register(struct reboot_mode_driver *reboot) { struct mode_info *info; + struct mode_info *next; struct property *prop; struct device_node *np = reboot->dev->of_node; size_t len = strlen(PREFIX); @@ -82,29 +85,27 @@ int reboot_mode_register(struct reboot_mode_driver *reboot) if (strncmp(prop->name, PREFIX, len)) continue; - info = devm_kzalloc(reboot->dev, sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { ret = -ENOMEM; goto error; } if (of_property_read_u32(np, prop->name, &info->magic)) { - dev_err(reboot->dev, "reboot mode %s without magic number\n", - info->mode); - devm_kfree(reboot->dev, info); + pr_err("reboot mode %s without magic number\n", info->mode); + kfree(info); continue; } info->mode = kstrdup_const(prop->name + len, GFP_KERNEL); if (!info->mode) { ret = -ENOMEM; - goto error; + goto err_info; } else if (info->mode[0] == '\0') { kfree_const(info->mode); ret = -EINVAL; - dev_err(reboot->dev, "invalid mode name(%s): too short!\n", - prop->name); - goto error; + pr_err("invalid mode name(%s): too short!\n", prop->name); + goto err_info; } list_add_tail(&info->list, &reboot->head); @@ -115,9 +116,14 @@ int reboot_mode_register(struct reboot_mode_driver *reboot) return 0; +err_info: + kfree(info); error: - list_for_each_entry(info, &reboot->head, list) + list_for_each_entry_safe(info, next, &reboot->head, list) { + list_del(&info->list); kfree_const(info->mode); + kfree(info); + } return ret; } @@ -130,11 +136,15 @@ EXPORT_SYMBOL_GPL(reboot_mode_register); int reboot_mode_unregister(struct reboot_mode_driver *reboot) { struct mode_info *info; + struct mode_info *next; unregister_reboot_notifier(&reboot->reboot_notifier); - list_for_each_entry(info, &reboot->head, list) + list_for_each_entry_safe(info, next, &reboot->head, list) { + list_del(&info->list); kfree_const(info->mode); + kfree(info); + } return 0; } From 236970c5aa2ec98fd57c7240b96355fb2a9d635f Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:15 +0530 Subject: [PATCH 175/438] power: reset: reboot-mode: Add firmware node based registration The reboot-mode driver does not have a strict requirement for device-based registration. It primarily uses the device's of_node to read mode- properties. Remove the dependency on struct device and introduce support for firmware node (fwnode) based registration. This enables drivers that are not associated with a struct device to leverage the reboot-mode framework. Signed-off-by: Shivendra Pratap Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-2-46e085bca4cc@oss.qualcomm.com --- drivers/power/reset/reboot-mode.c | 19 ++++++++++++++++--- include/linux/reboot-mode.h | 4 +++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index ac4223794083f..eff60d6e04df2 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -8,10 +8,12 @@ #include #include #include +#include #include #include #include #include +#include #define PREFIX "mode-" @@ -67,18 +69,26 @@ static int reboot_mode_notify(struct notifier_block *this, /** * reboot_mode_register - register a reboot mode driver * @reboot: reboot mode driver + * @fwnode: Firmware node with reboot-mode configuration * * Returns: 0 on success or a negative error code on failure. */ -int reboot_mode_register(struct reboot_mode_driver *reboot) +int reboot_mode_register(struct reboot_mode_driver *reboot, struct fwnode_handle *fwnode) { struct mode_info *info; struct mode_info *next; + struct device_node *np; struct property *prop; - struct device_node *np = reboot->dev->of_node; size_t len = strlen(PREFIX); int ret; + if (!fwnode) + return -EINVAL; + + np = to_of_node(fwnode); + if (!np) + return -EINVAL; + INIT_LIST_HEAD(&reboot->head); for_each_property_of_node(np, prop) { @@ -168,11 +178,14 @@ int devm_reboot_mode_register(struct device *dev, struct reboot_mode_driver **dr; int rc; + if (!reboot->dev || !reboot->dev->of_node) + return -EINVAL; + dr = devres_alloc(devm_reboot_mode_release, sizeof(*dr), GFP_KERNEL); if (!dr) return -ENOMEM; - rc = reboot_mode_register(reboot); + rc = reboot_mode_register(reboot, of_fwnode_handle(reboot->dev->of_node)); if (rc) { devres_free(dr); return rc; diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h index 4a2abb38d1d61..22f707ade4ba9 100644 --- a/include/linux/reboot-mode.h +++ b/include/linux/reboot-mode.h @@ -2,6 +2,8 @@ #ifndef __REBOOT_MODE_H__ #define __REBOOT_MODE_H__ +#include + struct reboot_mode_driver { struct device *dev; struct list_head head; @@ -9,7 +11,7 @@ struct reboot_mode_driver { struct notifier_block reboot_notifier; }; -int reboot_mode_register(struct reboot_mode_driver *reboot); +int reboot_mode_register(struct reboot_mode_driver *reboot, struct fwnode_handle *fwnode); int reboot_mode_unregister(struct reboot_mode_driver *reboot); int devm_reboot_mode_register(struct device *dev, struct reboot_mode_driver *reboot); From 61008e160ea530b0a038034619eaa129fffe2128 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:42:55 -0800 Subject: [PATCH 176/438] FROMLIST: dt-bindings: remoteproc: qcom,sm8550-pas: Add Kaanapali ADSP Document compatible for Qualcomm Kaanapali SoC ADSP PAS which looks fully compatible with SM8750, which can fallback to SM8550 except for one more interrupt ("shutdown-ack"). Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-remoteproc-v4-1-fcf0b04d01af@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- .../devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index 11b056d6a4808..cf3aaf5a46e47 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -28,7 +28,9 @@ properties: - qcom,x1e80100-adsp-pas - qcom,x1e80100-cdsp-pas - items: - - const: qcom,sm8750-adsp-pas + - enum: + - qcom,kaanapali-adsp-pas + - qcom,sm8750-adsp-pas - const: qcom,sm8550-adsp-pas - items: - const: qcom,sm8750-cdsp-pas @@ -95,6 +97,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-adsp-pas - qcom,sm8750-adsp-pas then: properties: From 928652aef92cf5bdafa735d17304ac4d0192bc90 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:42:56 -0800 Subject: [PATCH 177/438] FROMLIST: dt-bindings: remoteproc: qcom,sm8550-pas: Add Kaanapali CDSP Add remote processor PAS loader for Kaanapali CDSP processor, compatible with earlier SM8550 with minor difference: one more sixth "shutdown-ack" interrupt. It is not compatible with SM8650 because one memory region "global_sync_mem" is not managed by kernel on Kaanapali so it is removed in the remoteproc cdsp node. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-remoteproc-v4-2-fcf0b04d01af@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- .../devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index cf3aaf5a46e47..b117c82b057b3 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -32,6 +32,10 @@ properties: - qcom,kaanapali-adsp-pas - qcom,sm8750-adsp-pas - const: qcom,sm8550-adsp-pas + - items: + - enum: + - qcom,kaanapali-cdsp-pas + - const: qcom,sm8550-cdsp-pas - items: - const: qcom,sm8750-cdsp-pas - const: qcom,sm8650-cdsp-pas @@ -98,6 +102,7 @@ allOf: contains: enum: - qcom,kaanapali-adsp-pas + - qcom,kaanapali-cdsp-pas - qcom,sm8750-adsp-pas then: properties: From 2e4d4bab426b5e62d7ca96009c8dfcce29b18048 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 2 Feb 2026 22:06:18 -0800 Subject: [PATCH 178/438] FROMLIST: arm64: dts: qcom: kaanapali: add coresight nodes Add CoreSight nodes to enable trace paths such as TPDM->ETF and STM->ETF. These devices are part of the AOSS, CDSP, QDSS, modem and some small subsystems, such as DCC, GCC, ipcc and so on. Signed-off-by: Jie Gan Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-1-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 1160 +++++++++++++++++++++++ 1 file changed, 1160 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 9ef57ad0ca71d..6e231850d5d6c 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -1080,6 +1080,1114 @@ }; }; + stm@10002000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0x0 0x10002000 0x0 0x1000>, + <0x0 0x16280000 0x0 0x180000>; + reg-names = "stm-base", + "stm-stimulus-base"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + stm_out: endpoint { + remote-endpoint = <&funnel_in0_in7>; + }; + }; + }; + }; + + tpdm@10003000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10003000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_dcc_out: endpoint { + remote-endpoint = <&tpda_qdss_in0>; + }; + }; + }; + }; + + tpda@10004000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x10004000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_qdss_in0: endpoint { + remote-endpoint = <&tpdm_dcc_out>; + }; + }; + + port@1 { + reg = <1>; + + tpda_qdss_in1: endpoint { + remote-endpoint = <&tpdm_spdm_out>; + }; + }; + }; + + out-ports { + port { + tpda_qdss_out: endpoint { + remote-endpoint = <&funnel_in0_in6>; + }; + }; + }; + }; + + tpdm@1000f000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1000f000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_spdm_out: endpoint { + remote-endpoint = <&tpda_qdss_in1>; + }; + }; + }; + }; + + funnel@10041000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x10041000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + funnel_in0_in0: endpoint { + remote-endpoint = <&tn_ag_out>; + }; + }; + + port@6 { + reg = <6>; + + funnel_in0_in6: endpoint { + remote-endpoint = <&tpda_qdss_out>; + }; + }; + + port@7 { + reg = <7>; + + funnel_in0_in7: endpoint { + remote-endpoint = <&stm_out>; + }; + }; + }; + + out-ports { + port { + funnel_in0_out: endpoint { + remote-endpoint = <&funnel_aoss_in6>; + }; + }; + }; + }; + + tpdm@11000000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11000000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_modem0_out: endpoint { + remote-endpoint = <&tpda_modem_in0>; + }; + }; + }; + }; + + tpda@11004000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x11004000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_modem_in0: endpoint { + remote-endpoint = <&tpdm_modem0_out>; + }; + }; + + port@1 { + reg = <1>; + + tpda_modem_in1: endpoint { + remote-endpoint = <&tpdm_modem1_out>; + }; + }; + + port@2 { + reg = <2>; + + tpda_modem_in2: endpoint { + remote-endpoint = <&tpdm_modem2_out>; + }; + }; + }; + + out-ports { + port { + tpda_modem_out: endpoint { + remote-endpoint = <&funnel_modem_dl_in0>; + }; + }; + }; + }; + + funnel@11005000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x11005000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + funnel_modem_dl_in0: endpoint { + remote-endpoint = <&tpda_modem_out>; + }; + }; + }; + + out-ports { + port { + funnel_modem_dl_out: endpoint { + remote-endpoint = <&tn_ag_in13>; + }; + }; + }; + }; + + tpdm@1102c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1102c000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_gcc_out: endpoint { + remote-endpoint = <&tn_ag_in17>; + }; + }; + }; + }; + + tpdm@11180000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11180000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_cdsp_out: endpoint { + remote-endpoint = <&tpda_cdsp_in0>; + }; + }; + }; + }; + + tpdm@11183000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11183000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_cdsp_cmsr1_out: endpoint { + remote-endpoint = <&tpda_cdsp_in3>; + }; + }; + }; + }; + + tpdm@11184000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11184000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_cdsp_cmsr2_out: endpoint { + remote-endpoint = <&tpda_cdsp_in4>; + }; + }; + }; + }; + + tpdm@11185000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11185000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_cdsp_dpm1_out: endpoint { + remote-endpoint = <&tpda_cdsp_in5>; + }; + }; + }; + }; + + tpdm@11186000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11186000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_cdsp_dpm2_out: endpoint { + remote-endpoint = <&tpda_cdsp_in6>; + }; + }; + }; + }; + + tpda@11188000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x11188000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_cdsp_in0: endpoint { + remote-endpoint = <&tpdm_cdsp_out>; + }; + }; + + port@1 { + reg = <1>; + + tpda_cdsp_in1: endpoint { + remote-endpoint = <&tpdm_cdsp_llm_out>; + }; + }; + + port@2 { + reg = <2>; + + tpda_cdsp_in2: endpoint { + remote-endpoint = <&tpdm_cdsp_llm2_out>; + }; + }; + + port@3 { + reg = <3>; + + tpda_cdsp_in3: endpoint { + remote-endpoint = <&tpdm_cdsp_cmsr1_out>; + }; + }; + + port@4 { + reg = <4>; + + tpda_cdsp_in4: endpoint { + remote-endpoint = <&tpdm_cdsp_cmsr2_out>; + }; + }; + + port@5 { + reg = <5>; + + tpda_cdsp_in5: endpoint { + remote-endpoint = <&tpdm_cdsp_dpm1_out>; + }; + }; + + port@6 { + reg = <6>; + + tpda_cdsp_in6: endpoint { + remote-endpoint = <&tpdm_cdsp_dpm2_out>; + }; + }; + }; + + out-ports { + port { + tpda_cdsp_out: endpoint { + remote-endpoint = <&funnel_cdsp_in0>; + }; + }; + }; + }; + + funnel@11189000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x11189000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + funnel_cdsp_in0: endpoint { + remote-endpoint = <&tpda_cdsp_out>; + }; + }; + }; + + out-ports { + port { + funnel_cdsp_out: endpoint { + remote-endpoint = <&tn_ag_in16>; + }; + }; + }; + }; + + tpdm@111a3000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a3000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_pmu_out: endpoint { + remote-endpoint = <&tn_ag_in29>; + }; + }; + }; + }; + + tpdm@111a4000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a4000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_qrng_out: endpoint { + remote-endpoint = <&tn_ag_in18>; + }; + }; + }; + }; + + tpdm@111a5000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a5000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_dlmm_out: endpoint { + remote-endpoint = <&tn_ag_in25>; + }; + }; + }; + }; + + tpdm@111a6000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a6000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_north_dsb_out: endpoint { + remote-endpoint = <&tn_ag_in26>; + }; + }; + }; + }; + + tpdm@111a7000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a7000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_south_dsb_out: endpoint { + remote-endpoint = <&tn_ag_in27>; + }; + }; + }; + }; + + tpdm@111a8000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a8000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_rdpm_cmb0_out: endpoint { + remote-endpoint = <&tn_ag_in30>; + }; + }; + }; + }; + + tpdm@111a9000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111a9000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_rdpm_cmb1_out: endpoint { + remote-endpoint = <&tn_ag_in31>; + }; + }; + }; + }; + + tpdm@111aa000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111aa000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_rdpm_cmb2_out: endpoint { + remote-endpoint = <&tn_ag_in32>; + }; + }; + }; + }; + + tpdm@111ab000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111ab000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_ipcc_cmb0_out: endpoint { + remote-endpoint = <&tn_ag_in36>; + }; + }; + }; + }; + + tpdm@111ac000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111ac000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_ipcc_cmb1_out: endpoint { + remote-endpoint = <&tn_ag_in28>; + }; + }; + }; + }; + + tpdm@111ad000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111ad000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_ipcc_cmb2_out: endpoint { + remote-endpoint = <&tn_ag_in34>; + }; + }; + }; + }; + + tpdm@111ae000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111ae000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_ipcc_cmb3_out: endpoint { + remote-endpoint = <&tn_ag_in37>; + }; + }; + }; + }; + + tpdm@111af000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111af000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_ipcc_cmb4_out: endpoint { + remote-endpoint = <&tn_ag_in35>; + }; + }; + }; + }; + + tpdm@111b3000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111b3000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_pcie_rscc_out: endpoint { + remote-endpoint = <&tn_ag_in8>; + }; + }; + }; + }; + + tn@111b8000 { + compatible = "qcom,coresight-tnoc", "arm,primecell"; + reg = <0x0 0x111b8000 0x0 0x4200>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@8 { + reg = <8>; + + tn_ag_in8: endpoint { + remote-endpoint = <&tpdm_pcie_rscc_out>; + }; + }; + + port@d { + reg = <0xd>; + + tn_ag_in13: endpoint { + remote-endpoint = <&funnel_modem_dl_out>; + }; + }; + + port@10 { + reg = <0x10>; + + tn_ag_in16: endpoint { + remote-endpoint = <&funnel_cdsp_out>; + }; + }; + + port@11 { + reg = <0x11>; + + tn_ag_in17: endpoint { + remote-endpoint = <&tpdm_gcc_out>; + }; + }; + + port@12 { + reg = <0x12>; + + tn_ag_in18: endpoint { + remote-endpoint = <&tpdm_qrng_out>; + }; + }; + + port@13 { + reg = <0x13>; + + tn_ag_in19: endpoint { + remote-endpoint = <&tpdm_qm_out>; + }; + }; + + port@15 { + reg = <0x15>; + + tn_ag_in21: endpoint { + remote-endpoint = <&tpdm_ipa_out>; + }; + }; + + port@19 { + reg = <0x19>; + + tn_ag_in25: endpoint { + remote-endpoint = <&tpdm_dlmm_out>; + }; + }; + + port@1a { + reg = <0x1a>; + + tn_ag_in26: endpoint { + remote-endpoint = <&tpdm_north_dsb_out>; + }; + }; + + port@1b { + reg = <0x1b>; + + tn_ag_in27: endpoint { + remote-endpoint = <&tpdm_south_dsb_out>; + }; + }; + + port@1c { + reg = <0x1c>; + + tn_ag_in28: endpoint { + remote-endpoint = <&tpdm_ipcc_cmb1_out>; + }; + }; + + port@1d { + reg = <0x1d>; + + tn_ag_in29: endpoint { + remote-endpoint = <&tpdm_pmu_out>; + }; + }; + + port@1e { + reg = <0x1e>; + + tn_ag_in30: endpoint { + remote-endpoint = <&tpdm_rdpm_cmb0_out>; + }; + }; + + port@1f { + reg = <0x1f>; + + tn_ag_in31: endpoint { + remote-endpoint = <&tpdm_rdpm_cmb1_out>; + }; + }; + + port@20 { + reg = <0x20>; + + tn_ag_in32: endpoint { + remote-endpoint = <&tpdm_rdpm_cmb2_out>; + }; + }; + + port@22 { + reg = <0x22>; + + tn_ag_in34: endpoint { + remote-endpoint = <&tpdm_ipcc_cmb2_out>; + }; + }; + + port@23 { + reg = <0x23>; + + tn_ag_in35: endpoint { + remote-endpoint = <&tpdm_ipcc_cmb4_out>; + }; + }; + + port@24 { + reg = <0x24>; + + tn_ag_in36: endpoint { + remote-endpoint = <&tpdm_ipcc_cmb0_out>; + }; + }; + + port@25 { + reg = <37>; + + tn_ag_in37: endpoint { + remote-endpoint = <&tpdm_ipcc_cmb3_out>; + }; + }; + }; + + out-ports { + port { + tn_ag_out: endpoint { + remote-endpoint = <&funnel_in0_in0>; + }; + }; + }; + }; + + tpdm@111d0000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_qm_out: endpoint { + remote-endpoint = <&tn_ag_in19>; + }; + }; + }; + }; + + tpdm@11303000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11303000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_swao_prio4_out: endpoint { + remote-endpoint = <&tpda_aoss_in4>; + }; + }; + }; + }; + + funnel@11304000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x11304000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@5 { + reg = <5>; + + funnel_aoss_in5: endpoint { + remote-endpoint = <&tpda_aoss_out>; + }; + }; + + port@6 { + reg = <6>; + + funnel_aoss_in6: endpoint { + remote-endpoint = <&funnel_in0_out>; + }; + }; + + }; + + out-ports { + port { + funnel_aoss_out: endpoint { + remote-endpoint = <&tmc_etf_in>; + }; + }; + }; + }; + + tmc@11305000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x11305000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + tmc_etf_in: endpoint { + remote-endpoint = <&funnel_aoss_out>; + }; + }; + }; + }; + + tpda@11308000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x11308000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_aoss_in0: endpoint { + remote-endpoint = <&tpdm_swao_prio0_out>; + }; + }; + + port@1 { + reg = <1>; + + tpda_aoss_in1: endpoint { + remote-endpoint = <&tpdm_swao_prio1_out>; + }; + }; + + port@2 { + reg = <2>; + + tpda_aoss_in2: endpoint { + remote-endpoint = <&tpdm_swao_prio2_out>; + }; + }; + + port@3 { + reg = <3>; + + tpda_aoss_in3: endpoint { + remote-endpoint = <&tpdm_swao_prio3_out>; + }; + }; + + port@4 { + reg = <4>; + + tpda_aoss_in4: endpoint { + remote-endpoint = <&tpdm_swao_prio4_out>; + }; + }; + + port@5 { + reg = <5>; + + tpda_aoss_in5: endpoint { + remote-endpoint = <&tpdm_swao_out>; + }; + }; + }; + + out-ports { + port { + tpda_aoss_out: endpoint { + remote-endpoint = <&funnel_aoss_in5>; + }; + }; + }; + }; + + tpdm@11309000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11309000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_swao_prio0_out: endpoint { + remote-endpoint = <&tpda_aoss_in0>; + }; + }; + }; + }; + + tpdm@1130a000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1130a000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_swao_prio1_out: endpoint { + remote-endpoint = <&tpda_aoss_in1>; + }; + }; + }; + }; + + tpdm@1130b000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1130b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_swao_prio2_out: endpoint { + remote-endpoint = <&tpda_aoss_in2>; + }; + }; + }; + }; + + tpdm@1130c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1130c000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_swao_prio3_out: endpoint { + remote-endpoint = <&tpda_aoss_in3>; + }; + }; + }; + }; + + tpdm@1130d000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1130d000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_swao_out: endpoint { + remote-endpoint = <&tpda_aoss_in5>; + }; + }; + }; + }; + + tpdm@11422000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11422000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_ipa_out: endpoint { + remote-endpoint = <&tn_ag_in21>; + }; + }; + }; + }; + sram@14680000 { compatible = "qcom,kaanapali-imem", "mmio-sram"; reg = <0x0 0x14680000 0x0 0x1000>; @@ -1603,4 +2711,56 @@ , ; }; + + tpdm-cdsp-llm { + compatible = "qcom,coresight-static-tpdm"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_cdsp_llm_out: endpoint { + remote-endpoint = <&tpda_cdsp_in1>; + }; + }; + }; + }; + + tpdm-cdsp-llm2 { + compatible = "qcom,coresight-static-tpdm"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_cdsp_llm2_out: endpoint { + remote-endpoint = <&tpda_cdsp_in2>; + }; + }; + }; + }; + + tpdm-modem1 { + compatible = "qcom,coresight-static-tpdm"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_modem1_out: endpoint { + remote-endpoint = <&tpda_modem_in1>; + }; + }; + }; + }; + + tpdm-modem2 { + compatible = "qcom,coresight-static-tpdm"; + qcom,cmb-element-bits = <64>; + + out-ports { + port { + tpdm_modem2_out: endpoint { + remote-endpoint = <&tpda_modem_in2>; + }; + }; + }; + }; }; From a94fd1561e68de71e1c6b6779d256023ac62b69b Mon Sep 17 00:00:00 2001 From: Jyothi Kumar Seerapu Date: Mon, 2 Feb 2026 22:06:19 -0800 Subject: [PATCH 179/438] FROMLIST: arm64: dts: qcom: kaanapali: Add QUPv3 configuration for serial engines Add device tree support for QUPv3 serial engine protocols on Kaanapali. Kaanapali has 24 QUP serial engines across 4 QUP wrappers, each with support of GPI DMA engines, and it also includes 5 I2C hubs. Signed-off-by: Jyothi Kumar Seerapu Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-2-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 2226 ++++++++++++++++++++++- 1 file changed, 2159 insertions(+), 67 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 6e231850d5d6c..df05d204ed413 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -468,102 +469,1692 @@ #power-domain-cells = <1>; }; + gpi_dma2: dma-controller@800000 { + compatible = "qcom,kaanapali-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00800000 0x0 0x60000>; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + ; + + dma-channels = <12>; + dma-channel-mask = <0x1f>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0x436 0x0>; + dma-coherent; + }; + + qupv3_2: geniqup@8c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x008c0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_2_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0x423 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c8: i2c@880000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00880000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, + <&gpi_dma2 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c8_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi8: spi@880000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00880000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, + <&gpi_dma2 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c9: i2c@884000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00884000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, + <&gpi_dma2 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c9_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi9: spi@884000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00884000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, + <&gpi_dma2 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c10: i2c@888000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00888000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, + <&gpi_dma2 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c10_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi10: spi@888000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00888000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, + <&gpi_dma2 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c11: i2c@88c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0088c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, + <&gpi_dma2 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c11_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi11: spi@88c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0088c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, + <&gpi_dma2 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi11_data_clk>, <&qup_spi11_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c12: i2c@890000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00890000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, + <&gpi_dma2 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c12_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + i2c_master_hub: geniqup@9c0000 { + compatible = "qcom,geni-se-i2c-master-hub"; + reg = <0x0 0x009c0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_I2C_S_AHB_CLK>; + clock-names = "s-ahb"; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + i2c_hub_0: i2c@980000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00980000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_I2C_S0_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c0_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_1: i2c@984000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00984000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_I2C_S1_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c1_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_2: i2c@988000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00988000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_I2C_S2_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c2_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_3: i2c@98c000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x0098c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_I2C_S3_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c3_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_4: i2c@990000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00990000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_I2C_S4_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c4_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + gpi_dma1: dma-controller@a00000 { + compatible = "qcom,kaanapali-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00a00000 0x0 0x60000>; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + ; + + dma-channels = <12>; + dma-channel-mask = <0x1f>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0xb6 0x0>; + dma-coherent; + }; + qupv3_1: geniqup@ac0000 { compatible = "qcom,geni-se-qup"; reg = <0x0 0x00ac0000 0x0 0x2000>; - clocks = <&gcc GCC_QUPV3_WRAP_1_M_AXI_CLK>, - <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; - clock-names = "m-ahb", - "s-ahb"; + clocks = <&gcc GCC_QUPV3_WRAP_1_M_AXI_CLK>, + <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0xa3 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c0: i2c@a80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a80000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, + <&gpi_dma1 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c0_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi0: spi@a80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a80000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, + <&gpi_dma1 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c1: i2c@a84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a84000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, + <&gpi_dma1 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c1_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi1: spi@a84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a84000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, + <&gpi_dma1 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi1_data_clk>, <&qup_spi1_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c2: i2c@a88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a88000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, + <&gpi_dma1 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c2_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi2: spi@a88000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a88000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, + <&gpi_dma1 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c3: i2c@a8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, + <&gpi_dma1 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c3_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi3: spi@a8c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, + <&gpi_dma1 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c4: i2c@a90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a90000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, + <&gpi_dma1 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c4_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi4: spi@a90000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a90000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, + <&gpi_dma1 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c5: i2c@a94000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a94000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, + <&gpi_dma1 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c5_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi5: spi@a94000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a94000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, + <&gpi_dma1 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi5_data_clk>, <&qup_spi5_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c6: i2c@a98000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a98000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, + <&gpi_dma1 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c6_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi6: spi@a98000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a98000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, + <&gpi_dma1 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart7: serial@a9c000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x00a9c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart7_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + }; + + ipcc: mailbox@1106000 { + compatible = "qcom,kaanapali-ipcc", "qcom,ipcc"; + reg = <0x0 0x01106000 0x0 0x1000>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <3>; + + #mbox-cells = <2>; + }; + + cnoc_main: interconnect@1500000 { + compatible = "qcom,kaanapali-cnoc-main"; + reg = <0x0 0x01500000 0x0 0x1a080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + config_noc: interconnect@1600000 { + compatible = "qcom,kaanapali-cnoc-cfg"; + reg = <0x0 0x01600000 0x0 0x6200>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + system_noc: interconnect@1680000 { + compatible = "qcom,kaanapali-system-noc"; + reg = <0x0 0x01680000 0x0 0x1f080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + pcie_noc: interconnect@16c0000 { + compatible = "qcom,kaanapali-pcie-anoc"; + reg = <0x0 0x016c0000 0x0 0x11400>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CFG_NOC_PCIE_ANOC_AHB_CLK>; + }; + + aggre_noc: interconnect@16e0000 { + compatible = "qcom,kaanapali-aggre-noc"; + reg = <0x0 0x016e0000 0x0 0x42400>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&rpmhcc RPMH_IPA_CLK>; + }; + + mmss_noc: interconnect@1780000 { + compatible = "qcom,kaanapali-mmss-noc"; + reg = <0x0 0x01780000 0x0 0x5b800>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + gpi_dma3: dma-controller@1900000 { + compatible = "qcom,kaanapali-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x01900000 0x0 0x60000>; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + ; + + dma-channels = <12>; + dma-channel-mask = <0x1e>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0x4d6 0x0>; + dma-coherent; + }; + + qupv3_3: geniqup@19c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x019c0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_3_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_3_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0x4c3 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c13: i2c@1980000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01980000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 0 QCOM_GPI_I2C>, + <&gpi_dma3 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c13_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c14: i2c@1984000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01984000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 1 QCOM_GPI_I2C>, + <&gpi_dma3 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c14_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi14: spi@1984000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01984000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 1 QCOM_GPI_SPI>, + <&gpi_dma3 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi14_data_clk>, <&qup_spi14_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c15: i2c@1988000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01988000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 2 QCOM_GPI_I2C>, + <&gpi_dma3 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c15_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi15: spi@1988000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01988000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 2 QCOM_GPI_SPI>, + <&gpi_dma3 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi15_data_clk>, <&qup_spi15_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c16: i2c@198c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0198c000 0x0 0x4000>; + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 3 QCOM_GPI_I2C>, + <&gpi_dma3 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c16_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi16: spi@198c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x198c000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 3 QCOM_GPI_SPI>, + <&gpi_dma3 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi16_data_clk>, <&qup_spi16_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c17: i2c@1990000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01990000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 4 QCOM_GPI_I2C>, + <&gpi_dma3 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c17_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi17: spi@1990000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01990000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 4 QCOM_GPI_SPI>, + <&gpi_dma3 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi17_data_clk>, <&qup_spi17_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart18: serial@1994000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01994000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP3_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart18_default>, <&qup_uart18_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + }; + + gpi_dma4: dma-controller@1a00000 { + compatible = "qcom,kaanapali-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x01a00000 0x0 0x60000>; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + ; + + dma-channels = <12>; + dma-channel-mask = <0x1e>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0x536 0x0>; + dma-coherent; + }; + + qupv3_4: geniqup@1ac0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x01ac0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_4_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_4_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0x523 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c19: i2c@1a80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a80000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP4_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 0 QCOM_GPI_I2C>, + <&gpi_dma4 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c19_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi19: spi@1a80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01a80000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP4_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma4 0 0 QCOM_GPI_SPI>, + <&gpi_dma4 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi19_data_clk>, <&qup_spi19_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c20: i2c@1a84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a84000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP4_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 1 QCOM_GPI_I2C>, + <&gpi_dma4 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c20_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; - iommus = <&apps_smmu 0xa3 0x0>; + spi20: spi@1a84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01a84000 0x0 0x4000>; - dma-coherent; + interrupts = ; - #address-cells = <2>; - #size-cells = <2>; - ranges; + clocks = <&gcc GCC_QUPV3_WRAP4_S1_CLK>; + clock-names = "se"; - uart7: serial@a9c000 { - compatible = "qcom,geni-debug-uart"; - reg = <0x0 0x00a9c000 0x0 0x4000>; + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; - interrupts = ; + dmas = <&gpi_dma4 0 1 QCOM_GPI_SPI>, + <&gpi_dma4 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; - clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>; + pinctrl-0 = <&qup_spi20_data_clk>, <&qup_spi20_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c21: i2c@1a88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a88000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP4_S2_CLK>; clock-names = "se"; - interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS - &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY - &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 2 QCOM_GPI_I2C>, + <&gpi_dma4 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c21_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi21: spi@1a88000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01a88000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP4_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; interconnect-names = "qup-core", "qup-config"; - pinctrl-0 = <&qup_uart7_default>; + dmas = <&gpi_dma4 0 2 QCOM_GPI_SPI>, + <&gpi_dma4 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi21_data_clk>, <&qup_spi21_cs>; pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; }; - }; - ipcc: mailbox@1106000 { - compatible = "qcom,kaanapali-ipcc", "qcom,ipcc"; - reg = <0x0 0x01106000 0x0 0x1000>; + i2c22: i2c@1a8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a8c000 0x0 0x4000>; - interrupts = ; - interrupt-controller; - #interrupt-cells = <3>; + interrupts = ; - #mbox-cells = <2>; - }; + clocks = <&gcc GCC_QUPV3_WRAP4_S3_CLK>; + clock-names = "se"; - cnoc_main: interconnect@1500000 { - compatible = "qcom,kaanapali-cnoc-main"; - reg = <0x0 0x01500000 0x0 0x1a080>; - qcom,bcm-voters = <&apps_bcm_voter>; - #interconnect-cells = <2>; - }; + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; - config_noc: interconnect@1600000 { - compatible = "qcom,kaanapali-cnoc-cfg"; - reg = <0x0 0x01600000 0x0 0x6200>; - qcom,bcm-voters = <&apps_bcm_voter>; - #interconnect-cells = <2>; - }; + dmas = <&gpi_dma4 0 3 QCOM_GPI_I2C>, + <&gpi_dma4 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; - system_noc: interconnect@1680000 { - compatible = "qcom,kaanapali-system-noc"; - reg = <0x0 0x01680000 0x0 0x1f080>; - qcom,bcm-voters = <&apps_bcm_voter>; - #interconnect-cells = <2>; - }; + pinctrl-0 = <&qup_i2c22_data_clk>; + pinctrl-names = "default"; - pcie_noc: interconnect@16c0000 { - compatible = "qcom,kaanapali-pcie-anoc"; - reg = <0x0 0x016c0000 0x0 0x11400>; - qcom,bcm-voters = <&apps_bcm_voter>; - #interconnect-cells = <2>; - clocks = <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, - <&gcc GCC_CFG_NOC_PCIE_ANOC_AHB_CLK>; - }; + #address-cells = <1>; + #size-cells = <0>; - aggre_noc: interconnect@16e0000 { - compatible = "qcom,kaanapali-aggre-noc"; - reg = <0x0 0x016e0000 0x0 0x42400>; - qcom,bcm-voters = <&apps_bcm_voter>; - #interconnect-cells = <2>; - clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, - <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, - <&rpmhcc RPMH_IPA_CLK>; - }; + status = "disabled"; + }; - mmss_noc: interconnect@1780000 { - compatible = "qcom,kaanapali-mmss-noc"; - reg = <0x0 0x01780000 0x0 0x5b800>; - qcom,bcm-voters = <&apps_bcm_voter>; - #interconnect-cells = <2>; + i2c23: i2c@1a90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a90000 0x0 0x4000>; + + interrupts = ; + + clocks = <&gcc GCC_QUPV3_WRAP4_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 4 QCOM_GPI_I2C>, + <&gpi_dma4 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c23_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; }; pcie0: pcie@1c00000 { @@ -1017,6 +2608,491 @@ #interrupt-cells = <2>; wakeup-parent = <&pdc>; + hub_i2c0_data_clk: hub-i2c0-data-clk-state { + /* SDA, SCL */ + pins = "gpio66", "gpio67"; + function = "i2chub0_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c1_data_clk: hub-i2c1-data-clk-state { + /* SDA, SCL */ + pins = "gpio78", "gpio79"; + function = "i2chub0_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c2_data_clk: hub-i2c2-data-clk-state { + /* SDA, SCL */ + pins = "gpio68", "gpio69"; + function = "i2chub0_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c3_data_clk: hub-i2c3-data-clk-state { + /* SDA, SCL */ + pins = "gpio70", "gpio71"; + function = "i2chub0_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c4_data_clk: hub-i2c4-data-clk-state { + /* SDA, SCL */ + pins = "gpio72", "gpio73"; + function = "i2chub0_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c0_data_clk: qup-i2c0-data-clk-state { + /* SDA, SCL */ + pins = "gpio80", "gpio83"; + function = "qup1_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c1_data_clk: qup-i2c1-data-clk-state { + /* SDA, SCL */ + pins = "gpio74", "gpio75"; + function = "qup1_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c2_data_clk: qup-i2c2-data-clk-state { + /* SDA, SCL */ + pins = "gpio40", "gpio41"; + function = "qup1_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c3_data_clk: qup-i2c3-data-clk-state { + /* SDA, SCL */ + pins = "gpio44", "gpio45"; + function = "qup1_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c4_data_clk: qup-i2c4-data-clk-state { + /* SDA, SCL */ + pins = "gpio36", "gpio37"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c5_data_clk: qup-i2c5-data-clk-state { + /* SDA, SCL */ + pins = "gpio52", "gpio53"; + function = "qup1_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c6_data_clk: qup-i2c6-data-clk-state { + /* SDA, SCL */ + pins = "gpio56", "gpio57"; + function = "qup1_se6"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c8_data_clk: qup-i2c8-data-clk-state { + /* SDA, SCL */ + pins = "gpio0", "gpio1"; + function = "qup2_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c9_data_clk: qup-i2c9-data-clk-state { + /* SDA, SCL */ + pins = "gpio4", "gpio5"; + function = "qup2_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c10_data_clk: qup-i2c10-data-clk-state { + /* SDA, SCL */ + pins = "gpio117", "gpio118"; + function = "qup2_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c11_data_clk: qup-i2c11-data-clk-state { + /* SDA, SCL */ + pins = "gpio122", "gpio123"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c12_data_clk: qup-i2c12-data-clk-state { + /* SDA, SCL */ + pins = "gpio208", "gpio209"; + function = "qup2_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c13_data_clk: qup-i2c13-data-clk-state { + /* SDA, SCL */ + pins = "gpio64", "gpio65"; + function = "qup3_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c14_data_clk: qup-i2c14-data-clk-state { + /* SDA, SCL */ + pins = "gpio8", "gpio9"; + function = "qup3_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c15_data_clk: qup-i2c15-data-clk-state { + /* SDA, SCL */ + pins = "gpio12", "gpio13"; + function = "qup3_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c16_data_clk: qup-i2c16-data-clk-state { + /* SDA, SCL */ + pins = "gpio16", "gpio17"; + function = "qup3_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c17_data_clk: qup-i2c17-data-clk-state { + /* SDA, SCL */ + pins = "gpio20", "gpio21"; + function = "qup3_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c19_data_clk: qup-i2c19-data-clk-state { + /* SDA, SCL */ + pins = "gpio48", "gpio49"; + function = "qup4_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c20_data_clk: qup-i2c20-data-clk-state { + /* SDA, SCL */ + pins = "gpio28", "gpio29"; + function = "qup4_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c21_data_clk: qup-i2c21-data-clk-state { + /* SDA, SCL */ + pins = "gpio32", "gpio33"; + function = "qup4_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c22_data_clk: qup-i2c22-data-clk-state { + /* SDA, SCL */ + pins = "gpio121", "gpio84"; + function = "qup4_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c23_data_clk: qup-i2c23-data-clk-state { + /* SDA, SCL */ + pins = "gpio161", "gpio162"; + function = "qup4_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi0_cs: qup-spi0-cs-state { + pins = "gpio81"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi0_data_clk: qup-spi0-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio80", "gpio83", "gpio82"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi1_cs: qup-spi1-cs-state { + pins = "gpio77"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi1_data_clk: qup-spi1-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio74", "gpio75", "gpio76"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi2_cs: qup-spi2-cs-state { + pins = "gpio43"; + function = "qup1_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi2_data_clk: qup-spi2-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio40", "gpio41", "gpio42"; + function = "qup1_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi3_cs: qup-spi3-cs-state { + pins = "gpio47"; + function = "qup1_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi3_data_clk: qup-spi3-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio44", "gpio45", "gpio46"; + function = "qup1_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi4_cs: qup-spi4-cs-state { + pins = "gpio39"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi4_data_clk: qup-spi4-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio36", "gpio37", "gpio38"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi5_cs: qup-spi5-cs-state { + pins = "gpio55"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi5_data_clk: qup-spi5-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio52", "gpio53", "gpio54"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi6_cs: qup-spi6-cs-state { + pins = "gpio59"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi6_data_clk: qup-spi6-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio56", "gpio57", "gpio58"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi8_cs: qup-spi8-cs-state { + pins = "gpio3"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi8_data_clk: qup-spi8-data-clk-state { + /* MISO, MOSI, CLK */pins = "gpio0", "gpio1", "gpio2"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi9_cs: qup-spi9-cs-state { + pins = "gpio7"; + function = "qup2_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi9_data_clk: qup-spi9-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio4", "gpio5", "gpio6"; + function = "qup2_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi10_cs: qup-spi10-cs-state { + pins = "gpio120"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi10_data_clk: qup-spi10-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio117", "gpio118", "gpio119"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi11_cs: qup-spi11-cs-state { + pins = "gpio125"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi11_data_clk: qup-spi11-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio122", "gpio123", "gpio124"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi14_cs: qup-spi14-cs-state { + pins = "gpio11"; + function = "qup3_se1"; + drive-strength = <6>; + bias-pull-up; + }; + + qup_spi14_data_clk: qup-spi14-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio8", "gpio9", "gpio10"; + function = "qup3_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi15_cs: qup-spi15-cs-state { + pins = "gpio15"; + function = "qup3_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi15_data_clk: qup-spi15-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio12", "gpio13", "gpio14"; + function = "qup3_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi16_cs: qup-spi16-cs-state { + pins = "gpio19"; + function = "qup3_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi16_data_clk: qup-spi16-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio16", "gpio17", "gpio18"; + function = "qup3_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi17_cs: qup-spi17-cs-state { + pins = "gpio23"; + function = "qup3_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi17_data_clk: qup-spi17-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio20", "gpio21", "gpio22"; + function = "qup3_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi19_cs: qup-spi19-cs-state { + pins = "gpio51"; + function = "qup4_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi19_data_clk: qup-spi19-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio48", "gpio49", "gpio50"; + function = "qup4_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi20_cs: qup-spi20-cs-state { + pins = "gpio31"; + function = "qup4_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi20_data_clk: qup-spi20-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio28", "gpio29", "gpio30"; + function = "qup4_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi21_cs: qup-spi21-cs-state { + pins = "gpio35"; + function = "qup4_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi21_data_clk: qup-spi21-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio32", "gpio33", "gpio34"; + function = "qup4_se2"; + drive-strength = <6>; + bias-disable; + }; + qup_uart7_default: qup-uart7-state { /* TX, RX */ pins = "gpio62", "gpio63"; @@ -1025,6 +3101,22 @@ bias-disable; }; + qup_uart18_default: qup-uart18-default-state { + /* TX, RX */ + pins = "gpio26", "gpio27"; + function = "qup3_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_uart18_cts_rts: qup-uart18-cts-rts-state { + /* CTS, RTS */ + pins = "gpio24", "gpio25"; + function = "qup3_se5"; + drive-strength = <2>; + bias-pull-down; + }; + sdc2_default: sdc2-default-state { clk-pins { pins = "sdc2_clk"; From 05131964da1163dc7045dc15878d2755d5783c4f Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Mon, 2 Feb 2026 22:06:20 -0800 Subject: [PATCH 180/438] FROMLIST: arm64: dts: qcom: kaanapali: Add TSENS and thermal zones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Kaanapali includes seven TSENS instances, with a total of 55 thermal sensors distributed across various locations on the SoC. The TSENS max/reset threshold is configured to 130°C in the hardware. Enable all TSENS instances, and define the thermal zones with a hot trip at 120°C and critical trip at 125°C. Signed-off-by: Manaf Meethalavalappu Pallikunhi Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-3-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 1075 +++++++++++++++++++++++ 1 file changed, 1075 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index df05d204ed413..251e36cf74771 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -2583,6 +2583,90 @@ interrupt-controller; }; + tsens0: thermal-sensor@c229000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c229000 0x0 0x1000>, + <0x0 0x0c222000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <5>; + #thermal-sensor-cells = <1>; + }; + + tsens1: thermal-sensor@c22a000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22a000 0x0 0x1000>, + <0x0 0x0c223000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <12>; + #thermal-sensor-cells = <1>; + }; + + tsens2: thermal-sensor@c22b000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22b000 0x0 0x1000>, + <0x0 0x0c224000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <7>; + #thermal-sensor-cells = <1>; + }; + + tsens3: thermal-sensor@c22c000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22c000 0x0 0x1000>, + <0x0 0x0c225000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <4>; + #thermal-sensor-cells = <1>; + }; + + tsens4: thermal-sensor@c22d000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22d000 0x0 0x1000>, + <0x0 0x0c226000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <8>; + #thermal-sensor-cells = <1>; + }; + + tsens5: thermal-sensor@c22e000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22e000 0x0 0x1000>, + <0x0 0x0c227000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <12>; + #thermal-sensor-cells = <1>; + }; + + tsens6: thermal-sensor@c22f000 { + compatible = "qcom,kaanapali-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22f000 0x0 0x1000>, + <0x0 0x0c228000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <7>; + #thermal-sensor-cells = <1>; + }; + aoss_qmp: power-management@c300000 { compatible = "qcom,kaanapali-aoss-qmp", "qcom,aoss-qmp"; reg = <0x0 0x0c300000 0x0 0x400>; @@ -4795,6 +4879,997 @@ }; }; + thermal-zones { + cpullc-0-0-thermal { + thermal-sensors = <&tsens0 0>; + + trips { + cpullc-0-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpullc-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-0-1-thermal { + thermal-sensors = <&tsens0 1>; + + trips { + cpullc-0-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpullc-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-0-thermal { + thermal-sensors = <&tsens0 2>; + + trips { + qmx-0-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-1-thermal { + thermal-sensors = <&tsens0 3>; + + trips { + qmx-0-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-2-thermal { + thermal-sensors = <&tsens0 4>; + + trips { + qmx-0-2-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-0-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-0-0-thermal { + thermal-sensors = <&tsens1 0>; + + trips { + cpu-0-0-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-0-1-thermal { + thermal-sensors = <&tsens1 1>; + + trips { + cpu-0-0-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-1-0-thermal { + thermal-sensors = <&tsens1 2>; + + trips { + cpu-0-1-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-1-1-thermal { + thermal-sensors = <&tsens1 3>; + + trips { + cpu-0-1-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-2-0-thermal { + thermal-sensors = <&tsens1 4>; + + trips { + cpu-0-2-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-2-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-2-1-thermal { + thermal-sensors = <&tsens1 5>; + + trips { + cpu-0-2-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-2-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-3-0-thermal { + thermal-sensors = <&tsens1 6>; + + trips { + cpu-0-3-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-3-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-3-1-thermal { + thermal-sensors = <&tsens1 7>; + + trips { + cpu-0-3-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-3-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-4-0-thermal { + thermal-sensors = <&tsens1 8>; + + trips { + cpu-0-4-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-4-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-4-1-thermal { + thermal-sensors = <&tsens1 9>; + + trips { + cpu-0-4-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-4-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-5-0-thermal { + thermal-sensors = <&tsens1 10>; + + trips { + cpu-0-5-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-5-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-5-1-thermal { + thermal-sensors = <&tsens1 11>; + + trips { + cpu-0-5-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-5-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-1-0-thermal { + thermal-sensors = <&tsens2 0>; + + trips { + cpullc-1-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpullc-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-1-1-thermal { + thermal-sensors = <&tsens2 1>; + + trips { + cpullc-1-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpullc-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-0-thermal { + thermal-sensors = <&tsens2 2>; + + trips { + qmx-1-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-1-thermal { + thermal-sensors = <&tsens2 3>; + + trips { + qmx-1-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-2-thermal { + thermal-sensors = <&tsens2 4>; + + trips { + qmx-1-2-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-1-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-3-thermal { + thermal-sensors = <&tsens2 5>; + + trips { + qmx-1-3-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-1-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-4-thermal { + thermal-sensors = <&tsens2 6>; + + trips { + qmx-1-4-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-1-4-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-0-0-thermal { + thermal-sensors = <&tsens3 0>; + + trips { + cpu-1-0-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-0-1-thermal { + thermal-sensors = <&tsens3 1>; + + trips { + cpu-1-0-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-1-0-thermal { + thermal-sensors = <&tsens3 2>; + + trips { + cpu-1-1-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-1-1-thermal { + thermal-sensors = <&tsens3 3>; + + trips { + cpu-1-1-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-0-thermal { + thermal-sensors = <&tsens4 0>; + + trips { + nsphvx-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphvx-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-1-thermal { + thermal-sensors = <&tsens4 1>; + + trips { + nsphvx-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphvx-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-2-thermal { + thermal-sensors = <&tsens4 2>; + + trips { + nsphvx-2-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphvx-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-3-thermal { + thermal-sensors = <&tsens4 3>; + + trips { + nsphvx-3-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphvx-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-0-thermal { + thermal-sensors = <&tsens4 4>; + + trips { + nsphmx-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphmx-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-1-thermal { + thermal-sensors = <&tsens4 5>; + + trips { + nsphmx-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphmx-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-2-thermal { + thermal-sensors = <&tsens4 6>; + + trips { + nsphmx-2-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphmx-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-3-thermal { + thermal-sensors = <&tsens4 7>; + + trips { + nsphmx-3-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nsphmx-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-0-thermal { + thermal-sensors = <&tsens5 0>; + + trips { + gpuss-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-1-thermal { + thermal-sensors = <&tsens5 1>; + + trips { + gpuss-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-2-thermal { + thermal-sensors = <&tsens5 2>; + + trips { + gpuss-2-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-3-thermal { + thermal-sensors = <&tsens5 3>; + + trips { + gpuss-3-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-4-thermal { + thermal-sensors = <&tsens5 4>; + + trips { + gpuss-4-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-4-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-5-thermal { + thermal-sensors = <&tsens5 5>; + + trips { + gpuss-5-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-5-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-6-thermal { + thermal-sensors = <&tsens5 6>; + + trips { + gpuss-6-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-6-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-7-thermal { + thermal-sensors = <&tsens5 7>; + + trips { + gpuss-7-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-7-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-8-thermal { + thermal-sensors = <&tsens5 8>; + + trips { + gpuss-8-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-8-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-9-thermal { + thermal-sensors = <&tsens5 9>; + + trips { + gpuss-9-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-9-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-10-thermal { + thermal-sensors = <&tsens5 10>; + + trips { + gpuss-10-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-10-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + ddr-thermal { + thermal-sensors = <&tsens5 11>; + + trips { + ddr-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + ddr-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-0-thermal { + thermal-sensors = <&tsens6 0>; + + trips { + mdmss-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + mdmss-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-1-thermal { + thermal-sensors = <&tsens6 1>; + trips { + mdmss-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + mdmss-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-2-thermal { + thermal-sensors = <&tsens6 2>; + + trips { + mdmss-2-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + mdmss-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-3-thermal { + thermal-sensors = <&tsens6 3>; + + trips { + mdmss-3-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + mdmss-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + camera-0-thermal { + thermal-sensors = <&tsens6 4>; + + trips { + camera-0-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + camera-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + camera-1-thermal { + thermal-sensors = <&tsens6 5>; + + trips { + camera-1-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + camera-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + video-thermal { + thermal-sensors = <&tsens6 6>; + + trips { + video-hot { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + video-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; From 56fb80939c69e979a4967dfb86030a3b34e27001 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 2 Feb 2026 22:06:21 -0800 Subject: [PATCH 181/438] FROMLIST: arm64: dts: qcom: kaanapali: Add ADSP and CDSP for Kaanapali SoC Add remoteproc PAS loader for ADSP and CDSP with its SMP2P and fastrpc nodes. Co-developed-by: Kumari Pallavi Signed-off-by: Kumari Pallavi Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-4-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 314 ++++++++++++++++++++++++ 1 file changed, 314 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 251e36cf74771..c8f61200f2619 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -443,6 +443,58 @@ }; }; + smp2p-adsp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <443>, <429>; + qcom,local-pid = <0>; + qcom,remote-pid = <2>; + + smp2p_adsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_adsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-cdsp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <94>, <432>; + qcom,local-pid = <0>; + qcom,remote-pid = <5>; + + smp2p_cdsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_cdsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + soc: soc@0 { compatible = "simple-bus"; @@ -2478,6 +2530,111 @@ #reset-cells = <1>; }; + remoteproc_adsp: remoteproc@6800000 { + compatible = "qcom,kaanapali-adsp-pas", "qcom,sm8550-adsp-pas"; + reg = <0x0 0x06800000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", + "lmx"; + + memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + remoteproc_adsp_glink: glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <2>; + + label = "lpass"; + + fastrpc { + compatible = "qcom,kaanapali-fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + + iommus = <&apps_smmu 0x1003 0x80>, + <&apps_smmu 0x1043 0x20>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + + iommus = <&apps_smmu 0x1004 0x80>, + <&apps_smmu 0x1044 0x20>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + + iommus = <&apps_smmu 0x1005 0x80>, + <&apps_smmu 0x1045 0x20>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + + iommus = <&apps_smmu 0x1006 0x80>, + <&apps_smmu 0x1046 0x20>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + + iommus = <&apps_smmu 0x1007 0x40>, + <&apps_smmu 0x1067 0x0>, + <&apps_smmu 0x1087 0x0>; + dma-coherent; + }; + }; + }; + }; + lpass_lpiaon_noc: interconnect@7400000 { compatible = "qcom,kaanapali-lpass-lpiaon-noc"; reg = <0x0 0x07400000 0x0 0x19080>; @@ -4760,6 +4917,163 @@ #interconnect-cells = <2>; }; + remoteproc_cdsp: remoteproc@26300000 { + compatible = "qcom,kaanapali-cdsp-pas", "qcom,sm8550-cdsp-pas"; + reg = <0x0 0x26300000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_NSP>; + power-domain-names = "cx", + "mxc", + "nsp"; + + memory-region = <&cdsp_mem>, <&q6_cdsp_dtb_mem>; + qcom,qmp = <&aoss_qmp>; + qcom,smem-states = <&smp2p_cdsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + qcom,remote-pid = <5>; + label = "cdsp"; + + fastrpc { + compatible = "qcom,kaanapali-fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + iommus = <&apps_smmu 0x19c1 0x0>, + <&apps_smmu 0x1961 0x0>, + <&apps_smmu 0x0c21 0x0>, + <&apps_smmu 0x0c01 0x40>; + dma-coherent; + }; + + compute-cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + iommus = <&apps_smmu 0x1962 0x0>, + <&apps_smmu 0x0c02 0x20>, + <&apps_smmu 0x0c42 0x0>, + <&apps_smmu 0x19c2 0x0>; + dma-coherent; + }; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1963 0x0>, + <&apps_smmu 0x0c23 0x0>, + <&apps_smmu 0x0c03 0x40>, + <&apps_smmu 0x19c3 0x0>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1964 0x0>, + <&apps_smmu 0x0c44 0x0>, + <&apps_smmu 0x0c04 0x20>, + <&apps_smmu 0x19c4 0x0>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1965 0x0>, + <&apps_smmu 0x0c45 0x0>, + <&apps_smmu 0x0c05 0x20>, + <&apps_smmu 0x19c5 0x0>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x1966 0x0>, + <&apps_smmu 0x0c06 0x20>, + <&apps_smmu 0x0c46 0x0>, + <&apps_smmu 0x19c6 0x0>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x1967 0x0>, + <&apps_smmu 0x0c27 0x0>, + <&apps_smmu 0x0c07 0x40>, + <&apps_smmu 0x19c7 0x0>; + dma-coherent; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + iommus = <&apps_smmu 0x1968 0x0>, + <&apps_smmu 0x0c08 0x20>, + <&apps_smmu 0x0c48 0x0>, + <&apps_smmu 0x19c8 0x0>; + dma-coherent; + }; + + compute-cb@12 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <12>; + iommus = <&apps_smmu 0x196c 0x0>, + <&apps_smmu 0x0c2c 0x00>, + <&apps_smmu 0x0c0c 0x40>, + <&apps_smmu 0x19cc 0x0>; + dma-coherent; + }; + + compute-cb@13 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <13>; + iommus = <&apps_smmu 0x196d 0x0>, + <&apps_smmu 0x0c0d 0x40>, + <&apps_smmu 0x0c2e 0x0>, + <&apps_smmu 0x0c2d 0x0>, + <&apps_smmu 0x19cd 0x0>; + dma-coherent; + }; + }; + }; + }; + /* Cluster 0 */ pmu@310b3400 { compatible = "qcom,kaanapali-cpu-bwmon", "qcom,sdm845-bwmon"; From cf34a998ddaebd7f2909e6c51e957a35c35d1759 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Mon, 2 Feb 2026 22:06:22 -0800 Subject: [PATCH 182/438] FROMLIST: arm64: dts: qcom: kaanapali: Add support for audio Introduce audio support for Kaanapali SoC by adding LPASS macro codecs, TLMM pin controller and SoundWire controller with similar hardware implementation to SM8750 platform. Also add GPR (Generic Pack Router) node along with support for APM (Audio Process Manager) and PRM (Proxy Resource Manager) audio services. Signed-off-by: Prasad Kumpatla Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-5-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 367 ++++++++++++++++++++++++ 1 file changed, 367 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index c8f61200f2619..d9880a87a928d 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -16,7 +16,9 @@ #include #include #include +#include #include +#include #include "kaanapali-ipcc.h" @@ -2632,9 +2634,212 @@ dma-coherent; }; }; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = ; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = ; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1001 0x80>, + <&apps_smmu 0x1041 0x20>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; }; }; + lpass_wsa2macro: codec@6aa0000 { + compatible = "qcom,kaanapali-lpass-wsa-macro", + "qcom,sm8550-lpass-wsa-macro"; + reg = <0x0 0x06aa0000 0x0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_WSA2_CORE_TX_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_vamacro>; + clock-names = "mclk", + "macro", + "dcodec", + "fsgen"; + + #clock-cells = <0>; + clock-output-names = "wsa2-mclk"; + #sound-dai-cells = <1>; + }; + + swr3: soundwire@6ab0000 { + compatible = "qcom,soundwire-v2.2.0", "qcom,soundwire-v2.0.0"; + reg = <0 0x06ab0000 0 0x10000>; + interrupts = ; + clocks = <&lpass_wsa2macro>; + clock-names = "iface"; + label = "WSA2"; + + pinctrl-0 = <&wsa2_swr_active>; + pinctrl-names = "default"; + + qcom,din-ports = <4>; + qcom,dout-ports = <9>; + + qcom,ports-sinterval = /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0x18f 0xff 0xff 0x0f 0x0f 0xff 0x31f>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0x06 0x0d 0xff 0x00>; + qcom,ports-offset2 = /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x18>; + qcom,ports-block-pack-mode = /bits/ 8 <0x00 0x01 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x01 0x01 0x00 0x00>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + lpass_rxmacro: codec@6ac0000 { + compatible = "qcom,kaanapali-lpass-rx-macro", "qcom,sm8550-lpass-rx-macro"; + reg = <0x0 0x06ac0000 0x0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_RX_CORE_TX_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_vamacro>; + clock-names = "mclk", + "macro", + "dcodec", + "fsgen"; + + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + }; + + swr1: soundwire@6ad0000 { + compatible = "qcom,soundwire-v2.2.0", "qcom,soundwire-v2.0.0"; + reg = <0 0x06ad0000 0 0x10000>; + interrupts = ; + clocks = <&lpass_rxmacro>; + clock-names = "iface"; + label = "RX"; + + pinctrl-0 = <&rx_swr_active>; + pinctrl-names = "default"; + + qcom,din-ports = <1>; + qcom,dout-ports = <11>; + + qcom,ports-sinterval = /bits/ 16 <0x03 0x3f 0x1f 0x07 0x00 0x18f 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x0b 0x01 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x0b 0x00 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-hstart = /bits/ 8 <0xff 0x03 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0x06 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-word-length = /bits/ 8 <0x01 0x07 0x04 0xff 0xff 0x0f 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-block-pack-mode = /bits/ 8 <0xff 0x00 0x01 0xff 0xff 0x00 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0x01 0x00 0x00 0x00 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff>; + + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + lpass_txmacro: codec@6ae0000 { + compatible = "qcom,kaanapali-lpass-tx-macro", "qcom,sm8550-lpass-tx-macro"; + reg = <0x0 0x06ae0000 0x0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_vamacro>; + clock-names = "mclk", + "macro", + "dcodec", + "fsgen"; + + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + }; + + lpass_wsamacro: codec@6b00000 { + compatible = "qcom,kaanapali-lpass-wsa-macro", + "qcom,sm8550-lpass-wsa-macro"; + reg = <0x0 0x06b00000 0x0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_WSA_CORE_TX_MCLK + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_vamacro>; + clock-names = "mclk", + "macro", + "dcodec", + "fsgen"; + + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + }; + + swr0: soundwire@6b10000 { + compatible = "qcom,soundwire-v2.2.0", "qcom,soundwire-v2.0.0"; + reg = <0 0x06b10000 0 0x10000>; + interrupts = ; + clocks = <&lpass_wsamacro>; + clock-names = "iface"; + label = "WSA"; + + pinctrl-0 = <&wsa_swr_active>; + pinctrl-names = "default"; + + qcom,din-ports = <4>; + qcom,dout-ports = <9>; + + qcom,ports-sinterval = /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0x18f 0xff 0xff 0x0f 0x0f 0xff 0x31f>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0x06 0x0d 0xff 0x00>; + qcom,ports-offset2 = /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x18>; + qcom,ports-block-pack-mode = /bits/ 8 <0x00 0x01 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x01 0x01 0x00 0x00>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + lpass_lpiaon_noc: interconnect@7400000 { compatible = "qcom,kaanapali-lpass-lpiaon-noc"; reg = <0x0 0x07400000 0x0 0x19080>; @@ -2649,6 +2854,168 @@ #interconnect-cells = <2>; }; + swr2: soundwire@7630000 { + compatible = "qcom,soundwire-v2.2.0", "qcom,soundwire-v2.0.0"; + reg = <0 0x07630000 0 0x10000>; + interrupts-extended = <&intc GIC_SPI 761 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 40 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "core", "wakeup"; + clocks = <&lpass_txmacro>; + clock-names = "iface"; + label = "TX"; + + pinctrl-0 = <&tx_swr_active>; + pinctrl-names = "default"; + + qcom,din-ports = <4>; + qcom,dout-ports = <0>; + qcom,ports-sinterval-low = /bits/ 8 <0x01 0x01 0x03 0x03>; + qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x01 0x01>; + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x00 0x00>; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff>; + qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0x01 0x02 0x00 0x00>; + + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + lpass_vamacro: codec@7660000 { + compatible = "qcom,kaanapali-lpass-va-macro", "qcom,sm8550-lpass-va-macro"; + reg = <0 0x07660000 0 0x2000>; + clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "mclk", "macro", "dcodec"; + + #clock-cells = <0>; + clock-output-names = "fsgen"; + #sound-dai-cells = <1>; + }; + + lpass_tlmm: pinctrl@7760000 { + compatible = "qcom,sm8750-lpass-lpi-pinctrl", + "qcom,sm8650-lpass-lpi-pinctrl"; + reg = <0 0x07760000 0 0x20000>; + + clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "core", "audio"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&lpass_tlmm 0 0 23>; + + tx_swr_active: tx-swr-active-state { + clk-pins { + pins = "gpio0"; + function = "swr_tx_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio1", "gpio2", "gpio14"; + function = "swr_tx_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + + rx_swr_active: rx-swr-active-state { + clk-pins { + pins = "gpio3"; + function = "swr_rx_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio4", "gpio5"; + function = "swr_rx_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + + dmic01_default: dmic01-default-state { + clk-pins { + pins = "gpio6"; + function = "dmic1_clk"; + drive-strength = <8>; + output-high; + }; + + data-pins { + pins = "gpio7"; + function = "dmic1_data"; + drive-strength = <8>; + input-enable; + }; + }; + + dmic23_default: dmic23-default-state { + clk-pins { + pins = "gpio8"; + function = "dmic2_clk"; + drive-strength = <8>; + output-high; + }; + + data-pins { + pins = "gpio9"; + function = "dmic2_data"; + drive-strength = <8>; + input-enable; + }; + }; + + wsa_swr_active: wsa-swr-active-state { + clk-pins { + pins = "gpio10"; + function = "wsa_swr_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio11"; + function = "wsa_swr_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + + wsa2_swr_active: wsa2-swr-active-state { + clk-pins { + pins = "gpio15"; + function = "wsa2_swr_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio16"; + function = "wsa2_swr_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + }; + lpass_ag_noc: interconnect@7f40000 { compatible = "qcom,kaanapali-lpass-ag-noc"; reg = <0x0 0x07f40000 0x0 0xe080>; From 04dfdc9fdae7c760a6f51ba5cc3fd5d812df0835 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 2 Feb 2026 22:06:23 -0800 Subject: [PATCH 183/438] FROMLIST: arm64: dts: qcom: kaanapali-mtp: Enable ADSP and CDSP Enable ADSP and CDSP on Kaanapali MTP board. Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-6-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali-mtp.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts index 32a0825984346..3544f744fd1d8 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts +++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts @@ -684,6 +684,20 @@ reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; }; +&remoteproc_adsp { + firmware-name = "qcom/kaanapali/adsp.mbn", + "qcom/kaanapali/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/kaanapali/cdsp.mbn", + "qcom/kaanapali/cdsp_dtb.mbn"; + + status = "okay"; +}; + &sdhc_2 { cd-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>; From 3fb9b5371fb88fe25b8e54ebb2153d19d754d287 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 2 Feb 2026 22:06:24 -0800 Subject: [PATCH 184/438] FROMLIST: arm64: dts: qcom: kaanapali-qrd: Enable ADSP and CDSP Enable ADSP and CDSP on Kaanapali QRD board. Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-7-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali-qrd.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts b/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts index 66b423a497b39..32034eed03eb0 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts +++ b/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts @@ -682,6 +682,20 @@ status = "okay"; }; +&remoteproc_adsp { + firmware-name = "qcom/kaanapali/adsp.mbn", + "qcom/kaanapali/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/kaanapali/cdsp.mbn", + "qcom/kaanapali/cdsp_dtb.mbn"; + + status = "okay"; +}; + &tlmm { gpio-reserved-ranges = <36 4>, /* NFC eSE SPI */ <74 1>, /* eSE */ From 486ffa96a05def9dd7248abf93043bc21d5863b5 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Mon, 2 Feb 2026 22:06:25 -0800 Subject: [PATCH 185/438] FROMLIST: arm64: dts: qcom: kaanapali-mtp: Add audio support (WSA8845, WCD9395, DMIC) Add support for audio on the Kaanapali MTP platform by introducing device tree nodes for WSA8845 smart speaker amplifier for playback, DMIC microphone for capture, and sound card routing. The WCD9395 codec is add to supply MIC-BIAS, for enabling onboard microphone capture. Signed-off-by: Prasad Kumpatla Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-8-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali-mtp.dts | 226 +++++++++++++++++++++ 1 file changed, 226 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts index 3544f744fd1d8..bc57935c042c9 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts +++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts @@ -52,6 +52,115 @@ clock-div = <2>; }; }; + + sound { + compatible = "qcom,kaanapali-sndcard", "qcom,sm8450-sndcard"; + model = "Kaanapali-MTP"; + + audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", + "SpkrRight IN", "WSA_SPK2 OUT", + "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2", + "VA DMIC0", "MIC BIAS1", + "VA DMIC1", "MIC BIAS1", + "VA DMIC2", "MIC BIAS3", + "VA DMIC3", "MIC BIAS3", + "TX SWR_INPUT1", "ADC2_OUTPUT"; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-capture-dai-link { + link-name = "WCD Capture"; + + codec { + sound-dai = <&wcd939x 1>, <&swr2 0>, <&lpass_txmacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-playback-dai-link { + link-name = "WCD Playback"; + + codec { + sound-dai = <&wcd939x 0>, <&swr1 0>, <&lpass_rxmacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&north_spkr>, <&south_spkr>, <&swr0 0>, + <&lpass_wsamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + wcd939x: audio-codec { + compatible = "qcom,wcd9395-codec", "qcom,wcd9390-codec"; + + pinctrl-0 = <&wcd_default>; + pinctrl-names = "default"; + + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 + 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; + qcom,rx-device = <&wcd_rx>; + qcom,tx-device = <&wcd_tx>; + + reset-gpios = <&tlmm 161 GPIO_ACTIVE_LOW>; + + vdd-buck-supply = <&vreg_l15b_1p8>; + vdd-rxtx-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l15b_1p8>; + vdd-mic-bias-supply = <&vreg_bob1>; + vdd-px-supply = <&vreg_l1g_1p2>; + + #sound-dai-cells = <1>; + }; }; &apps_rsc { @@ -665,6 +774,14 @@ }; }; +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + + vdd-micb-supply = <&vreg_l10b_1p8>; + qcom,dmic-sample-rate = <4800000>; +}; + &pcie0 { pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -715,12 +832,114 @@ status = "okay"; }; +&swr0 { + status = "okay"; + + /* WSA8845, Speaker North */ + north_spkr: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + pinctrl-0 = <&spkr_0_sd_n_active>; + pinctrl-names = "default"; + powerdown-gpios = <&tlmm 76 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrLeft"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l2i_1p2>; + + /* + * WSA8845 Port 1 (DAC) <=> SWR0 Port 1 (SPKR_L) + * WSA8845 Port 2 (COMP) <=> SWR0 Port 2 (SPKR_L_COMP) + * WSA8845 Port 3 (BOOST) <=> SWR0 Port 3 (SPKR_L_BOOST) + * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR) + * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 10 (SPKR_L_VI) + * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS) + */ + qcom,port-mapping = <1 2 3 7 10 13>; + }; + + /* WSA8845, Speaker South */ + south_spkr: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + pinctrl-0 = <&spkr_1_sd_n_active>; + pinctrl-names = "default"; + powerdown-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrRight"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l2i_1p2>; + + /* + * WSA8845 Port 1 (DAC) <=> SWR0 Port 4 (SPKR_R) + * WSA8845 Port 2 (COMP) <=> SWR0 Port 5 (SPKR_R_COMP) + * WSA8845 Port 3 (BOOST) <=> SWR0 Port 6 (SPKR_R_BOOST) + * WSA8845 Port 4 (PBR) <=> SWR0 Port 7 (PBR) + * WSA8845 Port 5 (VISENSE) <=> SWR0 Port 11 (SPKR_R_VI) + * WSA8845 Port 6 (CPS) <=> SWR0 Port 13 (CPS) + */ + qcom,port-mapping = <4 5 6 7 11 13>; + }; +}; + +&swr1 { + status = "okay"; + + /* WCD9395 RX */ + wcd_rx: codec@0,4 { + compatible = "sdw20217010e00"; + reg = <0 4>; + + /* + * WCD9395 RX Port 1 (HPH_L/R) <=> SWR1 Port 1 (HPH_L/R) + * WCD9395 RX Port 2 (CLSH) <=> SWR1 Port 2 (CLSH) + * WCD9395 RX Port 3 (COMP_L/R) <=> SWR1 Port 3 (COMP_L/R) + * WCD9395 RX Port 4 (LO) <=> SWR1 Port 4 (LO) + * WCD9395 RX Port 5 (DSD_L/R) <=> SWR1 Port 5 (DSD_L/R) + * WCD9395 RX Port 6 (HIFI_PCM_L/R) <=> SWR1 Port 9 (HIFI_PCM_L/R) + */ + qcom,rx-port-mapping = <1 2 3 4 5 9>; + }; +}; + +&swr2 { + status = "okay"; + + /* WCD9395 TX */ + wcd_tx: codec@0,3 { + compatible = "sdw20217010e00"; + reg = <0 3>; + + /* + * WCD9395 TX Port 1 (ADC1,2,3,4) <=> SWR2 Port 2 (TX SWR_INPUT 0,1,2,3) + * WCD9395 TX Port 2 (ADC3,4 & DMIC0,1) <=> SWR2 Port 2 (TX SWR_INPUT 0,1,2,3) + * WCD9395 TX Port 3 (DMIC0,1,2,3 & MBHC) <=> SWR2 Port 3 (TX SWR_INPUT 4,5,6,7) + * WCD9395 TX Port 4 (DMIC4,5,6,7) <=> SWR2 Port 4 (TX SWR_INPUT 8,9,10,11) + */ + qcom,tx-port-mapping = <2 2 3 4>; + }; +}; + &tlmm { gpio-reserved-ranges = <36 4>, /* NFC eSE SPI */ <74 1>, /* eSE */ <119 2>, /* SoCCP */ <144 4>; /* CXM UART */ + spkr_0_sd_n_active: spkr-0-sd-n-active-state { + pins = "gpio76"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + spkr_1_sd_n_active: spkr-1-sd-n-active-state { + pins = "gpio77"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + pcie0_default_state: pcie0-default-state { perst-n-pins { pins = "gpio102"; @@ -743,6 +962,13 @@ bias-pull-up; }; }; + + wcd_default: wcd-reset-n-active-state { + pins = "gpio161"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; }; &uart7 { From d4a2309a85f89566e4df0afdf75683d1d4c1d34e Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 2 Feb 2026 22:06:26 -0800 Subject: [PATCH 186/438] FROMLIST: arm64: dts: qcom: kaanapali: Add support for MM clock controllers for Kaanapali Add the device nodes for the multimedia clock controllers (cambistmclkcc, camcc, dispcc, videocc, gpucc and gxclkctl). Signed-off-by: Taniya Das Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20260224-knp-dts-misc-v6-9-79d20dab8a60@oss.qualcomm.com/ Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 111 ++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index d9880a87a928d..54d6c235e1b10 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -3,7 +3,13 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ +#include +#include +#include #include +#include +#include +#include #include #include #include @@ -1557,6 +1563,24 @@ <&rpmhcc RPMH_IPA_CLK>; }; + cambistmclkcc: clock-controller@1760000 { + compatible = "qcom,kaanapali-cambistmclkcc"; + reg = <0x0 0x01760000 0x0 0x8000>; + + clocks = <&gcc GCC_CAM_BIST_MCLK_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + mmss_noc: interconnect@1780000 { compatible = "qcom,kaanapali-mmss-noc"; reg = <0x0 0x01780000 0x0 0x5b800>; @@ -2532,6 +2556,46 @@ #reset-cells = <1>; }; + videocc: clock-controller@20f0000 { + compatible = "qcom,kaanapali-videocc"; + reg = <0x0 0x020f0000 0x0 0x10000>; + clocks = <&bi_tcxo_div2>, + <&gcc GCC_VIDEO_AHB_CLK>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + gxclkctl: clock-controller@3d64000 { + compatible = "qcom,kaanapali-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc GPU_CC_CX_GDSC>; + + #power-domain-cells = <1>; + }; + + gpucc: clock-controller@3d90000 { + compatible = "qcom,kaanapali-gpucc"; + reg = <0x0 0x03d90000 0x0 0x9800>; + + clocks = <&bi_tcxo_div2>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + remoteproc_adsp: remoteproc@6800000 { compatible = "qcom,kaanapali-adsp-pas", "qcom,sm8550-adsp-pas"; reg = <0x0 0x06800000 0x0 0x10000>; @@ -3073,6 +3137,53 @@ }; }; + camcc: clock-controller@956d000 { + compatible = "qcom,kaanapali-camcc"; + reg = <0x0 0x0956d000 0x0 0x80000>; + + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + dispcc: clock-controller@9ba2000 { + compatible = "qcom,kaanapali-dispcc"; + reg = <0x0 0x09ba2000 0x0 0x20000>; + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&gcc GCC_DISP_AHB_CLK>, + <&sleep_clk>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,kaanapali-pdc", "qcom,pdc"; reg = <0x0 0x0b220000 0x0 0x10000>, From 3edb2fa58dd34290ca32b1b0837ec00707378356 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 24 Sep 2025 17:17:37 -0700 Subject: [PATCH 187/438] FROMLIST: arm64: dts: qcom: kaanapali: Add iris video node Add DT node for the kaanapali iris video node. Written with help from Taniya Das(added videocc node). Link: https://lore.kernel.org/all/20250924-knp-dts-v1-20-3fdbc4b9e1b1@oss.qualcomm.com/ Signed-off-by: Vikash Garodia Signed-off-by: Jingyi Wang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 138 ++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 54d6c235e1b10..0c9173db903fe 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -2556,6 +2556,144 @@ #reset-cells = <1>; }; + iris: video-codec@2000000 { + compatible = "qcom,kaanapali-iris"; + + reg = <0x0 0x02000000 0x0 0xf0000>; + + interrupts = ; + + power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>, + <&videocc VIDEO_CC_MVS0_GDSC>, + <&videocc VIDEO_CC_MVS0_VPP0_GDSC>, + <&videocc VIDEO_CC_MVS0_VPP1_GDSC>, + <&videocc VIDEO_CC_MVS0A_GDSC>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_MMCX>; + power-domain-names = "venus", + "vcodec0", + "vpp0", + "vpp1", + "apv", + "mxc", + "mmcx"; + + operating-points-v2 = <&iris_opp_table>; + + clocks = <&gcc GCC_VIDEO_AXI0_CLK>, + <&videocc VIDEO_CC_MVS0C_CLK>, + <&videocc VIDEO_CC_MVS0_CLK>, + <&gcc GCC_VIDEO_AXI1_CLK>, + <&videocc VIDEO_CC_MVS0C_FREERUN_CLK>, + <&videocc VIDEO_CC_MVS0_FREERUN_CLK>, + <&videocc VIDEO_CC_MVS0B_CLK>, + <&videocc VIDEO_CC_MVS0_VPP0_CLK>, + <&videocc VIDEO_CC_MVS0_VPP1_CLK>, + <&videocc VIDEO_CC_MVS0A_CLK>; + clock-names = "iface", + "core", + "vcodec0_core", + "iface1", + "core_freerun", + "vcodec0_core_freerun", + "vcodec_bse", + "vcodec_vpp0", + "vcodec_vpp1", + "vcodec_apv"; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_VIDEO_MVP QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "cpu-cfg", + "video-mem"; + + memory-region = <&video_mem>; + + resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>, + <&gcc GCC_VIDEO_AXI1_CLK_ARES>, + <&videocc VIDEO_CC_MVS0C_FREERUN_CLK_ARES>, + <&videocc VIDEO_CC_MVS0_FREERUN_CLK_ARES>; + reset-names = "bus0", + "bus1", + "core_freerun_reset", + "vcodec0_core_freerun_reset"; + + iommus = <&apps_smmu 0x1940 0x0>, + <&apps_smmu 0x1943 0x0>, + <&apps_smmu 0x1944 0x0>, + <&apps_smmu 0x1a20 0x0>; + + dma-coherent; + + /* + * IRIS firmware is signed by vendors, only + * enable on boards where the proper signed firmware + * is available. + */ + status = "disabled"; + + iris_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000 240000000 + 240000000 360000000>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + }; + + opp-338000000 { + opp-hz = /bits/ 64 <338000000 338000000 + 338000000 507000000>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + }; + + opp-420000000 { + opp-hz = /bits/ 64 <420000000 420000000 + 420000000 630000000>; + required-opps = <&rpmhpd_opp_svs>, + <&rpmhpd_opp_svs>; + }; + + opp-444000000 { + opp-hz = /bits/ 64 <444000000 444000000 + 444000000 666000000>; + required-opps = <&rpmhpd_opp_svs_l1>, + <&rpmhpd_opp_svs_l1>; + }; + + opp-533000000 { + opp-hz = /bits/ 64 <533000000 533000000 + 533000000 800000000>; + required-opps = <&rpmhpd_opp_nom>, + <&rpmhpd_opp_nom>; + }; + + opp-630000000 { + opp-hz = /bits/ 64 <630000000 630000000 + 630000000 1104000000>; + required-opps = <&rpmhpd_opp_turbo>, + <&rpmhpd_opp_turbo>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000 630000000 + 630000000 1260000000>; + required-opps = <&rpmhpd_opp_turbo_l0>, + <&rpmhpd_opp_turbo_l0>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000 630000000 + 850000000 1260000000>; + required-opps = <&rpmhpd_opp_turbo_l1>, + <&rpmhpd_opp_turbo_l1>; + }; + }; + }; + videocc: clock-controller@20f0000 { compatible = "qcom,kaanapali-videocc"; reg = <0x0 0x020f0000 0x0 0x10000>; From bd309241c1a5817e1418b78c266df48886e4e6dd Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:15:03 +0530 Subject: [PATCH 188/438] FROMLIST: arm64: dts: qcom: kaanpali: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the GCC_UFS_PHY_GDSC power domain is enabled. Specify both the GCC_UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for kaanapali. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-2-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 0c9173db903fe..ac4269dd90a78 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -2537,7 +2537,11 @@ "qcom,inline-crypto-engine"; reg = <0x0 0x01d88000 0x0 0x18000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc GCC_UFS_PHY_GDSC>; }; tcsr_mutex: hwlock@1f40000 { From b08a5d63b521973bbc34eb4f7aa4a709578b3acd Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:16 +0530 Subject: [PATCH 189/438] power: reset: reboot-mode: Add support for 64 bit magic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current reboot-mode supports a single 32-bit argument for any supported mode. Some reboot-mode based drivers may require passing two independent 32-bit arguments during a reboot sequence, for uses-cases, where a mode requires an additional argument. Such drivers may not be able to use the reboot-mode driver. For example, ARM PSCI vendor-specific resets, need two arguments for its operation – reset_type and cookie, to complete the reset operation. If a driver wants to implement this firmware-based reset, it cannot use reboot-mode framework. Introduce 64-bit magic values in reboot-mode driver to accommodate dual 32-bit arguments when specified via device tree. In cases, where no second argument is passed from device tree, keep the upper 32-bit of magic un-changed(0) to maintain backward compatibility. Update the current drivers using reboot-mode for a 64-bit magic value. Reviewed-by: Umang Chheda Reviewed-by: Nirmesh Kumar Singh Signed-off-by: Shivendra Pratap Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-3-46e085bca4cc@oss.qualcomm.com --- drivers/power/reset/nvmem-reboot-mode.c | 11 ++++++++--- drivers/power/reset/qcom-pon.c | 11 ++++++++--- drivers/power/reset/reboot-mode.c | 19 +++++++++++++------ drivers/power/reset/syscon-reboot-mode.c | 11 ++++++++--- include/linux/reboot-mode.h | 3 ++- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c index d260715fccf67..4479c874077c7 100644 --- a/drivers/power/reset/nvmem-reboot-mode.c +++ b/drivers/power/reset/nvmem-reboot-mode.c @@ -17,14 +17,19 @@ struct nvmem_reboot_mode { struct nvmem_cell *cell; }; -static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot, - unsigned int magic) +static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot, u64 magic) { struct nvmem_reboot_mode *nvmem_rbm; size_t buf_len; + u32 magic_32; void *buf; int ret; + if (magic > U32_MAX) + return -EINVAL; + + magic_32 = magic; + nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot); buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len); @@ -35,7 +40,7 @@ static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot, if (buf_len > sizeof(magic)) return -EINVAL; - ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len); + ret = nvmem_cell_write(nvmem_rbm->cell, &magic_32, sizeof(magic_32)); if (ret < 0) dev_err(reboot->dev, "update reboot mode bits failed\n"); diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c index 7e108982a582e..d0ed9431a0231 100644 --- a/drivers/power/reset/qcom-pon.c +++ b/drivers/power/reset/qcom-pon.c @@ -27,17 +27,22 @@ struct qcom_pon { long reason_shift; }; -static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot, - unsigned int magic) +static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot, u64 magic) { struct qcom_pon *pon = container_of (reboot, struct qcom_pon, reboot_mode); + u32 magic_32; int ret; + if (magic > U32_MAX || (magic << pon->reason_shift) > U32_MAX) + return -EINVAL; + + magic_32 = magic << pon->reason_shift; + ret = regmap_update_bits(pon->regmap, pon->baseaddr + PON_SOFT_RB_SPARE, GENMASK(7, pon->reason_shift), - magic << pon->reason_shift); + magic_32); if (ret < 0) dev_err(pon->dev, "update reboot mode bits failed\n"); diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index eff60d6e04df2..873ac45cd7659 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -19,12 +19,11 @@ struct mode_info { const char *mode; - u32 magic; + u64 magic; struct list_head list; }; -static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot, - const char *cmd) +static u64 get_reboot_mode_magic(struct reboot_mode_driver *reboot, const char *cmd) { const char *normal = "normal"; struct mode_info *info; @@ -56,7 +55,7 @@ static int reboot_mode_notify(struct notifier_block *this, unsigned long mode, void *cmd) { struct reboot_mode_driver *reboot; - unsigned int magic; + u64 magic; reboot = container_of(this, struct reboot_mode_driver, reboot_notifier); magic = get_reboot_mode_magic(reboot, cmd); @@ -80,6 +79,8 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, struct fwnode_handle struct device_node *np; struct property *prop; size_t len = strlen(PREFIX); + u32 magic_arg1; + u32 magic_arg2; int ret; if (!fwnode) @@ -101,12 +102,18 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, struct fwnode_handle goto error; } - if (of_property_read_u32(np, prop->name, &info->magic)) { - pr_err("reboot mode %s without magic number\n", info->mode); + if (of_property_read_u32(np, prop->name, &magic_arg1)) { + pr_err("reboot mode without magic number\n"); kfree(info); continue; } + if (of_property_read_u32_index(np, prop->name, 1, &magic_arg2)) + magic_arg2 = 0; + + info->magic = magic_arg2; + info->magic = (info->magic << 32) | magic_arg1; + info->mode = kstrdup_const(prop->name + len, GFP_KERNEL); if (!info->mode) { ret = -ENOMEM; diff --git a/drivers/power/reset/syscon-reboot-mode.c b/drivers/power/reset/syscon-reboot-mode.c index e0772c9f70f7a..3cbd000c51223 100644 --- a/drivers/power/reset/syscon-reboot-mode.c +++ b/drivers/power/reset/syscon-reboot-mode.c @@ -20,16 +20,21 @@ struct syscon_reboot_mode { u32 mask; }; -static int syscon_reboot_mode_write(struct reboot_mode_driver *reboot, - unsigned int magic) +static int syscon_reboot_mode_write(struct reboot_mode_driver *reboot, u64 magic) { struct syscon_reboot_mode *syscon_rbm; + u32 magic_32; int ret; + if (magic > U32_MAX) + return -EINVAL; + + magic_32 = magic; + syscon_rbm = container_of(reboot, struct syscon_reboot_mode, reboot); ret = regmap_update_bits(syscon_rbm->map, syscon_rbm->offset, - syscon_rbm->mask, magic); + syscon_rbm->mask, magic_32); if (ret < 0) dev_err(reboot->dev, "update reboot mode bits failed\n"); diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h index 22f707ade4ba9..e0d3e8a54050a 100644 --- a/include/linux/reboot-mode.h +++ b/include/linux/reboot-mode.h @@ -3,11 +3,12 @@ #define __REBOOT_MODE_H__ #include +#include struct reboot_mode_driver { struct device *dev; struct list_head head; - int (*write)(struct reboot_mode_driver *reboot, unsigned int magic); + int (*write)(struct reboot_mode_driver *reboot, u64 magic); struct notifier_block reboot_notifier; }; From a3610d89270355a7f5113f34b452332c351171d1 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:17 +0530 Subject: [PATCH 190/438] Documentation: ABI: Add sysfs-class-reboot-mode-reboot_modes Add ABI documentation for /sys/class/reboot-mode/*/reboot_modes, a read-only sysfs attribute exposing the list of supported reboot-mode arguments. This file is created by reboot-mode framework and provides a user-readable interface to query available reboot-mode arguments. Reviewed-by: Sebastian Reichel Signed-off-by: Shivendra Pratap Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-4-46e085bca4cc@oss.qualcomm.com --- .../sysfs-class-reboot-mode-reboot_modes | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes diff --git a/Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes b/Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes new file mode 100644 index 0000000000000..6a3fc379afae3 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes @@ -0,0 +1,39 @@ +What: /sys/class/reboot-mode//reboot_modes +Date: August 2025 +KernelVersion: 6.17.0-rc1 +Contact: linux-pm@vger.kernel.org + Description: + This interface exposes the reboot-mode arguments + registered with the reboot-mode framework. It is + a read-only interface and provides a space + separated list of reboot-mode arguments supported + on the current platform. + Example: + recovery fastboot bootloader + + The exact sysfs path may vary depending on the + name of the driver that registers the arguments. + Example: + /sys/class/reboot-mode/nvmem-reboot-mode/reboot_modes + /sys/class/reboot-mode/syscon-reboot-mode/reboot_modes + /sys/class/reboot-mode/qcom-pon/reboot_modes + + The supported arguments can be used by userspace + to invoke device reset using the reboot() system + call, with the "argument" as string to "*arg" + parameter along with LINUX_REBOOT_CMD_RESTART2. + Example: + reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_RESTART2, "bootloader"); + + A driver can expose the supported arguments by + registering them with the reboot-mode framework + using the property names that follow the + mode- format. + Example: + mode-bootloader, mode-recovery. + + This attribute is useful for scripts or initramfs + logic that need to programmatically determine + which reboot-mode arguments are valid before + triggering a reboot. From c31c1171d6011e224b6a08184095769e71017807 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:18 +0530 Subject: [PATCH 191/438] power: reset: reboot-mode: Expose sysfs for registered reboot_modes Currently, there is no standardized mechanism for userspace to discover which reboot-modes are supported on a given platform. This limitation forces tools and scripts to rely on hardcoded assumptions about the supported reboot-modes. Create a class 'reboot-mode' and a device under it to expose a sysfs interface to show the available reboot mode arguments to userspace. Use the driver_name field of the struct reboot_mode_driver to create the device. For device-based drivers, configure the device driver name as driver_name. This results in the creation of: /sys/class/reboot-mode//reboot_modes This read-only sysfs file will exposes the list of supported reboot modes arguments provided by the driver, enabling userspace to query the list of arguments. Signed-off-by: Shivendra Pratap Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-5-46e085bca4cc@oss.qualcomm.com --- drivers/power/reset/reboot-mode.c | 62 ++++++++++++++++++++++++++++++- include/linux/reboot-mode.h | 2 + 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index 873ac45cd7659..582aa7f8ed7fa 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -6,6 +6,7 @@ #define pr_fmt(fmt) "reboot-mode: " fmt #include +#include #include #include #include @@ -23,6 +24,8 @@ struct mode_info { struct list_head list; }; +static struct class *rb_class; + static u64 get_reboot_mode_magic(struct reboot_mode_driver *reboot, const char *cmd) { const char *normal = "normal"; @@ -65,6 +68,51 @@ static int reboot_mode_notify(struct notifier_block *this, return NOTIFY_DONE; } +static ssize_t reboot_modes_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct reboot_mode_driver *reboot; + struct mode_info *info; + ssize_t size = 0; + + reboot = (struct reboot_mode_driver *)dev_get_drvdata(dev); + if (!reboot) + return -ENODATA; + + list_for_each_entry(info, &reboot->head, list) + size += sysfs_emit_at(buf, size, "%s ", info->mode); + + if (size) { + size += sysfs_emit_at(buf, size - 1, "\n"); + return size; + } + + return -ENODATA; +} +static DEVICE_ATTR_RO(reboot_modes); + +static int create_reboot_mode_device(struct reboot_mode_driver *reboot) +{ + int ret = 0; + + if (!rb_class) { + rb_class = class_create("reboot-mode"); + if (IS_ERR(rb_class)) + return PTR_ERR(rb_class); + } + + reboot->reboot_dev = device_create(rb_class, NULL, 0, (void *)reboot, reboot->driver_name); + if (IS_ERR(reboot->reboot_dev)) + return PTR_ERR(reboot->reboot_dev); + + ret = device_create_file(reboot->reboot_dev, &dev_attr_reboot_modes); + if (ret) { + device_unregister(reboot->reboot_dev); + return ret; + } + + return ret; +} + /** * reboot_mode_register - register a reboot mode driver * @reboot: reboot mode driver @@ -83,13 +131,17 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, struct fwnode_handle u32 magic_arg2; int ret; - if (!fwnode) + if (!fwnode || !reboot->driver_name) return -EINVAL; np = to_of_node(fwnode); if (!np) return -EINVAL; + ret = create_reboot_mode_device(reboot); + if (ret) + return ret; + INIT_LIST_HEAD(&reboot->head); for_each_property_of_node(np, prop) { @@ -142,6 +194,8 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, struct fwnode_handle kfree(info); } + device_remove_file(reboot->reboot_dev, &dev_attr_reboot_modes); + device_unregister(reboot->reboot_dev); return ret; } EXPORT_SYMBOL_GPL(reboot_mode_register); @@ -155,6 +209,9 @@ int reboot_mode_unregister(struct reboot_mode_driver *reboot) struct mode_info *info; struct mode_info *next; + if (!reboot->reboot_dev) + return -EINVAL; + unregister_reboot_notifier(&reboot->reboot_notifier); list_for_each_entry_safe(info, next, &reboot->head, list) { @@ -163,6 +220,8 @@ int reboot_mode_unregister(struct reboot_mode_driver *reboot) kfree(info); } + device_remove_file(reboot->reboot_dev, &dev_attr_reboot_modes); + device_unregister(reboot->reboot_dev); return 0; } EXPORT_SYMBOL_GPL(reboot_mode_unregister); @@ -192,6 +251,7 @@ int devm_reboot_mode_register(struct device *dev, if (!dr) return -ENOMEM; + reboot->driver_name = reboot->dev->driver->name; rc = reboot_mode_register(reboot, of_fwnode_handle(reboot->dev->of_node)); if (rc) { devres_free(dr); diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h index e0d3e8a54050a..81c149edf40fb 100644 --- a/include/linux/reboot-mode.h +++ b/include/linux/reboot-mode.h @@ -7,6 +7,8 @@ struct reboot_mode_driver { struct device *dev; + struct device *reboot_dev; + const char *driver_name; struct list_head head; int (*write)(struct reboot_mode_driver *reboot, u64 magic); struct notifier_block reboot_notifier; From 258cb82c0171c9e27437cb4d31db85e5360840b1 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:20 +0530 Subject: [PATCH 192/438] firmware: psci: Implement vendor-specific resets as reboot-mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SoC vendors have different types of resets which are controlled through various hardware registers. For instance, Qualcomm SoC may have a requirement that reboot with “bootloader” command should reboot the device to bootloader flashing mode and reboot with “edl” should reboot the device into Emergency flashing mode. Setting up such reboots on Qualcomm devices can be inconsistent across SoC platforms and may require setting different HW registers, where some of these registers may not be accessible to HLOS. These knobs evolve over product generations and require more drivers. PSCI spec defines, SYSTEM_RESET2, vendor-specific reset which can help align this requirement. Add support for PSCI SYSTEM_RESET2, vendor-specific resets and align the implementation to allow user-space initiated reboots to trigger these resets. Implement the PSCI vendor-specific resets by registering to the reboot-mode framework. As psci init is done at early kernel init, reboot-mode registration cannot be done at the time of psci init. This is because reboot-mode creates a “reboot-mode” class for exposing sysfs, which can fail at early kernel init. To overcome this, introduce a late_initcall to register PSCI vendor-specific resets as reboot modes. Implement a reboot-mode write function that sets reset_type and cookie values during the reboot notifier callback. Introduce a firmware-based call for SYSTEM_RESET2 vendor-specific reset in the psci_sys_reset path, using reset_type and cookie if supported by secure firmware. Register a panic notifier and clear vendor_reset valid status during panic. This is needed for any kernel panic that occurs post reboot_notifiers. By using the above implementation, userspace will be able to issue such resets using the reboot() system call with the "*arg" parameter as a string based command. The commands can be defined in PSCI device tree node under “reboot-mode” and are based on the reboot-mode based commands. Reviewed-by: Umang Chheda Reviewed-by: Kathiravan Thirumoorthy Reviewed-by: Nirmesh Kumar Singh Signed-off-by: Shivendra Pratap Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-7-46e085bca4cc@oss.qualcomm.com --- drivers/firmware/psci/Kconfig | 2 + drivers/firmware/psci/psci.c | 92 ++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/psci/Kconfig b/drivers/firmware/psci/Kconfig index 97944168b5e66..93ff7b071a0c3 100644 --- a/drivers/firmware/psci/Kconfig +++ b/drivers/firmware/psci/Kconfig @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only config ARM_PSCI_FW bool + select POWER_RESET + select REBOOT_MODE config ARM_PSCI_CHECKER bool "ARM PSCI checker" diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index 38ca190d4a22d..ff82e7f4c27d1 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -8,15 +8,18 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include #include #include @@ -51,6 +54,24 @@ static int resident_cpu = -1; struct psci_operations psci_ops; static enum arm_smccc_conduit psci_conduit = SMCCC_CONDUIT_NONE; +struct psci_vendor_sysreset2 { + u32 reset_type; + u32 cookie; + bool valid; +}; + +static struct psci_vendor_sysreset2 vendor_reset; + +static int psci_panic_event(struct notifier_block *nb, unsigned long v, void *p) +{ + vendor_reset.valid = false; + return NOTIFY_DONE; +} + +static struct notifier_block psci_panic_block = { + .notifier_call = psci_panic_event +}; + bool psci_tos_resident_on(int cpu) { return cpu == resident_cpu; @@ -309,7 +330,10 @@ static int get_set_conduit_method(const struct device_node *np) static int psci_sys_reset(struct notifier_block *nb, unsigned long action, void *data) { - if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) && + if (vendor_reset.valid && psci_system_reset2_supported) { + invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), vendor_reset.reset_type, + vendor_reset.cookie, 0); + } else if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) && psci_system_reset2_supported) { /* * reset_type[31] = 0 (architectural) @@ -547,6 +571,72 @@ static const struct platform_suspend_ops psci_suspend_ops = { .enter = psci_system_suspend_enter, }; +static int psci_set_vendor_sys_reset2(struct reboot_mode_driver *reboot, u64 magic) +{ + u32 magic_32; + + if (psci_system_reset2_supported) { + magic_32 = magic & GENMASK(31, 0); + vendor_reset.reset_type = PSCI_1_1_RESET_TYPE_VENDOR_START | magic_32; + vendor_reset.cookie = (magic >> 32) & GENMASK(31, 0); + vendor_reset.valid = true; + } + + return NOTIFY_DONE; +} + +static int __init psci_init_vendor_reset(void) +{ + struct reboot_mode_driver *reboot; + struct device_node *psci_np; + struct device_node *np; + int ret; + + if (!psci_system_reset2_supported) + return -EINVAL; + + psci_np = of_find_compatible_node(NULL, NULL, "arm,psci-1.0"); + if (!psci_np) + return -ENODEV; + + np = of_find_node_by_name(psci_np, "reboot-mode"); + if (!np) { + of_node_put(psci_np); + return -ENODEV; + } + + ret = atomic_notifier_chain_register(&panic_notifier_list, &psci_panic_block); + if (ret) + goto err_notifier; + + reboot = kzalloc(sizeof(*reboot), GFP_KERNEL); + if (!reboot) { + ret = -ENOMEM; + goto err_kzalloc; + } + + reboot->write = psci_set_vendor_sys_reset2; + reboot->driver_name = "psci"; + + ret = reboot_mode_register(reboot, of_fwnode_handle(np)); + if (ret) + goto err_register; + + of_node_put(psci_np); + of_node_put(np); + return 0; + +err_register: + kfree(reboot); +err_kzalloc: + atomic_notifier_chain_unregister(&panic_notifier_list, &psci_panic_block); +err_notifier: + of_node_put(psci_np); + of_node_put(np); + return ret; +} +late_initcall(psci_init_vendor_reset) + static void __init psci_init_system_reset2(void) { int ret; From 9d8395758f46d4aa6cb8cd97878b20628aba7269 Mon Sep 17 00:00:00 2001 From: Le Qi Date: Mon, 9 Feb 2026 17:11:39 +0800 Subject: [PATCH 193/438] FROMLIST: arm64: dts: qcom: hamoa-evk: Add DP0/DP1 audio DAI links Add DAI links for DP0 and DP1 playback and set sound-name-prefix for both DisplayPort endpoints in the hamoa-evk DTS. Link: https://lore.kernel.org/all/20260209091139.622756-1-le.qi@oss.qualcomm.com/ Signed-off-by: Le Qi Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 1427e342e9047..e6c7b0ed385de 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -616,6 +616,38 @@ sound-dai = <&q6apm>; }; }; + + dp0-dai-link { + link-name = "DP0 Playback"; + + codec { + sound-dai = <&mdss_dp0>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + dp1-dai-link { + link-name = "DP1 Playback"; + + codec { + sound-dai = <&mdss_dp1>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_1>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; }; usb-1-ss0-sbu-mux { @@ -902,6 +934,7 @@ &mdss_dp0 { status = "okay"; + sound-name-prefix = "Display Port0"; }; &mdss_dp0_out { @@ -910,6 +943,7 @@ &mdss_dp1 { status = "okay"; + sound-name-prefix = "Display Port1"; }; &mdss_dp1_out { From 939816e8e5cd966916144932aaddf1b8837d15c3 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Wed, 28 Jan 2026 00:56:37 +0530 Subject: [PATCH 194/438] FROMLIST: arm64: dts: qcom: x1e80100: Add CAMCC block definition Add the CAMCC block for x1e80100. The x1e80100 CAMCC block is an iteration of previous CAMCC blocks with the exception of having two required power-domains not just one. Reviewed-by: Vladimir Zapolskiy Reviewed-by: Konrad Dybcio Signed-off-by: Bryan O'Donoghue Signed-off-by: Jagadeesh Kona Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-6-b23de57df5ba@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index cda308fee5659..d41cd617c34a7 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -5784,6 +5785,22 @@ #power-domain-cells = <1>; }; + camcc: clock-controller@ade0000 { + compatible = "qcom,x1e80100-camcc"; + reg = <0 0x0ade0000 0 0x20000>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + power-domains = <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + mdss: display-subsystem@ae00000 { compatible = "qcom,x1e80100-mdss"; reg = <0 0x0ae00000 0 0x1000>; From 6b6b0d95358c4e151774fc3eec7e6a2ab0b9a018 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:38 +0530 Subject: [PATCH 195/438] FROMLIST: arm64: dts: qcom: Update compatible for videocc and camcc nodes on purwa Update the compatible for videocc and camcc nodes to match with their respective purwa(X1P42100) specific drivers. Signed-off-by: Jagadeesh Kona Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-7-b23de57df5ba@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/purwa.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/purwa.dtsi b/arch/arm64/boot/dts/qcom/purwa.dtsi index 38f2df9e42b60..4f9357787fee7 100644 --- a/arch/arm64/boot/dts/qcom/purwa.dtsi +++ b/arch/arm64/boot/dts/qcom/purwa.dtsi @@ -6,6 +6,8 @@ /* X1P42100 is heavily based on hamoa, with some meaningful differences */ #include "hamoa.dtsi" +#include + /delete-node/ &bwmon_cluster0; /delete-node/ &cluster_pd2; /delete-node/ &cpu_map_cluster2; @@ -34,10 +36,18 @@ /delete-node/ &cluster2_rep_2_3; /delete-node/ &apss_funnel_in2; +&camcc { + compatible = "qcom,x1p42100-camcc"; +}; + &gcc { compatible = "qcom,x1p42100-gcc", "qcom,x1e80100-gcc"; }; +&videocc { + compatible = "qcom,x1p42100-videocc"; +}; + &gmu { compatible = "qcom,adreno-gmu-x145.0", "qcom,adreno-gmu"; }; From 796c839d9fc92443a4b5718107b9d59e174e9700 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 10 Feb 2026 12:33:21 +0530 Subject: [PATCH 196/438] FROMLIST: arm64: dts: qcom: x1e80100: Add '#cooling-cells' for CPU nodes Enable passive cooling for CPUs in the X1E80100 SoC by adding the '#cooling-cells' property. This will allow the OS to mitigate the CPU power dissipation with the help of SCMI DVFS. Signed-off-by: Manivannan Sadhasivam Tested-by: Gaurav Kohli Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260210070321.17033-1-manivannan.sadhasivam@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index d41cd617c34a7..e68d92c7c28c0 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -76,6 +76,7 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd0>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; l2_0: l2-cache { compatible = "cache"; @@ -92,6 +93,7 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd1>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu2: cpu@200 { @@ -102,6 +104,7 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd2>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu3: cpu@300 { @@ -112,6 +115,7 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd3>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu4: cpu@10000 { @@ -122,6 +126,7 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd4>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; l2_1: l2-cache { compatible = "cache"; @@ -138,6 +143,7 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd5>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu6: cpu@10200 { @@ -148,6 +154,7 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd6>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu7: cpu@10300 { @@ -158,6 +165,7 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd7>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu8: cpu@20000 { @@ -168,6 +176,7 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd8>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; l2_2: l2-cache { compatible = "cache"; @@ -184,6 +193,7 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd9>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu10: cpu@20200 { @@ -194,6 +204,7 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd10>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu11: cpu@20300 { @@ -204,6 +215,7 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd11>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; + #cooling-cells = <2>; }; cpu-map { From 0aa0ac3935b4d8249350f3ea6a96f5dd5d95e63e Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Sun, 15 Feb 2026 23:51:32 +0530 Subject: [PATCH 197/438] FROMLIST: misc: fastrpc: Move fdlist to invoke context structure The fdlist is currently part of the meta buffer, computed during put_args. This leads to code duplication when preparing and reading critical meta buffer contents used by the FastRPC driver. Move fdlist to the invoke context structure to improve maintainability and reduce redundancy. This centralizes its handling and simplifies meta buffer preparation and reading logic. Link: https://lore.kernel.org/all/20260215182136.3995111-2-ekansh.gupta@oss.qualcomm.com/ Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 47356a5d58042..c740ce0064710 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -233,6 +233,7 @@ struct fastrpc_invoke_ctx { int pid; int client_id; u32 sc; + u64 *fdlist; u32 *crc; u64 ctxid; u64 msg_sz; @@ -1016,6 +1017,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) rpra = ctx->buf->virt; list = fastrpc_invoke_buf_start(rpra, ctx->nscalars); pages = fastrpc_phy_page_start(list, ctx->nscalars); + ctx->fdlist = (u64 *)(pages + ctx->nscalars); args = (uintptr_t)ctx->buf->virt + metalen; rlen = pkt_size - metalen; ctx->rpra = rpra; @@ -1118,18 +1120,10 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, union fastrpc_remote_arg *rpra = ctx->rpra; struct fastrpc_user *fl = ctx->fl; struct fastrpc_map *mmap = NULL; - struct fastrpc_invoke_buf *list; - struct fastrpc_phy_page *pages; - u64 *fdlist; - int i, inbufs, outbufs, handles; + int i, inbufs; int ret = 0; inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); - outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc); - handles = REMOTE_SCALARS_INHANDLES(ctx->sc) + REMOTE_SCALARS_OUTHANDLES(ctx->sc); - list = fastrpc_invoke_buf_start(rpra, ctx->nscalars); - pages = fastrpc_phy_page_start(list, ctx->nscalars); - fdlist = (uint64_t *)(pages + inbufs + outbufs + handles); for (i = inbufs; i < ctx->nbufs; ++i) { if (!ctx->maps[i]) { @@ -1151,9 +1145,9 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, cleanup_fdlist: /* Clean up fdlist which is updated by DSP */ for (i = 0; i < FASTRPC_MAX_FDLIST; i++) { - if (!fdlist[i]) + if (!ctx->fdlist[i]) break; - if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap)) + if (!fastrpc_map_lookup(fl, (int)ctx->fdlist[i], &mmap)) fastrpc_map_put(mmap); } From 994a62b0e42bb99bb79fb4dc36eb357bb7105363 Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Sun, 15 Feb 2026 23:51:33 +0530 Subject: [PATCH 198/438] FROMLIST: misc: fastrpc: Replace hardcoded ctxid mask with GENMASK Replace the hardcoded context ID mask (0xFF0) with GENMASK(11, 4) to improve readability and follow kernel bitfield conventions. Use FIELD_PREP and FIELD_GET instead of manual shifts for setting and extracting ctxid values. Link: https://lore.kernel.org/all/20260215182136.3995111-3-ekansh.gupta@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index c740ce0064710..3334dafcf9258 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -37,7 +37,7 @@ #define FASTRPC_CTX_MAX (256) #define FASTRPC_INIT_HANDLE 1 #define FASTRPC_DSP_UTILITIES_HANDLE 2 -#define FASTRPC_CTXID_MASK (0xFF0) +#define FASTRPC_CTXID_MASK GENMASK(11, 4) #define INIT_FILELEN_MAX (2 * 1024 * 1024) #define INIT_FILE_NAMELEN_MAX (128) #define FASTRPC_DEVICE_NAME "fastrpc" @@ -515,7 +515,7 @@ static void fastrpc_context_free(struct kref *ref) fastrpc_buf_free(ctx->buf); spin_lock_irqsave(&cctx->lock, flags); - idr_remove(&cctx->ctx_idr, ctx->ctxid >> 4); + idr_remove(&cctx->ctx_idr, FIELD_GET(FASTRPC_CTXID_MASK, ctx->ctxid)); spin_unlock_irqrestore(&cctx->lock, flags); kfree(ctx->maps); @@ -649,7 +649,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( spin_unlock_irqrestore(&cctx->lock, flags); goto err_idr; } - ctx->ctxid = ret << 4; + ctx->ctxid = FIELD_PREP(FASTRPC_CTXID_MASK, ret); spin_unlock_irqrestore(&cctx->lock, flags); kref_init(&ctx->refcount); @@ -2504,7 +2504,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, if (len < sizeof(*rsp)) return -EINVAL; - ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); + ctxid = FIELD_GET(FASTRPC_CTXID_MASK, rsp->ctx); spin_lock_irqsave(&cctx->lock, flags); ctx = idr_find(&cctx->ctx_idr, ctxid); From fc99f1451725cd564c7f1035eecc5c88de873949 Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Sun, 15 Feb 2026 23:51:34 +0530 Subject: [PATCH 199/438] FROMLIST: misc: fastrpc: Expand context ID mask for DSP polling mode support Current FastRPC context uses a 12-bit mask: [ID(8 bits)][PD type(4 bits)] = GENMASK(11, 4) This works for normal calls but fails for DSP polling mode. Polling mode expects a 16-bit layout: [15:8] = context ID (8 bits) [7:5] = reserved [4] = async mode bit [3:0] = PD type (4 bits) If async bit (bit 4) is set, DSP disables polling. With current mask, odd IDs can set this bit, causing DSP to skip poll updates. Update FASTRPC_CTXID_MASK to GENMASK(15, 8) so IDs occupy upper byte and lower byte is left for DSP flags and PD type. Reserved bits remain unused. This change is compatible with polling mode and does not break non-polling behavior. Bit layout: [15:8] = CCCCCCCC (context ID) [7:5] = xxx (reserved) [4] = A (async mode) [3:0] = PPPP (PD type) Link: https://lore.kernel.org/all/20260215182136.3995111-4-ekansh.gupta@oss.qualcomm.com/ Reviewed-by: Dmitry Baryshkov Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 3334dafcf9258..f716a1a309b2a 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -37,7 +37,7 @@ #define FASTRPC_CTX_MAX (256) #define FASTRPC_INIT_HANDLE 1 #define FASTRPC_DSP_UTILITIES_HANDLE 2 -#define FASTRPC_CTXID_MASK GENMASK(11, 4) +#define FASTRPC_CTXID_MASK GENMASK(15, 8) #define INIT_FILELEN_MAX (2 * 1024 * 1024) #define INIT_FILE_NAMELEN_MAX (128) #define FASTRPC_DEVICE_NAME "fastrpc" From 54f1bd47ec9b67cc5b7e729220dca55fd0c0a260 Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Sun, 15 Feb 2026 23:51:35 +0530 Subject: [PATCH 200/438] FROMLIST: misc: fastrpc: Add polling mode support for fastRPC driver For any remote call to DSP, after sending an invocation message, fastRPC driver waits for glink response and during this time the CPU can go into low power modes. This adds latency to overall fastrpc call as CPU wakeup and scheduling latencies are included. Add polling mode support with which fastRPC driver will poll continuously on a memory after sending a message to remote subsystem which will eliminate CPU wakeup and scheduling latencies and reduce fastRPC overhead. Poll mode can be enabled by user by using FASTRPC_IOCTL_SET_OPTION ioctl request with FASTRPC_POLL_MODE request id. Link: https://lore.kernel.org/all/20260215182136.3995111-5-ekansh.gupta@oss.qualcomm.com/ Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 142 ++++++++++++++++++++++++++++++++++-- include/uapi/misc/fastrpc.h | 10 +++ 2 files changed, 145 insertions(+), 7 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index f716a1a309b2a..158514d72f8b9 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -37,6 +39,7 @@ #define FASTRPC_CTX_MAX (256) #define FASTRPC_INIT_HANDLE 1 #define FASTRPC_DSP_UTILITIES_HANDLE 2 +#define FASTRPC_MAX_STATIC_HANDLE (20) #define FASTRPC_CTXID_MASK GENMASK(15, 8) #define INIT_FILELEN_MAX (2 * 1024 * 1024) #define INIT_FILE_NAMELEN_MAX (128) @@ -105,6 +108,12 @@ #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev) +/* Poll response number from remote processor for call completion */ +#define FASTRPC_POLL_RESPONSE (0xdecaf) + +/* Polling mode timeout limit */ +#define FASTRPC_POLL_MAX_TIMEOUT_US (10000) + struct fastrpc_phy_page { dma_addr_t addr; /* dma address */ u64 size; /* size of contiguous region */ @@ -235,8 +244,14 @@ struct fastrpc_invoke_ctx { u32 sc; u64 *fdlist; u32 *crc; + /* Poll memory that DSP updates */ + u32 *poll; u64 ctxid; u64 msg_sz; + /* work done status flag */ + bool is_work_done; + /* process updates poll memory instead of glink response */ + bool is_polled; struct kref refcount; struct list_head node; /* list of ctxs */ struct completion work; @@ -307,6 +322,8 @@ struct fastrpc_user { int client_id; int pd; bool is_secure_dev; + /* Flags poll mode state */ + bool poll_mode; /* Lock for lists */ spinlock_t lock; /* lock for allocations */ @@ -922,7 +939,8 @@ static int fastrpc_get_meta_size(struct fastrpc_invoke_ctx *ctx) sizeof(struct fastrpc_invoke_buf) + sizeof(struct fastrpc_phy_page)) * ctx->nscalars + sizeof(u64) * FASTRPC_MAX_FDLIST + - sizeof(u32) * FASTRPC_MAX_CRCLIST; + sizeof(u32) * FASTRPC_MAX_CRCLIST + + sizeof(u32); return size; } @@ -1018,6 +1036,9 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) list = fastrpc_invoke_buf_start(rpra, ctx->nscalars); pages = fastrpc_phy_page_start(list, ctx->nscalars); ctx->fdlist = (u64 *)(pages + ctx->nscalars); + ctx->poll = (u32 *)((uintptr_t)ctx->fdlist + sizeof(u64) * FASTRPC_MAX_FDLIST + + sizeof(u32) * FASTRPC_MAX_CRCLIST); + args = (uintptr_t)ctx->buf->virt + metalen; rlen = pkt_size - metalen; ctx->rpra = rpra; @@ -1186,6 +1207,75 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, } +static inline u32 fastrpc_poll_op(void *p) +{ + struct fastrpc_invoke_ctx *ctx = p; + + dma_rmb(); + return READ_ONCE(*ctx->poll); +} + +static int poll_for_remote_response(struct fastrpc_invoke_ctx *ctx) +{ + u32 val; + int ret; + + /* + * Poll until DSP writes FASTRPC_POLL_RESPONSE into *ctx->poll + * or until another path marks the work done. + */ + ret = read_poll_timeout_atomic(fastrpc_poll_op, val, + (val == FASTRPC_POLL_RESPONSE) || + ctx->is_work_done, 1, + FASTRPC_POLL_MAX_TIMEOUT_US, false, ctx); + + if (!ret && val == FASTRPC_POLL_RESPONSE) { + ctx->is_work_done = true; + ctx->retval = 0; + } + + if (ret == -ETIMEDOUT) + ret = -EIO; + + return ret; +} + +static inline int fastrpc_wait_for_response(struct fastrpc_invoke_ctx *ctx, + u32 kernel) +{ + int err = 0; + + if (kernel) { + if (!wait_for_completion_timeout(&ctx->work, 10 * HZ)) + err = -ETIMEDOUT; + } else { + err = wait_for_completion_interruptible(&ctx->work); + } + + return err; +} + +static int fastrpc_wait_for_completion(struct fastrpc_invoke_ctx *ctx, + u32 kernel) +{ + int err; + + do { + if (ctx->is_polled) { + err = poll_for_remote_response(ctx); + /* If polling timed out, move to normal response mode */ + if (err) + ctx->is_polled = false; + } else { + err = fastrpc_wait_for_response(ctx, kernel); + if (err) + return err; + } + } while (!ctx->is_work_done); + + return err; +} + static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, u32 handle, u32 sc, struct fastrpc_invoke_args *args) @@ -1221,16 +1311,26 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, if (err) goto bail; - if (kernel) { - if (!wait_for_completion_timeout(&ctx->work, 10 * HZ)) - err = -ETIMEDOUT; - } else { - err = wait_for_completion_interruptible(&ctx->work); - } + /* + * Set message context as polled if the call is for a user PD + * dynamic module and user has enabled poll mode. + */ + if (handle > FASTRPC_MAX_STATIC_HANDLE && fl->pd == USER_PD && + fl->poll_mode) + ctx->is_polled = true; + + err = fastrpc_wait_for_completion(ctx, kernel); if (err) goto bail; + if (!ctx->is_work_done) { + err = -ETIMEDOUT; + dev_dbg(fl->sctx->dev, "Invalid workdone state for handle 0x%x, sc 0x%x\n", + handle, sc); + goto bail; + } + /* make sure that all memory writes by DSP are seen by CPU */ dma_rmb(); /* populate all the output buffers with results */ @@ -1810,6 +1910,30 @@ static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap, return 0; } +static int fastrpc_set_option(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_ioctl_set_option opt = {0}; + int i; + + if (copy_from_user(&opt, argp, sizeof(opt))) + return -EFAULT; + + for (i = 0; i < ARRAY_SIZE(opt.reserved); i++) { + if (opt.reserved[i] != 0) + return -EINVAL; + } + + if (opt.req != FASTRPC_POLL_MODE) + return -EINVAL; + + if (opt.value) + fl->poll_mode = true; + else + fl->poll_mode = false; + + return 0; +} + static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_ioctl_capability cap = {0}; @@ -2165,6 +2289,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_MEM_UNMAP: err = fastrpc_req_mem_unmap(fl, argp); break; + case FASTRPC_IOCTL_SET_OPTION: + err = fastrpc_set_option(fl, argp); + break; case FASTRPC_IOCTL_GET_DSP_INFO: err = fastrpc_get_dsp_info(fl, argp); break; @@ -2516,6 +2643,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, } ctx->retval = rsp->retval; + ctx->is_work_done = true; complete(&ctx->work); /* diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index c6e2925f47e69..c37e24a764ae6 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -16,6 +16,7 @@ #define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static) #define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map) #define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap) +#define FASTRPC_IOCTL_SET_OPTION _IOWR('R', 12, struct fastrpc_ioctl_set_option) #define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability) /** @@ -67,6 +68,9 @@ enum fastrpc_proc_attr { /* Fastrpc attribute for memory protection of buffers */ #define FASTRPC_ATTR_SECUREMAP (1) +/* Set option request ID to enable poll mode */ +#define FASTRPC_POLL_MODE (1) + struct fastrpc_invoke_args { __u64 ptr; __u64 length; @@ -133,6 +137,12 @@ struct fastrpc_mem_unmap { __s32 reserved[5]; }; +struct fastrpc_ioctl_set_option { + __u32 req; /* request id */ + __u32 value; /* value */ + __s32 reserved[6]; +}; + struct fastrpc_ioctl_capability { __u32 unused; /* deprecated, ignored by the kernel */ __u32 attribute_id; From fc4e84ceb77c9584de762ef7eeee8becbd9fa7c3 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 24 Nov 2025 02:24:34 -0800 Subject: [PATCH 201/438] FROMLIST: dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add Kaanapali compatible Document compatible for the QMP PCIe PHY on Kaanapali platform. Link: https://lore.kernel.org/all/20251124-kaanapali-pcie-phy-v4-1-d04ee9cca83b@oss.qualcomm.com/ Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Reviewed-by: Neil Armstrong Signed-off-by: Qiang Yu --- .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml index 3a35120a77ec0..83df98c352702 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml @@ -183,6 +183,7 @@ allOf: enum: - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy + - qcom,kaanapali-qmp-gen3x2-pcie-phy - qcom,qcs8300-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x4-pcie-phy From 11bb1bc83bd2624b99548070fce4e6988f14de66 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 28 Jan 2026 17:10:42 +0530 Subject: [PATCH 202/438] FROMLIST: PCI: dwc: Use common D3cold eligibility helper in suspend path Previously, the driver skipped putting the link into L2/device state in D3cold whenever L1 ASPM was enabled, since some devices (e.g. NVMe) expect low resume latency and may not tolerate deeper power states. However, such devices typically remain in D0 and are already covered by the new helper's requirement that all endpoints be in D3hot before the host bridge may enter D3cold. So, replace the local L1/L1SS-based check in dw_pcie_suspend_noirq() with the shared pci_host_common_can_enter_d3cold() helper to decide whether the DesignWare host bridge can safely transition to D3cold. Link: https://lore.kernel.org/r/20260128-d3cold-v1-2-dd8f3f0ce824@oss.qualcomm.com Signed-off-by: Krishna Chaitanya Chundru --- drivers/pci/controller/dwc/pcie-designware-host.c | 7 +------ drivers/pci/controller/dwc/pcie-designware.h | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 6ae6189e9b8a9..fafcef9aa33f8 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -1218,18 +1218,13 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci) int dw_pcie_suspend_noirq(struct dw_pcie *pci) { - u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); int ret = 0; u32 val; if (!dw_pcie_link_up(pci)) goto stop_link; - /* - * If L1SS is supported, then do not put the link into L2 as some - * devices such as NVMe expect low resume latency. - */ - if (dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKCTL) & PCI_EXP_LNKCTL_ASPM_L1) + if (!pci_host_common_can_enter_d3cold(pci->pp.bridge)) return 0; if (pci->pp.ops->pme_turn_off) { diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index ae6389dd9caa5..3f06b1af63c5f 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -26,6 +26,7 @@ #include #include +#include "../pci-host-common.h" #include "../../pci.h" /* DWC PCIe IP-core versions (native support since v4.70a) */ From b5a78e601aab82d30c53916ef378d7eeca515ac6 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 28 Jan 2026 17:10:41 +0530 Subject: [PATCH 203/438] FROMLIST: PCI: host-common: Add shared D3cold eligibility helper for host bridges Add a common helper, pci_host_common_can_enter_d3cold(), to determine whether a PCI host bridge can safely transition to D3cold. The helper walks all devices on the bridge's bus and only allows the host bridge to enter D3cold if all PCIe endpoints are already in PCI_D3hot. For devices that may wake the system, it additionally requires that the device supports PME wakeup from D3cold(with WAKE#). Devices without wakeup enabled are not restricted by this check and can be allowed to keep device in D3cold. Link: https://lore.kernel.org/r/20260128-d3cold-v1-1-dd8f3f0ce824@oss.qualcomm.com Signed-off-by: Krishna Chaitanya Chundru --- drivers/pci/controller/pci-host-common.c | 29 ++++++++++++++++++++++++ drivers/pci/controller/pci-host-common.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c index d6258c1cffe5e..1e53819f5e720 100644 --- a/drivers/pci/controller/pci-host-common.c +++ b/drivers/pci/controller/pci-host-common.c @@ -106,5 +106,34 @@ void pci_host_common_remove(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(pci_host_common_remove); +static int pci_host_common_check_d3cold(struct pci_dev *pdev, void *userdata) +{ + bool *d3cold_allow = userdata; + + if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT) + return 0; + + if (pdev->current_state != PCI_D3hot) + goto exit; + + if (device_may_wakeup(&pdev->dev) && !pci_pme_capable(pdev, PCI_D3cold)) + goto exit; + + return 0; +exit: + *d3cold_allow = false; + return -EBUSY; +} + +bool pci_host_common_can_enter_d3cold(struct pci_host_bridge *bridge) +{ + bool d3cold_allow = true; + + pci_walk_bus(bridge->bus, pci_host_common_check_d3cold, &d3cold_allow); + + return d3cold_allow; +} +EXPORT_SYMBOL_GPL(pci_host_common_can_enter_d3cold); + MODULE_DESCRIPTION("Common library for PCI host controller drivers"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h index b5075d4bd7eb3..18a731bca0588 100644 --- a/drivers/pci/controller/pci-host-common.h +++ b/drivers/pci/controller/pci-host-common.h @@ -20,4 +20,6 @@ void pci_host_common_remove(struct platform_device *pdev); struct pci_config_window *pci_host_common_ecam_create(struct device *dev, struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops); + +bool pci_host_common_can_enter_d3cold(struct pci_host_bridge *bridge); #endif From fb8bbdccef33e5c20e0648234a9736919843caf7 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 28 Jan 2026 17:10:43 +0530 Subject: [PATCH 204/438] FROMLIST: PCI: qcom: Add D3cold support Add pme_turn_off() support and use DWC common suspend resume methods for device D3cold entry & exit. If the device is not kept in D3cold use existing methods like keeping icc votes, opp votes etc.. intact. In qcom_pcie_deinit_2_7_0(), explicitly disable PCIe clocks and resets in the controller. Remove suspended flag from qcom_pcie structure as it is no longer needed. Link: https://lore.kernel.org/r/20260128-d3cold-v1-3-dd8f3f0ce824@oss.qualcomm.com Signed-off-by: Krishna Chaitanya Chundru --- drivers/pci/controller/dwc/pcie-qcom.c | 116 +++++++++++++++---------- 1 file changed, 69 insertions(+), 47 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 67a16af69ddc7..7793d92f0418f 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -144,6 +144,7 @@ /* ELBI_SYS_CTRL register fields */ #define ELBI_SYS_CTRL_LT_ENABLE BIT(0) +#define ELBI_SYS_CTRL_PME_TURNOFF_MSG BIT(4) /* AXI_MSTR_RESP_COMP_CTRL0 register fields */ #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K 0x4 @@ -282,7 +283,6 @@ struct qcom_pcie { const struct qcom_pcie_cfg *cfg; struct dentry *debugfs; struct list_head ports; - bool suspended; bool use_pm_opp; }; @@ -1064,6 +1064,12 @@ static void qcom_pcie_host_post_init_2_7_0(struct qcom_pcie *pcie) static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie) { struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0; + u32 val; + + /* Disable PCIe clocks and resets */ + val = readl(pcie->parf + PARF_PHY_CTRL); + val |= PHY_TEST_PWR_DOWN; + writel(val, pcie->parf + PARF_PHY_CTRL); clk_bulk_disable_unprepare(res->num_clks, res->clks); @@ -1367,10 +1373,18 @@ static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp) pcie->cfg->ops->host_post_init(pcie); } +static void qcom_pcie_host_pme_turn_off(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + + writel(ELBI_SYS_CTRL_PME_TURNOFF_MSG, pci->elbi_base + ELBI_SYS_CTRL); +} + static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { .init = qcom_pcie_host_init, .deinit = qcom_pcie_host_deinit, .post_init = qcom_pcie_host_post_init, + .pme_turn_off = qcom_pcie_host_pme_turn_off, }; /* Qcom IP rev.: 2.1.0 Synopsys IP rev.: 4.01a */ @@ -2034,53 +2048,51 @@ static int qcom_pcie_suspend_noirq(struct device *dev) if (!pcie) return 0; - /* - * Set minimum bandwidth required to keep data path functional during - * suspend. - */ - if (pcie->icc_mem) { - ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1)); - if (ret) { - dev_err(dev, - "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n", - ret); - return ret; - } - } + ret = dw_pcie_suspend_noirq(pcie->pci); + if (ret) + return ret; - /* - * Turn OFF the resources only for controllers without active PCIe - * devices. For controllers with active devices, the resources are kept - * ON and the link is expected to be in L0/L1 (sub)states. - * - * Turning OFF the resources for controllers with active PCIe devices - * will trigger access violation during the end of the suspend cycle, - * as kernel tries to access the PCIe devices config space for masking - * MSIs. - * - * Also, it is not desirable to put the link into L2/L3 state as that - * implies VDD supply will be removed and the devices may go into - * powerdown state. This will affect the lifetime of the storage devices - * like NVMe. - */ - if (!dw_pcie_link_up(pcie->pci)) { - qcom_pcie_host_deinit(&pcie->pci->pp); - pcie->suspended = true; - } + if (pcie->pci->suspended) { + ret = icc_disable(pcie->icc_mem); + if (ret) + dev_err(dev, "Failed to disable PCIe-MEM interconnect path: %d\n", ret); - /* - * Only disable CPU-PCIe interconnect path if the suspend is non-S2RAM. - * Because on some platforms, DBI access can happen very late during the - * S2RAM and a non-active CPU-PCIe interconnect path may lead to NoC - * error. - */ - if (pm_suspend_target_state != PM_SUSPEND_MEM) { ret = icc_disable(pcie->icc_cpu); if (ret) dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", ret); if (pcie->use_pm_opp) dev_pm_opp_set_opp(pcie->pci->dev, NULL); + } else { + /* + * Set minimum bandwidth required to keep data path functional during + * suspend. + */ + if (pcie->icc_mem) { + ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1)); + if (ret) { + dev_err(dev, + "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n", + ret); + return ret; + } + } + + /* + * Only disable CPU-PCIe interconnect path if the suspend is non-S2RAM. + * Because on some platforms, DBI access can happen very late during the + * S2RAM and a non-active CPU-PCIe interconnect path may lead to NoC + * error. + */ + if (pm_suspend_target_state != PM_SUSPEND_MEM) { + ret = icc_disable(pcie->icc_cpu); + if (ret) + dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", + ret); + + if (pcie->use_pm_opp) + dev_pm_opp_set_opp(pcie->pci->dev, NULL); + } } return ret; } @@ -2094,20 +2106,30 @@ static int qcom_pcie_resume_noirq(struct device *dev) if (!pcie) return 0; - if (pm_suspend_target_state != PM_SUSPEND_MEM) { + if (pcie->pci->suspended) { ret = icc_enable(pcie->icc_cpu); if (ret) { dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", ret); return ret; } - } - if (pcie->suspended) { - ret = qcom_pcie_host_init(&pcie->pci->pp); - if (ret) + ret = icc_enable(pcie->icc_mem); + if (ret) { + dev_err(dev, "Failed to enable PCIe-MEM interconnect path: %d\n", ret); return ret; - - pcie->suspended = false; + } + ret = dw_pcie_resume_noirq(pcie->pci); + if (ret && (ret != -ETIMEDOUT)) + return ret; + } else { + if (pm_suspend_target_state != PM_SUSPEND_MEM) { + ret = icc_enable(pcie->icc_cpu); + if (ret) { + dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", + ret); + return ret; + } + } } qcom_pcie_icc_opp_update(pcie); From ece953449797a67a6bca59f211113f3576ecd857 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 28 Jan 2026 17:52:42 +0530 Subject: [PATCH 205/438] FROMLIST: PCI: qcom: Prevent GDSC power down on suspend Currently, the driver expects the devices to remain in D0 across system suspend, but the genpd framework may still power down the associated GDSC during suspend. When that happens, the PCIe link goes down and cannot be recovered on resume. Prevent genpd from turning off the PCIe GDSC by using dev_pm_genpd_rpm_always_on() so that the power domain stays on while the controller is suspended. This preserves the link state across suspend/resume and avoids unrecoverable link failures. Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20260128-genpd_fix-v1-1-cd45a249d12f@oss.qualcomm.com Signed-off-by: Krishna Chaitanya Chundru --- drivers/pci/controller/dwc/pcie-qcom.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 7793d92f0418f..9aef8ee344ae7 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -2052,6 +2053,11 @@ static int qcom_pcie_suspend_noirq(struct device *dev) if (ret) return ret; + if (pcie->pci->suspended) + dev_pm_genpd_rpm_always_on(dev, false); + else + dev_pm_genpd_rpm_always_on(dev, true); + if (pcie->pci->suspended) { ret = icc_disable(pcie->icc_mem); if (ret) From 91f2fb16af20160cec4b73feb194ef3c10437c05 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Wed, 25 Feb 2026 21:41:13 -0800 Subject: [PATCH 206/438] FROMLIST: arm64: dts: qcom: hamoa: Add PSCI SYSTEM_RESET2 types Add support for SYSTEM_RESET2 vendor-specific resets as reboot-modes in the psci node. Describe the resets: "bootloader" will cause device to reboot and stop in the bootloader's fastboot mode. "edl" will cause device to reboot into "emergency download mode", which permits loading images via the Firehose protocol. Signed-off-by: Xin Liu Link: https://lore.kernel.org/all/20260226054113.4156874-1-xin.liu@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index e68d92c7c28c0..97d238f6b7ec9 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -667,6 +667,11 @@ #power-domain-cells = <0>; /* TODO: system-wide idle states */ }; + + reboot-mode { + mode-bootloader = <0x80010001 0x2>; + mode-edl = <0x80000000 0x1>; + }; }; reserved-memory { From 2491c442c15fafb4bdc8583615c7b472b8fb1c32 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Mon, 26 Jan 2026 22:24:25 -0800 Subject: [PATCH 207/438] FROMLIST: arm64: dts: qcom: hamoa: Add EL2 overlay for hamoa-evk Add support for building an EL2 combined DTB for the hamoa-evk in the Qualcomm DTS Makefile. The new hamoa-iot-evk-el2.dtb is generated by combining the base hamoa-iot-evk.dtb with the x1-el2.dtbo overlay, enabling EL2-specific configurations required by the platform. Reviewed-by: Konrad Dybcio Signed-off-by: Xin Liu Link: https://lore.kernel.org/all/20260127062425.1084673-1-xin.liu@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index d42296ed302e7..7aa407322466e 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -14,6 +14,10 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8094-sony-xperia-kitakami-karin_windy.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk.dtb + +hamoa-iot-evk-el2-dtbs := hamoa-iot-evk.dtb x1-el2.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-rdp432-c2.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-tplink-archer-ax55-v1.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5332-rdp441.dtb From 95041c109dc527b8c4f35c1dc933644cecbda7e8 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Mon, 2 Feb 2026 22:32:44 -0800 Subject: [PATCH 208/438] FROMLIST: arm64: dts: qcom: hamoa: Add remoteproc IOMMUS in EL2 device trees All the existing variants Hamoa boards are using Gunyah hypervisor which means that, so far, Linux-based OS could only boot in EL1 on those devices. However, it is possible for us to boot Linux at EL2 on these devices [1]. When running under Gunyah, the remote processor firmware IOMMU streams are controlled by Gunyah. However, without Gunyah, the IOMMU is managed by the consumer of this DeviceTree. Therefore, describe the firmware streams for each remote processor. Add remoteproc IOMMUS to the EL2 device trees to generate the corresponding -el2.dtb files. [1] https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Signed-off-by: Xin Liu Link: https://lore.kernel.org/all/20260203063244.1498699-1-xin.liu@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/x1-el2.dtso | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1-el2.dtso b/arch/arm64/boot/dts/qcom/x1-el2.dtso index 175679be01eba..ee006742d6f3b 100644 --- a/arch/arm64/boot/dts/qcom/x1-el2.dtso +++ b/arch/arm64/boot/dts/qcom/x1-el2.dtso @@ -52,6 +52,14 @@ status = "okay"; }; +&remoteproc_adsp { + iommus = <&apps_smmu 0x1000 0x80>; +}; + +&remoteproc_cdsp { + iommus = <&apps_smmu 0x0c00 0x0>; +}; + /* * The "SBSA watchdog" is implemented in software in Gunyah * and can't be used when running in EL2. From 9e3b2145bf5ff86ae84ce51a34b48a8bb20e8076 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 29 May 2025 17:06:00 +0530 Subject: [PATCH 209/438] QCLINUX: defconfig: Introduce prune.config fragment Add prune.config fragment to disable support for non-Qualcomm architectures. This helps reduce boot image size and improves kernel build KPIs by trimming unnecessary configuration options. Signed-off-by: Komal Bajaj --- arch/arm64/configs/prune.config | 326 ++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 arch/arm64/configs/prune.config diff --git a/arch/arm64/configs/prune.config b/arch/arm64/configs/prune.config new file mode 100644 index 0000000000000..54cf8fa1cd0e0 --- /dev/null +++ b/arch/arm64/configs/prune.config @@ -0,0 +1,326 @@ +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_AIROHA is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_APPLE is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BCM2835 is not set +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BCMBCA is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BLAIZE is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SPARX5 is not set +# CONFIG_ARCH_K3 is not set +# CONFIG_ARCH_LG1K is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_KEEMBAY is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_NXP is not set +# CONFIG_ARCH_MA35 is not set +# CONFIG_ARCH_NPCM is not set +# CONFIG_ARCH_REALTEK is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_INTEL_SOCFPGA is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SYNQUACER is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_TESLA_FSD is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_THUNDER2 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VISCONTI is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZYNQMP is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set +# CONFIG_NET_DSA_TAG_OCELOT is not set +# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set +# CONFIG_BT_HCIBTUSB_MTK is not set +# CONFIG_BT_HCIUART_BCM is not set +# CONFIG_BT_HCIUART_MRVL is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_MRVL_SDIO is not set +# CONFIG_PCIE_ALTERA is not set +# CONFIG_PCIE_ALTERA_MSI is not set +# CONFIG_PCI_HOST_THUNDER_PEM is not set +# CONFIG_PCI_HOST_THUNDER_ECAM is not set +# CONFIG_PCI_XGENE is not set +# CONFIG_PCI_MESON is not set +# CONFIG_PCI_HISI is not set +# CONFIG_PCIE_KIRIN is not set +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_GNSS_MTK_SERIAL is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_NAND_DENALI_DT is not set +# CONFIG_MTD_NAND_BRCMNAND is not set +# CONFIG_MTD_NAND_BRCMNAND_BCMBCA is not set +# CONFIG_MTD_NAND_BRCMNAND_BRCMSTB is not set +# CONFIG_MTD_NAND_BRCMNAND_IPROC is not set +# CONFIG_B53_SRAB_DRIVER is not set +# CONFIG_NET_DSA_BCM_SF2 is not set +# CONFIG_AMD_XGBE is not set +# CONFIG_BCMGENET is not set +# CONFIG_BNX2X is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_MACB is not set +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set +# CONFIG_HNS3_HCLGE is not set +# CONFIG_HNS3_ENET is not set +# CONFIG_MVMDIO is not set +# CONFIG_SKY2 is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLX5_CORE_EN is not set +# CONFIG_R8169 is not set +# CONFIG_SMC91X is not set +# CONFIG_SMSC911X is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM54140_PHY is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83TD510_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_CAN_FLEXCAN is not set +# CONFIG_CAN_MCP251XFD is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_MWIFIEX is not set +# CONFIG_MWIFIEX_SDIO is not set +# CONFIG_MWIFIEX_PCIE is not set +# CONFIG_MT7921E is not set +# CONFIG_WL18XX is not set +# CONFIG_WLCORE_SDIO is not set +# CONFIG_KEYBOARD_CROS_EC is not set +# CONFIG_KEYBOARD_MTK_PMIC is not set +# CONFIG_MOUSE_ELAN_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_ELAN is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_INPUT_TPS65219_PWRBUTTON is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_XILINX_PS_UART_CONSOLE is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LPUART_CONSOLE is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE is not set +# CONFIG_TCG_TIS_SPI_CR50 is not set +# CONFIG_TCG_TIS_I2C_CR50 is not set +# CONFIG_TCG_TIS_I2C_INFINEON is not set +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_CROS_EC_TUNNEL is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_DW_DMA is not set +# CONFIG_SPI_DW_MMIO is not set +# CONFIG_PINCTRL_MAX77620 is not set +# CONFIG_CHARGER_MT6360 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_PM8916_WATCHDOG is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_RK8XX_I2C is not set +# CONFIG_MFD_RK8XX_SPI is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_TPS65219 is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_REGULATOR_AXP20X is not set +# CONFIG_REGULATOR_BD718XX is not set +# CONFIG_REGULATOR_BD9571MWV is not set +# CONFIG_REGULATOR_CROS_EC is not set +# CONFIG_REGULATOR_FAN53555 is not set +# CONFIG_REGULATOR_HI6421V530 is not set +# CONFIG_REGULATOR_MAX77620 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MP8859 is not set +# CONFIG_REGULATOR_MT6315 is not set +# CONFIG_REGULATOR_MT6357 is not set +# CONFIG_REGULATOR_MT6358 is not set +# CONFIG_REGULATOR_MT6359 is not set +# CONFIG_REGULATOR_MT6360 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_RK808 is not set +# CONFIG_REGULATOR_S2MPS11 is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS65219 is not set +# CONFIG_REGULATOR_RK808 is not set +# CONFIG_REGULATOR_S2MPS11 is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS65219 is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_VIDEO_IMX219 is not set +# CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5645 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_KOMEDA is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set +# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set +# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set +# CONFIG_DRM_LONTIUM_LT8912B is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set +# CONFIG_DRM_PARADE_PS8640 is not set +# CONFIG_DRM_SAMSUNG_DSIM is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SIMPLE_BRIDGE is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TI_SN65DSI83 is not set +# CONFIG_DRM_TI_SN65DSI86 is not set +# CONFIG_DRM_I2C_ADV7511_AUDIO is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set +# CONFIG_DRM_ETNAVIV is not set +# CONFIG_DRM_HISI_HIBMC is not set +# CONFIG_DRM_HISI_KIRIN is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_LIMA is not set +# CONFIG_DRM_PANFROST is not set +# CONFIG_DRM_TIDSS is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_AUDMIX is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_FSL_MICFIL is not set +# CONFIG_SND_SOC_FSL_EASRC is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_ES7134 is not set +# CONFIG_SND_SOC_ES7241 is not set +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_RT5640 is not set +# CONFIG_SND_SOC_RT5659 is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8904 is not set +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_NAU8822 is not set +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_HI3798CV200 is not set +# CONFIG_MMC_DW_K3 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_MMC_SDHCI_AM654 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX77686 is not set +# CONFIG_RTC_DRV_RK808 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV8803 is not set +# CONFIG_RTC_DRV_S5M is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_CROS_EC is not set +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_BCM_SBA_RAID is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_MV_XOR_V2 is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_CROS_EC is not set +# CONFIG_CROS_EC_I2C is not set +# CONFIG_CROS_EC_RPMSG is not set +# CONFIG_CROS_EC_SPI is not set +# CONFIG_CROS_EC_CHARDEV is not set +# CONFIG_CLK_VEXPRESS_OSC is not set +# CONFIG_COMMON_CLK_RK808 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_COMMON_CLK_S2MPS11 is not set +# CONFIG_COMMON_CLK_XGENE is not set +# CONFIG_COMMON_CLK_RS9_PCIE is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_BD718XX is not set +# CONFIG_SOC_TI is not set +# CONFIG_TI_ADS1015 is not set +# CONFIG_TI_AM335X_ADC is not set +# CONFIG_IIO_CROS_EC_SENSORS_CORE is not set +# CONFIG_IIO_CROS_EC_SENSORS is not set +# CONFIG_IIO_ST_LSM6DSX is not set +# CONFIG_IIO_CROS_EC_LIGHT_PROX is not set +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_VCNL4000 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set +# CONFIG_IIO_CROS_EC_BARO is not set +# CONFIG_MPL3115 is not set +# CONFIG_PWM_CROS_EC is not set +# CONFIG_PHY_CADENCE_TORRENT is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_CRYPTO_DEV_HISI_SEC2 is not set +# CONFIG_CRYPTO_DEV_HISI_ZIP is not set +# CONFIG_CRYPTO_DEV_HISI_HPRE is not set +# CONFIG_CRYPTO_DEV_HISI_TRNG is not set +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set +# CONFIG_DEVMEM is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set From 74be87c47ff510c6bf815d2e884a0c5e9c9887ac Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 23 Sep 2025 14:20:27 +0530 Subject: [PATCH 210/438] QCLINUX: defconfig: Define qcom.config and enable DMABUF heaps Introduce `qcom.config`, a Qualcomm-specific kernel configuration fragment that enables features required by Qualcomm SoCs. It includes CONFIGs not acceptable under the community's common defconfig and ensures essential features and subsystems required by Qualcomm platforms are enbaled. This initial version of `qcom.config` enables DMABUF heap support, including the system heap and default CMA heap. These configurations are essential for buffer sharing across subsystems such as camera, display, and DSP on Qualcomm platforms like qcs6490. Signed-off-by: Komal Bajaj --- arch/arm64/configs/qcom.config | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 arch/arm64/configs/qcom.config diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config new file mode 100644 index 0000000000000..7458e86bdc06c --- /dev/null +++ b/arch/arm64/configs/qcom.config @@ -0,0 +1,8 @@ +# qcom.config for Qualcomm-specific kernel configuration +# +# $ make ARCH=arm64 defconfig qcom.config +# +# Keep alphabetically sorted +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_DMABUF_HEAPS_SYSTEM=y From d273c6852bd7c59dce3bd0f9ca2d16a811b2fcfa Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 26 Sep 2025 10:08:11 +0800 Subject: [PATCH 211/438] QCLINUX: arch: arm64: configs: Enable coresight components in qcom.config Add Coresight configs to enable Coresight device drivers on mainline. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom.config | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 7458e86bdc06c..52b94c17169d0 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -3,6 +3,12 @@ # $ make ARCH=arm64 defconfig qcom.config # # Keep alphabetically sorted +CONFIG_CORESIGHT_CORESIGHT_TNOC=m +CONFIG_CORESIGHT_CTCU=m +CONFIG_CORESIGHT_DUMMY=m +CONFIG_CORESIGHT_SOURCE_ETM4X=m +CONFIG_CORESIGHT_TGU=m +CONFIG_CORESIGHT_TPDM=m CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y From 1dbf038e38a8d742e5dbea706037ede8737ecc0a Mon Sep 17 00:00:00 2001 From: Charan Teja Kalla Date: Tue, 30 Sep 2025 18:27:55 +0530 Subject: [PATCH 212/438] QCLINUX: defconfig: enable zram defconfig on qcom.config Enable ZRAM defconfig on qcom.config. This empowers users to use the compressed block devices for usecases, eg: swap device on zram. Tested: make ARCH=arm64 menuconfig defconfig qcom.config, booted with this configuration on QEMU and verified if /dev/zram0 is exist. Signed-off-by: Charan Teja Kalla --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 52b94c17169d0..93e642c519059 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -12,3 +12,4 @@ CONFIG_CORESIGHT_TPDM=m CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_ZRAM=y From 93f6040418f2899405e4f5e1344899099631607e Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 6 Oct 2025 16:56:58 +0530 Subject: [PATCH 213/438] QCLINUX: defconfig: Enable scheduler and thermal related configs Enabled key configs for thermal management (CPU_IDLE_THERMAL, IDLE_INJECT), scheduler (SCHED_DEBUG, SCHEDSTATS, TRACE_MMIO_ACCESS), and power control (POWERCAP, UCLAMP_TASK). Also enabled KPROBES, PAN emulation and watchdog pretimeout panic governor for improved instrumentation and security. Signed-off-by: Komal Bajaj --- arch/arm64/configs/qcom.config | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 93e642c519059..9cd2b50f8b367 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -3,13 +3,30 @@ # $ make ARCH=arm64 defconfig qcom.config # # Keep alphabetically sorted +CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_CORESIGHT_CORESIGHT_TNOC=m CONFIG_CORESIGHT_CTCU=m CONFIG_CORESIGHT_DUMMY=m CONFIG_CORESIGHT_SOURCE_ETM4X=m CONFIG_CORESIGHT_TGU=m CONFIG_CORESIGHT_TPDM=m +CONFIG_CPU_IDLE_THERMAL=y +# CONFIG_DEBUG_INFO_REDUCED is not set CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_IDLE_INJECT=y +CONFIG_KPROBES=y +CONFIG_POWERCAP=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TRACE_MMIO_ACCESS=y +CONFIG_UCLAMP_TASK_GROUP=y +CONFIG_UCLAMP_TASK=y +# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m +CONFIG_WATCHDOG_PRETIMEOUT_GOV=y CONFIG_ZRAM=y From b5273917d1d512153252161c745deaf8b620e6dd Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 6 Oct 2025 17:11:01 +0530 Subject: [PATCH 214/438] QCLINUX: debug: Enable additional Qualcomm-specific debug configs Enabled various debug-related kernel config options to improve system diagnostics and aid in development and issue analysis. Signed-off-by: Komal Bajaj --- kernel/configs/debug.config | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config index 774702591d26c..a7e00c8d6a30a 100644 --- a/kernel/configs/debug.config +++ b/kernel/configs/debug.config @@ -117,3 +117,12 @@ CONFIG_FUNCTION_TRACER=y # CONFIG_DEBUG_PREEMPT=y CONFIG_PREEMPT=y + +# +# Qualcomm Debug Configs +# +CONFIG_CMA_DEBUG=y +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_PAGEALLOC=y +# CONFIG_FW_LOADER_DEBUG is not set +CONFIG_HARDLOCKUP_DETECTOR=y From a2f417594e00856f9789db6d228087a80a02a300 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 31 Oct 2025 15:58:40 +0800 Subject: [PATCH 215/438] QCLINUX: arch: arm64: configs: Enable stm components in qcom.config Add STM configs to enable STM functions, like stm ftrace and stm heartbeat. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 9cd2b50f8b367..00e740e4e29de 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -20,6 +20,11 @@ CONFIG_KPROBES=y CONFIG_POWERCAP=y CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y +CONFIG_STM_PROTO_BASIC=m +CONFIG_STM_PROTO_SYS_T=m +CONFIG_STM_SOURCE_CONSOLE=m +CONFIG_STM_SOURCE_FTRACE=m +CONFIG_STM_SOURCE_HEARTBEAT=m CONFIG_TRACE_MMIO_ACCESS=y CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_TASK=y From 1ba7112807aafb00d3f0f57ecba4a8662e5d1e63 Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Tue, 4 Nov 2025 17:35:07 +0800 Subject: [PATCH 216/438] QCLINUX: defconfig: enable Crypto and ICE related configs Enabled key config of Crypto (CONFIG_CRYPTO_USER_API, CONFIG_CRYPTO_USER_API_HASH, CONFIG_CRYPTO_USER_API_SKCIPHER, CONFIG_CRYPTO_USER_API_AEAD). And else for support ICE config. Signed-off-by: Wenjia Zhang --- arch/arm64/configs/qcom.config | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 00e740e4e29de..68f9420987e84 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -35,3 +35,20 @@ CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m CONFIG_WATCHDOG_PRETIMEOUT_GOV=y CONFIG_ZRAM=y + +# Add config to support Crypto and ICE +CONFIG_SCSI_UFS_QCOM=y +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_AEAD=y +CONFIG_BLK_INLINE_ENCRYPTION=y +CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y +CONFIG_FS_ENCRYPTION_INLINE_CRYPT_FALLBACK=y +CONFIG_FS_ENCRYPTION_HW_WRAPPED_KEYS=y +CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_QCOM_INLINE_CRYPTO_ENGINE=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_BLK_INLINE_ENCRYPTION_HW_WRAPPED_KEYS=y + From 94fc6107a1dccda8de5488b3e5d2e361d7267600 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 5 Nov 2025 14:26:27 +0530 Subject: [PATCH 217/438] QCLINUX: defconfig: enable amc6821 defconfig on qcom.config Enable SENSOR_AMC6821 defconfig to enable fan controller support. Signed-off-by: Gaurav Kohli --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 68f9420987e84..ad4bb73a69202 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -25,6 +25,7 @@ CONFIG_STM_PROTO_SYS_T=m CONFIG_STM_SOURCE_CONSOLE=m CONFIG_STM_SOURCE_FTRACE=m CONFIG_STM_SOURCE_HEARTBEAT=m +CONFIG_SENSORS_AMC6821=y CONFIG_TRACE_MMIO_ACCESS=y CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_TASK=y From 6e68f8a22ec828d5432318a6a2be686ed0d64318 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Thu, 13 Nov 2025 14:59:19 +0530 Subject: [PATCH 218/438] QCLINUX: defconfig: Enable QCA808X ethernet phy config Enable the config for the QCA808X ethernet PHY driver. Ethernet is non functional without this driver on Lemans and Monaco EVK. Signed-off-by: Mohd Ayaan Anwar --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index ad4bb73a69202..24fba94365ed2 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -18,6 +18,7 @@ CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y CONFIG_POWERCAP=y +CONFIG_QCA808X_PHY=m CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y CONFIG_STM_PROTO_BASIC=m From 461276b9922f852697d33441bb236516b35932c0 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 14 Nov 2025 19:08:45 +0530 Subject: [PATCH 219/438] QCLINUX: defconfig: Enable EDAC_QCOM on qcom.config Enable QCOM EDAC driver support for QCOM SoCs. Signed-off-by: Komal Bajaj --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 24fba94365ed2..5358c519a2102 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -15,6 +15,7 @@ CONFIG_CPU_IDLE_THERMAL=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_EDAC_QCOM=m CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y CONFIG_POWERCAP=y From 996fc1b1b617fc98251ea438ae2a06a2f7dd43d3 Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Wed, 12 Nov 2025 11:29:07 +0800 Subject: [PATCH 220/438] QCLINUX: debug: Enable WLAN related debug configs Enable WLAN related debug configs. Signed-off-by: Yingying Tang --- kernel/configs/debug.config | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config index a7e00c8d6a30a..0bbd9e2780894 100644 --- a/kernel/configs/debug.config +++ b/kernel/configs/debug.config @@ -121,8 +121,31 @@ CONFIG_PREEMPT=y # # Qualcomm Debug Configs # +CONFIG_ATH11K_COREDUMP=y +CONFIG_ATH11K_DEBUG=y +CONFIG_ATH11K_DEBUGFS=y +CONFIG_ATH11K_TRACING=y +CONFIG_ATH12K_DEBUG=y +CONFIG_ATH12K_DEBUGFS=y +CONFIG_ATH12K_TRACING=y +CONFIG_ATH12K_COREDUMP=y +CONFIG_CFG80211_DEBUGFS=y CONFIG_CMA_DEBUG=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_PAGEALLOC=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_FUNCTION_GRAPH_TRACER=y # CONFIG_FW_LOADER_DEBUG is not set CONFIG_HARDLOCKUP_DETECTOR=y +CONFIG_IRQSOFF_TRACER=y +CONFIG_KPROBE_EVENTS=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_NL80211_TESTMODE=y +CONFIG_PREEMPT_TRACER=y +CONFIG_PREEMPTIRQ_TRACEPOINTS=y +CONFIG_SCHED_TRACER=y +CONFIG_STACK_TRACER=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACING=y +CONFIG_UPROBE_EVENTS=y From 6284a52915340086a321224ccc9d8a0f13f1c6cf Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Wed, 12 Nov 2025 12:01:17 +0800 Subject: [PATCH 221/438] QCLINUX: defconfig: Enable ATH reg setting Enable ATH reg setting, then user can change country code by netlink command. Signed-off-by: Yingying Tang --- arch/arm64/configs/qcom.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 5358c519a2102..f024f6b9a39dd 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -4,6 +4,8 @@ # # Keep alphabetically sorted CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y +CONFIG_CFG80211_CERTIFICATION_ONUS=y CONFIG_CORESIGHT_CORESIGHT_TNOC=m CONFIG_CORESIGHT_CTCU=m CONFIG_CORESIGHT_DUMMY=m @@ -16,6 +18,7 @@ CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_EDAC_QCOM=m +CONFIG_EXPERT=y CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y CONFIG_POWERCAP=y From 8c100fc0351c887b01ef19f9c974b3ebb4a462c3 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Wed, 19 Nov 2025 19:55:44 +0530 Subject: [PATCH 222/438] QCLINUX: defconfig: Enable BT_RFCOMM, BT_BNEP and UHID Enable as modules the BT_BNEP and BT_RFCOMM drivers which are required for Bluetooth profiles such as PAN and SPP. Without these modules, PAN and SPP functionality will not be available. Enable UHID support to allow HID over GATT operations. Without this, user-space cannot create virtual HID devices, which impacts HID profile usage over Bluetooth. Signed-off-by: Wei Deng --- arch/arm64/configs/qcom.config | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index f024f6b9a39dd..3fb7c7776c892 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -5,6 +5,11 @@ # Keep alphabetically sorted CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y CONFIG_CFG80211_CERTIFICATION_ONUS=y CONFIG_CORESIGHT_CORESIGHT_TNOC=m CONFIG_CORESIGHT_CTCU=m @@ -34,6 +39,7 @@ CONFIG_SENSORS_AMC6821=y CONFIG_TRACE_MMIO_ACCESS=y CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_TASK=y +CONFIG_UHID=m # CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y From 5cc87c384d26babfcad8ef736a87df3024e2ceff Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 21 Nov 2025 10:01:00 +0530 Subject: [PATCH 223/438] QCLINUX: defconfig: Enable various power management configs Enable various PM configs to enable suspend-resume. Signed-off-by: Maulik Shah --- arch/arm64/configs/qcom.config | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 3fb7c7776c892..8311dc4f933e9 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -26,6 +26,13 @@ CONFIG_EDAC_QCOM=m CONFIG_EXPERT=y CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM=y CONFIG_POWERCAP=y CONFIG_QCA808X_PHY=m CONFIG_SCHED_DEBUG=y From 814ae57e5f805d151d819826cd152a6593bdd00d Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 21 Nov 2025 13:32:46 +0530 Subject: [PATCH 224/438] QCLINUX: debug: Enable power management debug configs Enabled various power management debug related kernel config options to improve system diagnostics and aid in development and issue analysis. Signed-off-by: Maulik Shah --- kernel/configs/debug.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config index 0bbd9e2780894..2d27a3c9104bb 100644 --- a/kernel/configs/debug.config +++ b/kernel/configs/debug.config @@ -144,6 +144,9 @@ CONFIG_MAC80211_DEBUGFS=y CONFIG_NL80211_TESTMODE=y CONFIG_PREEMPT_TRACER=y CONFIG_PREEMPTIRQ_TRACEPOINTS=y +CONFIG_PM_ADVANCED_DEBUG=y +CONFIG_PM_DEBUG=y +CONFIG_PM_SLEEP_DEBUG=y CONFIG_SCHED_TRACER=y CONFIG_STACK_TRACER=y CONFIG_TRACEPOINTS=y From 8f4214573f9c440676accc88be9b3a081c89a661 Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Thu, 20 Nov 2025 16:28:06 +0530 Subject: [PATCH 225/438] FROMLIST: defconfig: qcom: Enable lt8713sx bridge driver Lontium LT8713sx DP bridge hub can be found in monaco-evk for converting 1 DP to 3 DP output. Co-developed-by: Prahlad Valluru Signed-off-by: Prahlad Valluru Signed-off-by: Vishnu Saini Link: https://lore.kernel.org/all/20251120-lt8713sx-bridge-linux-for-next-v1-2-2246fc5fb490@qti.qualcomm.com/ --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index b67d5b1fc45b0..0a11c9aa45007 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1001,6 +1001,7 @@ CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m CONFIG_DRM_DISPLAY_CONNECTOR=m CONFIG_DRM_FSL_LDB=m CONFIG_DRM_ITE_IT6263=m +CONFIG_DRM_LONTIUM_LT8713SX=m CONFIG_DRM_LONTIUM_LT8912B=m CONFIG_DRM_LONTIUM_LT9611=m CONFIG_DRM_LONTIUM_LT9611UXC=m From 9887580ba09b12266e775a17c577c3cb13498ae6 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 27 Nov 2025 15:03:55 +0530 Subject: [PATCH 226/438] QCLINUX: Revert "QCLINUX: defconfig: enable Crypto and ICE related configs" Revert commit 68f6c9a13767b281d3859caf834fbdd3c027ee22. Enabling ICE-related configurations causes crashes on the lemans-evk device, so this change is being reverted until the issue is resolved. Signed-off-by: Komal Bajaj --- arch/arm64/configs/qcom.config | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 8311dc4f933e9..4133da26d73aa 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -54,20 +54,3 @@ CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m CONFIG_WATCHDOG_PRETIMEOUT_GOV=y CONFIG_ZRAM=y - -# Add config to support Crypto and ICE -CONFIG_SCSI_UFS_QCOM=y -CONFIG_CRYPTO_USER_API=y -CONFIG_CRYPTO_USER_API_HASH=y -CONFIG_CRYPTO_USER_API_SKCIPHER=y -CONFIG_CRYPTO_USER_API_AEAD=y -CONFIG_BLK_INLINE_ENCRYPTION=y -CONFIG_FS_ENCRYPTION=y -CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y -CONFIG_FS_ENCRYPTION_INLINE_CRYPT_FALLBACK=y -CONFIG_FS_ENCRYPTION_HW_WRAPPED_KEYS=y -CONFIG_SCSI_UFS_CRYPTO=y -CONFIG_QCOM_INLINE_CRYPTO_ENGINE=y -CONFIG_CRYPTO_DEV_QCOM_ICE=y -CONFIG_BLK_INLINE_ENCRYPTION_HW_WRAPPED_KEYS=y - From 9ef322034c9e43a65718380aad1e3c2352e0c3b5 Mon Sep 17 00:00:00 2001 From: Nikhil V Date: Thu, 27 Nov 2025 15:15:16 +0530 Subject: [PATCH 227/438] QCLINUX: defconfig: Enable watchdog drivers for VM usecases CrosVM supports vCPU Stall watchdog. QEMU supports I6300 ESB watchdog. Enable corresponding drivers for Guest VM usecases. Signed-off-by: Nikhil V --- arch/arm64/configs/qcom.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 4133da26d73aa..5fa9e6af25edb 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -24,6 +24,7 @@ CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_EDAC_QCOM=m CONFIG_EXPERT=y +CONFIG_I6300ESB_WDT=y CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y CONFIG_PM_SLEEP=y @@ -47,6 +48,7 @@ CONFIG_TRACE_MMIO_ACCESS=y CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_TASK=y CONFIG_UHID=m +CONFIG_VCPU_STALL_DETECTOR=y # CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y From 6af6bae32041e525db33a9341c61ddcc4dd20e05 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 28 Nov 2025 12:38:09 +0530 Subject: [PATCH 228/438] QCLINUX: debug.config: Drop heavy debug configs Removed UBSAN, KASAN, kmemleak, lock proving, and function tracing from debug.config to reduce bootup time and prevent probe deferring issues. Signed-off-by: Komal Bajaj --- kernel/configs/debug.config | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config index 2d27a3c9104bb..799bedc6953e9 100644 --- a/kernel/configs/debug.config +++ b/kernel/configs/debug.config @@ -33,12 +33,12 @@ CONFIG_SECTION_MISMATCH_WARN_ONLY=y CONFIG_DEBUG_FS=y CONFIG_DEBUG_FS_ALLOW_ALL=y CONFIG_DEBUG_IRQFLAGS=y -CONFIG_UBSAN=y -CONFIG_UBSAN_BOOL=y -CONFIG_UBSAN_BOUNDS=y -CONFIG_UBSAN_ENUM=y -CONFIG_UBSAN_SHIFT=y -CONFIG_UBSAN_UNREACHABLE=y +# CONFIG_UBSAN is not set +# CONFIG_UBSAN_BOOL is not set +# CONFIG_UBSAN_BOUNDS is not set +# CONFIG_UBSAN_ENUM is not set +# CONFIG_UBSAN_SHIFT is not set +# CONFIG_UBSAN_UNREACHABLE is not set # # Networking Debugging # @@ -57,8 +57,8 @@ CONFIG_DEBUG_NET=y # CONFIG_SLUB_STATS is not set CONFIG_PAGE_EXTENSION=y CONFIG_PAGE_OWNER=y -CONFIG_DEBUG_KMEMLEAK=y -CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN is not set CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 CONFIG_DEBUG_OBJECTS_FREE=y @@ -73,10 +73,10 @@ CONFIG_DEBUG_VM=y CONFIG_DEBUG_VM_PGFLAGS=y CONFIG_DEBUG_VM_RB=y CONFIG_DEBUG_VM_VMACACHE=y -CONFIG_KASAN=y -CONFIG_KASAN_GENERIC=y -CONFIG_KASAN_INLINE=y -CONFIG_KASAN_VMALLOC=y +# CONFIG_KASAN is not set +# CONFIG_KASAN_GENERIC is not set +# CONFIG_KASAN_INLINE is not set +# CONFIG_KASAN_VMALLOC is not set CONFIG_PTDUMP_DEBUGFS=y CONFIG_SCHED_STACK_END_CHECK=y CONFIG_SLUB_DEBUG_ON=y @@ -94,7 +94,7 @@ CONFIG_SOFTLOCKUP_DETECTOR=y # Lock Debugging (spinlocks, mutexes, etc...) # # CONFIG_PROVE_RAW_LOCK_NESTING is not set -CONFIG_PROVE_LOCKING=y +# CONFIG_PROVE_LOCKING is not set # # Debug kernel data structures # @@ -102,16 +102,16 @@ CONFIG_BUG_ON_DATA_CORRUPTION=y # # RCU Debugging # -CONFIG_RCU_EXPERT=y -CONFIG_PROVE_RCU=y -CONFIG_PROVE_RCU_LIST=y +# CONFIG_RCU_EXPERT is not set +# CONFIG_PROVE_RCU is not set +# CONFIG_PROVE_RCU_LIST is not set # # Tracers # CONFIG_BRANCH_PROFILE_NONE=y CONFIG_DYNAMIC_FTRACE=y CONFIG_FTRACE=y -CONFIG_FUNCTION_TRACER=y +# CONFIG_FUNCTION_TRACER is not set # # Preemption # From b009163b56ac2741c92db624cde4d92ec6fb536c Mon Sep 17 00:00:00 2001 From: Jiaxing Li Date: Tue, 18 Nov 2025 00:16:10 +0800 Subject: [PATCH 229/438] QCLINUX: defconfig: Enable Trusted Execution Environment (TEE) driver for Qualcomm TEE (QTEE) We are planning to replace QPTEE with QCOMTEE on all QCOM-released kernel versions. QTEE allows Trusted Applications (TAs) and services to run securely and offers the same functionality as OPTEE. Signed-off-by: Jiaxing Li Link: https://github.com/qualcomm-linux/kernel-topics/pull/121 --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 0a11c9aa45007..308e37cc178fb 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1835,6 +1835,7 @@ CONFIG_FPGA_MGR_ZYNQMP_FPGA=m CONFIG_FPGA_MGR_VERSAL_FPGA=m CONFIG_TEE=y CONFIG_OPTEE=y +CONFIG_QCOMTEE=y CONFIG_MUX_GPIO=m CONFIG_MUX_MMIO=y CONFIG_SLIMBUS=m From 4277b05eea089e7af6cb1d955f3494a4430cd111 Mon Sep 17 00:00:00 2001 From: Nikhil V Date: Thu, 20 Nov 2025 15:11:23 +0530 Subject: [PATCH 230/438] QCLINUX: defconfig: Enable support for vhost-net, vsock Added the required configs to enable host kernel accelerator for virtio net(vhost-net) and virtual socket protocol(vsock). Signed-off-by: Nikhil V --- arch/arm64/configs/qcom.config | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 5fa9e6af25edb..ecfe6f69a3880 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -27,6 +27,8 @@ CONFIG_EXPERT=y CONFIG_I6300ESB_WDT=y CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y +CONFIG_MACVLAN=y +CONFIG_MACVTAP=y CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y CONFIG_PM_AUTOSLEEP=y @@ -49,6 +51,11 @@ CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_TASK=y CONFIG_UHID=m CONFIG_VCPU_STALL_DETECTOR=y +CONFIG_VHOST_NET=y +CONFIG_VHOST_VSOCK=y +CONFIG_VSOCKETS=y +# CONFIG_VSOCKETS_DIAG is not set +# CONFIG_VSOCKETS_LOOPBACK is not set # CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y From e036587e9536a3db06ed3440563082b61cbf66e1 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 3 Dec 2025 10:12:17 +0530 Subject: [PATCH 231/438] FROMLIST: arm64: defconfig: Enable Sound DMIC driver Enable CONFIG_SND_SOC_DMIC as a module in the arm64 defconfig to support digital microphone functionality on Qualcomm's Monaco and Lemans platforms. Link: https://lore.kernel.org/all/20251218084604.2054971-1-ravi.hothi@oss.qualcomm.com/ Signed-off-by: Ravi Hothi --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 308e37cc178fb..16eeabf360bc1 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1140,6 +1140,7 @@ CONFIG_SND_SOC_XILINX_SPDIF=m CONFIG_SND_SOC_AK4613=m CONFIG_SND_SOC_AK4619=m CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m CONFIG_SND_SOC_ES8316=m From 7c0408f5b61bfe8cae3a4c492378171842bcda63 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Thu, 4 Dec 2025 18:20:29 +0530 Subject: [PATCH 232/438] QCLINUX: arm64: configs: qcom.config: Enable GUNYAH_WATCHDOG Enable Gunyah watchdog driver for rb3gen2. Signed-off-by: Shivendra Pratap --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index ecfe6f69a3880..d2fe51d328e50 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -24,6 +24,7 @@ CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_EDAC_QCOM=m CONFIG_EXPERT=y +CONFIG_GUNYAH_WATCHDOG=y CONFIG_I6300ESB_WDT=y CONFIG_IDLE_INJECT=y CONFIG_KPROBES=y From 27063d7968e24f238f6b426dbdc1b7a5c72eac9d Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 5 Feb 2026 17:50:42 +0530 Subject: [PATCH 233/438] FROMLIST: arm64: defconfig: Enable Glymur configs for boot to shell The serial engine must be properly setup before kernel reaches "init", so UART driver and its dependencies needs to be built in. Enable its dependency clocks,interconnect and pinctrl as built-in to boot Qualcomm's dev platform - Glymur CRD board to UART console with rootfs on nvme storage. DISPCC enabled as module, used for display. Link: https://lore.kernel.org/r/20260205-upstream_v3_glymur_introduction-v7-2-849e7a9e6888@oss.qualcomm.com Reviewed-by: Krzysztof Kozlowski Signed-off-by: Pankaj Patil Reviewed-by: Dmitry Baryshkov --- arch/arm64/configs/defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 16eeabf360bc1..73a98df9748cf 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -647,6 +647,7 @@ CONFIG_PINCTRL_IMX91=y CONFIG_PINCTRL_IMX93=y CONFIG_PINCTRL_IMX_SCMI=y CONFIG_PINCTRL_MSM=y +CONFIG_PINCTRL_GLYMUR=y CONFIG_PINCTRL_IPQ5018=y CONFIG_PINCTRL_IPQ5332=y CONFIG_PINCTRL_IPQ5424=y @@ -1456,6 +1457,9 @@ CONFIG_COMMON_CLK_MT8192_SCP_ADSP=y CONFIG_COMMON_CLK_MT8192_VDECSYS=y CONFIG_COMMON_CLK_MT8192_VENCSYS=y CONFIG_COMMON_CLK_QCOM=y +CONFIG_CLK_GLYMUR_DISPCC=m +CONFIG_CLK_GLYMUR_GCC=y +CONFIG_CLK_GLYMUR_TCSRCC=m CONFIG_CLK_KAANAPALI_GCC=y CONFIG_CLK_KAANAPALI_TCSRCC=m CONFIG_CLK_X1E80100_CAMCC=m @@ -1849,6 +1853,7 @@ CONFIG_INTERCONNECT_IMX8MN=m CONFIG_INTERCONNECT_IMX8MQ=m CONFIG_INTERCONNECT_IMX8MP=y CONFIG_INTERCONNECT_QCOM=y +CONFIG_INTERCONNECT_QCOM_GLYMUR=y CONFIG_INTERCONNECT_QCOM_KAANAPALI=y CONFIG_INTERCONNECT_QCOM_MSM8916=m CONFIG_INTERCONNECT_QCOM_MSM8953=y From e4ceff1fb68697571c2b2a5e1ce9a31b6ef53056 Mon Sep 17 00:00:00 2001 From: Raghavender Reddy Bujala Date: Wed, 10 Dec 2025 16:16:53 +0530 Subject: [PATCH 234/438] QCLINUX: arm64: configs: qcom.config: Enable UINPUT Enable UINPUT, which is required for BT AVRC profile to register the events and All passthrough commands of AVRCP will be listed in this event under /dev/input/ Signed-off-by: Raghavender Reddy Bujala --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index d2fe51d328e50..7dc21568d5cf5 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -27,6 +27,7 @@ CONFIG_EXPERT=y CONFIG_GUNYAH_WATCHDOG=y CONFIG_I6300ESB_WDT=y CONFIG_IDLE_INJECT=y +CONFIG_INPUT_UINPUT=y CONFIG_KPROBES=y CONFIG_MACVLAN=y CONFIG_MACVTAP=y From cd19025434092fd52d17d6468a9720db18fa8f78 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Mon, 15 Dec 2025 12:37:54 +0530 Subject: [PATCH 235/438] QCLINUX: defconfig: enable EMC2305 defconfig on qcom.config Enable SENSOR_EMC2305 defconfig to enable fan controller support. Signed-off-by: Gaurav Kohli --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 7dc21568d5cf5..4fff1e0a0aabb 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -48,6 +48,7 @@ CONFIG_STM_SOURCE_CONSOLE=m CONFIG_STM_SOURCE_FTRACE=m CONFIG_STM_SOURCE_HEARTBEAT=m CONFIG_SENSORS_AMC6821=y +CONFIG_SENSORS_EMC2305=y CONFIG_TRACE_MMIO_ACCESS=y CONFIG_UCLAMP_TASK_GROUP=y CONFIG_UCLAMP_TASK=y From 3f516fe96aaa8ef1fad2ee675261e8a49ca4cd06 Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Wed, 17 Dec 2025 18:42:40 +0530 Subject: [PATCH 236/438] QCLINUX: arm64: configs: Added new rt.config for RT kernel Enabled PREEMPT_RT in new rt.config to enable RT kernel features. Signed-off-by: Anurag Pateriya --- arch/arm64/configs/rt.config | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 arch/arm64/configs/rt.config diff --git a/arch/arm64/configs/rt.config b/arch/arm64/configs/rt.config new file mode 100644 index 0000000000000..ca92615d38a17 --- /dev/null +++ b/arch/arm64/configs/rt.config @@ -0,0 +1,3 @@ +# rt.config for Real time kernel features +CONFIG_EXPERT=y +CONFIG_PREEMPT_RT=y From b326331fa8aaa0619827e099b0a91cf472899200 Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya Date: Thu, 11 Dec 2025 16:41:21 +0530 Subject: [PATCH 237/438] QCLINUX: arm64: configs: qcom.config: Enable I2C_QCOM_GENI as built-in On Lemans and Monaco EVK platforms the boot-from-SD-card feature requires an IO expander to be enabled at an early stage to detect the SD card. This IO expander is connected over I2C. Currently the I2C driver is built as a loadable module which resides on the SD card along with other modules. This creates a circular dependency where to detect the SD card the IO expander must be initialized the IO expander depends on the I2C driver and the I2C driver is on the SD card which cannot be accessed until detection succeeds. To break this dependency enable I2C_QCOM_GENI as built-in so that the driver is available during early boot. Signed-off-by: Viken Dadhaniya --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 4fff1e0a0aabb..0707e99b09ace 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -25,6 +25,7 @@ CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_EDAC_QCOM=m CONFIG_EXPERT=y CONFIG_GUNYAH_WATCHDOG=y +CONFIG_I2C_QCOM_GENI=y CONFIG_I6300ESB_WDT=y CONFIG_IDLE_INJECT=y CONFIG_INPUT_UINPUT=y From 3fd299733557d52ec7691f6a308d5bbce190b742 Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Thu, 18 Dec 2025 15:10:56 +0530 Subject: [PATCH 238/438] QCLINUX: arm64: configs: Added Kubernetes support in qcom.config Adding config options for Kubernetes support in qcom.config Signed-off-by: Anurag Pateriya --- arch/arm64/configs/qcom.config | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 0707e99b09ace..4cb8bc80ee0df 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -67,3 +67,13 @@ CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m CONFIG_WATCHDOG_PRETIMEOUT_GOV=y CONFIG_ZRAM=y + +# Kubernetes support +CONFIG_CFS_BANDWIDTH=y +CONFIG_CGROUP_FAVOR_DYNMODS=y +CONFIG_IPC_NS=y +CONFIG_NAMESPACES=y +CONFIG_NET_NS=y +CONFIG_PID_NS=y +CONFIG_UTS_NS=y + From 3997e61a8cae28951775660c9923c801f43ba6ea Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 23 Dec 2025 17:07:14 +0530 Subject: [PATCH 239/438] QCLINUX: qcom.comfig: disable ICE/UFS crypto RB3GEN2 on v6.19-rc2 crashes in qcom_ice_probe() and fails to boot. Disable inline crypto (ICE) and UFS crypto as a temporary workaround. Disabled: - CONFIG_QCOM_INLINE_CRYPTO_ENGINE - CONFIG_SCSI_UFS_CRYPTO Will be reverted once ICE probe is fixed. Signed-off-by: Komal Bajaj --- arch/arm64/configs/qcom.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 4cb8bc80ee0df..e3c45f29461f2 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -77,3 +77,6 @@ CONFIG_NET_NS=y CONFIG_PID_NS=y CONFIG_UTS_NS=y +# Disable ICE/UFS crypto +# CONFIG_QCOM_INLINE_CRYPTO_ENGINE is not set +# CONFIG_SCSI_UFS_CRYPTO is not set From bc5fd79aaaca690ecdb250f5f4efa7f16fc47f03 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 24 Dec 2025 18:34:18 +0530 Subject: [PATCH 240/438] QCLINUX: defconfig: enable Remoteproc cooling feature Enable Remoteproc cooling feature config. Signed-off-by: Gaurav Kohli --- arch/arm64/configs/qcom.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index e3c45f29461f2..4be5a6115b4ef 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -41,6 +41,8 @@ CONFIG_PM_WAKELOCKS_LIMIT=0 CONFIG_PM=y CONFIG_POWERCAP=y CONFIG_QCA808X_PHY=m +CONFIG_QCOM_QMI_COOLING=y +CONFIG_REMOTEPROC_THERMAL=y CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y CONFIG_STM_PROTO_BASIC=m From 05f630638a4fcbbd9a23c9f58e55fd7c4eeff3ba Mon Sep 17 00:00:00 2001 From: Jagadeesh Pagadala Date: Thu, 8 Jan 2026 14:14:29 +0530 Subject: [PATCH 241/438] QCLINUX: arm64: configs: qcom.config: Enable CONNECTOR, PROC_EVENTS Enable CONFIG_CONNECTOR and CONFIG_PROC_EVENTS to allow userspace to receive process lifecycle events (fork/exec/exit) via the proc connector over netlink. Signed-off-by: Jagadeesh Pagadala --- arch/arm64/configs/qcom.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 4be5a6115b4ef..b87760e3d1d86 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -11,6 +11,7 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CONNECTOR=y CONFIG_CORESIGHT_CORESIGHT_TNOC=m CONFIG_CORESIGHT_CTCU=m CONFIG_CORESIGHT_DUMMY=m @@ -40,6 +41,7 @@ CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set CONFIG_PM=y CONFIG_POWERCAP=y +CONFIG_PROC_EVENTS=y CONFIG_QCA808X_PHY=m CONFIG_QCOM_QMI_COOLING=y CONFIG_REMOTEPROC_THERMAL=y From 4119e10be39063a6374de33f3d73fd6c37247a91 Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Mon, 5 Jan 2026 15:59:47 +0800 Subject: [PATCH 242/438] QCLINUX: qcom.config: add crypto corresponding config Enable crypto api for user test. The configs are for testapp that's why the kernel upstream team would suggest having this enabled for clients who needs it and not by default since in qcom we need this, we should be enabling ideally in qcom-next. Signed-off-by: Wenjia Zhang --- arch/arm64/configs/qcom.config | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index b87760e3d1d86..896ceb9454054 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -84,3 +84,9 @@ CONFIG_UTS_NS=y # Disable ICE/UFS crypto # CONFIG_QCOM_INLINE_CRYPTO_ENGINE is not set # CONFIG_SCSI_UFS_CRYPTO is not set + +# Support Crypto api +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_AEAD=y From 05113c034fb3264c2394855d2a88c4f990fd8001 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jan 2026 22:54:34 +0530 Subject: [PATCH 243/438] FROMLIST: arm64: defconfig: Enable camcc, videocc clock controllers on SM8750 Enable the SM8750 video, camera clock controller for their respective functionalities on the Qualcomm SM8750 MTP platform. Link: https://lore.kernel.org/all/20260113-enable_mmcc_defconfig-v1-1-4b709daadd1f@oss.qualcomm.com/ Signed-off-by: Taniya Das --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 73a98df9748cf..25953dbd11cf1 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1531,6 +1531,7 @@ CONFIG_SM_CAMCC_MILOS=m CONFIG_SM_CAMCC_8250=m CONFIG_SM_CAMCC_8550=m CONFIG_SM_CAMCC_8650=m +CONFIG_SM_CAMCC_8750=m CONFIG_SM_DISPCC_6115=m CONFIG_SM_DISPCC_8250=y CONFIG_SM_DISPCC_6350=m @@ -1564,6 +1565,7 @@ CONFIG_SM_VIDEOCC_6350=m CONFIG_SM_VIDEOCC_MILOS=m CONFIG_SM_VIDEOCC_8250=y CONFIG_SM_VIDEOCC_8550=m +CONFIG_SM_VIDEOCC_8750=m CONFIG_QCOM_HFPLL=y CONFIG_CLK_GFM_LPASS_SM8250=m CONFIG_SM_VIDEOCC_8450=m From a2c73acc40a80a3ac36df6c309a98ff9128da847 Mon Sep 17 00:00:00 2001 From: Yongxing Mou Date: Mon, 19 Jan 2026 15:47:00 +0800 Subject: [PATCH 244/438] QCLINUX: prune.config: Enable backlight config for Hamoa/Purwa Hamoa/Purwa currently requires the backlight node from the eDP device, but this macro was overridden by CONFIG_DRM_NOUVEAU. Remove it from prune.config to properly enable the BACKLIGHT_* related config. Signed-off-by: Yongxing Mou --- arch/arm64/configs/prune.config | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/configs/prune.config b/arch/arm64/configs/prune.config index 54cf8fa1cd0e0..fba07d6ebe12d 100644 --- a/arch/arm64/configs/prune.config +++ b/arch/arm64/configs/prune.config @@ -188,7 +188,6 @@ # CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_MALI_DISPLAY is not set # CONFIG_DRM_KOMEDA is not set -# CONFIG_DRM_NOUVEAU is not set # CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set # CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set # CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set From 37e64ad7d5807fe97137e8c004450d1d9b728e91 Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Fri, 23 Jan 2026 13:32:49 +0530 Subject: [PATCH 245/438] QCLINUX: qcom.config: Enable 39-bit VA space for 4K-page builds For Qualcomm 4K-page based builds, explicitly enable VA_BITS_39 in the qcom.config fragment. Lower-end arm64 systems typically do not benefit from a 48/52-bit VA space, while they do benefit from smaller page tables and reduced TLB pressure. Selecting 39-bit VA sizing aligns better with constraints and performance characteristics of lower-end Qualcomm platforms. This change does not affect 64K-page builds (which retain 48/52-bit VA). Background: - With 4K pages, arm64 supports 39-bit (3-level) or 48-bit (4-level) VAs. - 52-bit VAs are only available with 64K pages and ARMv8.2-LVA, and kernels must be able to fall back to 48-bit at boot. Signed-off-by: Anurag Pateriya --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 896ceb9454054..8190237481eee 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -4,6 +4,7 @@ # # Keep alphabetically sorted CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_ARM64_VA_BITS_39=y CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y From 1b601f5e5fbecedbf667834048aa5248279fd55b Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Tue, 27 Jan 2026 15:59:30 +0800 Subject: [PATCH 246/438] QCLINUX: qcom.config: enable the ICE related config Below is the reason why config aren't enable in upstream: Not all filesystem support encryption, the default config must be safe for all situation. Upstream kernel keeps optional features off by default. Filesystem encryption must be enabled in per-filesystem. Kernel developmenters added options to dosable fscrypt per-filesystem means it's not intended as default. CRs-Fixed: 4418940 Signed-off-by: Wenjia Zhang --- arch/arm64/configs/qcom.config | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 8190237481eee..1663137c14770 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -82,12 +82,15 @@ CONFIG_NET_NS=y CONFIG_PID_NS=y CONFIG_UTS_NS=y -# Disable ICE/UFS crypto -# CONFIG_QCOM_INLINE_CRYPTO_ENGINE is not set -# CONFIG_SCSI_UFS_CRYPTO is not set - # Support Crypto api CONFIG_CRYPTO_USER_API=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y CONFIG_CRYPTO_USER_API_AEAD=y + +# Support ICE/UFS crypto driver +CONFIG_BLK_INLINE_ENCRYPTION=y +CONFIG_QCOM_INLINE_CRYPTO_ENGINE=m +CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y +CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_FS_ENCRYPTION=y From 3891542b5df5856b6babe77d66f7a4decbc14955 Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Wed, 12 Nov 2025 20:18:12 +0530 Subject: [PATCH 247/438] FROMLIST: arm64: configs: Update defconfig for DSI-LVDS bridge support Enable the LT9211 bridge driver to support DSI-to-LVDS conversion on the Qualcomm RB3GEN2 Industrial Kit. Signed-off-by: Gopi Botlagunta Co-developed-by: Yi Zhang Signed-off-by: Yi Zhang Link: https://lore.kernel.org/lkml/20260130-add-lt9211c-bridge-for-rb3gen2-industrial-mezzanine-v2-2-a98714fa1531@oss.qualcomm.com/ --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 25953dbd11cf1..bfc48ce1aaeea 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1004,6 +1004,7 @@ CONFIG_DRM_FSL_LDB=m CONFIG_DRM_ITE_IT6263=m CONFIG_DRM_LONTIUM_LT8713SX=m CONFIG_DRM_LONTIUM_LT8912B=m +CONFIG_DRM_LONTIUM_LT9211=m CONFIG_DRM_LONTIUM_LT9611=m CONFIG_DRM_LONTIUM_LT9611UXC=m CONFIG_DRM_ITE_IT66121=m From d3cb48f6b3c37591388eaa42c614aeb50dd5df0a Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 24 Feb 2026 23:19:25 -0800 Subject: [PATCH 248/438] FROMLIST: arm64: defconfig: Enable Kaanapali clock controllers Enable the Kaanapali display, video, camera and gpu clock controller for their respective functionalities on the Qualcomm Kaanapali QRD and MTP boards. Link: https://lore.kernel.org/r/20260224-knp-dts-misc-v6-10-79d20dab8a60@oss.qualcomm.com Signed-off-by: Taniya Das Reviewed-by: Abel Vesa Signed-off-by: Jingyi Wang --- arch/arm64/configs/defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index bfc48ce1aaeea..3cb1a49e8312f 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1461,8 +1461,12 @@ CONFIG_COMMON_CLK_QCOM=y CONFIG_CLK_GLYMUR_DISPCC=m CONFIG_CLK_GLYMUR_GCC=y CONFIG_CLK_GLYMUR_TCSRCC=m +CONFIG_CLK_KAANAPALI_CAMCC=m +CONFIG_CLK_KAANAPALI_DISPCC=m CONFIG_CLK_KAANAPALI_GCC=y +CONFIG_CLK_KAANAPALI_GPUCC=m CONFIG_CLK_KAANAPALI_TCSRCC=m +CONFIG_CLK_KAANAPALI_VIDEOCC=m CONFIG_CLK_X1E80100_CAMCC=m CONFIG_CLK_X1E80100_DISPCC=m CONFIG_CLK_X1E80100_GCC=y From 33dee4fcf4c0cd3a59299562dd085906e42770f1 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 29 Jan 2026 15:52:47 +0530 Subject: [PATCH 249/438] QCLINUX: qcom.config: Enable FTRACE option for performance profiling Enable kernel tracing option in qcom.config to support performance profiling on Qualcomm arm64 builds. Signed-off-by: Komal Bajaj --- arch/arm64/configs/qcom.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 1663137c14770..bd33d12832ab7 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -94,3 +94,6 @@ CONFIG_QCOM_INLINE_CRYPTO_ENGINE=m CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_SCSI_UFS_CRYPTO=y CONFIG_FS_ENCRYPTION=y + +# Support performance profiling +CONFIG_FTRACE=y From 73c1f41dbfa7ab272c920b37691d5f1fa92b4f16 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:39 +0530 Subject: [PATCH 250/438] FROMLIST: arm64: defconfig: Enable VIDEOCC and CAMCC drivers on Qualcomm X1P42100 Enable video and camera clock controller drivers for their respective functionalities on Qualcomm X1P42100-CRD and similar other platforms with Snapdragon X1P42100 SoC. Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20260128-purwa-videocc-camcc-v1-8-b23de57df5ba@oss.qualcomm.com Signed-off-by: Taniya Das --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 3cb1a49e8312f..4d352b1a5a4c5 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1472,7 +1472,9 @@ CONFIG_CLK_X1E80100_DISPCC=m CONFIG_CLK_X1E80100_GCC=y CONFIG_CLK_X1E80100_GPUCC=m CONFIG_CLK_X1E80100_TCSRCC=y +CONFIG_CLK_X1P42100_CAMCC=m CONFIG_CLK_X1P42100_GPUCC=m +CONFIG_CLK_X1P42100_VIDEOCC=m CONFIG_CLK_QCM2290_GPUCC=m CONFIG_QCOM_A53PLL=y CONFIG_QCOM_CLK_APCS_MSM8916=y From 25d52a5ed9a8fd8f57a73dc4f55dfda06294ff69 Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Wed, 18 Feb 2026 12:00:01 +0530 Subject: [PATCH 251/438] Revert "QCLINUX: qcom.config: Enable 39-bit VA space for 4K-page builds" This reverts commit 02fdded1047f4a65082e9ee523dec4af032d99bc. Since bootup issues are observed after enabling 39-bit VA, reverting it untill issues are root caused and fixed. Signed-off-by: Anurag Pateriya --- arch/arm64/configs/qcom.config | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index bd33d12832ab7..c0033a973b164 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -4,7 +4,6 @@ # # Keep alphabetically sorted CONFIG_ARM64_SW_TTBR0_PAN=y -CONFIG_ARM64_VA_BITS_39=y CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y From a72ddd9caa74a75c66fbdc7c6aa3caca62f2f897 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 20 Feb 2026 08:33:37 +0530 Subject: [PATCH 252/438] QCLINUX: qcom.config: Enable CPUidle Teo and Menu governors Menu governor gets default enabled if Teo governor is not compiled in. Menu still stays as default governor when both are compiled in due to menu having higher rating than teo. Keeping Teo available helps in evaluating power and performance without spinning builds. Enable both menu and teo governors for CPUidle. Signed-off-by: Maulik Shah --- arch/arm64/configs/qcom.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index c0033a973b164..54195f5b6277a 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -18,6 +18,8 @@ CONFIG_CORESIGHT_DUMMY=m CONFIG_CORESIGHT_SOURCE_ETM4X=m CONFIG_CORESIGHT_TGU=m CONFIG_CORESIGHT_TPDM=m +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_GOV_TEO=y CONFIG_CPU_IDLE_THERMAL=y # CONFIG_DEBUG_INFO_REDUCED is not set CONFIG_DMABUF_HEAPS=y From 5c4bcf96377d1bd8b317cdaf5202bd336159ab62 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sun, 22 Feb 2026 22:17:52 +0530 Subject: [PATCH 253/438] FROMLIST: arm64: defconfig: Enable SM8750 clock controllers Enable the SM8750 video, camera and gpu clock controller for their respective functionalities on the Qualcomm SM8750 MTP boards. Link: https://lore.kernel.org/lkml/20260220-sm8750_defconfig_cc-v1-1-666aa922b392@oss.qualcomm.com/ Signed-off-by: Taniya Das --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 4d352b1a5a4c5..849572b1a55ac 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1564,6 +1564,7 @@ CONFIG_SM_GPUCC_8350=m CONFIG_SM_GPUCC_8450=m CONFIG_SM_GPUCC_8550=m CONFIG_SM_GPUCC_8650=m +CONFIG_SM_GPUCC_8750=m CONFIG_SM_TCSRCC_8550=y CONFIG_SM_TCSRCC_8650=y CONFIG_SM_TCSRCC_8750=m From 4a5ea14f1765b6f97b3dfdde6444d4c24c227537 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 20 Feb 2026 15:46:58 +0530 Subject: [PATCH 254/438] FROMLIST: arm64: defconfig: Enable Glymur clock controllers Enable the Glymur video and gpu clock controller for their respective functionalities on the Qualcomm Glymur CRD boards. Link: https://lore.kernel.org/r/20260220-glymur_mmcc_dt_config-v1-2-e0e2f43a32af@oss.qualcomm.com Signed-off-by: Taniya Das --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 849572b1a55ac..e1e67dd61fb3c 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1460,7 +1460,9 @@ CONFIG_COMMON_CLK_MT8192_VENCSYS=y CONFIG_COMMON_CLK_QCOM=y CONFIG_CLK_GLYMUR_DISPCC=m CONFIG_CLK_GLYMUR_GCC=y +CONFIG_CLK_GLYMUR_GPUCC=m CONFIG_CLK_GLYMUR_TCSRCC=m +CONFIG_CLK_GLYMUR_VIDEOCC=m CONFIG_CLK_KAANAPALI_CAMCC=m CONFIG_CLK_KAANAPALI_DISPCC=m CONFIG_CLK_KAANAPALI_GCC=y From be65cc66fef5fa8f6494f6809c5a29bc45d9bd39 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Tue, 27 Jan 2026 17:32:06 +0530 Subject: [PATCH 255/438] FROMLIST: drm/msm/adreno: Add GPU to MODULE_DEVICE_TABLE Since it is possible to independently probe Adreno GPU, add GPU match table to MODULE_DEVICE_TABLE to allow auto-loading of msm module. Signed-off-by: Akhil P Oommen Link: https://lore.kernel.org/lkml/20260124-adreno-module-table-v1-1-9c2dbb2638b4@oss.qualcomm.com/ --- drivers/gpu/drm/msm/adreno/adreno_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 554d746f115b2..4edfe80c5be7c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -302,6 +302,7 @@ static const struct of_device_id dt_match[] = { { .compatible = "qcom,kgsl-3d0" }, {} }; +MODULE_DEVICE_TABLE(of, dt_match); static int adreno_runtime_resume(struct device *dev) { From 8a483f5d645ec0de5a881a00694373d5ddee0a58 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Fri, 17 Oct 2025 11:25:35 +0530 Subject: [PATCH 256/438] QCLINUX: arm64: dts: qcom: Add camera DT binding Add the camera DT binding header, which will be utilized by the camera downstream drivers and DTSI files. Signed-off-by: Chandan Kumar Jha --- include/dt-bindings/camera/msm-camera.h | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 include/dt-bindings/camera/msm-camera.h diff --git a/include/dt-bindings/camera/msm-camera.h b/include/dt-bindings/camera/msm-camera.h new file mode 100644 index 0000000000000..97228c26e7040 --- /dev/null +++ b/include/dt-bindings/camera/msm-camera.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __MSM_CAMERA_H +#define __MSM_CAMERA_H + +/* CPAS path data types */ +#define CAM_CPAS_PATH_DATA_IFE_START_OFFSET 0 +#define CAM_CPAS_PATH_DATA_IFE_LINEAR (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 0) +#define CAM_CPAS_PATH_DATA_IFE_VID (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_IFE_DISP (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 2) +#define CAM_CPAS_PATH_DATA_IFE_STATS (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 3) +#define CAM_CPAS_PATH_DATA_IFE_RDI0 (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 4) +#define CAM_CPAS_PATH_DATA_IFE_RDI1 (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 5) +#define CAM_CPAS_PATH_DATA_IFE_RDI2 (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 6) +#define CAM_CPAS_PATH_DATA_IFE_RDI3 (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 7) +#define CAM_CPAS_PATH_DATA_IFE_PDAF (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 8) +#define CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 9) +#define CAM_CPAS_PATH_DATA_IFE_MAX_OFFSET (CAM_CPAS_PATH_DATA_IFE_START_OFFSET + 31) + +#define CAM_CPAS_PATH_DATA_IPE_START_OFFSET 32 +#define CAM_CPAS_PATH_DATA_IPE_RD_IN (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 0) +#define CAM_CPAS_PATH_DATA_IPE_RD_REF (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_IPE_WR_VID (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 2) +#define CAM_CPAS_PATH_DATA_IPE_WR_DISP (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 3) +#define CAM_CPAS_PATH_DATA_IPE_WR_REF (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 4) +#define CAM_CPAS_PATH_DATA_IPE_WR_APP (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 5) +#define CAM_CPAS_PATH_DATA_IPE_MAX_OFFSET (CAM_CPAS_PATH_DATA_IPE_START_OFFSET + 31) + +#define CAM_CPAS_PATH_DATA_OPE_START_OFFSET 64 +#define CAM_CPAS_PATH_DATA_OPE_RD_IN (CAM_CPAS_PATH_DATA_OPE_START_OFFSET + 0) +#define CAM_CPAS_PATH_DATA_OPE_RD_REF (CAM_CPAS_PATH_DATA_OPE_START_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_OPE_WR_VID (CAM_CPAS_PATH_DATA_OPE_START_OFFSET + 2) +#define CAM_CPAS_PATH_DATA_OPE_WR_DISP (CAM_CPAS_PATH_DATA_OPE_START_OFFSET + 3) +#define CAM_CPAS_PATH_DATA_OPE_WR_REF (CAM_CPAS_PATH_DATA_OPE_START_OFFSET + 4) +#define CAM_CPAS_PATH_DATA_OPE_MAX_OFFSET (CAM_CPAS_PATH_DATA_OPE_START_OFFSET + 31) + +#define CAM_CPAS_PATH_DATA_SFE_START_OFFSET 96 +#define CAM_CPAS_PATH_DATA_SFE_NRDI (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 0) +#define CAM_CPAS_PATH_DATA_SFE_RDI0 (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_SFE_RDI1 (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 2) +#define CAM_CPAS_PATH_DATA_SFE_RDI2 (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 3) +#define CAM_CPAS_PATH_DATA_SFE_RDI3 (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 4) +#define CAM_CPAS_PATH_DATA_SFE_RDI4 (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 5) +#define CAM_CPAS_PATH_DATA_SFE_STATS (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 6) +#define CAM_CPAS_PATH_DATA_SFE_MAX_OFFSET (CAM_CPAS_PATH_DATA_SFE_START_OFFSET + 31) + +#define CAM_CPAS_PATH_DATA_CRE_START_OFFSET (CAM_CPAS_PATH_DATA_SFE_MAX_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_CRE_RD_IN (CAM_CPAS_PATH_DATA_CRE_START_OFFSET + 0) +#define CAM_CPAS_PATH_DATA_CRE_WR_OUT (CAM_CPAS_PATH_DATA_CRE_START_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_CRE_MAX_OFFSET (CAM_CPAS_PATH_DATA_CRE_START_OFFSET + 31) + +#define CAM_CPAS_PATH_DATA_OFE_START_OFFSET (CAM_CPAS_PATH_DATA_CRE_MAX_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_OFE_RD_EXT (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 0) +#define CAM_CPAS_PATH_DATA_OFE_RD_INT_PDI (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_OFE_RD_INT_HDR (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 2) +#define CAM_CPAS_PATH_DATA_OFE_WR_VID (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 3) +#define CAM_CPAS_PATH_DATA_OFE_WR_DISP (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 4) +#define CAM_CPAS_PATH_DATA_OFE_WR_IR (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 5) +#define CAM_CPAS_PATH_DATA_OFE_WR_HDR_LTM (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 6) +#define CAM_CPAS_PATH_DATA_OFE_WR_DC4 (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 7) +#define CAM_CPAS_PATH_DATA_OFE_WR_AI (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 8) +#define CAM_CPAS_PATH_DATA_OFE_WR_PDI (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 9) +#define CAM_CPAS_PATH_DATA_OFE_WR_IDEALRAW (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 10) +#define CAM_CPAS_PATH_DATA_OFE_WR_STATS (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 11) +#define CAM_CPAS_PATH_DATA_OFE_MAX_OFFSET (CAM_CPAS_PATH_DATA_OFE_START_OFFSET + 31) + +#define CAM_CPAS_PATH_DATA_CONSO_OFFSET 256 +#define CAM_CPAS_PATH_DATA_ALL (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 0) + +/* IFE consolidated paths */ +#define CAM_CPAS_PATH_DATA_IFE_LINEAR_PDAF (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 1) +#define CAM_CPAS_PATH_DATA_IFE_UBWC_STATS (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 2) +#define CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 3) +#define CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 4) +#define CAM_CPAS_PATH_DATA_IFE_RDI_ALL (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 5) +#define CAM_CPAS_PATH_DATA_IFE_UBWC (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 6) +#define CAM_CPAS_PATH_DATA_IFE_LINEAR_STATS (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 7) +#define CAM_CPAS_PATH_DATA_IFE_UBWC_LINEAR (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 8) +#define CAM_CPAS_PATH_DATA_IFE_PDAF_LINEAR (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 9) + +/* IPE Consolidated paths */ +#define CAM_CPAS_PATH_DATA_IPE_WR_VID_DISP (CAM_CPAS_PATH_DATA_CONSO_OFFSET + 1) + +/* CPAS transaction types */ +#define CAM_CPAS_TRANSACTION_READ 0 +#define CAM_CPAS_TRANSACTION_WRITE 1 + +/* CPAS traffic merge types */ +#define CAM_CPAS_TRAFFIC_MERGE_SUM 0 +#define CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE 1 + +/* Feature bit type */ +#define CAM_CPAS_FEATURE_TYPE_DISABLE 0 +#define CAM_CPAS_FEATURE_TYPE_ENABLE 1 +#define CAM_CPAS_FEATURE_TYPE_VALUE 2 + +/* Feature support bit positions in feature fuse register*/ +#define CAM_CPAS_QCFA_BINNING_ENABLE 0 +#define CAM_CPAS_SECURE_CAMERA_ENABLE 1 +#define CAM_CPAS_MF_HDR_ENABLE 2 +#define CAM_CPAS_MP_LIMIT_FUSE 3 +#define CAM_CPAS_ISP_FUSE 4 +#define CAM_CPAS_ISP_PIX_FUSE 5 +#define CAM_CPAS_ISP_LITE_FUSE 6 +#define CAM_CPAS_CSIPHY_FUSE 7 +#define CAM_CPAS_IPE_VID_OUT_8BPP_LIMIT_ENABLE 8 +#define CAM_CPAS_SFE_FUSE 9 +#define CAM_CPAS_CUSTOM_FUSE 10 +#define CAM_CPAS_CAM_FUSE 11 +#define CAM_CPAS_SHDR_FUSE 12 +#define CAM_CPAS_RT_OT_FUSE 13 +#define CAM_CPAS_FUSE_FEATURE_MAX 14 + +/* Flash type*/ +#define CAM_FLASH_TYPE_PMIC 0 +#define CAM_FLASH_TYPE_I2C 1 +#define CAM_FLASH_TYPE_GPIO 2 + +/* CCI master */ +#define CCI_MASTER_0 0 +#define CCI_MASTER_1 1 +#define CCI_MASTER_MAX 2 + +/* AON Camera IDs*/ +#define AON_CAM1 0 +#define AON_CAM2 1 +#define MAX_AON_CAM 2 +#define NOT_AON_CAM 255 + +/* Camera DRV enable masks */ +#define CAM_DDR_DRV 0x1 +#define CAM_CLK_DRV 0x2 + +/* Port index for BW voting */ +#define CAM_CPAS_PORT_HLOS_DRV 0 +#define CAM_CPAS_PORT_DRV_0 1 +#define CAM_CPAS_PORT_DRV_1 2 +#define CAM_CPAS_PORT_DRV_2 3 +#define CAM_CPAS_PORT_DRV_DYN 32 + +/* Domain ID types */ +#define CAM_CPAS_NON_SECURE_DOMAIN 0 +#define CAM_CPAS_SECURE_DOMAIN 1 + +/* Debug bypass driver */ +#define CAM_BYPASS_RGLTR 0x1 +#define CAM_BYPASS_RGLTR_MODE 0x2 +#define CAM_BYPASS_CLKS 0x4 +#define CAM_BYPASS_CESTA 0x8 +#define CAM_BYPASS_ICC 0x10 + +#endif From 3211f0e058011de2050b82d62671a42a5ab0bb81 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Fri, 10 Oct 2025 16:51:48 +0530 Subject: [PATCH 257/438] QCLINUX: arm64: dts: qcom: Add lemans camx overlay dts Add CAMX overlay dts file for lemans boards. This change also enables the compilation of the CAMX overlay on Lemans boards. Co-developed-by: Vikram Sharma Signed-off-by: Vikram Sharma Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/Makefile | 20 + .../boot/dts/qcom/lemans-camera-sensor.dtsi | 502 ++++ arch/arm64/boot/dts/qcom/lemans-camera.dtsi | 2559 +++++++++++++++++ .../dts/qcom/lemans-evk-camera-sensor.dtsi | 736 +++++ arch/arm64/boot/dts/qcom/lemans-evk-camx.dtso | 138 + .../boot/dts/qcom/sa8775p-ride-camx.dtso | 16 + 6 files changed, 3971 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/lemans-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/lemans-camera.dtsi create mode 100644 arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/lemans-evk-camx.dtso create mode 100644 arch/arm64/boot/dts/qcom/sa8775p-ride-camx.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index f80b5d9cf1e80..695be4f5de750 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -392,3 +392,23 @@ x1p42100-lenovo-thinkbook-16-el2-dtbs := x1p42100-lenovo-thinkbook-16.dtb x1-el2 dtb-$(CONFIG_ARCH_QCOM) += x1p42100-lenovo-thinkbook-16.dtb x1p42100-lenovo-thinkbook-16-el2.dtb x1p64100-microsoft-denali-el2-dtbs := x1p64100-microsoft-denali.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1p64100-microsoft-denali.dtb x1p64100-microsoft-denali-el2.dtb + +lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb + +qcs9100-ride-camx-dtbs:= qcs9100-ride.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-camx.dtb + +qcs9100-ride-r3-camx-dtbs:= qcs9100-ride-r3.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3-camx.dtb + +sa8775p-ride-camx-dtbs:= sa8775p-ride.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-camx.dtb + +sa8775p-ride-r3-camx-dtbs:= sa8775p-ride-r3.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3-camx.dtb diff --git a/arch/arm64/boot/dts/qcom/lemans-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/lemans-camera-sensor.dtsi new file mode 100644 index 0000000000000..d531f89dda08e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-camera-sensor.dtsi @@ -0,0 +1,502 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&cam_cci0 { + /* GMSL deserializer 0 */ + qcom,cam-gmsl-deserializer0 { + cell-index = <0>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 7 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser0_port0: endpoint { + remote-endpoint = <&gmsl_sensor0_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser0_port1: endpoint { + remote-endpoint = <&gmsl_sensor1_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser0_port2: endpoint { + remote-endpoint = <&gmsl_sensor2_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser0_port3: endpoint { + remote-endpoint = <&gmsl_sensor3_ep>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 0 */ + qcom,cam-gmsl-sensor0 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <0>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor0_ep: endpoint { + remote-endpoint = <&deser0_port0>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 1 */ + qcom,cam-gmsl-sensor1 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <1>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor1_ep: endpoint { + remote-endpoint = <&deser0_port1>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 2 */ + qcom,cam-gmsl-sensor2 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <2>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor2_ep: endpoint { + remote-endpoint = <&deser0_port2>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 3 */ + qcom,cam-gmsl-sensor3 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <3>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor3_ep: endpoint { + remote-endpoint = <&deser0_port3>; + }; + }; + }; +}; + +&cam_cci1 { + /* GMSL deserializer 1 */ + qcom,cam-gmsl-deserializer1 { + cell-index = <1>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 8 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser1_port0: endpoint { + remote-endpoint = <&gmsl_sensor4_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser1_port1: endpoint { + remote-endpoint = <&gmsl_sensor5_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser1_port2: endpoint { + remote-endpoint = <&gmsl_sensor6_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser1_port3: endpoint { + remote-endpoint = <&gmsl_sensor7_ep>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 0 */ + qcom,cam-gmsl-sensor4 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <4>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor4_ep: endpoint { + remote-endpoint = <&deser1_port0>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 1 */ + qcom,cam-gmsl-sensor5 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <5>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor5_ep: endpoint { + remote-endpoint = <&deser1_port1>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 2 */ + qcom,cam-gmsl-sensor6 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <6>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor6_ep: endpoint { + remote-endpoint = <&deser1_port2>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 3 */ + qcom,cam-gmsl-sensor7 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <7>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor7_ep: endpoint { + remote-endpoint = <&deser1_port3>; + }; + }; + }; +}; + +&cam_cci2 { + /* GMSL deserializer 2 */ + qcom,cam-gmsl-deserializer2 { + cell-index = <2>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 9 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET2"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser2_port0: endpoint { + remote-endpoint = <&gmsl_sensor8_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser2_port1: endpoint { + remote-endpoint = <&gmsl_sensor9_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser2_port2: endpoint { + remote-endpoint = <&gmsl_sensor10_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser2_port3: endpoint { + remote-endpoint = <&gmsl_sensor11_ep>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 0 */ + qcom,cam-gmsl-sensor8 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <8>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor8_ep: endpoint { + remote-endpoint = <&deser2_port0>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 1 */ + qcom,cam-gmsl-sensor9 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <9>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor9_ep: endpoint { + remote-endpoint = <&deser2_port1>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 2 */ + qcom,cam-gmsl-sensor10 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <10>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor10_ep: endpoint { + remote-endpoint = <&deser2_port2>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 3 */ + qcom,cam-gmsl-sensor11 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <11>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor11_ep: endpoint { + remote-endpoint = <&deser2_port3>; + }; + }; + }; +}; + +&cam_cci3 { + /* GMSL deserializer 3 */ + qcom,cam-gmsl-deserializer3 { + cell-index = <3>; + csiphy-sd-index = <3>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active>; + pinctrl-1 = <&cam_sensor_mclk3_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 10 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET3"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser3_port0: endpoint { + remote-endpoint = <&gmsl_sensor12_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser3_port1: endpoint { + remote-endpoint = <&gmsl_sensor13_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser3_port2: endpoint { + remote-endpoint = <&gmsl_sensor14_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser3_port3: endpoint { + remote-endpoint = <&gmsl_sensor15_ep>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 0 */ + qcom,cam-gmsl-sensor12 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <12>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor12_ep: endpoint { + remote-endpoint = <&deser3_port0>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 1 */ + qcom,cam-gmsl-sensor13 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <13>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor13_ep: endpoint { + remote-endpoint = <&deser3_port1>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 2 */ + qcom,cam-gmsl-sensor14 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <14>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor14_ep: endpoint { + remote-endpoint = <&deser3_port2>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 3 */ + qcom,cam-gmsl-sensor15 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <15>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor15_ep: endpoint { + remote-endpoint = <&deser3_port3>; + }; + }; + }; +}; + +&soc { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + gpios-shared = <518 519 520 521>; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi new file mode 100644 index 0000000000000..18d78926b1f17 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi @@ -0,0 +1,2559 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&soc { + cam_cci0: qcom,cci0@ac13000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac13000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x13000>; + interrupts = ; + interrupt-names = "CCI0"; + operating-points-v2 = <&cci0_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>, + <&camcc CAM_CC_CCI_0_CLK>; + clock-names = "cci_0_clk_src", + "cci_0_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_0_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci0_active>; + pinctrl-1 = <&cci0_suspend>; + pinctrl-2 = <&cci1_active>; + pinctrl-3 = <&cci1_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <0>; + status = "ok"; + + cci0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci0: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci0: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci0: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci0: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_cci1: qcom,cci1@ac14000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac14000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x14000>; + interrupts = ; + interrupt-names = "CCI1"; + operating-points-v2 = <&cci1_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>, + <&camcc CAM_CC_CCI_1_CLK>; + clock-names = "cci_1_clk_src", + "cci_1_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_1_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci2_active>; + pinctrl-1 = <&cci2_suspend>; + pinctrl-2 = <&cci3_active>; + pinctrl-3 = <&cci3_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <1>; + status = "ok"; + + cci1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci1: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci1: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci1: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci1: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_cci2: qcom,cci2@ac15000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac15000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x15000>; + interrupts = ; + interrupt-names = "CCI2"; + operating-points-v2 = <&cci2_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_2_CLK_SRC>, + <&camcc CAM_CC_CCI_2_CLK>; + clock-names = "cci_2_clk_src", + "cci_2_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_2_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci4_active>; + pinctrl-1 = <&cci4_suspend>; + pinctrl-2 = <&cci5_active>; + pinctrl-3 = <&cci5_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <2>; + status = "ok"; + + cci2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci2: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci2: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci2: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci2: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_cci3: qcom,cci3@ac16000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac16000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x16000>; + interrupts = ; + interrupt-names = "CCI3"; + operating-points-v2 = <&cci3_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_3_CLK_SRC>, + <&camcc CAM_CC_CCI_3_CLK>; + clock-names = "cci_3_clk_src", + "cci_3_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_3_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci6_active>; + pinctrl-1 = <&cci6_suspend>; + pinctrl-2 = <&cci7_active>; + pinctrl-3 = <&cci7_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <3>; + status = "ok"; + + cci3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci3: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci3: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci3: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci3: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_csiphy0: qcom,csiphy0@ac9c000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0x0ac9c000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy0_opp_table>; + reg-cam-base = <0x9c000>; + interrupts = ; + interrupt-names = "CSIPHY0"; + csi-vdd-1p2-supply = <&vreg_l1c>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1140000 831000>; + rgltr-max-voltage = <1260000 920000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy0_clk", + "csi0phytimer_clk_src", + "csi0phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + aggregator-rx; + cell-index = <0>; + status = "ok"; + + csiphy0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy1: qcom,csiphy1@ac9e000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0xac9e000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy1_opp_table>; + reg-cam-base = <0x9e000>; + interrupts = ; + interrupt-names = "CSIPHY1"; + csi-vdd-1p2-supply = <&vreg_l1c>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1140000 831000>; + rgltr-max-voltage = <1260000 920000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy1_clk", + "csi1phytimer_clk_src", + "csi1phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + cell-index = <1>; + aggregator-rx; + status = "ok"; + + csiphy1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy2: qcom,csiphy2@aca0000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0xaca0000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy2_opp_table>; + reg-cam-base = <0xa0000>; + interrupts = ; + interrupt-names = "CSIPHY2"; + csi-vdd-1p2-supply = <&vreg_l1c>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1140000 831000>; + rgltr-max-voltage = <1260000 920000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy2_clk", + "csi2phytimer_clk_src", + "csi2phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + cell-index = <2>; + aggregator-rx; + status = "ok"; + + csiphy2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy3: qcom,csiphy3@aca2000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0xaca2000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy3_opp_table>; + reg-cam-base = <0xa2000>; + interrupts = ; + interrupt-names = "CSIPHY3"; + csi-vdd-1p2-supply = <&vreg_l1c>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1140000 831000>; + rgltr-max-voltage = <1260000 920000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY3_CLK>, + <&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI3PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy3_clk", + "csi3phytimer_clk_src", + "csi3phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + cell-index = <3>; + aggregator-rx; + status = "ok"; + + csiphy3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy_tpg17: qcom,tpg17@acac000 { + compatible = "qcom,cam-tpg1031"; + reg = <0x0 0xacac000 0x0 0x400>, + <0x0 0xac11000 0x0 0x1000>; + reg-names = "tpg0", "cam_cpas_top"; + reg-cam-base = <0xac000 0x11000>; + operating-points-v2 = <&csiphy_tpg0_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + interrupts = ; + interrupt-names = "tpg0"; + shared-clks = <1 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cphy_rx_clk_src", + "csid_csiphy_rx_clk"; + clock-rates = <400000000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cphy_rx_clk_src"; + cell-index = <17>; + phy-id = <0>; + status = "ok"; + + csiphy_tpg0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy_tpg18: qcom,tpg18@acad000 { + compatible = "qcom,cam-tpg1031"; + reg = <0x0 0xacad000 0x0 0x400>, + <0x0 0xac11000 0x0 0x1000>; + reg-names = "tpg1", "cam_cpas_top"; + reg-cam-base = <0xad000 0x11000>; + operating-points-v2 = <&csiphy_tpg1_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + interrupts = ; + interrupt-names = "tpg1"; + shared-clks = <1 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cphy_rx_clk_src", + "csid_csiphy_rx_clk"; + clock-rates = <400000000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cphy_rx_clk_src"; + cell-index = <18>; + phy-id = <1>; + status = "ok"; + + csiphy_tpg1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy_tpg19: qcom,tpg19@acae000 { + compatible = "qcom,cam-tpg1031"; + reg = <0x0 0xacae000 0x0 0x400>, + <0x0 0xac11000 0x0 0x1000>; + reg-names = "tpg2", "cam_cpas_top"; + reg-cam-base = <0xae000 0x11000>; + operating-points-v2 = <&csiphy_tpg2_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + interrupts = ; + interrupt-names = "tpg2"; + shared-clks = <1 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cphy_rx_clk_src", + "csid_csiphy_rx_clk"; + clock-rates = <400000000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cphy_rx_clk_src"; + cell-index = <19>; + phy-id = <2>; + status = "ok"; + + csiphy_tpg2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,cam-cdm-intf { + compatible = "qcom,cam-cdm-intf"; + cell-index = <0>; + label = "cam-cdm-intf"; + num-hw-cdm = <1>; + cdm-client-names = "vfe"; + status = "ok"; + }; + + qcom,cam-cpas { + compatible = "qcom,cam-cpas"; + label = "cpas"; + arch-compat = "cpas_top"; + reg = <0x0 0xac11000 0x0 0x1000>, + <0x0 0xac1A000 0x0 0x9400>, + <0x0 0xbbf0000 0x0 0x1f00>; + reg-names = "cam_cpas_top", "cam_camnoc", "cam_rpmh"; + reg-cam-base = <0x11000 0x1A000 0x0bbf0000>; + interrupts = ; + interrupt-names = "cpas_camnoc"; + camnoc-axi-min-ib-bw = <3000000000>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&gcc GCC_CAMERA_SF_AXI_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CORE_AHB_CLK>, + <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_FAST_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "gcc_camera_sf_axi_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk", + "cam_cc_core_ahb_clk", + "cam_cc_fast_ahb_clk_src", + "cam_cc_cpas_fast_ahb_clk", + "cam_cc_camnoc_axi_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_qdss_debug_xo_clk"; + src-clock-name = "cam_cc_fast_ahb_clk_src"; + clock-rates = <0 0 0 0 0 0 0 0 0 0 0>, + <0 0 0 80000000 0 0 300000000 0 400000000 0 0>, + <0 0 0 80000000 0 0 400000000 0 400000000 0 0>; + clock-cntl-level = "suspend", "svs_l1", "nominal"; + clock-names-option = "cam_icp_clk"; + clocks-option = <&camcc CAM_CC_ICP_CLK>; + clock-rates-option = <480000000>; + operating-points-v2 = <&cpas_opp_table>; + control-camnoc-axi-clk; + camnoc-bus-width = <32>; + camnoc-axi-clk-bw-margin-perc = <20>; + cam-icc-path-names = "cam_ahb"; + interconnects = <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_CAMERA_CFG 0>, + <&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>, + <&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI1 0>, + <&mmss_noc MASTER_CAMNOC_ICP 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp"; + cam-ahb-num-cases = <7>; + cam-ahb-bw-KBps = <0 0>, <0 76800>, <0 150000>, <0 150000>, + <0 300000>, <0 300000>, <0 300000>; + vdd-corners = ; + vdd-corner-ahb-mapping = "suspend", "lowsvs", "lowsvs", "svs", "svs_l1", + "nominal", "nominal", "nominal", "turbo", "turbo"; + client-id-based; + client-names = "csiphy0", "csiphy1", "csiphy2", "csiphy3", + "cci0", "cci1", "cci2", "cci3","csid0", "csid1", + "csid2", "csid3", "csid4", "csid5", "csid6", + "ife0", "ife1", "ife2", "ife3", "ife4", + "ife5", "ife6", "ipe0", "sfe0", "sfe1", + "cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2", + "rt-cdm3", "icp0", "tpg17", "tpg18", "tpg19"; + + enable-secure-qos-update; + cell-index = <0>; + status = "ok"; + + cpas_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + + camera-bus-nodes { + level0-nodes { + level-index = <0>; + + icp_all_rd: icp-all-rd { + cell-index = <0>; + node-name = "icp-all-rd"; + client-name = "icp0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level2_icp_rd>; + }; + + ife_0_wr_0: ife-0-wr-0 { + cell-index = <1>; + node-name = "ife-0-wr-0"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_0_wr_1: ife-0-wr-1 { + cell-index = <2>; + node-name = "ife-0-wr-1"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr1>; + }; + + ife_1_wr_0: ife-1-wr-0 { + cell-index = <3>; + node-name = "ife-1-wr-0"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + + ife_1_wr_1: ife-1-wr-1 { + cell-index = <4>; + node-name = "ife-1-wr-1"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr1>; + }; + + ife_lite_0_wr_0: ife-lite-0-wr-0 { + cell-index = <5>; + node-name = "ife-lite-0-wr-0"; + client-name = "ife2"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_1_wr_0: ife-lite-1-wr-0 { + cell-index = <6>; + node-name = "ife-lite-1-wr-0"; + client-name = "ife3"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_2_wr_0: ife-lite-2-wr-0 { + cell-index = <7>; + node-name = "ife-lite-2-wr-0"; + client-name = "ife4"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_3_wr_0: ife-lite-3-wr-0 { + cell-index = <8>; + node-name = "ife-lite-3-wr-0"; + client-name = "ife5"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_4_wr_0: ife-lite-4-wr-0 { + cell-index = <9>; + node-name = "ife-lite-4-wr-0"; + client-name = "ife6"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ipe_0_rd_all: ipe-0-rd-all { + cell-index = <10>; + node-name = "ipe-0-rd-all"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level2_nrt_rd1>; + }; + + ipe_0_wr_2: ipe-0-wr-2 { + cell-index = <11>; + node-name = "ipe-0-wr-2"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level2_nrt_wr2>; + }; + + ipe_cdm0_all_rd: ipe-cdm0-all-rd { + cell-index = <12>; + node-name = "ipe-cdm0-all-rd"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 { + cell-index = <13>; + node-name = "rt-cdm0-all-rd-2"; + client-name = "rt-cdm0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 { + cell-index = <14>; + node-name = "rt-cdm1-all-rd-2"; + client-name = "rt-cdm1"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 { + cell-index = <15>; + node-name = "rt-cdm2-all-rd-2"; + client-name = "rt-cdm2"; + traffic-data = ; + traffic-transaction-type = + ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 { + cell-index = <16>; + node-name = "rt-cdm3-all-rd-2"; + client-name = "rt-cdm3"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + sfe_0_rd_0: sfe-0-rd-0 { + cell-index = <17>; + node-name = "sfe-0-rd-0"; + client-name = "sfe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_rd0>; + }; + + sfe_1_rd_0: sfe-1-rd-0 { + cell-index = <18>; + node-name = "sfe-1-rd-0"; + client-name = "sfe1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_rd0>; + }; + }; + + level1-nodes { + level-index = <1>; + camnoc-max-needed; + + level1_nrt_rd2: level1-nrt-rd2 { + cell-index = <19>; + node-name = "level1-nrt-rd2"; + parent-node = <&level2_nrt_rd2>; + traffic-merge-type = ; + }; + + level1_rt_rd0: level1-rt-read0 { + cell-index = <20>; + node-name = "level1-rt-rd0"; + parent-node = <&level2_rt_rd0>; + traffic-merge-type = ; + }; + + level1_rt_wr0: level1-rt-wr0 { + cell-index = <21>; + node-name = "level1-rt-wr0"; + parent-node = <&level2_rt_wr0>; + traffic-merge-type = ; + }; + + level1_rt_wr1: level1-rt-wr1 { + cell-index = <22>; + node-name = "level1-rt-wr1"; + parent-node = <&level2_rt_wr1>; + traffic-merge-type = ; + }; + }; + + level2-nodes { + level-index = <2>; + camnoc-max-needed; + + level2_icp_rd: level2-icp-rd { + cell-index = <23>; + node-name = "level2-icp-rd"; + parent-node = <&level3_nrt1_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt_rd1: level2-nrt-rd1 { + cell-index = <24>; + node-name = "level2-nrt-rd1"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt_rd2: level2-nrt-rd2 { + cell-index = <25>; + node-name = "level2-nrt-rd2"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt_wr2: level2-nrt-wr2 { + cell-index = <26>; + node-name = "level2-nrt-wr2"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt_rd0: level2-rt-read0 { + cell-index = <27>; + node-name = "level2-rt-rd0"; + parent-node = <&level3_rt_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt_wr0: level2-rt-wr0 { + cell-index = <28>; + node-name = "level2-rt-wr0"; + parent-node = <&level3_rt_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt_wr1: level2-rt-wr1 { + cell-index = <29>; + node-name = "level2-rt-wr1"; + parent-node = <&level3_rt_rd_wr_sum>; + traffic-merge-type = ; + }; + }; + + level3-nodes { + level-index = <3>; + + level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum { + cell-index = <30>; + node-name = "level3-nrt0-rd-wr-sum"; + traffic-merge-type = + ; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_sf_0"; + }; + }; + + level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum { + cell-index = <31>; + node-name = "level3-nrt1-rd-wr-sum"; + traffic-merge-type = + ; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_sf_icp"; + }; + }; + + level3_rt_rd_wr_sum: level3-rt-rd-wr-sum { + cell-index = <32>; + node-name = "level3-rt-rd-wr-sum"; + traffic-merge-type = + ; + ib-bw-voting-needed; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_hf_0"; + }; + }; + }; + }; + }; + + qcom,cam-icp { + compatible = "qcom,cam-icp"; + compat-hw-name = "qcom,icp", "qcom,ipe0"; + num-icp = <1>; + num-ipe = <1>; + icp_use_pil; + status = "ok"; + }; + + qcom,cam-i3c-id-table { + i3c-sensor-id-table = <0x1B0 0x0766>; + i3c-eeprom-id-table = <>; + i3c-actuator-id-table = <>; + i3c-ois-id-table = <>; + status = "disabled"; + }; + + qcom,cam-isp { + compatible = "qcom,cam-isp"; + arch-compat = "ife"; + status = "ok"; + }; + + qcom,cam-req-mgr { + compatible = "qcom,cam-req-mgr"; + status = "ok"; + }; + + qcom,cam-sync { + compatible = "qcom,cam-sync"; + status = "ok"; + }; + + qcom,cam-smmu { + compatible = "qcom,msm-cam-smmu", "simple-bus"; + force_cache_allocs; + status = "ok"; + + msm-cam-smmu-cdm { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0860 0x400>, + <&apps_smmu 0x0C60 0x400>; + cam-smmu-label = "rt-cdm"; + dma-coherent; + multiple-client-devices; + + rt_cdm_iova_mem_map: iova-mem-map { + iova-mem-region-io { + /* IO region is approximately 4.0 GB */ + iova-region-name = "io"; + /* 1 MB pad for start */ + iova-region-start = <0x100000>; + /* 1 MB pad for end */ + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-icp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0800 0x400>, + <&apps_smmu 0x0840 0x480>, + <&apps_smmu 0x08C0 0x480>, + <&apps_smmu 0x0C00 0x400>, + <&apps_smmu 0x0C40 0x480>, + <&apps_smmu 0x0CC0 0x480>; + cam-smmu-label = "icp"; + qcom,iommu-faults = "stall-disable", "non-fatal"; + iova-region-discard = <0xe0000000 0x800000>; + dma-coherent; + + icp_iova_mem_map: iova-mem-map { + iova-mem-region-fwuncached-region { + /* FW uncached region is 7MB long */ + iova-region-name = "fw_uncached"; + iova-region-start = <0x10400000>; + iova-region-len = <0x700000>; + iova-region-id = <0x6>; + subregion_support; + status = "ok"; + + /* Used for HFI queues/sec heap */ + iova-mem-region-generic-region { + iova-region-name = "icp_hfi"; + iova-region-start = <0x10400000>; + iova-region-len = <0x200000>; + iova-region-id = <0x0>; + }; + }; + + iova-mem-region-io { + /* IO region is approximately 3.8 GB */ + iova-region-name = "io"; + iova-region-start = <0x10c00000>; + iova-region-len = <0xee300000>; + iova-region-id = <0x3>; + iova-region-discard = <0xe0000000 0x800000>; + status = "ok"; + }; + + iova-mem-region-qdss { + /* QDSS region is appropriate 1MB */ + iova-region-name = "qdss"; + iova-region-start = <0x10b00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x5>; + qdss-phy-addr = <0x16790000>; + status = "ok"; + }; + + iova-mem-region-shared { + /* Shared region is ~250MB long */ + iova-region-name = "shared"; + iova-region-start = <0x800000>; + iova-region-len = <0xfc00000>; + iova-region-id = <0x1>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-ife { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x3400 0x0020>, + <&apps_smmu 0x3420 0x0020>; + cam-smmu-label = "ife", "sfe"; + multiple-client-devices; + dma-coherent; + + ife_iova_mem_map: iova-mem-map { + /* IO region is approximately 64 GB */ + iova-mem-region-io { + iova-region-name = "io"; + /* start address: 0x100000 */ + /* leaving 1 MB pad at start */ + iova-region-start = <0x100000>; + /* Length: 0xfffe00000 */ + /* leaving 1 MB pad at end */ + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-secure { + compatible = "qcom,msm-cam-smmu-cb"; + cam-smmu-label = "cam-secure"; + qcom,secure-cb; + }; + }; + + qcom,camera-main { + compatible = "qcom,camera"; + status = "ok"; + }; + + cam_csid0: qcom,csid0 { + compatible = "qcom,csid690"; + reg = <0x0 0xac7a000 0x0 0xf01>, + <0x0 0xac78000 0x0 0x1000>; + reg-names = "csid0", "csid_top"; + reg-cam-base = <0x7a000 0x78000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "csid0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CSID_CLK_SRC>, + <&camcc CAM_CC_CSID_CLK>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cam_cc_csid_clk_src", + "cam_cc_csid_clk", + "cam_cc_csid_csiphy_rx_clk"; + clock-rates = <400000000 0 0>; + clock-cntl-level = "svs_l1"; + src-clock-name = "cam_cc_csid_clk_src"; + operating-points-v2 = <&csid0_opp_table>; + clock-control-debugfs = "true"; + cell-index = <0>; + status = "ok"; + + csid0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + cam_csid1: qcom,csid1 { + compatible = "qcom,csid690"; + reg = <0x0 0xac7c000 0x0 0xf01>, + <0x0 0xac78000 0x0 0x1000>; + reg-names = "csid1", "csid_top"; + reg-cam-base = <0x7c000 0x78000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "csid0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CSID_CLK_SRC>, + <&camcc CAM_CC_CSID_CLK>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cam_cc_csid_clk_src", + "cam_cc_csid_clk", + "cam_cc_csid_csiphy_rx_clk"; + clock-rates = <400000000 0 0>; + clock-cntl-level = "svs_l1"; + src-clock-name = "cam_cc_csid_clk_src"; + operating-points-v2 = <&csid1_opp_table>; + clock-control-debugfs = "true"; + cell-index = <1>; + status = "ok"; + + csid1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + cam_csid_lite0: qcom,csid-lite0 { + compatible = "qcom,csid-lite690"; + reg = <0x0 0xac84000 0x0 0xf01>; + reg-names = "csid-lite0"; + reg-cam-base = <0x84000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite0_opp_table>; + clock-control-debugfs = "true"; + cell-index = <2>; + status = "ok"; + + csid_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite1: qcom,csid-lite1 { + compatible = "qcom,csid-lite690"; + reg = <0x0 0xac88000 0x0 0xf01>; + reg-names = "csid-lite1"; + reg-cam-base = <0x88000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite1_opp_table>; + clock-control-debugfs = "true"; + cell-index = <3>; + status = "ok"; + + csid_lite1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite2: qcom,csid-lite2 { + compatible = "qcom,csid-lite690"; + reg = <0x0 0xac8c000 0x0 0xf01>; + reg-names = "csid-lite2"; + reg-cam-base = <0x8c000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite2"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite2_opp_table>; + clock-control-debugfs = "true"; + cell-index = <4>; + status = "ok"; + + csid_lite2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite3: qcom,csid-lite3 { + compatible = "qcom,csid-lite690"; + reg = <0x0 0xac90000 0x0 0xf01>; + reg-names = "csid-lite3"; + reg-cam-base = <0x90000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite3"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite3_opp_table>; + clock-control-debugfs = "true"; + cell-index = <5>; + status = "ok"; + + csid_lite3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite4: qcom,csid-lite4 { + compatible = "qcom,csid-lite690"; + reg = <0x0 0xac94000 0x0 0xf01>; + reg-names = "csid-lite4"; + reg-cam-base = <0x94000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite4"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite4_opp_table>; + clock-control-debugfs = "true"; + cell-index = <6>; + status = "ok"; + + csid_lite4_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_icp: qcom,icp { + compatible = "qcom,cam-icp_v3_0"; + reg = <0x0 0xac01000 0x0 0x400>, + <0x0 0xac01800 0x0 0x400>, + <0x0 0xac04000 0x0 0x1000>; + reg-names ="icp_csr", "icp_cirq", "icp_wd0"; + reg-cam-base = <0x1000 0x1800 0x4000>; + interrupts = ; + interrupt-names = "icp"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + memory-region = <&pil_camera_mem>; + src-clock-name = "cam_cc_icp_clk_src"; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_ICP_AHB_CLK>, + <&camcc CAM_CC_ICP_CLK_SRC>, + <&camcc CAM_CC_ICP_CLK>; + clock-names = "cam_cc_soc_fast_ahb_clk_src", + "cam_cc_icp_ahb_clk", + "cam_cc_icp_clk_src", + "cam_cc_icp_clk"; + clock-rates = <300000000 0 480000000 0>, + <400000000 0 600000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + nrt-device; + fw_name = "CAMERA_ICP"; + ubwc-ipe-fetch-cfg = <0x707b 0x7083>; + ubwc-ipe-write-cfg = <0x161ef 0x1620f>; + qos-val = <0xa0a>; + operating-points-v2 = <&icp_opp_table>; + icp-version = <0x0300>; + cam_hw_pid = <12>; + cell-index = <0>; + status = "ok"; + + icp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe0: qcom,ife0 { + compatible = "qcom,vfe690"; + reg = <0x0 0xac4d000 0x0 0xd000>, + <0x0 0xac1a000 0x0 0x9400>; + reg-names = "ife0", "cam_camnoc"; + reg-cam-base = <0x4d000 0x1a000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "ife0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_CLK_SRC>, + <&camcc CAM_CC_IFE_0_FAST_AHB_CLK>; + clock-names = "cam_cc_cpas_ife_0_clk", + "cam_cc_ife_0_clk", + "cam_cc_ife_0_clk_src", + "cam_cc_ife_0_fast_ahb_clk"; + clock-rates = <0 0 480000000 0>, + <0 0 600000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_0_clk_src"; + operating-points-v2 = <&vfe0_opp_table>; + clock-control-debugfs = "true"; + ubwc-static-cfg = <0x1026 0x1036>; + cam_hw_pid = <8 16>; + cell-index = <0>; + status = "ok"; + + vfe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe1: qcom,ife1 { + compatible = "qcom,vfe690"; + reg = <0x0 0xac5a000 0x0 0xd000>, + <0x0 0xac1a000 0x0 0x9400>; + reg-names = "ife1", "cam_camnoc"; + reg-cam-base = <0x5a000 0x1a000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "ife1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_CLK_SRC>, + <&camcc CAM_CC_IFE_1_FAST_AHB_CLK>; + clock-names = "cam_cc_cpas_ife_1_clk", + "cam_cc_ife_1_clk", + "cam_cc_ife_1_clk_src", + "cam_cc_ife_1_fast_ahb_clk"; + clock-rates = <0 0 480000000 0>, + <0 0 600000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_1_clk_src"; + operating-points-v2 = <&vfe1_opp_table>; + clock-control-debugfs = "true"; + ubwc-static-cfg = <0x1026 0x1036>; + cam_hw_pid = <9 17>; + cell-index = <1>; + status = "ok"; + + vfe1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite0: qcom,ife-lite0 { + compatible = "qcom,vfe-lite690"; + reg = <0x0 0xac84000 0x0 0x1d00>; + reg-names = "ife-lite0"; + reg-cam-base = <0x84000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite0_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <2>; + status = "ok"; + + vfe_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite1: qcom,ife-lite1 { + compatible = "qcom,vfe-lite690"; + reg = <0x0 0xac88000 0x0 0x1d00>; + reg-names = "ife-lite1"; + reg-cam-base = <0x88000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite1_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <3>; + status = "ok"; + + vfe_lite1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite2: qcom,ife-lite2 { + compatible = "qcom,vfe-lite690"; + reg = <0x0 0xac8c000 0x0 0x1d00>; + reg-names = "ife-lite2"; + reg-cam-base = <0x8c000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite2"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite2_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <4>; + status = "ok"; + + vfe_lite2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite3: qcom,ife-lite3 { + compatible = "qcom,vfe-lite690"; + reg = <0x0 0xac90000 0x0 0x1d00>; + reg-names = "ife-lite3"; + reg-cam-base = <0x90000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite3"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite3_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <5>; + status = "ok"; + + vfe_lite3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite4: qcom,ife-lite4 { + compatible = "qcom,vfe-lite690"; + reg = <0x0 0xac94000 0x0 0x1d00>; + reg-names = "ife-lite4"; + reg-cam-base = <0x94000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite4"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite4_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <6>; + status = "ok"; + + vfe_lite4_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_ipe0: qcom,ipe0 { + compatible = "qcom,cam-ipe"; + reg = <0x0 0xac2d000 0x0 0x18000>; + reg-names = "ipe0_top"; + reg-cam-base = <0x2d000>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + src-clock-name = "cam_cc_ipe_clk_src"; + clocks = <&camcc CAM_CC_CPAS_IPE_CLK>, + <&camcc CAM_CC_IPE_AHB_CLK>, + <&camcc CAM_CC_IPE_CLK>, + <&camcc CAM_CC_IPE_CLK_SRC>, + <&camcc CAM_CC_IPE_FAST_AHB_CLK>, + <&camcc CAM_CC_FAST_AHB_CLK_SRC>; + clock-names = "cam_cc_cpas_ipe_clk", + "cam_cc_ipe_ahb_clk", + "cam_cc_ipe_clk", + "cam_cc_ipe_clk_src", + "cam_cc_ipe_fast_ahb_clk", + "cam_cc_fast_ahb_clk_src"; + clock-rates = <0 0 0 480000000 0 300000000>, + <0 0 0 600000000 0 400000000>; + clock-cntl-level = "svs_l1", "nominal"; + operating-points-v2 = <&ipe0_opp_table>; + nrt-device; + cam_hw_pid = <14 15>; + cell-index = <0>; + status = "ok"; + + ipe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + + }; + + qcom,rt-cdm0 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac26000 0x0 0x1000>; + reg-names = "rt-cdm0"; + reg-cam-base = <0x26000>; + interrupts = ; + interrupt-names = "rt-cdm0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_fast_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_fast_ahb_clk_src"; + clock-rates = <300000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table0>; + clock-cntl-level = "svs"; + cdm-client-names = "ife0", "dualife0"; + single-context-cdm; + cell-index = <0>; + status = "ok"; + + cdm_cpas_opp_table0: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,rt-cdm1 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac27000 0x0 0x1000>; + reg-names = "rt-cdm1"; + reg-cam-base = <0x27000>; + interrupts = ; + interrupt-names = "rt-cdm1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_fast_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_fast_ahb_clk_src"; + clock-rates = <300000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table1>; + clock-cntl-level = "svs_l1"; + cdm-client-names = "ife1", "dualife1"; + single-context-cdm; + cell-index = <1>; + status = "ok"; + + cdm_cpas_opp_table1: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,rt-cdm2 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac28000 0x0 0x1000>; + reg-names = "rt-cdm2"; + reg-cam-base = <0x28000>; + interrupts = ; + interrupt-names = "rt-cdm2"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_slow_ahb_clk_src"; + clock-rates = <80000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table2>; + clock-cntl-level = "svs_l1"; + cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6"; + single-context-cdm; + cell-index = <2>; + status = "ok"; + + cdm_cpas_opp_table2: opp-table { + compatible = "operating-points-v2"; + + opp-80000000 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,rt-cdm3 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac29000 0x0 0x1000>; + reg-names = "rt-cdm3"; + reg-cam-base = <0x29000>; + interrupts = ; + interrupt-names = "rt-cdm3"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_slow_ahb_clk_src"; + clock-rates = <80000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table3>; + clock-cntl-level = "svs"; + cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6"; + single-context-cdm; + cell-index = <3>; + status = "ok"; + + cdm_cpas_opp_table3: opp-table { + compatible = "operating-points-v2"; + + opp-80000000 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_sfe_lite0: qcom,sfe-lite0 { + compatible = "qcom,sfe-lite690"; + reg = <0x0 0xac74000 0x0 0x1000>; + reg-names = "sfe-lite0"; + reg-cam-base = <0x74000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "sfe-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clock-names = "cam_cc_sfe_lite_0_fast_ahb_clk", + "cam_cc_sfe_lite_0_clk", + "cam_cc_cpas_sfe_lite_0_clk"; + clocks = <&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>, + <&camcc CAM_CC_SFE_LITE_0_CLK>, + <&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>; + clock-rates = <0 480000000 300000000>, + <0 600000000 400000000>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_sfe_lite_0_clk"; + operating-points-v2 = <&cam_sfe_lite_opp_table0>; + cam_hw_pid = <4>; + clock-control-debugfs = "true"; + cell-index = <0>; + status = "ok"; + + cam_sfe_lite_opp_table0: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_sfe_lite1: qcom,sfe-lite1 { + compatible = "qcom,sfe-lite690"; + reg = <0x0 0xac75000 0x0 0x1000>; + reg-names = "sfe-lite1"; + reg-cam-base = <0x75000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "sfe-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SFE_LITE_1_FAST_AHB_CLK>, + <&camcc CAM_CC_SFE_LITE_1_CLK>, + <&camcc CAM_CC_CPAS_SFE_LITE_1_CLK>; + clock-names = "cam_cc_sfe_lite_1_fast_ahb_clk", + "cam_cc_sfe_lite_1_clk", + "cam_cc_cpas_sfe_1_clk"; + clock-rates = <0 480000000 300000000>, + <0 600000000 400000000>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_sfe_lite_1_clk"; + operating-points-v2 = <&cam_sfe_lite_opp_table1>; + cam_hw_pid = <5>; + clock-control-debugfs = "true"; + cell-index = <1>; + status = "ok"; + + cam_sfe_lite_opp_table1: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; +}; + +&tlmm { + cam_sensor_mclk0_active: cam-sensor-mclk0-active { + /* MCLK0 */ + mux { + pins = "gpio72"; + function = "cam_mclk"; + }; + + config { + pins = "gpio72"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk0_suspend: cam-sensor-mclk0-suspend { + /* MCLK0 */ + mux { + pins = "gpio72"; + function = "cam_mclk"; + }; + + config { + pins = "gpio72"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk1_active: cam-sensor-mclk1-active { + /* MCLK1 */ + mux { + pins = "gpio73"; + function = "cam_mclk"; + }; + + config { + pins = "gpio73"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk1_suspend: cam-sensor-mclk1-suspend { + /* MCLK1 */ + mux { + pins = "gpio73"; + function = "cam_mclk"; + }; + + config { + pins = "gpio73"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_active: cam-sensor-mclk2-active { + /* MCLK2 */ + mux { + pins = "gpio74"; + function = "cam_mclk"; + }; + + config { + pins = "gpio74"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_suspend: cam-sensor-mclk2-suspend { + /* MCLK2 */ + mux { + pins = "gpio74"; + function = "cam_mclk"; + }; + + config { + pins = "gpio74"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_active: cam-sensor-mclk3-active { + /* MCLK3 */ + mux { + pins = "gpio75"; + function = "cam_mclk"; + }; + + config { + pins = "gpio75"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_suspend: cam-sensor-mclk3-suspend { + /* MCLK3 */ + mux { + pins = "gpio75"; + function = "cam_mclk"; + }; + + config { + pins = "gpio75"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci0_active: cci0-active { + mux { + /* CLK, DATA */ + pins = "gpio61","gpio60"; + function = "cci_i2c"; + }; + + config { + pins = "gpio61","gpio60"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci0_suspend: cci0-suspend { + mux { + /* CLK, DATA */ + pins = "gpio61","gpio60"; + function = "cci_i2c"; + }; + + config { + pins = "gpio61","gpio60"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci1_active: cci1-active { + mux { + /* CLK, DATA */ + pins = "gpio53","gpio52"; + function = "cci_i2c"; + }; + + config { + pins = "gpio53","gpio52"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci1_suspend: cci1-suspend { + mux { + /* CLK, DATA */ + pins = "gpio53","gpio52"; + function = "cci_i2c"; + }; + + config { + pins = "gpio53","gpio52"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci2_active: cci2-active { + mux { + /* CLK, DATA */ + pins = "gpio63","gpio62"; + function = "cci_i2c"; + }; + + config { + pins = "gpio63","gpio62"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci2_suspend: cci2-suspend { + mux { + /* CLK, DATA */ + pins = "gpio63","gpio62"; + function = "cci_i2c"; + }; + + config { + pins = "gpio63","gpio62"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci3_active: cci3-active { + mux { + /* CLK, DATA */ + pins = "gpio55","gpio54"; + function = "cci_i2c"; + }; + + config { + pins = "gpio55","gpio54"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci3_suspend: cci3-suspend { + mux { + /* CLK, DATA */ + pins = "gpio55","gpio54"; + function = "cci_i2c"; + }; + + config { + pins = "gpio55","gpio54"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci4_active: cci4-active { + mux { + /* CLK, DATA */ + pins = "gpio65","gpio64"; + function = "cci_i2c"; + }; + + config { + pins = "gpio65","gpio64"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci4_suspend: cci4-suspend { + mux { + /* CLK, DATA */ + pins = "gpio65","gpio64"; + function = "cci_i2c"; + }; + + config { + pins = "gpio65","gpio64"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci5_active: cci5-active { + mux { + /* CLK, DATA */ + pins = "gpio57","gpio56"; + function = "cci_i2c"; + }; + + config { + pins = "gpio57","gpio56"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci5_suspend: cci5-suspend { + mux { + /* CLK, DATA */ + pins = "gpio57","gpio56"; + function = "cci_i2c"; + }; + + config { + pins = "gpio57","gpio56"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci6_active: cci6-active { + mux { + /* CLK, DATA */ + pins = "gpio67","gpio66"; + function = "cci_i2c"; + }; + + config { + pins = "gpio67","gpio66"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci6_suspend: cci6-suspend { + mux { + /* CLK, DATA */ + pins = "gpio67","gpio66"; + function = "cci_i2c"; + }; + + config { + pins = "gpio67","gpio66"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci7_active: cci7-active { + mux { + /* CLK, DATA */ + pins = "gpio59","gpio58"; + function = "cci_i2c"; + }; + + config { + pins = "gpio59","gpio58"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; /* I2C PULL */ + }; + }; + + cci7_suspend: cci7-suspend { + mux { + /* CLK, DATA */ + pins = "gpio59","gpio58"; + function = "cci_i2c"; + }; + + config { + pins = "gpio59","gpio58"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi new file mode 100644 index 0000000000000..8eb1026e7da1b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi @@ -0,0 +1,736 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&cam_cci0 { + /* GMSL deserializer 0 */ + qcom,cam-gmsl-deserializer0 { + cell-index = <0>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 7 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser0_port0: endpoint { + remote-endpoint = <&gmsl_sensor0_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser0_port1: endpoint { + remote-endpoint = <&gmsl_sensor1_ep>; + }; + }; + + port@2 { + reg = <0>; + deser0_port2: endpoint { + remote-endpoint = <&gmsl_sensor2_ep>; + }; + }; + + port@3 { + reg = <1>; + deser0_port3: endpoint { + remote-endpoint = <&gmsl_sensor3_ep>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 0 */ + qcom,cam-gmsl-sensor0 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <0>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor0_ep: endpoint { + remote-endpoint = <&deser0_port0>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 1 */ + qcom,cam-gmsl-sensor1 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <1>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor1_ep: endpoint { + remote-endpoint = <&deser0_port1>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 2 */ + qcom,cam-gmsl-sensor2 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <2>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor2_ep: endpoint { + remote-endpoint = <&deser0_port2>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 3 */ + qcom,cam-gmsl-sensor3 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <3>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor3_ep: endpoint { + remote-endpoint = <&deser0_port3>; + }; + }; + }; + + /*cam0a-ov9282*/ + qcom,cam-sensor1 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 72 0>, + <&tlmm 132 0>, + <&pmm8654au_0_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <20>; + status = "ok"; + }; + + /*cam24-ov13858*/ + qcom,cam-sensor24 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam24>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 72 0>, + <&tlmm 132 0>, + <&pmm8654au_0_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <24>; + status = "ok"; + }; + + eeprom_cam24: qcom,eeprom24 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 72 0>, + <&tlmm 132 0>, + <&pmm8654au_0_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <24>; + status = "ok"; + }; +}; + +&cam_cci1 { + /* GMSL deserializer 1 */ + qcom,cam-gmsl-deserializer1 { + cell-index = <1>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 8 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser1_port0: endpoint { + remote-endpoint = <&gmsl_sensor4_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser1_port1: endpoint { + remote-endpoint = <&gmsl_sensor5_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser1_port2: endpoint { + remote-endpoint = <&gmsl_sensor6_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser1_port3: endpoint { + remote-endpoint = <&gmsl_sensor7_ep>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 0 */ + qcom,cam-gmsl-sensor4 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <4>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor4_ep: endpoint { + remote-endpoint = <&deser1_port0>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 1 */ + qcom,cam-gmsl-sensor5 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <5>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor5_ep: endpoint { + remote-endpoint = <&deser1_port1>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 2 */ + qcom,cam-gmsl-sensor6 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <6>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor6_ep: endpoint { + remote-endpoint = <&deser1_port2>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 3 */ + qcom,cam-gmsl-sensor7 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <7>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor7_ep: endpoint { + remote-endpoint = <&deser1_port3>; + }; + }; + }; + + /*cam1-ov9282*/ + qcom,cam-sensor21 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>, + <&tlmm 133 0>, + <&pmm8654au_0_gpios 8 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <21>; + status = "ok"; + }; +}; + +&cam_cci2 { + /* GMSL deserializer 2 */ + qcom,cam-gmsl-deserializer2 { + cell-index = <2>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 9 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET2"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser2_port0: endpoint { + remote-endpoint = <&gmsl_sensor8_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser2_port1: endpoint { + remote-endpoint = <&gmsl_sensor9_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser2_port2: endpoint { + remote-endpoint = <&gmsl_sensor10_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser2_port3: endpoint { + remote-endpoint = <&gmsl_sensor11_ep>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 0 */ + qcom,cam-gmsl-sensor8 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <8>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor8_ep: endpoint { + remote-endpoint = <&deser2_port0>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 1 */ + qcom,cam-gmsl-sensor9 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <9>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor9_ep: endpoint { + remote-endpoint = <&deser2_port1>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 2 */ + qcom,cam-gmsl-sensor10 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <10>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor10_ep: endpoint { + remote-endpoint = <&deser2_port2>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 3 */ + qcom,cam-gmsl-sensor11 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <11>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor11_ep: endpoint { + remote-endpoint = <&deser2_port3>; + }; + }; + }; + + /*cam2-ov9282*/ + qcom,cam-sensor22 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 74 0>, + <&tlmm 134 0>, + <&pmm8654au_0_gpios 9 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK2", + "CAMIF_RESET2", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <22>; + status = "ok"; + }; +}; + +&cam_cci3 { + /* GMSL deserializer 3 */ + qcom,cam-gmsl-deserializer3 { + cell-index = <3>; + csiphy-sd-index = <3>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active>; + pinctrl-1 = <&cam_sensor_mclk3_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&pmm8654au_0_gpios 10 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET3"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser3_port0: endpoint { + remote-endpoint = <&gmsl_sensor12_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser3_port1: endpoint { + remote-endpoint = <&gmsl_sensor13_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser3_port2: endpoint { + remote-endpoint = <&gmsl_sensor14_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser3_port3: endpoint { + remote-endpoint = <&gmsl_sensor15_ep>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 0 */ + qcom,cam-gmsl-sensor12 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <12>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor12_ep: endpoint { + remote-endpoint = <&deser3_port0>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 1 */ + qcom,cam-gmsl-sensor13 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <13>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor13_ep: endpoint { + remote-endpoint = <&deser3_port1>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 2 */ + qcom,cam-gmsl-sensor14 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <14>; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor14_ep: endpoint { + remote-endpoint = <&deser3_port2>; + }; + }; + }; + + /* GMSL deserializer 3 sensor 3 */ + qcom,cam-gmsl-sensor15 { + cell-index = <15>; + compatible = "qcom,cam-gmsl-sensor"; + csiphy-sd-index = <3>; + status = "ok"; + + port { + gmsl_sensor15_ep: endpoint { + remote-endpoint = <&deser3_port3>; + }; + }; + }; + + /*cam3-ov9282*/ + qcom,cam-sensor23 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <3>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst3>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst3>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 75 0>, + <&tlmm 135 0>, + <&pmm8654au_0_gpios 10 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK3", + "CAMIF_RESET3", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <23>; + status = "ok"; + }; +}; + +&soc { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + gpios-shared = <518 519 520 521>; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-camx.dtso b/arch/arm64/boot/dts/qcom/lemans-evk-camx.dtso new file mode 100644 index 0000000000000..520fb14660142 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-evk-camx.dtso @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "lemans-camera.dtsi" +#include "lemans-evk-camera-sensor.dtsi" + +&camss { + status = "disabled"; +}; + +&tlmm { + cam_sensor_active_rst0: cam-sensor-active-rst0 { + /* RESET */ + mux { + pins = "gpio132"; + function = "gpio"; + }; + + config { + pins = "gpio132"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst1: cam-sensor-active-rst1 { + /* RESET */ + mux { + pins = "gpio133"; + function = "gpio"; + }; + + config { + pins = "gpio133"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst2: cam-sensor-active-rst2 { + /* RESET */ + mux { + pins = "gpio134"; + function = "gpio"; + }; + + config { + pins = "gpio134"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst3: cam-sensor-active-rst3 { + /* RESET */ + mux { + pins = "gpio135"; + function = "gpio"; + }; + + config { + pins = "gpio135"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_rst0: cam-sensor-suspend-rst0 { + /* RESET */ + mux { + pins = "gpio132"; + function = "gpio"; + }; + + config { + pins = "gpio132"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst1: cam-sensor-suspend-rst1 { + /* RESET */ + mux { + pins = "gpio133"; + function = "gpio"; + }; + + config { + pins = "gpio133"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst2: cam-sensor-suspend-rst2 { + /* RESET */ + mux { + pins = "gpio134"; + function = "gpio"; + }; + + config { + pins = "gpio134"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst3: cam-sensor-suspend-rst3 { + /* RESET */ + mux { + pins = "gpio135"; + function = "gpio"; + }; + + config { + pins = "gpio135"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride-camx.dtso b/arch/arm64/boot/dts/qcom/sa8775p-ride-camx.dtso new file mode 100644 index 0000000000000..f81fa6565f281 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sa8775p-ride-camx.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "lemans-camera.dtsi" +#include "lemans-camera-sensor.dtsi" From 057d4c2c7ea2c31a5af9d6143b30426d61e75b66 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Fri, 17 Oct 2025 11:25:35 +0530 Subject: [PATCH 258/438] QCLINUX: arm64: dts: qcom: Add rb3gen2 camx overlay dts Add CAMX overlay dts file for rb3gen2 vision mezzanine board. This change also enables the compilation of the CAMX overlay for Kodiak rb3gen2 vision mezzanine board. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/Makefile | 5 + arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi | 2471 +++++++++++++++++ .../qcom/qcs6490-rb3gen2-camera-sensor.dtsi | 551 ++++ ...qcs6490-rb3gen2-vision-mezzanine-camx.dtso | 24 + 4 files changed, 3051 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine-camx.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 695be4f5de750..b420c6f2bd0b3 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -397,6 +397,11 @@ lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb +qcs6490-rb3gen2-vision-mezzanine-camx-dtbs := qcs6490-rb3gen2-vision-mezzanine.dtb \ + qcs6490-rb3gen2-vision-mezzanine-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine-camx.dtb + qcs9100-ride-camx-dtbs:= qcs9100-ride.dtb sa8775p-ride-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-camx.dtb diff --git a/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi new file mode 100644 index 0000000000000..f6af6827784bd --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi @@ -0,0 +1,2471 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&soc { + cam_a5: qcom,a5 { + compatible = "qcom,cam-a5"; + cell-index = <0>; + reg = <0x0 0xac00000 0x0 0x6000>, + <0x0 0xac10000 0x0 0x8000>, + <0x0 0xac18000 0x0 0x3000>; + reg-names = "a5_qgic", "a5_sierra", "a5_csr"; + reg-cam-base = <0x00000 0x10000 0x18000>; + interrupts = ; + interrupt-names = "a5"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_ICP_AHB_CLK>, + <&camcc CAM_CC_ICP_CLK_SRC>, + <&camcc CAM_CC_ICP_CLK>; + clock-names = "soc_fast_ahb", + "icp_ahb_clk", + "icp_clk_src", + "icp_clk"; + clock-rates = <100000000 0 400000000 0>, + <200000000 0 400000000 0>, + <300000000 0 600000000 0>, + <400000000 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal"; + src-clock-name = "soc_fast_ahb"; + operating-points-v2 = <&a5_opp_table>; + fw_name = "CAMERA_ICP_170.elf"; + ubwc-ipe-fetch-cfg = <0x7073 0x707b>; + ubwc-ipe-write-cfg = <0x161cf 0x161ef>; + ubwc-bps-fetch-cfg = <0x7073 0x707b>; + ubwc-bps-write-cfg = <0x161cf 0x161ef>; + qos-val = <0x00000A0A>; + status = "ok"; + + a5_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_bps: qcom,bps { + compatible = "qcom,cam-bps"; + cell-index = <0>; + reg = <0x0 0xac6f000 0x0 0x8000>; + reg-names = "bps_top"; + reg-cam-base = <0x6f000>; + power-domains = <&camcc CAM_CC_BPS_GDSC>; + clocks = <&camcc CAM_CC_BPS_AHB_CLK>, + <&camcc CAM_CC_BPS_AREG_CLK>, + <&camcc CAM_CC_BPS_AXI_CLK>, + <&camcc CAM_CC_BPS_CLK_SRC>, + <&camcc CAM_CC_BPS_CLK>; + clock-names = "bps_ahb_clk", + "bps_areg_clk", + "bps_axi_clk", + "bps_clk_src", + "bps_clk"; + clock-rates = <0 0 0 200000000 0>, + <0 0 0 400000000 0>, + <0 0 0 480000000 0>, + <0 0 0 600000000 0>, + <0 0 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", + "nominal", "turbo"; + src-clock-name = "bps_clk_src"; + operating-points-v2 = <&bps_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + bps_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + qcom,cam-cdm-intf { + compatible = "qcom,cam-cdm-intf"; + cell-index = <0>; + label = "cam-cdm-intf"; + num-hw-cdm = <1>; + cdm-client-names = "vfe", + "jpegdma", + "jpegenc", + "lrmecdm"; + status = "ok"; + }; + + qcom,cam-cpas { + compatible = "qcom,cam-cpas"; + cell-index = <0>; + label = "cpas"; + arch-compat = "cpas_top"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0 0x0ac40000 0x0 0x1000>, + <0x0 0x0ac9f000 0x0 0x10000>; + reg-names = "cam_cpas_top", "cam_camnoc"; + reg-cam-base = <0x40000 0x9f000>; + cam_hw_fuse = , + , + , + , + , + ; + interrupts = ; + interrupt-names = "cpas_camnoc"; + camnoc-axi-min-ib-bw = <3000000000>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&gcc GCC_CAMERA_SF_AXI_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_ICP_AHB_CLK>, + <&camcc CAM_CC_ICP_CLK>; + clock-names = "gcc_camera_hf_axi_clk", + "gcc_camera_sf_axi_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_icp_ahb_clk", + "cam_cc_icp_clk"; + src-clock-name = "cam_cc_camnoc_axi_clk_src"; + clock-rates = <0 0 0 0 0 0 0 0>, + <0 0 80000000 0 150000000 0 0 0>, + <0 0 80000000 0 240000000 0 0 0>, + <0 0 80000000 0 320000000 0 0 0>, + <0 0 80000000 0 400000000 0 0 0>, + <0 0 80000000 0 480000000 0 0 0>; + clock-cntl-level = "suspend", "lowsvs", "svs", + "svs_l1", "nominal", "turbo"; + operating-points-v2 = <&cpas_opp_table>; + control-camnoc-axi-clk; + camnoc-bus-width = <32>; + camnoc-axi-clk-bw-margin-perc = <20>; + interconnects = <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>, + <&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>, + <&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI1 0>, + <&mmss_noc MASTER_CAMNOC_ICP 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp"; + cam-ahb-num-cases = <7>; + cam-ahb-bw-KBps = <0 0>, <0 76800>, <0 150000>, <0 150000>, + <0 300000>, <0 300000>, <0 300000>; + vdd-corners = ; + vdd-corner-ahb-mapping = "suspend", "lowsvs", "lowsvs", "svs", "svs_l1", + "nominal", "nominal", "nominal", "turbo", "turbo"; + client-id-based; + client-names = "csiphy0", "csiphy1", "csiphy2", "csiphy3", + "csiphy4", "cci0", "cci1", "csid0", "csid1", + "csid2", "csid3", "csid4", "ife0", "ife1", + "ife2", "ife3", "ife4", "ipe0", "cam-cdm-intf0", + "cpas-cdm0", "bps0", "icp0", "jpeg-dma0", "jpeg-enc0", + "lrmecpas0"; + status = "ok"; + + cpas_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-150000000 { + opp-hz = /bits/ 64 <150000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + + camera-bus-nodes { + level0-nodes { + level-index = <0>; + + bps0_all_rd: bps0-all-rd { + cell-index = <0>; + node-name = "bps0-all-rd"; + client-name = "bps0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read0>; + }; + + bps0_all_wr: bps0-all-wr { + cell-index = <1>; + node-name = "bps0-all-wr"; + client-name = "bps0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write0>; + }; + + cpas_cdm0_all_rd: cpas-cdm0-all-rd { + cell-index = <2>; + node-name = "cpas-cdm0-all-rd"; + client-name = "cpas-cdm0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level2_nrt0_read0>; + }; + + icp0_all_rd: icp0-all-rd { + cell-index = <3>; + node-name = "icp0-all-rd"; + client-name = "icp0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level2_nrt1_read0>; + }; + + ife0_pixelall_wr: ife0-pixelall-wr { + cell-index = <4>; + node-name = "ife0-pixelall-wr"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt1_write0>; + }; + + ife0_rdi_wr: ife0-rdi-wr { + cell-index = <5>; + node-name = "ife0-rdi-wr"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife1_pixelall_wr: ife1-pixelall-wr { + cell-index = <6>; + node-name = "ife1-pixelall-wr"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt1_write0>; + }; + + ife1_rdi_wr: ife1-rdi-wr { + cell-index = <7>; + node-name = "ife1-rdi-wr"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife2_pixelall_wr: ife2-pixelall-wr { + cell-index = <8>; + node-name = "ife2-pixelall-wr"; + client-name = "ife2"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt1_write1>; + }; + + ife2_rdi_wr: ife2-rdi-wr { + cell-index = <9>; + node-name = "ife2-rdi-wr"; + client-name = "ife2"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife3_rdi_wr: ife3-rdi-wr { + cell-index = <10>; + node-name = "ife3-rdi-wr"; + client-name = "ife3"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife4_rdi_wr: ife4-rdi-wr { + cell-index = <11>; + node-name = "ife4-rdi-wr"; + client-name = "ife4"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ipe0_all_rd: ipe0-all-rd { + cell-index = <12>; + node-name = "ipe0-all-rd"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_nrt0_read0>; + }; + + ipe0_ref_wr: ipe0-ref-wr { + cell-index = <13>; + node-name = "ipe0-ref-wr"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write0>; + }; + + ipe0_viddisp_wr: ipe0-viddisp-wr { + cell-index = <14>; + node-name = "ipe0-viddisp-wr"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_nrt0_write0>; + }; + + jpeg_dma0_all_rd: jpeg-dma0-all-rd { + cell-index = <15>; + node-name = "jpeg-dma0-all-rd"; + client-name = "jpeg-dma0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt1_read0>; + }; + + jpeg_dma0_all_wr: jpeg-dma0-all-wr { + cell-index = <16>; + node-name = "jpeg-dma0-all-wr"; + client-name = "jpeg-dma0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt1_write0>; + }; + + jpeg_enc0_all_rd: jpeg-enc0-all-rd { + cell-index = <17>; + node-name = "jpeg-enc0-all-rd"; + client-name = "jpeg-enc0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt1_read0>; + }; + + jpeg_enc0_all_wr: jpeg-enc0-all-wr { + cell-index = <18>; + node-name = "jpeg-enc0-all-wr"; + client-name = "jpeg-enc0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt1_write0>; + }; + + lrme0_all_rd: lrme0-all-rd { + cell-index = <19>; + node-name = "lrme0-all-rd"; + client-name = "lrmecpas0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read0>; + }; + + lrme0_all_wr: lrme0-all-wr { + cell-index = <20>; + node-name = "lrme0-all-wr"; + client-name = "lrmecpas0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write0>; + }; + }; + + level1-nodes { + level-index = <1>; + camnoc-max-needed; + + level1_nrt0_write0: level1-nrt0-write0 { + cell-index = <21>; + node-name = "level1-nrt0-write0"; + parent-node = <&level2_nrt0_write0>; + traffic-merge-type = ; + }; + + level1_nrt0_read0: level1-nrt0-read0 { + cell-index = <22>; + node-name = "level1-nrt0-read0"; + parent-node = <&level2_nrt0_read0>; + traffic-merge-type = ; + }; + + level1_nrt1_write0: level1-nrt1-write0 { + cell-index = <23>; + node-name = "level1-nrt1-write0"; + parent-node = <&level2_nrt0_write0>; + traffic-merge-type = ; + }; + + level1_nrt1_read0: level1-nrt1-read0 { + cell-index = <24>; + node-name = "level1-nrt1-read0"; + parent-node = <&level2_nrt0_read0>; + traffic-merge-type = ; + }; + + level1_rt0_write0: level1-rt0-write0 { + cell-index = <25>; + node-name = "level1-rt0-write0"; + parent-node = <&level2_rt0_write0>; + traffic-merge-type = ; + }; + + level1_rt1_write0: level1-rt1-write0 { + cell-index = <26>; + node-name = "level1-rt1-write0"; + parent-node = <&level2_rt1_write0>; + traffic-merge-type = ; + }; + + level1_rt1_write1: level1-rt1-write1 { + cell-index = <27>; + node-name = "level1-rt1-write1"; + parent-node = <&level2_rt1_write0>; + traffic-merge-type = ; + }; + }; + + level2-nodes { + level-index = <3>; + camnoc-max-needed; + + level2_nrt0_write0: level2-nrt0-write0 { + cell-index = <28>; + node-name = "level2-nrt0-write0"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt0_read0: level2-nrt0-read0 { + cell-index = <29>; + node-name = "level2-nrt0-read0"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt1_read0: level2-nrt1-read0 { + cell-index = <30>; + node-name = "level2-nrt1-read0"; + parent-node = <&level3_nrt1_rd_sum>; + traffic-merge-type = + ; + bus-width-factor = <4>; + }; + + level2_rt0_write0: level2-rt0-write0 { + cell-index = <31>; + node-name = "level2-rt0-write0"; + parent-node = <&level3_rt0_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt1_write0: level2-rt1-write0 { + cell-index = <32>; + node-name = "level2-rt1-write0"; + parent-node = <&level3_rt0_wr_sum>; + traffic-merge-type = ; + }; + }; + + level3-nodes { + level-index = <3>; + + level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum { + cell-index = <33>; + node-name = "level3-nrt0-rd-wr-sum"; + traffic-merge-type = ; + + qcom,axi-port-mnoc { + interconnect-names = "cam_sf_0"; + interconnects = + <&mmss_noc MASTER_CAMNOC_SF 0 + &mc_virt SLAVE_EBI1 0>; + }; + }; + + level3_nrt1_rd_sum: level3-nrt1-rd-sum { + cell-index = <34>; + node-name = "level3-nrt1-rd-sum"; + traffic-merge-type = ; + + qcom,axi-port-mnoc { + interconnect-names = "cam_sf_icp"; + interconnects = + <&mmss_noc MASTER_CAMNOC_ICP 0 + &mc_virt SLAVE_EBI1 0>; + }; + }; + + level3_rt0_wr_sum: level3-rt0-wr-sum { + cell-index = <35>; + node-name = "level3-rt0-wr-sum"; + traffic-merge-type = ; + ib-bw-voting-needed; + + qcom,axi-port-mnoc { + interconnect-names = "cam_hf_0"; + interconnects = + <&mmss_noc MASTER_CAMNOC_HF 0 + &mc_virt SLAVE_EBI1 0>; + }; + }; + }; + }; + }; + + qcom,cam-icp { + compatible = "qcom,cam-icp"; + compat-hw-name = "qcom,a5", + "qcom,ipe0", + "qcom,bps"; + num-a5 = <1>; + num-ipe = <1>; + num-bps = <1>; + icp_pc_en; + status = "ok"; + }; + + qcom,cam-isp { + compatible = "qcom,cam-isp"; + arch-compat = "ife"; + status = "ok"; + }; + + qcom,cam-req-mgr { + compatible = "qcom,cam-req-mgr"; + status = "ok"; + }; + + qcom,cam-jpeg { + compatible = "qcom,cam-jpeg"; + compat-hw-name = "qcom,jpegenc", + "qcom,jpegdma"; + num-jpeg-enc = <1>; + num-jpeg-dma = <1>; + status = "ok"; + }; + + qcom,cam-lrme { + compatible = "qcom,cam-lrme"; + arch-compat = "lrme"; + status = "ok"; + }; + + qcom,camera-main { + compatible = "qcom,camera_kt"; + status = "ok"; + }; + + qcom,cam-smmu { + compatible = "qcom,msm-cam-smmu", "simple-bus"; + force_cache_allocs; + status = "ok"; + + msm-cam-icp-fw { + compatible = "qcom,msm-cam-smmu-fw-dev"; + label="icp"; + memory-region = <&camera_mem>; + }; + + msm-cam-smmu-cpas-cdm { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x2040 0x0>; + cam-smmu-label = "cpas-cdm"; + dma-coherent; + + cpas_cdm_iova_mem_map: iova-mem-map { + iova-mem-region-io { + /* IO region is approximately 3.4 GB */ + iova-region-name = "io"; + iova-region-start = <0x100000>; + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm_cam_smmu_icp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x2000 0x20>, + <&apps_smmu 0x2020 0x20>, + <&apps_smmu 0x2062 0x0>, + <&apps_smmu 0x2080 0x20>, + <&apps_smmu 0x20A0 0x20>, + <&apps_smmu 0x2140 0x0>; + cam-smmu-label = "icp"; + dma-coherent; + + icp_iova_mem_map: iova-mem-map { + iova-mem-region-firmware { + /* Firmware region is 5MB */ + iova-region-name = "firmware"; + iova-region-start = <0x0>; + iova-region-len = <0x500000>; + iova-region-id = <0x0>; + status = "ok"; + }; + + iova-mem-region-io { + /* IO region is approximately 3.7 GB */ + iova-region-name = "io"; + iova-region-start = <0x10c00000>; + iova-region-len = <0xcf300000>; + iova-region-id = <0x3>; + status = "ok"; + }; + + iova-mem-region-qdss { + /* QDSS region is appropriate 1MB */ + iova-region-name = "qdss"; + iova-region-start = <0x10b00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x5>; + qdss-phy-addr = <0x16790000>; + status = "ok"; + }; + + iova-mem-region-secondary-heap { + /* Secondary heap region is 1MB long */ + iova-region-name = "secheap"; + iova-region-start = <0x10a00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x4>; + status = "ok"; + }; + + iova-mem-region-shared { + /* Shared region is 150MB long */ + iova-region-name = "shared"; + iova-region-start = <0x7400000>; + iova-region-len = <0x9600000>; + iova-region-id = <0x1>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-ife { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x800 0x4E0>, + <&apps_smmu 0x820 0x4E0>, + <&apps_smmu 0x840 0x4E0>, + <&apps_smmu 0x860 0x4E0>, + <&apps_smmu 0x880 0x4E0>, + <&apps_smmu 0x8A0 0x4E0>, + <&apps_smmu 0x8C0 0x4E0>, + <&apps_smmu 0x8E0 0x4E0>, + <&apps_smmu 0xC00 0x4E0>, + <&apps_smmu 0xC20 0x4E0>, + <&apps_smmu 0xC40 0x4E0>, + <&apps_smmu 0xC60 0x4E0>, + <&apps_smmu 0xC80 0x4E0>, + <&apps_smmu 0xCA0 0x4E0>, + <&apps_smmu 0xCC0 0x4E0>, + <&apps_smmu 0xCE0 0x4E0>; + cam-smmu-label = "ife"; + multiple-client-devices; + dma-coherent; + + ife_iova_mem_map: iova-mem-map { + /* IO region is approximately 4 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x100000>; + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-jpeg { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x20C0 0x20>, + <&apps_smmu 0x20E0 0x20>; + cam-smmu-label = "jpeg"; + dma-coherent; + + jpeg_iova_mem_map: iova-mem-map { + /* IO region is approximately 3.4 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x100000>; + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-lrme { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x2100 0x20>, + <&apps_smmu 0x2120 0x20>; + cam-smmu-label = "lrme"; + dma-coherent; + + lrme_iova_mem_map: iova-mem-map { + iova-mem-region-shared { + /* Shared region is 100MB long */ + iova-region-name = "shared"; + iova-region-start = <0x7400000>; + iova-region-len = <0x6400000>; + iova-region-id = <0x1>; + status = "ok"; + }; + + /* IO region is approximately 3.3 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x100000>; + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-secure { + compatible = "qcom,msm-cam-smmu-cb"; + cam-smmu-label = "cam-secure"; + qcom,secure-cb; + }; + }; + + qcom,cam-sync { + compatible = "qcom,cam-sync"; + status = "ok"; + }; + + cam_cci0: qcom,cci0 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac4a000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x4a000>; + interrupts = ; + interrupt-names = "cci"; + operating-points-v2 = <&cci0_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>, + <&camcc CAM_CC_CCI_0_CLK>; + clock-names = "cci_0_clk_src", + "cci_0_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_0_clk_src"; + pinctrl-0 = <&cci0_active &cci1_active>; + pinctrl-1 = <&cci0_suspend &cci1_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 69 0>, + <&tlmm 70 0>, + <&tlmm 71 0>, + <&tlmm 72 0>; + gpio-req-tbl-num = <0 1 2 3>; + gpio-req-tbl-flags = <1 1 1 1>; + gpio-req-tbl-label = "CCI_I2C_DATA0", + "CCI_I2C_CLK0", + "CCI_I2C_DATA1", + "CCI_I2C_CLK1"; + cell-index = <0>; + status = "ok"; + + cci0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci0: qcom,i2c-custom-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci0: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci0: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <0>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci0: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_cci1: qcom,cci1 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac4b000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x4b000>; + interrupts = ; + interrupt-names = "cci"; + operating-points-v2 = <&cci1_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>, + <&camcc CAM_CC_CCI_1_CLK>; + clock-names = "cci_1_clk_src", + "cci_1_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_1_clk_src"; + pinctrl-0 = <&cci2_active &cci3_active>; + pinctrl-1 = <&cci2_suspend &cci3_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>, + <&tlmm 74 0>, + <&tlmm 75 0>, + <&tlmm 76 0>; + gpio-req-tbl-num = <0 1 2 3>; + gpio-req-tbl-flags = <1 1 1 1>; + gpio-req-tbl-label = "CCI_I2C_DATA2", + "CCI_I2C_CLK2", + "CCI_I2C_DATA3", + "CCI_I2C_CLK3"; + cell-index = <1>; + status = "ok"; + + cci1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci1: qcom,i2c-custom-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci1: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci1: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <0>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci1: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + qcom,cpas-cdm0 { + compatible = "qcom,cam170-cpas-cdm0"; + cell-index = <0>; + label = "cpas-cdm"; + reg = <0x0 0xac48000 0x0 0x1000>; + reg-names = "cpas-cdm"; + reg-cam-base = <0x48000>; + interrupts = ; + interrupt-names = "cpas-cdm"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + clock-rates = <80000000 0>; + clock-cntl-level = "svs"; + src-clock-name = "cam_cc_slow_ahb_clk_src"; + operating-points-v2 = <&cdm_cpas_opp_table>; + cdm-client-names = "ife0", "ife1", "ife2", + "ife3", "ife4", "dualife"; + status = "ok"; + + cdm_cpas_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-80000000 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csid0: qcom,csid0 { + compatible = "qcom,csid165_204"; + cell-index = <0>; + reg = <0x0 0xacb3000 0x0 0x1000>; + reg-names = "csid"; + reg-cam-base = <0xb3000>; + interrupts = ; + interrupt-names = "csid0"; + power-domains = <&camcc CAM_CC_IFE_0_GDSC>; + clocks = <&camcc CAM_CC_IFE_0_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CSID_CLK>, + <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_0_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_AXI_CLK>; + clock-names = "ife_csid_clk_src", + "ife_csid_clk", + "ife_cphy_rx_clk", + "ife_clk_src", + "ife_clk", + "ife_axi_clk"; + clock-rates = <300000000 0 0 380000000 0 0>, + <400000000 0 0 510000000 0 0>, + <400000000 0 0 637000000 0 0>, + <400000000 0 0 760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_csid_clk_src"; + operating-points-v2 = <&csid0_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + csid0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-637000000 { + opp-hz = /bits/ 64 <637000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid1: qcom,csid1 { + compatible = "qcom,csid165_204"; + cell-index = <1>; + reg = <0x0 0xacba000 0x0 0x1000>; + reg-names = "csid"; + reg-cam-base = <0xba000>; + interrupts = ; + interrupt-names = "csid1"; + power-domains = <&camcc CAM_CC_IFE_1_GDSC>; + clocks = <&camcc CAM_CC_IFE_1_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CSID_CLK>, + <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_1_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_AXI_CLK>; + clock-names = "ife_csid_clk_src", + "ife_csid_clk", + "ife_cphy_rx_clk", + "ife_clk_src", + "ife_clk", + "ife_axi_clk"; + clock-rates = <300000000 0 0 380000000 0 0>, + <400000000 0 0 510000000 0 0>, + <400000000 0 0 637000000 0 0>, + <400000000 0 0 760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_csid_clk_src"; + operating-points-v2 = <&csid1_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + csid1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-637000000 { + opp-hz = /bits/ 64 <637000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid2: qcom,csid2 { + compatible = "qcom,csid165_204"; + cell-index = <2>; + reg = <0x0 0x0acc1000 0x0 0x1000>; + reg-names = "csid"; + reg-cam-base = <0xc1000>; + interrupts = ; + interrupt-names = "csid2"; + power-domains = <&camcc CAM_CC_IFE_2_GDSC>; + clocks = <&camcc CAM_CC_IFE_2_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_2_CSID_CLK>, + <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_2_CLK_SRC>, + <&camcc CAM_CC_IFE_2_CLK>, + <&camcc CAM_CC_IFE_2_AXI_CLK>; + clock-names = "ife_csid_clk_src", + "ife_csid_clk", + "ife_cphy_rx_clk", + "ife_clk_src", + "ife_clk", + "ife_axi_clk"; + clock-rates = <300000000 0 0 380000000 0 0>, + <400000000 0 0 510000000 0 0>, + <400000000 0 0 637000000 0 0>, + <400000000 0 0 760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_csid_clk_src"; + operating-points-v2 = <&csid2_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + csid2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-637000000 { + opp-hz = /bits/ 64 <637000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite0: qcom,csid-lite0 { + compatible = "qcom,csid-lite165"; + cell-index = <3>; + reg = <0x0 0xacc8000 0x0 0x1000>; + reg-names = "csid-lite"; + reg-cam-base = <0xc8000>; + interrupts = ; + interrupt-names = "csid-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_IFE_LITE_0_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_0_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_0_CLK>; + clock-names = "ife_csid_clk_src", + "ife_csid_clk", + "ife_cphy_rx_clk", + "ife_clk_src", + "ife_clk"; + clock-rates = <300000000 0 0 320000000 0>, + <400000000 0 0 400000000 0>, + <400000000 0 0 480000000 0>, + <400000000 0 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_csid_clk_src"; + operating-points-v2 = <&csid_lite0_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + csid_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite1: qcom,csid-lite1 { + compatible = "qcom,csid-lite165"; + cell-index = <4>; + reg = <0x0 0x0accf000 0x0 0x1000>; + reg-names = "csid-lite"; + reg-cam-base = <0xcf000>; + interrupts = ; + interrupt-names = "csid-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_IFE_LITE_1_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_1_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_1_CLK>; + clock-names = "ife_csid_clk_src", + "ife_csid_clk", + "ife_cphy_rx_clk", + "ife_clk_src", + "ife_clk"; + clock-rates = <300000000 0 0 320000000 0>, + <400000000 0 0 400000000 0>, + <400000000 0 0 480000000 0>, + <400000000 0 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_csid_clk_src"; + operating-points-v2 = <&csid_lite1_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + csid_lite1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csiphy0: qcom,csiphy0 { + compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy"; + cell-index = <0>; + reg = <0x0 0x0ace0000 0x0 0x2000>; + reg-names = "csiphy"; + reg-cam-base = <0xe0000>; + interrupts = ; + interrupt-names = "csiphy0"; + operating-points-v2 = <&csiphy0_opp_table>; + csi-vdd-1p2-supply = <&vreg_l6b_1p2>; + csi-vdd-0p9-supply = <&vreg_l10c_0p88>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1260000 1050000>; + rgltr-load-current = <54000 96400>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy0_clk", + "csi0phytimer_clk_src", + "csi0phytimer_clk"; + clock-rates = <300000000 0 300000000 0>, + <400000000 0 300000000 0>; + clock-cntl-level = "lowsvs", "svs"; + src-clock-name = "csi0phytimer_clk_src"; + status = "ok"; + + csiphy0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + }; + }; + + cam_csiphy1: qcom,csiphy1 { + cell-index = <1>; + compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy"; + reg = <0x0 0xace2000 0x0 0x2000>; + reg-names = "csiphy"; + reg-cam-base = <0xe2000>; + interrupts = ; + interrupt-names = "csiphy1"; + operating-points-v2 = <&csiphy1_opp_table>; + csi-vdd-1p2-supply = <&vreg_l6b_1p2>; + csi-vdd-0p9-supply = <&vreg_l10c_0p88>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1260000 1050000>; + rgltr-load-current = <54000 96400>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy1_clk", + "csi1phytimer_clk_src", + "csi1phytimer_clk"; + src-clock-name = "csi1phytimer_clk_src"; + clock-cntl-level = "lowsvs", "svs"; + clock-rates = <300000000 0 300000000 0>, + <400000000 0 300000000 0>; + status = "ok"; + + csiphy1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + }; + }; + + cam_csiphy2: qcom,csiphy2 { + cell-index = <2>; + compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy"; + reg = <0x0 0xace4000 0x0 0x2000>; + reg-names = "csiphy"; + reg-cam-base = <0xe4000>; + interrupts = ; + interrupt-names = "csiphy2"; + operating-points-v2 = <&csiphy2_opp_table>; + csi-vdd-1p2-supply = <&vreg_l6b_1p2>; + csi-vdd-0p9-supply = <&vreg_l10c_0p88>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1260000 1050000>; + rgltr-load-current = <54000 96400>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy2_clk", + "csi2phytimer_clk_src", + "csi2phytimer_clk"; + src-clock-name = "csi2phytimer_clk_src"; + clock-cntl-level = "lowsvs", "svs"; + clock-rates = <300000000 0 300000000 0>, + <400000000 0 300000000 0>; + status = "ok"; + + csiphy2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + }; + }; + + cam_csiphy3: qcom,csiphy3 { + cell-index = <3>; + compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy"; + reg = <0x0 0xace6000 0x0 0x2000>; + reg-names = "csiphy"; + reg-cam-base = <0xe6000>; + interrupts = ; + interrupt-names = "csiphy3"; + operating-points-v2 = <&csiphy3_opp_table>; + csi-vdd-1p2-supply = <&vreg_l6b_1p2>; + csi-vdd-0p9-supply = <&vreg_l10c_0p88>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1260000 1050000>; + rgltr-load-current = <54000 96400>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY3_CLK>, + <&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI3PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy3_clk", + "csi3phytimer_clk_src", + "csi3phytimer_clk"; + src-clock-name = "csi3phytimer_clk_src"; + clock-cntl-level = "lowsvs", "svs"; + clock-rates = <300000000 0 300000000 0>, + <400000000 0 300000000 0>; + status = "ok"; + + csiphy3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + }; + }; + + cam_csiphy4: qcom,csiphy4 { + cell-index = <4>; + compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy"; + reg = <0x0 0xace8000 0x0 0x2000>; + reg-names = "csiphy"; + reg-cam-base = <0xe8000>; + interrupts = ; + interrupt-names = "csiphy4"; + operating-points-v2 = <&csiphy4_opp_table>; + csi-vdd-1p2-supply = <&vreg_l6b_1p2>; + csi-vdd-0p9-supply = <&vreg_l10c_0p88>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1260000 1050000>; + rgltr-load-current = <54000 96400>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY4_CLK>, + <&camcc CAM_CC_CSI4PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI4PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy4_clk", + "csi4phytimer_clk_src", + "csi4phytimer_clk"; + src-clock-name = "csi4phytimer_clk_src"; + clock-cntl-level = "lowsvs", "svs"; + clock-rates = <300000000 0 300000000 0>, + <400000000 0 300000000 0>; + status = "ok"; + + csiphy4_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + }; + }; + + cam_ipe0: qcom,ipe0 { + compatible = "qcom,cam-ipe"; + cell-index = <0>; + reg = <0x0 0xac87000 0x0 0xa000>; + reg-names = "ipe0_top"; + reg-cam-base = <0x87000>; + power-domains = <&camcc CAM_CC_IPE_0_GDSC>; + clocks = <&camcc CAM_CC_IPE_0_AHB_CLK>, + <&camcc CAM_CC_IPE_0_AREG_CLK>, + <&camcc CAM_CC_IPE_0_AXI_CLK>, + <&camcc CAM_CC_IPE_0_CLK_SRC>, + <&camcc CAM_CC_IPE_0_CLK>; + clock-names = "ipe_0_ahb_clk", + "ipe_0_areg_clk", + "ipe_0_axi_clk", + "ipe_0_clk_src", + "ipe_0_clk"; + clock-rates = <0 0 0 300000000 0>, + <0 0 0 430000000 0>, + <0 0 0 520000000 0>, + <0 0 0 600000000 0>, + <0 0 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", + "nominal", "turbo"; + src-clock-name = "ipe_0_clk_src"; + operating-points-v2 = <&ipe0_opp_table>; + clock-control-debugfs = "true"; + status = "ok"; + + ipe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-430000000 { + opp-hz = /bits/ 64 <430000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-520000000 { + opp-hz = /bits/ 64 <520000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_jpeg_dma: qcom,jpegdma { + compatible = "qcom,cam_jpeg_dma_165"; + cell-index = <0>; + reg = <0x0 0xac52000 0x0 0x4000>, + <0x0 0x0ac9f000 0x0 0x10000>; + reg-names = "jpegdma_hw", "cam_camnoc"; + reg-cam-base = <0x52000 0x9f000>; + interrupts = ; + interrupt-names = "jpegdma"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_JPEG_CLK_SRC>, + <&camcc CAM_CC_JPEG_CLK>; + clock-names = "jpegdma_clk_src", + "jpegdma_clk"; + clock-rates = <600000000 0>; + clock-cntl-level = "nominal"; + src-clock-name = "jpegdma_clk_src"; + operating-points-v2 = <&jpeg_dma_opp_table>; + cam_hw_pid = <20 21>; + cam_hw_rd_mid = <0>; + cam_hw_wr_mid = <2>; + status = "ok"; + + jpeg_dma_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_jpeg_enc: qcom,jpegenc { + compatible = "qcom,cam_jpeg_enc_165"; + cell-index = <0>; + reg = <0x0 0xac4e000 0x0 0x4000>, + <0x0 0x0ac9f000 0x0 0x10000>; + reg-names = "jpege_hw", "cam_camnoc"; + reg-cam-base = <0x4e000 0x9f000>; + interrupts = ; + interrupt-names = "jpeg"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_JPEG_CLK_SRC>, + <&camcc CAM_CC_JPEG_CLK>; + clock-names = "jpegenc_clk_src", + "jpegenc_clk"; + clock-rates = <600000000 0>; + clock-cntl-level = "nominal"; + src-clock-name = "jpegenc_clk_src"; + operating-points-v2 = <&jpeg_enc_opp_table>; + cam_hw_pid = <22 23>; + cam_hw_rd_mid = <0>; + cam_hw_wr_mid = <2>; + status = "ok"; + + jpeg_enc_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_lrme: qcom,lrme { + compatible = "qcom,lrme"; + cell-index = <0>; + reg = <0x0 0xac6b000 0x0 0x1000>; + reg-names = "lrme"; + reg-cam-base = <0x6b000>; + interrupts = ; + interrupt-names = "lrme"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_LRME_CLK_SRC>, + <&camcc CAM_CC_LRME_CLK>; + clock-names = "lrme_clk_src", + "lrme_clk"; + clock-rates = <240000000 0>, + <300000000 0>, + <320000000 0>, + <400000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal"; + src-clock-name = "lrme_clk_src"; + operating-points-v2 = <&lrme_opp_table>; + status = "ok"; + + lrme_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe0: qcom,vfe0 { + compatible = "qcom,vfe165_160"; + reg = <0x0 0xacaf000 0x0 0x5200>; + reg-names = "ife"; + reg-cam-base = <0xaf000>; + interrupts = ; + interrupt-names = "ife0"; + power-domains = <&camcc CAM_CC_IFE_0_GDSC>; + clocks = <&camcc CAM_CC_IFE_0_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_AXI_CLK>; + clock-names = "ife_clk_src", + "ife_clk", + "ife_axi_clk"; + clock-rates = <380000000 0 0>, + <510000000 0 0>, + <637000000 0 0>, + <760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + operating-points-v2 = <&vfe0_opp_table>; + clock-control-debugfs = "true"; + clock-names-option = "ife_dsp_clk"; + clocks-option = <&camcc CAM_CC_IFE_0_DSP_CLK>; + clock-rates-option = <760000000>; + cam_hw_pid = <24 8>; + cell-index = <0>; + status = "ok"; + + vfe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-637000000 { + opp-hz = /bits/ 64 <637000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe1: qcom,vfe1 { + compatible = "qcom,vfe165_160"; + reg = <0x0 0xacb6000 0x0 0x5200>; + reg-names = "ife"; + reg-cam-base = <0xb6000>; + interrupts = ; + interrupt-names = "ife1"; + power-domains = <&camcc CAM_CC_IFE_1_GDSC>; + clocks = <&camcc CAM_CC_IFE_1_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_AXI_CLK>; + clock-names = "ife_clk_src", + "ife_clk", + "ife_axi_clk"; + clock-rates = <380000000 0 0>, + <510000000 0 0>, + <637000000 0 0>, + <760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + operating-points-v2 = <&vfe1_opp_table>; + clock-control-debugfs = "true"; + clock-names-option = "ife_dsp_clk"; + clocks-option = <&camcc CAM_CC_IFE_1_DSP_CLK>; + clock-rates-option = <760000000>; + cam_hw_pid = <25 9>; + cell-index = <1>; + status = "ok"; + + vfe1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-637000000 { + opp-hz = /bits/ 64 <637000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + + cam_vfe2: qcom,vfe2 { + compatible = "qcom,vfe165_160"; + reg = <0x0 0x0acbd000 0x0 0x5200>; + reg-names = "ife"; + reg-cam-base = <0xbd000>; + interrupts = ; + interrupt-names = "ife2"; + power-domains = <&camcc CAM_CC_IFE_2_GDSC>; + clocks = <&camcc CAM_CC_IFE_2_CLK_SRC>, + <&camcc CAM_CC_IFE_2_CLK>, + <&camcc CAM_CC_IFE_2_AXI_CLK>; + clock-names = "ife_clk_src", + "ife_clk", + "ife_axi_clk"; + clock-rates = <380000000 0 0>, + <510000000 0 0>, + <637000000 0 0>, + <760000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + operating-points-v2 = <&vfe2_opp_table>; + clock-control-debugfs = "true"; + clock-names-option = "ife_dsp_clk"; + clocks-option = <&camcc CAM_CC_IFE_2_DSP_CLK>; + clock-rates-option = <760000000>; + cam_hw_pid = <3 10>; + cell-index = <2>; + status = "ok"; + + vfe2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-637000000 { + opp-hz = /bits/ 64 <637000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite0: qcom,vfe-lite0 { + compatible = "qcom,vfe-lite165"; + cell-index = <3>; + reg = <0x0 0xacc4000 0x0 0x5000>; + reg-names = "ife-lite"; + reg-cam-base = <0xc4000>; + interrupts = ; + interrupt-names = "ife-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_IFE_LITE_0_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_0_CLK>; + clock-names = "ife_clk_src", + "ife_clk"; + clock-rates = <320000000 0>, + <400000000 0>, + <480000000 0>, + <600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + operating-points-v2 = <&vfe_lite0_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <11>; + status = "ok"; + + vfe_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite1: qcom,vfe-lite1 { + compatible = "qcom,vfe-lite165"; + reg = <0x0 0x0accb000 0x0 0x5000>; + reg-names = "ife-lite"; + reg-cam-base = <0xcb000>; + interrupts = ; + interrupt-names = "ife-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_IFE_LITE_1_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_1_CLK>; + clock-names = "ife_clk_src", + "ife_clk"; + clock-rates = <320000000 0>, + <400000000 0>, + <480000000 0>, + <600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo"; + src-clock-name = "ife_clk_src"; + operating-points-v2 = <&vfe_lite1_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <12>; + cell-index = <4>; + status = "ok"; + + vfe_lite1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; +}; + +&tlmm { + cam_sensor_active_mux: cam-sensor-active-mux { + /* GC630 bypass mux */ + mux { + pins = "gpio1"; + function = "gpio"; + }; + + config { + pins = "gpio1"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst0: cam-sensor-active-rst0 { + /* RESET REAR */ + mux { + pins = "gpio20"; + function = "gpio"; + }; + + config { + pins = "gpio20"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst1: cam-sensor-active-rst1 { + /* RESET REARAUX */ + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst2: cam-sensor-active-rst2 { + /* RESET 2 */ + mux { + pins = "gpio77"; + function = "gpio"; + }; + + config { + pins = "gpio77"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst3: cam-sensor-active-rst3 { + /* RESET 3 */ + mux { + pins = "gpio78"; + function = "gpio"; + }; + + config { + pins = "gpio78"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst4: cam-sensor-active-rst4 { + /* RESET 4 */ + mux { + pins = "gpio79"; + function = "gpio"; + }; + + config { + pins = "gpio79"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk0_active: cam_sensor-mclk0-active { + /* MCLK0 */ + mux { + pins = "gpio64"; + function = "cam_mclk"; + }; + + config { + pins = "gpio64"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk0_suspend: cam-sensor-mclk0-suspend { + /* MCLK0 */ + mux { + pins = "gpio64"; + function = "cam_mclk"; + }; + + config { + pins = "gpio64"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk1_active: cam-sensor-mclk1-active { + /* MCLK1 */ + mux { + pins = "gpio65"; + function = "cam_mclk"; + }; + + config { + pins = "gpio65"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk1_suspend: cam-sensor-mclk1-suspend { + /* MCLK1 */ + mux { + pins = "gpio65"; + function = "cam_mclk"; + }; + + config { + pins = "gpio65"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_active: cam-sensor-mclk2-active { + /* MCLK2 */ + mux { + pins = "gpio66"; + function = "cam_mclk"; + }; + + config { + pins = "gpio66"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_suspend: cam-sensor-mclk2-suspend { + /* MCLK2 */ + mux { + pins = "gpio66"; + function = "cam_mclk"; + }; + + config { + pins = "gpio66"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_active: cam-sensor-mclk3-active { + /* MCLK3 */ + mux { + pins = "gpio67"; + function = "cam_mclk"; + }; + + config { + pins = "gpio67"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_suspend: cam-sensor-mclk3-suspend { + /* MCLK3 */ + mux { + pins = "gpio67"; + function = "cam_mclk"; + }; + + config { + pins = "gpio67"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk4_active: cam-sensor-mclk4-active { + /* MCLK4 */ + mux { + pins = "gpio68"; + function = "cam_mclk"; + }; + + config { + pins = "gpio68"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk4_suspend: cam-sensor-mclk4-suspend { + /* MCLK4 */ + mux { + pins = "gpio68"; + function = "cam_mclk"; + }; + + config { + pins = "gpio68"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk5_active: cam-sensor-mclk5-active { + /* MCLK5 */ + mux { + pins = "gpio98"; + function = "cam_mclk"; + }; + + config { + pins = "gpio98"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk5_suspend: cam-sensor-mclk5-suspend { + /* MCLK5 */ + mux { + pins = "gpio98"; + function = "cam_mclk"; + }; + + config { + pins = "gpio98"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_mux: cam-sensor-suspend-mux { + /* GC630 bypass mux */ + mux { + pins = "gpio1"; + function = "gpio"; + }; + + config { + pins = "gpio1"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst0: cam_sensor-suspend-rst0 { + /* RESET REAR */ + mux { + pins = "gpio20"; + function = "gpio"; + }; + + config { + pins = "gpio20"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst1: cam-sensor-suspend-rst1 { + /* RESET REARAUX */ + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst2: cam-sensor-suspend-rst2 { + /* RESET 2 */ + mux { + pins = "gpio77"; + function = "gpio"; + }; + + config { + pins = "gpio77"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst3: cam-sensor-suspend-rst3 { + /* RESET 3 */ + mux { + pins = "gpio78"; + function = "gpio"; + }; + + config { + pins = "gpio78"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst4: cam-sensor-suspend-rst4 { + /* RESET 4 */ + mux { + pins = "gpio79"; + function = "gpio"; + }; + + config { + pins = "gpio79"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cci0_active: cci0-active { + mux { + /* DATA, CLK */ + pins = "gpio69","gpio70"; // Only 2 + function = "cci_i2c"; + }; + + config { + pins = "gpio69","gpio70"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci0_suspend: cci0-suspend { + mux { + /* DATA, CLK */ + pins = "gpio69","gpio70"; + function = "cci_i2c"; + }; + + config { + pins = "gpio69","gpio70"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci1_active: cci1-active { + mux { + /* DATA, CLK */ + pins = "gpio71","gpio72"; + function = "cci_i2c"; + }; + + config { + pins = "gpio71","gpio72"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci1_suspend: cci1-suspend { + mux { + /* DATA, CLK */ + pins = "gpio71","gpio72"; + function = "cci_i2c"; + }; + + config { + pins = "gpio71","gpio72"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci2_active: cci2-active { + mux { + /* DATA, CLK */ + pins = "gpio73","gpio74"; + function = "cci_i2c"; + }; + + config { + pins = "gpio73","gpio74"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci2_suspend: cci2-suspend { + mux { + /* DATA, CLK */ + pins = "gpio73","gpio74"; + function = "cci_i2c"; + }; + + config { + pins = "gpio73","gpio74"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci3_active: cci3-active { + mux { + /* DATA, CLK */ + pins = "gpio75","gpio76"; + function = "cci_i2c"; + }; + + config { + pins = "gpio75","gpio76"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci3_suspend: cci3-suspend { + mux { + /* DATA, CLK */ + pins = "gpio75","gpio76"; + function = "cci_i2c"; + }; + + config { + pins = "gpio75","gpio76"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-camera-sensor.dtsi new file mode 100644 index 0000000000000..8b75b1a441db4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-camera-sensor.dtsi @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&cam_cci0 { + //cam1 interpose on dk csi0 + actuator_rear_cam11: qcom,actuator11 { + compatible = "qcom,actuator"; + cell-index = <11>; + cci-master = <1>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2856000>; + rgltr-max-voltage = <3104000>; + rgltr-load-current = <100000>; + }; + + eeprom_rear_cam11: qcom,eeprom11 { + compatible = "qcom,eeprom"; + cell-index = <11>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio", "cam_clk"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <120000 0>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 65 0>, + <&tlmm 21 0>, + <&pm7250b_gpios 3 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam0a-ov9282*/ + qcom,cam-sensor1 { + compatible = "qcom,cam-sensor"; + cell-index = <1>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 64 0>, + <&tlmm 20 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam1-ov9282*/ + qcom,cam-sensor6 { + compatible = "qcom,cam-sensor"; + cell-index = <6>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 65 0>, + <&tlmm 21 0>, + <&pm7250b_gpios 3 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam1-imx586/imx686*/ + qcom,cam-sensor11 { + compatible = "qcom,cam-sensor"; + cell-index = <11>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_rear_cam11>; + eeprom-src = <&eeprom_rear_cam11>; + cam_vio-supply = <&vreg_l18b_1p8>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <120000 0>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 65 0>, + <&tlmm 21 0>, + <&pm7250b_gpios 3 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + +}; + +&cam_cci1 { + eeprom_cam2: qcom,eeprom0 { + compatible = "qcom,eeprom"; + cell-index = <8>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 66 0>, + <&tlmm 77 0>, + <&pm7250b_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + eeprom_cam3: qcom,eeprom3 { + compatible = "qcom,eeprom"; + cell-index = <0>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst3>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst3>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 67 0>, + <&tlmm 78 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3"; + sensor-position = <1>; + sensor-mode = <0>; + cci-master = <1>; + qcom,cam-power-seq-type ="cam_reset","cam_vio", + "cam_clk","cam_reset"; + qcom,cam-power-seq-val = "cam_reset","cam_vio", + "cam_mclk","cam_reset"; + qcom,cam-power-seq-cfg-val = <0 1 24000000 1>; + qcom,cam-power-seq-delay = <1 0 1 18>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam3-imx577*/ + qcom,cam-sensor0 { + compatible = "qcom,cam-sensor"; + cell-index = <0>; + csiphy-sd-index = <3>; + eeprom-src = <&eeprom_cam3>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst3>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst3>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 67 0>, + <&tlmm 78 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3"; + sensor-mode = <0>; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /* GMSL 1 */ + qcom,cam-sensor4 { + compatible = "qcom,cam-sensor"; + cell-index = <4>; + csiphy-sd-index = <4>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + gpios = <&tlmm 93 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_4"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + }; + + /* GMSL 2 */ + qcom,cam-sensor5 { + compatible = "qcom,cam-sensor"; + cell-index = <5>; + csiphy-sd-index = <3>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + gpios = <&tlmm 93 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_5"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + }; + + /*cam0b-ov9282*/ + qcom,cam-sensor7 { + compatible = "qcom,cam-sensor"; + cell-index = <7>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk4_active + &cam_sensor_active_rst5>; + pinctrl-1 = <&cam_sensor_mclk4_suspend + &cam_sensor_suspend_rst5>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 68 0>, + <&tlmm 149 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK4", + "CAM_RESET5"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK4_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam2-imx577*/ + qcom,cam-sensor8 { + compatible = "qcom,cam-sensor"; + cell-index = <8>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam2>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 66 0>, + <&tlmm 77 0>, + <&pm7250b_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /* GMSL 3 */ + qcom,cam-sensor9 { + compatible = "qcom,cam-sensor"; + cell-index = <9>; + csiphy-sd-index = <4>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + gpios = <&tlmm 93 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_9"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + }; + + /* GMSL 4 */ + qcom,cam-sensor10 { + compatible = "qcom,cam-sensor"; + cell-index = <10>; + csiphy-sd-index = <4>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_l18b_1p8>; + regulator-names = "cam_vio"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + gpios = <&tlmm 93 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_10"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + }; +}; + +&soc { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + gpios-shared-pinctrl = <640>; + shared-pctrl-gpio-names = "gmsl"; + pinctrl-0 = <&cam_sensor_active_gmsl>; + pinctrl-1 = <&cam_sensor_suspend_gmsl>; + pinctrl-names = "gmsl_active", "gmsl_suspend"; + status = "ok"; + }; +}; + +&tlmm { + cam_sensor_active_gmsl: cam-sensor-active-gmsl { + /* GMSL_ENABLE */ + mux { + pins = "gpio93"; + function = "gpio"; + }; + + config { + pins = "gpio93"; + bias-pull-up; + drive-strength = <2>; /* 2 MA */ + output-high; + }; + }; + + cam_sensor_active_rst5: cam-sensor-active-rst5 { + /* RESET 5 */ + mux { + pins = "gpio115"; + function = "gpio"; + }; + + config { + pins = "gpio115"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_gmsl: cam-sensor-suspend-gmsl { + /* GMSL_ENABLE */ + mux { + pins = "gpio93"; + function = "gpio"; + }; + + config { + pins = "gpio93"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst5: cam-sensor-suspend-rst5 { + /* RESET 5 */ + mux { + pins = "gpio115"; + function = "gpio"; + }; + + config { + pins = "gpio115"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine-camx.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine-camx.dtso new file mode 100644 index 0000000000000..eb183d7dbd3d5 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine-camx.dtso @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "qcs6490-camera.dtsi" +#include "qcs6490-rb3gen2-camera-sensor.dtsi" + +&camss { + status = "disabled"; +}; + +&cci1 { + status = "disabled"; +}; From 42718a177e9387be0fcbed07f23a9b3b84b2c09b Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Sun, 19 Oct 2025 11:20:50 +0530 Subject: [PATCH 259/438] QCLINUX: arm64: dts: qcom: Add monaco camx overlay dts Add CAMX overlay dts file for Monaco boards. This change also enables the compilation of the CAMX overlay for Monaco boards. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/Makefile | 8 + .../boot/dts/qcom/monaco-camera-sensor.dtsi | 380 +++ arch/arm64/boot/dts/qcom/monaco-camera.dtsi | 2505 +++++++++++++++++ .../dts/qcom/monaco-evk-camera-sensor.dtsi | 794 ++++++ arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso | 107 + .../boot/dts/qcom/qcs8300-ride-camx.dtso | 16 + 6 files changed, 3810 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/monaco-camera.dtsi create mode 100644 arch/arm64/boot/dts/qcom/monaco-evk-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso create mode 100644 arch/arm64/boot/dts/qcom/qcs8300-ride-camx.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index b420c6f2bd0b3..7bc3445f34870 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -397,11 +397,19 @@ lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb +monaco-evk-camx-dtbs := monaco-evk.dtb monaco-evk-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camx.dtb + qcs6490-rb3gen2-vision-mezzanine-camx-dtbs := qcs6490-rb3gen2-vision-mezzanine.dtb \ qcs6490-rb3gen2-vision-mezzanine-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine-camx.dtb +qcs8300-ride-camx-dtbs:= qcs8300-ride.dtb qcs8300-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride-camx.dtb + qcs9100-ride-camx-dtbs:= qcs9100-ride.dtb sa8775p-ride-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-camx.dtb diff --git a/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi new file mode 100644 index 0000000000000..0023c97edce91 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&cam_cci0 { + /* GMSL deserializer 0 */ + qcom,cam-gmsl-deserializer0 { + cell-index = <0>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser0_port0: endpoint { + remote-endpoint = <&gmsl_sensor0_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser0_port1: endpoint { + remote-endpoint = <&gmsl_sensor1_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser0_port2: endpoint { + remote-endpoint = <&gmsl_sensor2_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser0_port3: endpoint { + remote-endpoint = <&gmsl_sensor3_ep>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 0 */ + qcom,cam-gmsl-sensor0 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <0>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor0_ep: endpoint { + remote-endpoint = <&deser0_port0>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 1 */ + qcom,cam-gmsl-sensor1 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <1>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor1_ep: endpoint { + remote-endpoint = <&deser0_port1>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 2 */ + qcom,cam-gmsl-sensor2 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <2>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor2_ep: endpoint { + remote-endpoint = <&deser0_port2>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 3 */ + qcom,cam-gmsl-sensor3 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <3>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor3_ep: endpoint { + remote-endpoint = <&deser0_port3>; + }; + }; + }; +}; + +&cam_cci1 { + /* GMSL deserializer 1 */ + qcom,cam-gmsl-deserializer1 { + cell-index = <1>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 74 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser1_port0: endpoint { + remote-endpoint = <&gmsl_sensor4_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser1_port1: endpoint { + remote-endpoint = <&gmsl_sensor5_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser1_port2: endpoint { + remote-endpoint = <&gmsl_sensor6_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser1_port3: endpoint { + remote-endpoint = <&gmsl_sensor7_ep>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 0 */ + qcom,cam-gmsl-sensor4 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <4>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor4_ep: endpoint { + remote-endpoint = <&deser1_port0>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 1 */ + qcom,cam-gmsl-sensor5 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <5>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor5_ep: endpoint { + remote-endpoint = <&deser1_port1>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 2 */ + qcom,cam-gmsl-sensor6 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <6>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor6_ep: endpoint { + remote-endpoint = <&deser1_port2>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 3 */ + qcom,cam-gmsl-sensor7 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <7>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor7_ep: endpoint { + remote-endpoint = <&deser1_port3>; + }; + }; + }; +}; + +&cam_cci2 { + /* GMSL deserializer 2 */ + qcom,cam-gmsl-deserializer2 { + cell-index = <2>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 75 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET2"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser2_port0: endpoint { + remote-endpoint = <&gmsl_sensor8_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser2_port1: endpoint { + remote-endpoint = <&gmsl_sensor9_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser2_port2: endpoint { + remote-endpoint = <&gmsl_sensor10_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser2_port3: endpoint { + remote-endpoint = <&gmsl_sensor11_ep>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 0 */ + qcom,cam-gmsl-sensor8 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <8>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor8_ep: endpoint { + remote-endpoint = <&deser2_port0>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 1 */ + qcom,cam-gmsl-sensor9 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <9>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor9_ep: endpoint { + remote-endpoint = <&deser2_port1>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 2 */ + qcom,cam-gmsl-sensor10 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <10>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor10_ep: endpoint { + remote-endpoint = <&deser2_port2>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 3 */ + qcom,cam-gmsl-sensor11 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <11>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor11_ep: endpoint { + remote-endpoint = <&deser2_port3>; + }; + }; + }; +}; + +&soc { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + gpios-shared = <518 519 520 521>; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi new file mode 100644 index 0000000000000..bd619b507831f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi @@ -0,0 +1,2505 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&soc { + cam_cci0: qcom,cci0@ac13000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac13000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x13000>; + interrupts = ; + interrupt-names = "CCI0"; + operating-points-v2 = <&cci0_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>, + <&camcc CAM_CC_CCI_0_CLK>; + clock-names = "cci_0_clk_src", + "cci_0_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_0_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci_i2c_scl0_active &cci_i2c_sda0_active>; + pinctrl-1 = <&cci_i2c_scl0_suspend &cci_i2c_sda0_suspend>; + pinctrl-2 = <&cci_i2c_scl1_active &cci_i2c_sda1_active>; + pinctrl-3 = <&cci_i2c_scl1_suspend &cci_i2c_sda1_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <0>; + status = "ok"; + + cci0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci0: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci0: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci0: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci0: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_cci1: qcom,cci1@ac14000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac14000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x14000>; + interrupts = ; + interrupt-names = "CCI1"; + operating-points-v2 = <&cci1_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>, + <&camcc CAM_CC_CCI_1_CLK>; + clock-names = "cci_1_clk_src", + "cci_1_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_1_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci_i2c_scl2_active &cci_i2c_sda2_active>; + pinctrl-1 = <&cci_i2c_scl2_suspend &cci_i2c_sda2_suspend>; + pinctrl-2 = <&cci_i2c_scl3_active &cci_i2c_sda3_active>; + pinctrl-3 = <&cci_i2c_scl3_suspend &cci_i2c_sda3_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <1>; + status = "ok"; + + cci1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci1: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci1: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci1: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci1: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_cci2: qcom,cci2@ac15000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac15000 0x0 0x1000>; + reg-names = "cci"; + reg-cam-base = <0x15000>; + interrupts = ; + interrupt-names = "CCI2"; + operating-points-v2 = <&cci2_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_2_CLK_SRC>, + <&camcc CAM_CC_CCI_2_CLK>; + clock-names = "cci_2_clk_src", + "cci_2_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_2_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci_i2c_scl4_active &cci_i2c_sda4_active>; + pinctrl-1 = <&cci_i2c_scl4_suspend &cci_i2c_sda4_suspend>; + pinctrl-2 = <&cci_i2c_scl5_active &cci_i2c_sda5_active>; + pinctrl-3 = <&cci_i2c_scl5_suspend &cci_i2c_sda5_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <2>; + status = "ok"; + + cci2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci2: qcom,i2c-custom-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_400Khz_cci2: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_1Mhz_cci2: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <1>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + + i2c_freq_100Khz_cci2: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "ok"; + }; + }; + + cam_csiphy0: qcom,csiphy0@ac9c000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0x0ac9c000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy0_opp_table>; + reg-cam-base = <0x9c000>; + interrupts = ; + interrupt-names = "CSIPHY0"; + csi-vdd-1p2-supply = <&vreg_l5a>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1200000 912000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy0_clk", + "csi0phytimer_clk_src", + "csi0phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + cell-index = <0>; + aggregator-rx; + status = "ok"; + + csiphy0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy1: qcom,csiphy1@ac9e000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0xac9e000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy1_opp_table>; + reg-cam-base = <0x9e000>; + interrupts = ; + interrupt-names = "CSIPHY1"; + csi-vdd-1p2-supply = <&vreg_l5a>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1200000 912000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy1_clk", + "csi1phytimer_clk_src", + "csi1phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + cell-index = <1>; + aggregator-rx; + status = "ok"; + + csiphy1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy2: qcom,csiphy2@aca0000 { + compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy"; + reg = <0x0 0xaca0000 0x0 0x2000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy2_opp_table>; + reg-cam-base = <0xa0000>; + interrupts = ; + interrupt-names = "CSIPHY2"; + csi-vdd-1p2-supply = <&vreg_l5a>; + csi-vdd-0p9-supply = <&vreg_l4a>; + regulator-names = "csi-vdd-1p2", "csi-vdd-0p9"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + rgltr-min-voltage = <1200000 880000>; + rgltr-max-voltage = <1200000 912000>; + rgltr-load-current = <8900 15900>; + shared-clks = <1 0 0 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", + "csiphy2_clk", + "csi2phytimer_clk_src", + "csi2phytimer_clk"; + src-clock-name = "cphy_rx_clk_src"; + clock-cntl-level = "lowsvs"; + clock-rates = <400000000 0 400000000 0>; + cell-index = <2>; + aggregator-rx; + status = "ok"; + + csiphy2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy_tpg13: qcom,tpg13@acac000 { + compatible = "qcom,cam-tpg1031"; + reg = <0x0 0xacac000 0x0 0x400>, + <0x0 0xac11000 0x0 0x1000>; + reg-names = "tpg0", "cam_cpas_top"; + reg-cam-base = <0xac000 0x11000>; + operating-points-v2 = <&csiphy_tpg0_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + interrupts = ; + interrupt-names = "tpg0"; + shared-clks = <1 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cphy_rx_clk_src", + "csid_csiphy_rx_clk"; + clock-rates = <400000000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cphy_rx_clk_src"; + cell-index = <13>; + phy-id = <0>; + status = "ok"; + + csiphy_tpg0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy_tpg14: qcom,tpg14@acad000 { + compatible = "qcom,cam-tpg1031"; + reg = <0x0 0xacad000 0x0 0x400>, + <0x0 0xac11000 0x0 0x1000>; + reg-names = "tpg1", "cam_cpas_top"; + reg-cam-base = <0xad000 0x11000>; + operating-points-v2 = <&csiphy_tpg1_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + interrupts = ; + interrupt-names = "tpg1"; + shared-clks = <1 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cphy_rx_clk_src", + "csid_csiphy_rx_clk"; + clock-rates = <400000000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cphy_rx_clk_src"; + cell-index = <14>; + phy-id = <1>; + status = "ok"; + + csiphy_tpg1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_csiphy_tpg15: qcom,tpg15@acae000 { + compatible = "qcom,cam-tpg1031"; + reg = <0x0 0xacae000 0x0 0x400>, + <0x0 0xac11000 0x0 0x1000>; + reg-names = "tpg2", "cam_cpas_top"; + reg-cam-base = <0xae000 0x11000>; + operating-points-v2 = <&csiphy_tpg2_opp_table>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + interrupts = ; + interrupt-names = "tpg2"; + shared-clks = <1 0>; + clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cphy_rx_clk_src", + "csid_csiphy_rx_clk"; + clock-rates = <400000000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cphy_rx_clk_src"; + cell-index = <15>; + phy-id = <2>; + status = "ok"; + + csiphy_tpg2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,cam-cdm-intf { + compatible = "qcom,cam-cdm-intf"; + cell-index = <0>; + label = "cam-cdm-intf"; + num-hw-cdm = <1>; + cdm-client-names = "vfe"; + status = "ok"; + }; + + qcom,cam-cpas { + compatible = "qcom,cam-cpas"; + label = "cpas"; + arch-compat = "cpas_top"; + reg = <0x0 0xac11000 0x0 0x1000>, + <0x0 0xac1A000 0x0 0x9400>, + <0x0 0xbbf0000 0x0 0x1f00>; + reg-names = "cam_cpas_top", "cam_camnoc", "cam_rpmh"; + reg-cam-base = <0x11000 0x1A000 0x0bbf0000>; + interrupts = ; + interrupt-names = "cpas_camnoc"; + camnoc-axi-min-ib-bw = <3000000000>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&gcc GCC_CAMERA_SF_AXI_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CORE_AHB_CLK>, + <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_FAST_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "gcc_camera_sf_axi_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk", + "cam_cc_core_ahb_clk", + "cam_cc_fast_ahb_clk_src", + "cam_cc_cpas_fast_ahb_clk", + "cam_cc_camnoc_axi_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_qdss_debug_xo_clk"; + src-clock-name = "cam_cc_fast_ahb_clk_src"; + clock-rates = <0 0 0 0 0 0 0 0 0 0 0>, + <0 0 0 80000000 0 0 300000000 0 400000000 0 0>, + <0 0 0 80000000 0 0 400000000 0 400000000 0 0>; + clock-cntl-level = "suspend", "svs_l1", "nominal"; + clock-names-option = "cam_icp_clk"; + clocks-option = <&camcc CAM_CC_ICP_CLK>; + clock-rates-option = <480000000>; + operating-points-v2 = <&cpas_opp_table>; + control-camnoc-axi-clk; + camnoc-bus-width = <32>; + camnoc-axi-clk-bw-margin-perc = <20>; + cam-icc-path-names = "cam_ahb"; + interconnects = <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_CAMERA_CFG 0>, + <&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>, + <&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI1 0>, + <&mmss_noc MASTER_CAMNOC_ICP 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp"; + cam-ahb-num-cases = <7>; + cam-ahb-bw-KBps = <0 0>, <0 76800>, <0 150000>, <0 150000>, + <0 300000>, <0 300000>, <0 300000>; + vdd-corners = ; + vdd-corner-ahb-mapping = "suspend", "lowsvs", "lowsvs", "svs", "svs_l1", + "nominal", "nominal", "nominal", "turbo", "turbo"; + client-id-based; + client-names = "csiphy0", "csiphy1", "csiphy2", + "cci0", "cci1", "cci2", + "csid0", "csid1", "csid2", "csid3", + "csid4", "csid5", "csid6", "ife0", + "ife1", "ife2", "ife3", "ife4", + "ife5", "ife6", "ipe0", "sfe0", "sfe1", + "cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2", + "rt-cdm3", "icp0", "tpg13", "tpg14", "tpg15"; + enable-secure-qos-update; + cell-index = <0>; + status = "ok"; + + cpas_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + + camera-bus-nodes { + level0-nodes { + level-index = <0>; + + icp_all_rd: icp-all-rd { + cell-index = <0>; + node-name = "icp-all-rd"; + client-name = "icp0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level2_icp_rd>; + }; + + ife_0_wr_0: ife-0-wr-0 { + cell-index = <1>; + node-name = "ife-0-wr-0"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_0_wr_1: ife-0-wr-1 { + cell-index = <2>; + node-name = "ife-0-wr-1"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr1>; + }; + + ife_1_wr_0: ife-1-wr-0 { + cell-index = <3>; + node-name = "ife-1-wr-0"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_1_wr_1: ife-1-wr-1 { + cell-index = <3>; + node-name = "ife-1-wr-1"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr1>; + }; + + ife_lite_0_wr_0: ife-lite-0-wr-0 { + cell-index = <4>; + node-name = "ife-lite-0-wr-0"; + client-name = "ife2"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_1_wr_0: ife-lite-1-wr-0 { + cell-index = <5>; + node-name = "ife-lite-1-wr-0"; + client-name = "ife3"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_2_wr_0: ife-lite-2-wr-0 { + cell-index = <6>; + node-name = "ife-lite-2-wr-0"; + client-name = "ife4"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_3_wr_0: ife-lite-3-wr-0 { + cell-index = <7>; + node-name = "ife-lite-3-wr-0"; + client-name = "ife5"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ife_lite_4_wr_0: ife-lite-4-wr-0 { + cell-index = <8>; + node-name = "ife-lite-4-wr-0"; + client-name = "ife6"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_wr0>; + }; + + ipe_0_rd_all: ipe-0-rd-all { + cell-index = <9>; + node-name = "ipe-0-rd-all"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level2_nrt_rd1>; + }; + + ipe_0_wr_2: ipe-0-wr-2 { + cell-index = <10>; + node-name = "ipe-0-wr-2"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level2_nrt_wr2>; + }; + + ipe_cdm0_all_rd: ipe-cdm0-all-rd { + cell-index = <11>; + node-name = "ipe-cdm0-all-rd"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 { + cell-index = <12>; + node-name = "rt-cdm0-all-rd-2"; + client-name = "rt-cdm0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 { + cell-index = <13>; + node-name = "rt-cdm1-all-rd-2"; + client-name = "rt-cdm1"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 { + cell-index = <14>; + node-name = "rt-cdm2-all-rd-2"; + client-name = "rt-cdm2"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 { + cell-index = <15>; + node-name = "rt-cdm3-all-rd-2"; + client-name = "rt-cdm3"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt_rd2>; + }; + + sfe_0_rd_0: sfe-0-rd-0 { + cell-index = <16>; + node-name = "sfe-0-rd-0"; + client-name = "sfe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_rd0>; + }; + + sfe_1_rd_0: sfe-1-rd-0 { + cell-index = <17>; + node-name = "sfe-1-rd-0"; + client-name = "sfe1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt_rd0>; + }; + }; + + level1-nodes { + level-index = <1>; + camnoc-max-needed; + + level1_nrt_rd2: level1-nrt-rd2 { + cell-index = <22>; + node-name = "level1-nrt-rd2"; + parent-node = <&level2_nrt_rd2>; + traffic-merge-type = ; + }; + + level1_rt_rd0: level1-rt-read0 { + cell-index = <21>; + node-name = "level1-rt-rd0"; + parent-node = <&level2_rt_rd0>; + traffic-merge-type = ; + }; + + level1_rt_wr0: level1-rt-wr0 { + cell-index = <19>; + node-name = "level1-rt-wr0"; + parent-node = <&level2_rt_wr0>; + traffic-merge-type = ; + }; + + level1_rt_wr1: level1-rt-wr1 { + cell-index = <20>; + node-name = "level1-rt-wr1"; + parent-node = <&level2_rt_wr1>; + traffic-merge-type = ; + }; + }; + + level2-nodes { + level-index = <2>; + camnoc-max-needed; + + level2_icp_rd: level2-icp-rd { + cell-index = <23>; + node-name = "level2-icp-rd"; + parent-node = <&level3_nrt1_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt_rd1: level2-nrt-rd1 { + cell-index = <24>; + node-name = "level2-nrt-rd1"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt_rd2: level2-nrt-rd2 { + cell-index = <25>; + node-name = "level2-nrt-rd2"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_nrt_wr2: level2-nrt-wr2 { + cell-index = <26>; + node-name = "level2-nrt-wr2"; + parent-node = <&level3_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt_rd0: level2-rt-read0 { + cell-index = <27>; + node-name = "level2-rt-rd0"; + parent-node = <&level3_rt_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt_wr0: level2-rt-wr0 { + cell-index = <28>; + node-name = "level2-rt-wr0"; + parent-node = <&level3_rt_rd_wr_sum>; + traffic-merge-type = ; + }; + + level2_rt_wr1: level2-rt-wr1 { + cell-index = <29>; + node-name = "level2-rt-wr1"; + parent-node = <&level3_rt_rd_wr_sum>; + traffic-merge-type = ; + }; + }; + + level3-nodes { + level-index = <3>; + + level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum { + cell-index = <30>; + node-name = "level3-nrt0-rd-wr-sum"; + traffic-merge-type = ; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_sf_0"; + }; + }; + + level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum { + cell-index = <31>; + node-name = "level3-nrt1-rd-wr-sum"; + traffic-merge-type = ; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_sf_icp"; + }; + }; + + level3_rt_rd_wr_sum: level3-rt-rd-wr-sum { + cell-index = <32>; + node-name = "level3-rt-rd-wr-sum"; + traffic-merge-type = ; + ib-bw-voting-needed; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_hf_0"; + }; + }; + }; + }; + }; + + qcom,cam-icp { + compatible = "qcom,cam-icp"; + compat-hw-name = "qcom,icp", + "qcom,ipe0"; + num-icp = <1>; + num-ipe = <1>; + icp_use_pil; + status = "ok"; + }; + + qcom,cam-i3c-id-table { + compatible = "qcom,cam-i3c-id-table"; + i3c-sensor-id-table = <0x1B0 0x0766>; + i3c-eeprom-id-table = <>; + i3c-actuator-id-table = <>; + i3c-ois-id-table = <>; + status = "disabled"; + }; + + qcom,cam-isp { + compatible = "qcom,cam-isp"; + arch-compat = "ife"; + status = "ok"; + }; + + qcom,cam-req-mgr { + compatible = "qcom,cam-req-mgr"; + status = "ok"; + }; + + qcom,camera-main { + compatible = "qcom,camera"; + status = "ok"; + }; + + qcom,cam-smmu { + compatible = "qcom,msm-cam-smmu", "simple-bus"; + force_cache_allocs; + status = "ok"; + + msm-cam-smmu-cdm { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0860 0x400>, + <&apps_smmu 0x0C60 0x400>; + cam-smmu-label = "rt-cdm"; + dma-coherent; + multiple-client-devices; + rt_cdm_iova_mem_map: iova-mem-map { + iova-mem-region-io { + /* IO region is approximately 4.0 GB */ + iova-region-name = "io"; + /* 1 MB pad for start */ + iova-region-start = <0x100000>; + /* 1 MB pad for end */ + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-icp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0800 0x400>, + <&apps_smmu 0x0840 0x480>, + <&apps_smmu 0x08C0 0x480>, + <&apps_smmu 0x0C00 0x400>, + <&apps_smmu 0x0C40 0x480>, + <&apps_smmu 0x0CC0 0x480>; + cam-smmu-label = "icp"; + qcom,iommu-faults = "stall-disable", "non-fatal"; + iova-region-discard = <0xe0000000 0x800000>; + dma-coherent; + + icp_iova_mem_map: iova-mem-map { + iova-mem-region-fwuncached-region { + /* FW uncached region is 7MB long */ + iova-region-name = "fw_uncached"; + iova-region-start = <0x10400000>; + iova-region-len = <0x700000>; + iova-region-id = <0x6>; + subregion_support; + status = "ok"; + /* Used for HFI queues/sec heap */ + iova-mem-region-generic-region { + iova-region-name = "icp_hfi"; + iova-region-start = <0x10400000>; + iova-region-len = <0x200000>; + iova-region-id = <0x0>; + }; + }; + + iova-mem-region-io { + /* IO region is approximately 3.8 GB */ + iova-region-name = "io"; + iova-region-start = <0x10c00000>; + iova-region-len = <0xee300000>; + iova-region-id = <0x3>; + iova-region-discard = <0xe0000000 0x800000>; + status = "ok"; + }; + + iova-mem-region-qdss { + /* QDSS region is appropriate 1MB */ + iova-region-name = "qdss"; + iova-region-start = <0x10b00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x5>; + qdss-phy-addr = <0x16790000>; + status = "ok"; + }; + + iova-mem-region-shared { + /* Shared region is ~250MB long */ + iova-region-name = "shared"; + iova-region-start = <0x800000>; + iova-region-len = <0xfc00000>; + iova-region-id = <0x1>; + status = "ok"; + }; + + }; + }; + + msm-cam-smmu-ife { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x2400 0x0020>, + <&apps_smmu 0x2420 0x0020>; + cam-smmu-label = "ife", "sfe"; + multiple-client-devices; + dma-coherent; + + ife_iova_mem_map: iova-mem-map { + /* IO region is approximately 64 GB */ + iova-mem-region-io { + iova-region-name = "io"; + /* start address: 0x100000 */ + /* leaving 1 MB pad at start */ + iova-region-start = <0x100000>; + /* Length: 0xfffe00000 */ + /* leaving 1 MB pad at end */ + iova-region-len = <0xffe00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + + msm-cam-smmu-secure { + compatible = "qcom,msm-cam-smmu-cb"; + cam-smmu-label = "cam-secure"; + qcom,secure-cb; + }; + }; + + qcom,cam-sync { + compatible = "qcom,cam-sync"; + status = "ok"; + }; + + cam_csid0: qcom,csid0 { + compatible = "qcom,csid692"; + reg = <0x0 0xac7a000 0x0 0xf01>, + <0x0 0xac78000 0x0 0x1000>; + reg-names = "csid0", "csid_top"; + reg-cam-base = <0x7a000 0x78000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "csid0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CSID_CLK_SRC>, + <&camcc CAM_CC_CSID_CLK>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cam_cc_csid_clk_src", + "cam_cc_csid_clk", + "cam_cc_csid_csiphy_rx_clk"; + clock-rates = <400000000 0 0>; + clock-cntl-level = "svs_l1"; + src-clock-name = "cam_cc_csid_clk_src"; + operating-points-v2 = <&csid0_opp_table>; + clock-control-debugfs = "true"; + cell-index = <0>; + status = "ok"; + + csid0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + cam_csid1: qcom,csid1 { + compatible = "qcom,csid692"; + reg = <0x0 0xac7c000 0x0 0xf01>, + <0x0 0xac78000 0x0 0x1000>; + reg-names = "csid1", "csid_top"; + reg-cam-base = <0x7c000 0x78000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "csid1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CSID_CLK_SRC>, + <&camcc CAM_CC_CSID_CLK>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>; + clock-names = "cam_cc_csid_clk_src", + "cam_cc_csid_clk", + "cam_cc_csid_csiphy_rx_clk"; + clock-rates = <400000000 0 0>; + clock-cntl-level = "svs_l1"; + src-clock-name = "cam_cc_csid_clk_src"; + operating-points-v2 = <&csid1_opp_table>; + clock-control-debugfs = "true"; + cell-index = <1>; + status = "ok"; + + csid1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + cam_csid_lite0: qcom,csid-lite0 { + compatible = "qcom,csid-lite692"; + reg = <0x0 0xac84000 0x0 0xf01>; + reg-names = "csid-lite0"; + reg-cam-base = <0x84000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite0_opp_table>; + clock-control-debugfs = "true"; + cell-index = <2>; + status = "ok"; + + csid_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite1: qcom,csid-lite1 { + compatible = "qcom,csid-lite692"; + reg = <0x0 0xac88000 0x0 0xf01>; + reg-names = "csid-lite1"; + reg-cam-base = <0x88000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "csid-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite1_opp_table>; + clock-control-debugfs = "true"; + cell-index = <3>; + status = "ok"; + + csid_lite1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite3: qcom,csid-lite3 { + cell-index = <5>; + compatible = "qcom,csid-lite692"; + reg-names = "csid-lite3"; + reg = <0x0 0xac90000 0x0 0xf01>; + reg-cam-base = <0x90000>; + rt-wrapper-base = <0x83000>; + interrupt-names = "csid-lite3"; + interrupts = ; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clock-names = + "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clocks = + <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-rates = + <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite3_opp_table>; + + clock-control-debugfs = "true"; + status = "ok"; + + csid_lite3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite2: qcom,csid-lite2 { + cell-index = <4>; + compatible = "qcom,csid-lite692"; + reg-names = "csid-lite2"; + reg = <0x0 0xac8c000 0x0 0xf01>; + reg-cam-base = <0x8c000>; + rt-wrapper-base = <0x83000>; + interrupt-names = "csid-lite2"; + interrupts = ; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clock-names = + "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clocks = + <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-rates = + <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite2_opp_table>; + + clock-control-debugfs = "true"; + status = "ok"; + + csid_lite2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_csid_lite4: qcom,csid-lite4 { + cell-index = <6>; + compatible = "qcom,csid-lite692"; + reg-names = "csid-lite4"; + reg = <0x0 0xac94000 0x0 0xf01>; + reg-cam-base = <0x94000>; + rt-wrapper-base = <0x83000>; + interrupt-names = "csid-lite4"; + interrupts = ; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clock-names = + "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clocks = + <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-rates = + <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite4_opp_table>; + + clock-control-debugfs = "true"; + status = "ok"; + + csid_lite4_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_icp: qcom,icp { + compatible = "qcom,cam-icp_v3_0"; + reg = <0x0 0xac01000 0x0 0x400>, + <0x0 0xac01800 0x0 0x400>, + <0x0 0xac04000 0x0 0x1000>; + reg-names ="icp_csr", "icp_cirq", "icp_wd0"; + reg-cam-base = <0x1000 0x1800 0x4000>; + interrupts = ; + interrupt-names = "icp"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + memory-region = <&camera_mem>; + src-clock-name = "cam_cc_icp_clk_src"; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_ICP_AHB_CLK>, + <&camcc CAM_CC_ICP_CLK_SRC>, + <&camcc CAM_CC_ICP_CLK>; + clock-names = "cam_cc_soc_fast_ahb_clk_src", + "cam_cc_icp_ahb_clk", + "cam_cc_icp_clk_src", + "cam_cc_icp_clk"; + clock-rates = <300000000 0 480000000 0>, + <400000000 0 600000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + nrt-device; + fw_name = "CAMERA_ICP"; + ubwc-ipe-fetch-cfg = <0x707b 0x7083>; + ubwc-ipe-write-cfg = <0x161ef 0x1620f>; + qos-val = <0xa0a>; + operating-points-v2 = <&icp_opp_table>; + icp-version = <0x0300>; + cam_hw_pid = <12>; + cell-index = <0>; + status = "ok"; + + icp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe0: qcom,ife0 { + compatible = "qcom,vfe692"; + reg = <0x0 0xac4d000 0x0 0xf000>, + <0x0 0xac1a000 0x0 0x9400>; + reg-names = "ife0", "cam_camnoc"; + reg-cam-base = <0x4d000 0x1a000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "ife0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_CLK_SRC>, + <&camcc CAM_CC_IFE_0_FAST_AHB_CLK>; + clock-names = "cam_cc_cpas_ife_0_clk", + "cam_cc_ife_0_clk", + "cam_cc_ife_0_clk_src", + "cam_cc_ife_0_fast_ahb_clk"; + clock-rates = <0 0 480000000 0>, + <0 0 600000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_0_clk_src"; + operating-points-v2 = <&vfe0_opp_table>; + clock-control-debugfs = "true"; + ubwc-static-cfg = <0x1026 0x1036>; + cam_hw_pid = <8 16>; + cell-index = <0>; + status = "ok"; + + vfe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe1: qcom,ife1 { + compatible = "qcom,vfe692"; + reg = <0x0 0xac60000 0x0 0xf000>, + <0x0 0xac1a000 0x0 0x9400>; + reg-names = "ife1", "cam_camnoc"; + reg-cam-base = <0x60000 0x1a000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "ife1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_CLK_SRC>, + <&camcc CAM_CC_IFE_1_FAST_AHB_CLK>; + clock-names = "cam_cc_cpas_ife_1_clk", + "cam_cc_ife_1_clk", + "cam_cc_ife_1_clk_src", + "cam_cc_ife_1_fast_ahb_clk"; + clock-rates = <0 0 480000000 0>, + <0 0 600000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_1_clk_src"; + operating-points-v2 = <&vfe1_opp_table>; + clock-control-debugfs = "true"; + ubwc-static-cfg = <0x1026 0x1036>; + cam_hw_pid = <9 17>; + cell-index = <1>; + status = "ok"; + + vfe1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite0: qcom,ife-lite0 { + compatible = "qcom,vfe-lite692"; + reg = <0x0 0xac84000 0x0 0x1d00>; + reg-names = "ife-lite0"; + reg-cam-base = <0x84000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite0_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <2>; + status = "ok"; + + vfe_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite1: qcom,ife-lite1 { + compatible = "qcom,vfe-lite692"; + reg = <0x0 0xac88000 0x0 0x1d00>; + reg-names = "ife-lite1"; + reg-cam-base = <0x88000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite1_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <3>; + status = "ok"; + + vfe_lite1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite2: qcom,ife-lite2 { + compatible = "qcom,vfe-lite692"; + reg = <0x0 0xac8c000 0x0 0x1d00>; + reg-names = "ife-lite2"; + reg-cam-base = <0x8c000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite2"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite2_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <4>; + status = "ok"; + + vfe_lite2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite3: qcom,ife-lite3 { + compatible = "qcom,vfe-lite692"; + reg = <0x0 0xac90000 0x0 0x1d00>; + reg-names = "ife-lite3"; + reg-cam-base = <0x90000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite3"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite3_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <5>; + status = "ok"; + + vfe_lite3_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_vfe_lite4: qcom,ife-lite4 { + compatible = "qcom,vfe-lite692"; + reg = <0x0 0xac94000 0x0 0x1d00>; + reg-names = "ife-lite4"; + reg-cam-base = <0x94000>; + rt-wrapper-base = <0x83000>; + interrupts = ; + interrupt-names = "ife-lite4"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite4_opp_table>; + clock-control-debugfs = "true"; + cam_hw_pid = <27>; + cell-index = <6>; + status = "ok"; + + vfe_lite4_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_ipe0: qcom,ipe0 { + compatible = "qcom,cam-ipe"; + reg = <0x0 0xac2d000 0x0 0x18000>; + reg-names = "ipe0_top"; + reg-cam-base = <0x2d000>; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + src-clock-name = "cam_cc_ipe_clk_src"; + clocks = <&camcc CAM_CC_CPAS_IPE_CLK>, + <&camcc CAM_CC_IPE_AHB_CLK>, + <&camcc CAM_CC_IPE_CLK>, + <&camcc CAM_CC_IPE_CLK_SRC>, + <&camcc CAM_CC_IPE_FAST_AHB_CLK>, + <&camcc CAM_CC_FAST_AHB_CLK_SRC>; + clock-names = "cam_cc_cpas_ipe_clk", + "cam_cc_ipe_ahb_clk", + "cam_cc_ipe_clk", + "cam_cc_ipe_clk_src", + "cam_cc_ipe_fast_ahb_clk", + "cam_cc_fast_ahb_clk_src"; + clock-rates = <0 0 0 480000000 0 300000000>, + <0 0 0 600000000 0 400000000>; + clock-cntl-level = "svs_l1", "nominal"; + operating-points-v2 = <&ipe0_opp_table>; + nrt-device; + cam_hw_pid = <14 15>; + cell-index = <0>; + status = "ok"; + + ipe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + qcom,rt-cdm0 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac26000 0x0 0x1000>; + reg-names = "rt-cdm0"; + reg-cam-base = <0x26000>; + interrupts = ; + interrupt-names = "rt-cdm0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_fast_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_fast_ahb_clk_src"; + clock-rates = <300000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table0>; + clock-cntl-level = "svs"; + cdm-client-names = "ife0", "dualife0"; + single-context-cdm; + cell-index = <0>; + status = "ok"; + + cdm_cpas_opp_table0: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,rt-cdm1 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac27000 0x0 0x1000>; + reg-names = "rt-cdm1"; + reg-cam-base = <0x27000>; + interrupts = ; + interrupt-names = "rt-cdm1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_fast_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_fast_ahb_clk_src"; + clock-rates = <300000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table1>; + clock-cntl-level = "svs_l1"; + cdm-client-names = "ife1", "dualife1"; + single-context-cdm; + cell-index = <1>; + status = "ok"; + + cdm_cpas_opp_table1: opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,rt-cdm2 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac28000 0x0 0x1000>; + reg-names = "rt-cdm2"; + reg-cam-base = <0x28000>; + interrupts = ; + interrupt-names = "rt-cdm2"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_slow_ahb_clk_src"; + clock-rates = <80000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table2>; + clock-cntl-level = "svs_l1"; + cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6"; + single-context-cdm; + cell-index = <2>; + status = "ok"; + + cdm_cpas_opp_table2: opp-table { + compatible = "operating-points-v2"; + + opp-80000000 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + qcom,rt-cdm3 { + compatible = "qcom,cam-rt-cdm2_1"; + label = "rt-cdm"; + reg = <0x0 0xac29000 0x0 0x1000>; + reg-names = "rt-cdm3"; + reg-cam-base = <0x29000>; + interrupts = ; + interrupt-names = "rt-cdm3"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk"; + src-clock-name = "cam_cc_slow_ahb_clk_src"; + clock-rates = <80000000 0>; + operating-points-v2 = <&cdm_cpas_opp_table3>; + clock-cntl-level = "svs"; + cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6"; + single-context-cdm; + cell-index = <3>; + status = "ok"; + + cdm_cpas_opp_table3: opp-table { + compatible = "operating-points-v2"; + + opp-80000000 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_sfe_lite0: qcom,sfe-lite0 { + compatible = "qcom,sfe-lite692"; + reg = <0x0 0xac74000 0x0 0x1000>; + reg-names = "sfe-lite0"; + reg-cam-base = <0x74000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "sfe-lite0"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>, + <&camcc CAM_CC_SFE_LITE_0_CLK>, + <&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>; + clock-names = "cam_cc_sfe_lite_0_fast_ahb_clk", + "cam_cc_sfe_lite_0_clk", + "cam_cc_cpas_sfe_lite_0_clk"; + clock-rates = <0 480000000 300000000>, + <0 600000000 400000000>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_sfe_lite_0_clk"; + operating-points-v2 = <&cam_sfe_lite_opp_table0>; + cam_hw_pid = <4>; + clock-control-debugfs = "true"; + cell-index = <0>; + status = "ok"; + + cam_sfe_lite_opp_table0: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_sfe_lite1: qcom,sfe-lite1 { + compatible = "qcom,sfe-lite692"; + reg = <0x0 0xac75000 0x0 0x1000>; + reg-names = "sfe-lite1"; + reg-cam-base = <0x75000>; + rt-wrapper-base = <0x4d000>; + interrupts = ; + interrupt-names = "sfe-lite1"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_SFE_LITE_1_FAST_AHB_CLK>, + <&camcc CAM_CC_SFE_LITE_1_CLK>, + <&camcc CAM_CC_CPAS_SFE_LITE_1_CLK>; + clock-names = "cam_cc_sfe_lite_1_fast_ahb_clk", + "cam_cc_sfe_lite_1_clk", + "cam_cc_cpas_sfe_1_clk"; + clock-rates = <0 480000000 300000000>, + <0 600000000 400000000>; + clock-cntl-level = "svs_l1", "nominal"; + src-clock-name = "cam_cc_sfe_lite_1_clk"; + operating-points-v2 = <&cam_sfe_lite_opp_table1>; + cam_hw_pid = <5>; + clock-control-debugfs = "true"; + cell-index = <1>; + status = "ok"; + + cam_sfe_lite_opp_table1: opp-table { + compatible = "operating-points-v2"; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; +}; + +&tlmm { + cam_sensor_mclk0_active: cam-sensor-mclk0-active { + /* MCLK0 */ + mux { + pins = "gpio67"; + function = "cam_mclk"; + }; + + config { + pins = "gpio67"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk0_suspend: cam-sensor-mclk0-suspend { + /* MCLK0 */ + mux { + pins = "gpio67"; + function = "cam_mclk"; + }; + + config { + pins = "gpio67"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk1_active: cam-sensor-mclk1-active { + /* MCLK1 */ + mux { + pins = "gpio68"; + function = "cam_mclk"; + }; + + config { + pins = "gpio68"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk1_suspend: cam-sensor-mclk1-suspend { + /* MCLK1 */ + mux { + pins = "gpio68"; + function = "cam_mclk"; + }; + + config { + pins = "gpio68"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_active: cam-sensor-mclk2-active { + /* MCLK2 */ + mux { + pins = "gpio69"; + function = "cam_mclk"; + }; + + config { + pins = "gpio69"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_suspend: cam-sensor-mclk2-suspend { + /* MCLK2 */ + mux { + pins = "gpio69"; + function = "cam_mclk"; + }; + + config { + pins = "gpio69"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl0_active: cci-i2c-scl0-active { + mux { + /* CLK, DATA */ + pins = "gpio58"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio58"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_scl0_suspend: cci-i2c-scl0-suspend { + mux { + /* CLK, DATA */ + pins = "gpio58"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio58"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl1_active: cci-i2c-scl1-active { + mux { + /* CLK, DATA */ + pins = "gpio30"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio30"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_scl1_suspend: cci-i2c-scl1-suspend { + mux { + /* CLK, DATA */ + pins = "gpio30"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio30"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl2_active: cci-i2c-scl2-active { + mux { + /* CLK, DATA */ + pins = "gpio60"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio60"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_scl2_suspend: cci-i2c-scl2-suspend { + mux { + /* CLK, DATA */ + pins = "gpio60"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio60"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl3_active: cci-i2c-scl3-active { + mux { + pins = "gpio32"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio32"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_scl3_suspend: cci-i2c-scl3-suspend { + mux { + pins = "gpio32"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio32"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl4_active: cci-i2c-scl4-active { + mux { + /* CLK, DATA */ + pins = "gpio62"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio62"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_scl4_suspend: cci-i2c-scl4-suspend { + mux { + /* CLK, DATA */ + pins = "gpio62"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio62"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl5_active: cci-i2c-scl5-active { + mux { + /* CLK, DATA */ + pins = "gpio55"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio55"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_scl5_suspend: cci-i2c-scl5-suspend { + mux { + /* CLK, DATA */ + pins = "gpio55"; + function = "cci_i2c_scl"; + }; + + config { + pins = "gpio55"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda0_active: cci-i2c-sda0-active { + mux { + /* CLK, DATA */ + pins = "gpio57"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio57"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_sda0_suspend: cci-i2c-sda0-suspend { + mux { + /* CLK, DATA */ + pins = "gpio57"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio57"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda1_active: cci-i2c-sda1-active { + mux { + /* CLK, DATA */ + pins = "gpio29"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio29"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_sda1_suspend: cci-i2c-sda1-suspend { + mux { + /* CLK, DATA */ + pins = "gpio29"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio29"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda2_active: cci-i2c-sda2-active { + mux { + /* CLK, DATA */ + pins = "gpio59"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio59"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_sda2_suspend: cci-i2c-sda2-suspend { + mux { + /* CLK, DATA */ + pins = "gpio59"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio59"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda3_active: cci-i2c-sda3-active { + mux { + pins = "gpio31"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio31"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_sda3_suspend: cci-i2c-sda3-suspend { + mux { + pins = "gpio31"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio31"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda4_active: cci-i2c-sda4-active { + mux { + /* CLK, DATA */ + pins = "gpio61"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio61"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_sda4_suspend: cci-i2c-sda4-suspend { + mux { + /* CLK, DATA */ + pins = "gpio61"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio61"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda5_active: cci-i2c-sda5-active { + mux { + /* CLK, DATA */ + pins = "gpio54"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio54"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + qcom,i2c_pull; + }; + }; + + cci_i2c_sda5_suspend: cci-i2c-sda5-suspend { + mux { + /* CLK, DATA */ + pins = "gpio54"; + function = "cci_i2c_sda"; + }; + + config { + pins = "gpio54"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/monaco-evk-camera-sensor.dtsi new file mode 100644 index 0000000000000..167b85c0e8844 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-evk-camera-sensor.dtsi @@ -0,0 +1,794 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&cam_cci0 { + /* GMSL deserializer 0 */ + qcom,cam-gmsl-deserializer0 { + cell-index = <0>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser0_port0: endpoint { + remote-endpoint = <&gmsl_sensor0_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser0_port1: endpoint { + remote-endpoint = <&gmsl_sensor1_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser0_port2: endpoint { + remote-endpoint = <&gmsl_sensor2_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser0_port3: endpoint { + remote-endpoint = <&gmsl_sensor3_ep>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 0 */ + qcom,cam-gmsl-sensor0 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <0>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor0_ep: endpoint { + remote-endpoint = <&deser0_port0>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 1 */ + qcom,cam-gmsl-sensor1 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <1>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor1_ep: endpoint { + remote-endpoint = <&deser0_port1>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 2 */ + qcom,cam-gmsl-sensor2 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <2>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor2_ep: endpoint { + remote-endpoint = <&deser0_port2>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 3 */ + qcom,cam-gmsl-sensor3 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <3>; + csiphy-sd-index = <0>; + status = "ok"; + + port { + gmsl_sensor3_ep: endpoint { + remote-endpoint = <&deser0_port3>; + }; + }; + }; + + /*cam0-ov9282*/ + rb4_slot0: qcom,cam-sensor16 { + compatible = "qcom,cam-sensor"; + cell-index = <16>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 67 0>, + <&tlmm 73 0>, + <&expander2 0 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam0-imx577*/ + qcom,cam-sensor20 { + compatible = "qcom,cam-sensor"; + cell-index = <20>; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam20>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 67 0>, + <&tlmm 73 0>, + <&expander2 0 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + eeprom_cam20: qcom,eeprom20 { + cell-index = <20>; + compatible = "qcom,eeprom"; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 67 0>, + <&tlmm 73 0>, + <&expander2 0 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + }; +}; + +&cam_cci1 { + /* GMSL deserializer 1 */ + qcom,cam-gmsl-deserializer1 { + cell-index = <1>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 74 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser1_port0: endpoint { + remote-endpoint = <&gmsl_sensor4_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser1_port1: endpoint { + remote-endpoint = <&gmsl_sensor5_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser1_port2: endpoint { + remote-endpoint = <&gmsl_sensor6_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser1_port3: endpoint { + remote-endpoint = <&gmsl_sensor7_ep>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 0 */ + qcom,cam-gmsl-sensor4 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <4>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor4_ep: endpoint { + remote-endpoint = <&deser1_port0>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 1 */ + qcom,cam-gmsl-sensor5 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <5>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor5_ep: endpoint { + remote-endpoint = <&deser1_port1>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 2 */ + qcom,cam-gmsl-sensor6 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <6>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor6_ep: endpoint { + remote-endpoint = <&deser1_port2>; + }; + }; + }; + + /* GMSL deserializer 1 sensor 3 */ + qcom,cam-gmsl-sensor7 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <7>; + csiphy-sd-index = <1>; + status = "ok"; + + port { + gmsl_sensor7_ep: endpoint { + remote-endpoint = <&deser1_port3>; + }; + }; + }; + + /*cam1-ov9282*/ + rb4_slot1: qcom,cam-sensor17 { + compatible = "qcom,cam-sensor"; + cell-index = <17>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 68 0>, + <&tlmm 74 0>, + <&expander2 1 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam0-imx577*/ + qcom,cam-sensor19 { + compatible = "qcom,cam-sensor"; + cell-index = <19>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam19>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 68 0>, + <&tlmm 74 0>, + <&expander2 1 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam0-imx577*/ + qcom,cam-sensor21 { + compatible = "qcom,cam-sensor"; + cell-index = <21>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam21>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 68 0>, + <&tlmm 74 0>, + <&expander2 1 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + eeprom_cam19: qcom,eeprom19 { + compatible = "qcom,eeprom"; + cell-index = <19>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 68 0>, + <&tlmm 74 0>, + <&expander2 1 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + eeprom_cam21: qcom,eeprom21 { + compatible = "qcom,eeprom"; + cell-index = <21>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 68 0>, + <&tlmm 74 0>, + <&expander2 1 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; +}; + +&cam_cci2 { + /* GMSL deserializer 2 */ + qcom,cam-gmsl-deserializer2 { + cell-index = <2>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 75 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET2"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + port@0 { + reg = <0>; + + deser2_port0: endpoint { + remote-endpoint = <&gmsl_sensor8_ep>; + }; + }; + + port@1 { + reg = <1>; + + deser2_port1: endpoint { + remote-endpoint = <&gmsl_sensor9_ep>; + }; + }; + + port@2 { + reg = <0>; + + deser2_port2: endpoint { + remote-endpoint = <&gmsl_sensor10_ep>; + }; + }; + + port@3 { + reg = <1>; + + deser2_port3: endpoint { + remote-endpoint = <&gmsl_sensor11_ep>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 0 */ + qcom,cam-gmsl-sensor8 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <8>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor8_ep: endpoint { + remote-endpoint = <&deser2_port0>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 1 */ + qcom,cam-gmsl-sensor9 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <9>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor9_ep: endpoint { + remote-endpoint = <&deser2_port1>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 2 */ + qcom,cam-gmsl-sensor10 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <10>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor10_ep: endpoint { + remote-endpoint = <&deser2_port2>; + }; + }; + }; + + /* GMSL deserializer 2 sensor 3 */ + qcom,cam-gmsl-sensor11 { + compatible = "qcom,cam-gmsl-sensor"; + cell-index = <11>; + csiphy-sd-index = <2>; + status = "ok"; + + port { + gmsl_sensor11_ep: endpoint { + remote-endpoint = <&deser2_port3>; + }; + }; + }; + + /*cam2-ov9282*/ + rb4_slot2: qcom,cam-sensor18 { + compatible = "qcom,cam-sensor"; + cell-index = <18>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 69 0>, + <&tlmm 75 0>, + <&expander2 2 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK2", + "CAMIF_RESET2", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + /*cam2-imx577*/ + qcom,cam-sensor22 { + compatible = "qcom,cam-sensor"; + cell-index = <22>; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam22>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 69 0>, + <&tlmm 75 0>, + <&expander2 2 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK2", + "CAMIF_RESET2", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; + + eeprom_cam22: qcom,eeprom22 { + compatible = "qcom,eeprom"; + cell-index = <22>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 69 0>, + <&tlmm 75 0>, + <&expander2 2 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK2", + "CAMIF_RESET2", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + }; +}; + +&soc { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + gpios-shared = <609 610 611>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso b/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso new file mode 100644 index 0000000000000..3945c77528ccb --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "monaco-camera.dtsi" +#include "monaco-evk-camera-sensor.dtsi" + +&camss { + status = "disabled"; +}; + +&tlmm { + cam_sensor_active_rst0: cam-sensor-active-rst0 { + /* RESET */ + mux { + pins = "gpio73"; + function = "gpio"; + }; + + config { + pins = "gpio73"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst1: cam-sensor-active-rst1 { + /* RESET */ + mux { + pins = "gpio74"; + function = "gpio"; + }; + + config { + pins = "gpio74"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst2: cam-sensor-active-rst2 { + /* RESET */ + mux { + pins = "gpio75"; + function = "gpio"; + }; + + config { + pins = "gpio75"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_rst0: cam-sensor-suspend-rst0 { + /* RESET */ + mux { + pins = "gpio73"; + function = "gpio"; + }; + + config { + pins = "gpio73"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst1: cam-sensor-suspend-rst1 { + /* RESET */ + mux { + pins = "gpio74"; + function = "gpio"; + }; + config { + pins = "gpio74"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst2: cam-sensor-suspend-rst2 { + /* RESET */ + mux { + pins = "gpio75"; + function = "gpio"; + }; + config { + pins = "gpio75"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride-camx.dtso b/arch/arm64/boot/dts/qcom/qcs8300-ride-camx.dtso new file mode 100644 index 0000000000000..8f26e6dc070b0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride-camx.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "monaco-camera.dtsi" +#include "monaco-camera-sensor.dtsi" From a4fd9df6d4848d16748d4db6d68803ab4ab48a7a Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Thu, 30 Oct 2025 00:58:58 +0530 Subject: [PATCH 260/438] PENDING: arm64: dts: qcom: qcs8300: Update camera PIL region to 7MB The camera firmware size for IoT variant qcs8300 SoC is more than 5MB. Update the PIL memory region size of camera to 7MB to accomodate the same. Signed-off-by: Umang Chheda --- arch/arm64/boot/dts/qcom/monaco.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 5d2df4305d1c1..47fbf6fea0e1a 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -776,7 +776,7 @@ }; camera_mem: camera-region@95200000 { - reg = <0x0 0x95200000 0x0 0x500000>; + reg = <0x0 0x95200000 0x0 0x700000>; no-map; }; From e1d749fd747deb0de120341638ee537e259347f3 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 27 Oct 2025 23:48:22 +0530 Subject: [PATCH 261/438] QCLINUX: arm64: dts: qcom: Update rbgen2 camx overlay dts - Fix the indentation issue. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi index f6af6827784bd..37ea48e35d09c 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi @@ -620,8 +620,8 @@ qcom,cam-icp { compatible = "qcom,cam-icp"; compat-hw-name = "qcom,a5", - "qcom,ipe0", - "qcom,bps"; + "qcom,ipe0", + "qcom,bps"; num-a5 = <1>; num-ipe = <1>; num-bps = <1>; @@ -643,7 +643,7 @@ qcom,cam-jpeg { compatible = "qcom,cam-jpeg"; compat-hw-name = "qcom,jpegenc", - "qcom,jpegdma"; + "qcom,jpegdma"; num-jpeg-enc = <1>; num-jpeg-dma = <1>; status = "ok"; From 5b20947b1cd7ef2479596c4eef4d106830bb9d6f Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 27 Oct 2025 23:42:23 +0530 Subject: [PATCH 262/438] QCLINUX: arm64: dts: qcom: Update Monaco camx overlay dts - Fix the indentation issue. - Update DT clock property name after clock. - Short DT nodes. - Fix indexing issue. - Update gpios shared pin. Signed-off-by: Chandan Kumar Jha --- .../boot/dts/qcom/monaco-camera-sensor.dtsi | 2 +- arch/arm64/boot/dts/qcom/monaco-camera.dtsi | 204 +++++++++--------- 2 files changed, 100 insertions(+), 106 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi index 0023c97edce91..a2a2cd0a27a3a 100644 --- a/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco-camera-sensor.dtsi @@ -374,7 +374,7 @@ &soc { qcom,cam-res-mgr { compatible = "qcom,cam-res-mgr"; - gpios-shared = <518 519 520 521>; + gpios-shared = <609 610 611>; status = "ok"; }; }; diff --git a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi index bd619b507831f..f72161e75f7e7 100644 --- a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi @@ -565,8 +565,8 @@ "cam_cc_qdss_debug_xo_clk"; src-clock-name = "cam_cc_fast_ahb_clk_src"; clock-rates = <0 0 0 0 0 0 0 0 0 0 0>, - <0 0 0 80000000 0 0 300000000 0 400000000 0 0>, - <0 0 0 80000000 0 0 400000000 0 400000000 0 0>; + <0 0 0 80000000 0 0 300000000 0 400000000 0 0>, + <0 0 0 80000000 0 0 400000000 0 400000000 0 0>; clock-cntl-level = "suspend", "svs_l1", "nominal"; clock-names-option = "cam_icp_clk"; clocks-option = <&camcc CAM_CC_ICP_CLK>; @@ -679,7 +679,7 @@ }; ife_1_wr_1: ife-1-wr-1 { - cell-index = <3>; + cell-index = <4>; node-name = "ife-1-wr-1"; client-name = "ife1"; traffic-data = ; @@ -693,7 +693,7 @@ }; ife_lite_0_wr_0: ife-lite-0-wr-0 { - cell-index = <4>; + cell-index = <5>; node-name = "ife-lite-0-wr-0"; client-name = "ife2"; traffic-data = ; @@ -707,7 +707,7 @@ }; ife_lite_1_wr_0: ife-lite-1-wr-0 { - cell-index = <5>; + cell-index = <6>; node-name = "ife-lite-1-wr-0"; client-name = "ife3"; traffic-data = ; @@ -721,7 +721,7 @@ }; ife_lite_2_wr_0: ife-lite-2-wr-0 { - cell-index = <6>; + cell-index = <7>; node-name = "ife-lite-2-wr-0"; client-name = "ife4"; traffic-data = ; @@ -735,7 +735,7 @@ }; ife_lite_3_wr_0: ife-lite-3-wr-0 { - cell-index = <7>; + cell-index = <8>; node-name = "ife-lite-3-wr-0"; client-name = "ife5"; traffic-data = ; @@ -749,7 +749,7 @@ }; ife_lite_4_wr_0: ife-lite-4-wr-0 { - cell-index = <8>; + cell-index = <9>; node-name = "ife-lite-4-wr-0"; client-name = "ife6"; traffic-data = ; @@ -763,7 +763,7 @@ }; ipe_0_rd_all: ipe-0-rd-all { - cell-index = <9>; + cell-index = <10>; node-name = "ipe-0-rd-all"; client-name = "ipe0"; traffic-data = ; @@ -774,7 +774,7 @@ }; ipe_0_wr_2: ipe-0-wr-2 { - cell-index = <10>; + cell-index = <11>; node-name = "ipe-0-wr-2"; client-name = "ipe0"; traffic-data = ; @@ -787,7 +787,7 @@ }; ipe_cdm0_all_rd: ipe-cdm0-all-rd { - cell-index = <11>; + cell-index = <12>; node-name = "ipe-cdm0-all-rd"; client-name = "ipe0"; traffic-data = ; @@ -796,7 +796,7 @@ }; rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 { - cell-index = <12>; + cell-index = <13>; node-name = "rt-cdm0-all-rd-2"; client-name = "rt-cdm0"; traffic-data = ; @@ -805,7 +805,7 @@ }; rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 { - cell-index = <13>; + cell-index = <14>; node-name = "rt-cdm1-all-rd-2"; client-name = "rt-cdm1"; traffic-data = ; @@ -814,7 +814,7 @@ }; rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 { - cell-index = <14>; + cell-index = <15>; node-name = "rt-cdm2-all-rd-2"; client-name = "rt-cdm2"; traffic-data = ; @@ -823,7 +823,7 @@ }; rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 { - cell-index = <15>; + cell-index = <16>; node-name = "rt-cdm3-all-rd-2"; client-name = "rt-cdm3"; traffic-data = ; @@ -832,7 +832,7 @@ }; sfe_0_rd_0: sfe-0-rd-0 { - cell-index = <16>; + cell-index = <17>; node-name = "sfe-0-rd-0"; client-name = "sfe0"; traffic-data = ; @@ -842,7 +842,7 @@ }; sfe_1_rd_0: sfe-1-rd-0 { - cell-index = <17>; + cell-index = <18>; node-name = "sfe-1-rd-0"; client-name = "sfe1"; traffic-data = ; @@ -857,28 +857,28 @@ camnoc-max-needed; level1_nrt_rd2: level1-nrt-rd2 { - cell-index = <22>; + cell-index = <19>; node-name = "level1-nrt-rd2"; parent-node = <&level2_nrt_rd2>; traffic-merge-type = ; }; level1_rt_rd0: level1-rt-read0 { - cell-index = <21>; + cell-index = <20>; node-name = "level1-rt-rd0"; parent-node = <&level2_rt_rd0>; traffic-merge-type = ; }; level1_rt_wr0: level1-rt-wr0 { - cell-index = <19>; + cell-index = <21>; node-name = "level1-rt-wr0"; parent-node = <&level2_rt_wr0>; traffic-merge-type = ; }; level1_rt_wr1: level1-rt-wr1 { - cell-index = <20>; + cell-index = <22>; node-name = "level1-rt-wr1"; parent-node = <&level2_rt_wr1>; traffic-merge-type = ; @@ -978,8 +978,7 @@ qcom,cam-icp { compatible = "qcom,cam-icp"; - compat-hw-name = "qcom,icp", - "qcom,ipe0"; + compat-hw-name = "qcom,icp", "qcom,ipe0"; num-icp = <1>; num-ipe = <1>; icp_use_pil; @@ -1023,6 +1022,7 @@ cam-smmu-label = "rt-cdm"; dma-coherent; multiple-client-devices; + rt_cdm_iova_mem_map: iova-mem-map { iova-mem-region-io { /* IO region is approximately 4.0 GB */ @@ -1059,6 +1059,7 @@ iova-region-id = <0x6>; subregion_support; status = "ok"; + /* Used for HFI queues/sec heap */ iova-mem-region-generic-region { iova-region-name = "icp_hfi"; @@ -1096,7 +1097,6 @@ iova-region-id = <0x1>; status = "ok"; }; - }; }; @@ -1298,49 +1298,46 @@ }; }; - cam_csid_lite3: qcom,csid-lite3 { - cell-index = <5>; + cam_csid_lite2: qcom,csid-lite2 { compatible = "qcom,csid-lite692"; - reg-names = "csid-lite3"; - reg = <0x0 0xac90000 0x0 0xf01>; - reg-cam-base = <0x90000>; + reg = <0x0 0xac8c000 0x0 0xf01>; + reg-names = "csid-lite2"; + reg-cam-base = <0x8c000>; rt-wrapper-base = <0x83000>; - interrupt-names = "csid-lite3"; - interrupts = ; + interrupts = ; + interrupt-names = "csid-lite2"; power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; - clock-names = - "cam_cc_cpas_ife_lite_clk", - "cam_cc_ife_lite_ahb_clk", - "cam_cc_ife_lite_csid_clk_src", - "cam_cc_ife_lite_csid_clk", - "cam_cc_ife_lite_cphy_rx_clk", - "cam_cc_ife_lite_clk_src", - "cam_cc_ife_lite_clk"; - clocks = - <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, - <&camcc CAM_CC_IFE_LITE_AHB_CLK>, - <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, - <&camcc CAM_CC_IFE_LITE_CSID_CLK>, - <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, - <&camcc CAM_CC_IFE_LITE_CLK_SRC>, - <&camcc CAM_CC_IFE_LITE_CLK>; - clock-rates = - <0 0 400000000 0 0 400000000 0>, - <0 0 400000000 0 0 480000000 0>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; clock-cntl-level = "svs_l1", "nominal"; src-clock-name = "cam_cc_ife_lite_csid_clk_src"; - operating-points-v2 = <&csid_lite3_opp_table>; - + operating-points-v2 = <&csid_lite2_opp_table>; clock-control-debugfs = "true"; + cell-index = <4>; status = "ok"; - csid_lite3_opp_table: opp-table { + csid_lite2_opp_table: opp-table { compatible = "operating-points-v2"; opp-400000000 { opp-hz = /bits/ 64 <400000000>; required-opps = <&rpmhpd_opp_svs_l1>; }; + opp-480000000 { opp-hz = /bits/ 64 <480000000>; required-opps = <&rpmhpd_opp_nom>; @@ -1348,49 +1345,46 @@ }; }; - cam_csid_lite2: qcom,csid-lite2 { - cell-index = <4>; + cam_csid_lite3: qcom,csid-lite3 { compatible = "qcom,csid-lite692"; - reg-names = "csid-lite2"; - reg = <0x0 0xac8c000 0x0 0xf01>; - reg-cam-base = <0x8c000>; + reg = <0x0 0xac90000 0x0 0xf01>; + reg-names = "csid-lite3"; + reg-cam-base = <0x90000>; rt-wrapper-base = <0x83000>; - interrupt-names = "csid-lite2"; - interrupts = ; + interrupts = ; + interrupt-names = "csid-lite3"; power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; - clock-names = - "cam_cc_cpas_ife_lite_clk", - "cam_cc_ife_lite_ahb_clk", - "cam_cc_ife_lite_csid_clk_src", - "cam_cc_ife_lite_csid_clk", - "cam_cc_ife_lite_cphy_rx_clk", - "cam_cc_ife_lite_clk_src", - "cam_cc_ife_lite_clk"; - clocks = - <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, - <&camcc CAM_CC_IFE_LITE_AHB_CLK>, - <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, - <&camcc CAM_CC_IFE_LITE_CSID_CLK>, - <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, - <&camcc CAM_CC_IFE_LITE_CLK_SRC>, - <&camcc CAM_CC_IFE_LITE_CLK>; - clock-rates = - <0 0 400000000 0 0 400000000 0>, - <0 0 400000000 0 0 480000000 0>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; clock-cntl-level = "svs_l1", "nominal"; src-clock-name = "cam_cc_ife_lite_csid_clk_src"; - operating-points-v2 = <&csid_lite2_opp_table>; - + operating-points-v2 = <&csid_lite3_opp_table>; clock-control-debugfs = "true"; + cell-index = <5>; status = "ok"; - csid_lite2_opp_table: opp-table { + csid_lite3_opp_table: opp-table { compatible = "operating-points-v2"; opp-400000000 { opp-hz = /bits/ 64 <400000000>; required-opps = <&rpmhpd_opp_svs_l1>; }; + opp-480000000 { opp-hz = /bits/ 64 <480000000>; required-opps = <&rpmhpd_opp_nom>; @@ -1399,39 +1393,35 @@ }; cam_csid_lite4: qcom,csid-lite4 { - cell-index = <6>; compatible = "qcom,csid-lite692"; - reg-names = "csid-lite4"; reg = <0x0 0xac94000 0x0 0xf01>; + reg-names = "csid-lite4"; reg-cam-base = <0x94000>; rt-wrapper-base = <0x83000>; - interrupt-names = "csid-lite4"; interrupts = ; + interrupt-names = "csid-lite4"; power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; - clock-names = - "cam_cc_cpas_ife_lite_clk", - "cam_cc_ife_lite_ahb_clk", - "cam_cc_ife_lite_csid_clk_src", - "cam_cc_ife_lite_csid_clk", - "cam_cc_ife_lite_cphy_rx_clk", - "cam_cc_ife_lite_clk_src", - "cam_cc_ife_lite_clk"; - clocks = - <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, - <&camcc CAM_CC_IFE_LITE_AHB_CLK>, - <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, - <&camcc CAM_CC_IFE_LITE_CSID_CLK>, - <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, - <&camcc CAM_CC_IFE_LITE_CLK_SRC>, - <&camcc CAM_CC_IFE_LITE_CLK>; - clock-rates = - <0 0 400000000 0 0 400000000 0>, - <0 0 400000000 0 0 480000000 0>; + clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; + clock-rates = <0 0 400000000 0 0 400000000 0>, + <0 0 400000000 0 0 480000000 0>; clock-cntl-level = "svs_l1", "nominal"; src-clock-name = "cam_cc_ife_lite_csid_clk_src"; operating-points-v2 = <&csid_lite4_opp_table>; - clock-control-debugfs = "true"; + cell-index = <6>; status = "ok"; csid_lite4_opp_table: opp-table { @@ -1441,6 +1431,7 @@ opp-hz = /bits/ 64 <400000000>; required-opps = <&rpmhpd_opp_svs_l1>; }; + opp-480000000 { opp-hz = /bits/ 64 <480000000>; required-opps = <&rpmhpd_opp_nom>; @@ -1489,6 +1480,7 @@ opp-hz = /bits/ 64 <480000000>; required-opps = <&rpmhpd_opp_svs_l1>; }; + opp-600000000 { opp-hz = /bits/ 64 <600000000>; required-opps = <&rpmhpd_opp_nom>; @@ -1532,6 +1524,7 @@ opp-hz = /bits/ 64 <480000000>; required-opps = <&rpmhpd_opp_svs_l1>; }; + opp-600000000 { opp-hz = /bits/ 64 <600000000>; required-opps = <&rpmhpd_opp_nom>; @@ -1575,6 +1568,7 @@ opp-hz = /bits/ 64 <480000000>; required-opps = <&rpmhpd_opp_svs_l1>; }; + opp-600000000 { opp-hz = /bits/ 64 <600000000>; required-opps = <&rpmhpd_opp_nom>; From 07c317563d4367e5b98b02e56761fd1194be17e7 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 27 Oct 2025 23:36:51 +0530 Subject: [PATCH 263/438] QCLINUX: arm64: dts: qcom: Update Lemans camx overlay dts - Fix the indentation issue. - Update DT clock property name after clock. - Shorted DT nodes. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/lemans-camera.dtsi | 43 +++++++++------------ 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi index 18d78926b1f17..855d29dff618f 100644 --- a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi @@ -743,7 +743,6 @@ "ife5", "ife6", "ipe0", "sfe0", "sfe1", "cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2", "rt-cdm3", "icp0", "tpg17", "tpg18", "tpg19"; - enable-secure-qos-update; cell-index = <0>; status = "ok"; @@ -817,7 +816,6 @@ parent-node = <&level1_rt_wr0>; }; - ife_1_wr_1: ife-1-wr-1 { cell-index = <4>; node-name = "ife-1-wr-1"; @@ -958,8 +956,7 @@ node-name = "rt-cdm2-all-rd-2"; client-name = "rt-cdm2"; traffic-data = ; - traffic-transaction-type = - ; + traffic-transaction-type = ; parent-node = <&level1_nrt_rd2>; }; @@ -1086,8 +1083,7 @@ level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum { cell-index = <30>; node-name = "level3-nrt0-rd-wr-sum"; - traffic-merge-type = - ; + traffic-merge-type = ; qcom,axi-port-mnoc { cam-icc-path-names = "cam_sf_0"; @@ -1097,8 +1093,7 @@ level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum { cell-index = <31>; node-name = "level3-nrt1-rd-wr-sum"; - traffic-merge-type = - ; + traffic-merge-type = ; qcom,axi-port-mnoc { cam-icc-path-names = "cam_sf_icp"; @@ -1108,8 +1103,7 @@ level3_rt_rd_wr_sum: level3-rt-rd-wr-sum { cell-index = <32>; node-name = "level3-rt-rd-wr-sum"; - traffic-merge-type = - ; + traffic-merge-type = ; ib-bw-voting-needed; qcom,axi-port-mnoc { @@ -1148,8 +1142,8 @@ status = "ok"; }; - qcom,cam-sync { - compatible = "qcom,cam-sync"; + qcom,camera-main { + compatible = "qcom,camera"; status = "ok"; }; @@ -1274,8 +1268,8 @@ }; }; - qcom,camera-main { - compatible = "qcom,camera"; + qcom,cam-sync { + compatible = "qcom,cam-sync"; status = "ok"; }; @@ -1544,13 +1538,6 @@ interrupts = ; interrupt-names = "csid-lite4"; power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; - clock-names = "cam_cc_cpas_ife_lite_clk", - "cam_cc_ife_lite_ahb_clk", - "cam_cc_ife_lite_csid_clk_src", - "cam_cc_ife_lite_csid_clk", - "cam_cc_ife_lite_cphy_rx_clk", - "cam_cc_ife_lite_clk_src", - "cam_cc_ife_lite_clk"; clocks = <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, <&camcc CAM_CC_IFE_LITE_AHB_CLK>, <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, @@ -1558,6 +1545,13 @@ <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, <&camcc CAM_CC_IFE_LITE_CLK_SRC>, <&camcc CAM_CC_IFE_LITE_CLK>; + clock-names = "cam_cc_cpas_ife_lite_clk", + "cam_cc_ife_lite_ahb_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_ife_lite_clk"; clock-rates = <0 0 400000000 0 0 400000000 0>, <0 0 400000000 0 0 480000000 0>; clock-cntl-level = "svs_l1", "nominal"; @@ -2000,7 +1994,6 @@ required-opps = <&rpmhpd_opp_nom>; }; }; - }; qcom,rt-cdm0 { @@ -2140,12 +2133,12 @@ interrupts = ; interrupt-names = "sfe-lite0"; power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; - clock-names = "cam_cc_sfe_lite_0_fast_ahb_clk", - "cam_cc_sfe_lite_0_clk", - "cam_cc_cpas_sfe_lite_0_clk"; clocks = <&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>, <&camcc CAM_CC_SFE_LITE_0_CLK>, <&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>; + clock-names = "cam_cc_sfe_lite_0_fast_ahb_clk", + "cam_cc_sfe_lite_0_clk", + "cam_cc_cpas_sfe_lite_0_clk"; clock-rates = <0 480000000 300000000>, <0 600000000 400000000>; clock-cntl-level = "svs_l1", "nominal"; From 060b7a435cbb89e044eea430548e115ac6661bd6 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Wed, 24 Dec 2025 14:00:56 +0800 Subject: [PATCH 264/438] PENDING: arm64: dts: qcom: change pil camera memory map Add the pil camera carveout region based on v2 memory map. Signed-off-by: Qingqing Zhou Signed-off-by: Xin Liu --- arch/arm64/boot/dts/qcom/talos.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 75716b4a58d6d..f7fca3d0a9735 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -651,6 +651,11 @@ reg = <0x0 0x95900000 0x0 0x1e00000>; no-map; }; + + pil_camera_mem: pil-camera-region@97717000 { + reg = <0x0 0x97717000 0x0 0x800000>; + no-map; + }; }; soc: soc@0 { From 147ae3e30842bdc0006f588c437c4607c6b2c566 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 24 Dec 2025 16:16:57 +0530 Subject: [PATCH 265/438] QCLINUX: arm64: dts: qcom: Add Talos camx overlay dts Add CAMX overlay dts file for Talos boards. This change also enables the compilation of the CAMX overlay on Talos boards. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/Makefile | 4 + .../arm64/boot/dts/qcom/qcs615-ride-camx.dtso | 16 + .../boot/dts/qcom/talos-camera-sensor.dtsi | 152 ++ arch/arm64/boot/dts/qcom/talos-camera.dtsi | 1984 +++++++++++++++++ 4 files changed, 2156 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qcs615-ride-camx.dtso create mode 100644 arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/talos-camera.dtsi diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 7bc3445f34870..1c854ab0054ae 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -401,6 +401,10 @@ monaco-evk-camx-dtbs := monaco-evk.dtb monaco-evk-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camx.dtb +qcs615-ride-camx-dtbs := qcs615-ride.dtb qcs615-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride-camx.dtb + qcs6490-rb3gen2-vision-mezzanine-camx-dtbs := qcs6490-rb3gen2-vision-mezzanine.dtb \ qcs6490-rb3gen2-vision-mezzanine-camx.dtbo diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride-camx.dtso b/arch/arm64/boot/dts/qcom/qcs615-ride-camx.dtso new file mode 100644 index 0000000000000..a40d8817a7a20 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs615-ride-camx.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "talos-camera.dtsi" +#include "talos-camera-sensor.dtsi" diff --git a/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi new file mode 100644 index 0000000000000..7e76197614781 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +&cam_cci { + /*cam0-imx577*/ + tl_slot0: qcom,cam-sensor0 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam0>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 28 0>, + <&tlmm 75 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAM_MCLK0", "CAMIF_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <0>; + status = "okay"; + }; + + /*cam1-imx577*/ + t1_slot1: qcom,cam-sensor1 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam1>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst1>; + gpios = <&tlmm 30 0>, + <&tlmm 29 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAM_MCLK1", "CAMIF_RESET1"; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <1>; + status = "okay"; + }; + + /*cam0-imx577-eeprom*/ + eeprom_cam0: qcom,eeprom0 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 28 0>, + <&tlmm 75 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAM_MCLK0", "CAMIF_RESET0"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <0>; + status = "okay"; + }; + + /*cam1-imx577-eeprom*/ + eeprom_cam1: qcom,eeprom1 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 30 0>, + <&tlmm 29 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAM_MCLK1", "CAMIF_RESET1"; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <1>; + status = "okay"; + }; +}; + +&soc { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/talos-camera.dtsi b/arch/arm64/boot/dts/qcom/talos-camera.dtsi new file mode 100644 index 0000000000000..e2daa14db1e80 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-camera.dtsi @@ -0,0 +1,1984 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +&soc { + cam_icp: qcom,icp@ac00000 { + compatible = "qcom,cam-icp_v1"; + icp-version = <0x0100>; + reg = <0x0 0xac00000 0x0 0x6000>, + <0x0 0xac10000 0x0 0x8000>, + <0x0 0xac18000 0x0 0x3000>; + reg-names = "icp_qgic", "icp_sierra", "icp_csr"; + reg-cam-base = <0x00000 0x10000 0x18000>; + interrupts = ; + interrupt-names = "a5"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_FAST_AHB_CLK_SRC>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_ICP_CLK>, + <&camcc CAM_CC_ICP_CLK_SRC>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_fast_ahb_clk_src", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk", + "cam_cc_icp_clk", + "cam_cc_icp_clk_src"; + clock-rates = <0 0 100000000 0 0 0 0 240000000>, + <0 0 200000000 0 0 0 0 360000000>, + <0 0 300000000 0 0 0 0 432000000>, + <0 0 404000000 0 0 0 0 480000000>, + <0 0 404000000 0 0 0 0 540000000>, + <0 0 404000000 0 0 0 0 600000000>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "nominal_l1", "turbo"; + src-clock-name = "cam_cc_icp_clk_src"; + operating-points-v2 = <&a5_opp_table>; + fw_name = "CAMERA_ICP.elf"; + ubwc-cfg = <0x73 0x1CF>; + cam_hw_pid = <15>; + cell-index = <0>; + status = "okay"; + + a5_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-360000000 { + opp-hz = /bits/ 64 <360000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-432000000 { + opp-hz = /bits/ 64 <432000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + qcom,cam-cpas@ac40000 { + compatible = "qcom,cam-cpas"; + label = "cpas"; + arch-compat = "cpas_top"; + reg = <0x0 0xac40000 0x0 0x1000>, + <0x0 0xac42000 0x0 0x5000>; + reg-names = "cam_cpas_top", "cam_camnoc"; + reg-cam-base = <0x40000 0x42000>; + interrupts = ; + interrupt-names = "cpas_camnoc"; + camnoc-axi-min-ib-bw = <3000000000>; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk"; + clock-rates = <0 0 0 0 0 0>, + <0 0 0 80000000 0 150000000>, + <0 0 0 80000000 0 240000000>, + <0 0 0 80000000 0 265000000>, + <0 0 0 80000000 0 355000000>, + <0 0 0 80000000 0 426000000>; + clock-cntl-level = "suspend", "lowsvs", "svs", + "svs_l1", "nominal", "turbo"; + src-clock-name = "cam_cc_camnoc_axi_clk"; + operating-points-v2 = <&cpas_opp_table>; + control-camnoc-axi-clk; + camnoc-bus-width = <32>; + camnoc-axi-clk-bw-margin-perc = <20>; + cam-icc-path-names = "cam_ahb"; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_CAMNOC_HF0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_HF1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "cam_ahb", + "cam_hf_0_mnoc", + "cam_hf_1_mnoc", + "cam_sf_0_mnoc"; + cam-ahb-num-cases = <7>; + cam-ahb-bw-KBps = <0 0>, <0 76800>, <0 150000>, <0 150000>, + <0 300000>, <0 300000>, <0 300000>; + vdd-corners = ; + vdd-corner-ahb-mapping = "suspend", "lowsvs", "lowsvs", "svs", + "svs_l1", "nominal", "nominal", + "nominal", "turbo", "turbo"; + client-id-based; + client-names = "csiphy0", "csiphy1", "csiphy2", "cci0", + "csid0", "csid1", "csid2","ife0", + "ife1", "ife2", "ipe0", "cam-cdm-intf0", + "cpas-cdm0", "bps0", "icp0", "jpeg-dma0", + "jpeg-enc0", "lrmecpas0"; + cell-index = <0>; + status = "okay"; + + cpas_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-150000000 { + opp-hz = /bits/ 64 <150000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-265000000 { + opp-hz = /bits/ 64 <265000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-355000000 { + opp-hz = /bits/ 64 <355000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-426000000 { + opp-hz = /bits/ 64 <426000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + + camera-bus-nodes { + level0-nodes { + level-index = <0>; + + bps0_all_rd: bps0-all-rd { + cell-index = <0>; + node-name = "bps0-all-rd"; + client-name = "bps0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read0>; + }; + + bps0_all_wr: bps0-all-wr { + cell-index = <1>; + node-name = "bps0-all-wr"; + client-name = "bps0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write0>; + }; + + cpas_cdm0_all_rd: cpas-cdm0-all-rd { + cell-index = <2>; + node-name = "cpas-cdm0-all-rd"; + client-name = "cpas-cdm0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read2>; + }; + + icp0_all_rd: icp0-all-rd { + cell-index = <3>; + node-name = "icp0-all-rd"; + client-name = "icp0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read3>; + }; + + ife0_linear_pdaf_wr: ife0-linear-pdaf-wr { + cell-index = <4>; + node-name = "ife0-linear-pdaf-wr"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife0_rdi_pixel_raw_wr: ife0-rdi-pixel-raw-wr { + cell-index = <5>; + node-name = "ife0-rdi-pixel-raw-wr"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife0_ubwc_stats_wr: ife0-ubwc-stats-wr { + cell-index = <6>; + node-name = "ife0-ubwc-stats-wr"; + client-name = "ife0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ife1_linear_pdaf_wr: ife1-linear-pdaf-wr { + cell-index = <7>; + node-name = "ife1-linear-pdaf-wr"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt1_write0>; + }; + + ife1_rdi_pixel_raw_wr: ife1-rdi-pixel-raw-wr { + cell-index = <8>; + node-name = "ife1-rdi-pixel-raw-wr"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt1_write0>; + }; + + ife1_ubwc_stats_wr: ife1-ubwc-stats-wr { + cell-index = <9>; + node-name = "ife1-ubwc-stats-wr"; + client-name = "ife1"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt1_write0>; + }; + + ife2_rdi_wr: ife2-rdi-wr { + cell-index = <10>; + node-name = "ife2-rdi-wr"; + client-name = "ife2"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_rt0_write0>; + }; + + ipe0_all_rd: ipe0-all-rd { + cell-index = <11>; + node-name = "ipe0-all-rd"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_nrt0_read0>; + }; + + ipe0_ref_wr: ipe0-ref-wr { + cell-index = <12>; + node-name = "ipe0-ref-wr"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write0>; + }; + + ipe0_viddisp_wr: ipe0-viddisp-wr { + cell-index = <13>; + node-name = "ipe0-viddisp-wr"; + client-name = "ipe0"; + traffic-data = ; + traffic-transaction-type = ; + constituent-paths = ; + parent-node = <&level1_nrt0_write0>; + }; + + jpeg_dma0_all_rd: jpeg-dma0-all-rd { + cell-index = <14>; + node-name = "jpeg-dma0-all-rd"; + client-name = "jpeg-dma0"; + traffic-data = ; + traffic-transaction-type = + ; + parent-node = <&level1_nrt0_read1>; + }; + + jpeg_dma0_all_wr: jpeg-dma0-all-wr { + cell-index = <15>; + node-name = "jpeg-dma0-all-wr"; + client-name = "jpeg-dma0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write1>; + }; + + jpeg_enc0_all_rd: jpeg-enc0-all-rd { + cell-index = <16>; + node-name = "jpeg-enc0-all-rd"; + client-name = "jpeg-enc0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read1>; + }; + + jpeg_enc0_all_wr: jpeg-enc0-all-wr { + cell-index = <17>; + node-name = "jpeg-enc0-all-wr"; + client-name = "jpeg-enc0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write1>; + }; + + lrme0_all_rd: lrme0-all-rd { + cell-index = <18>; + node-name = "lrme0-all-rd"; + client-name = "lrmecpas0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_read0>; + }; + + lrme0_all_wr: lrme0-all-wr { + cell-index = <19>; + node-name = "lrme0-all-wr"; + client-name = "lrmecpas0"; + traffic-data = ; + traffic-transaction-type = ; + parent-node = <&level1_nrt0_write0>; + }; + }; + + level1-nodes { + level-index = <1>; + camnoc-max-needed; + + level1_nrt0_read0: level1-nrt0-read0 { + cell-index = <20>; + node-name = "level1-nrt0-read0"; + parent-node = <&level2_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_nrt0_read1: level1-nrt0-read1 { + cell-index = <21>; + node-name = "level1-nrt0-read1"; + parent-node = <&level2_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_nrt0_read2: level1-nrt0-read2 { + cell-index = <22>; + node-name = "level1-nrt0-read2"; + parent-node = <&level2_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_nrt0_read3: level1-nrt0-read3 { + cell-index = <23>; + node-name = "level1-nrt0-read3"; + parent-node = <&level2_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_nrt0_write0: level1-nrt0-write0 { + cell-index = <24>; + node-name = "level1-nrt0-write0"; + parent-node = <&level2_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_nrt0_write1: level1-nrt0-write1 { + cell-index = <25>; + node-name = "level1-nrt0-write1"; + parent-node = <&level2_nrt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_rt0_write0: level1-rt0-write0 { + cell-index = <26>; + node-name = "level1-rt0-write0"; + parent-node = <&level2_rt0_rd_wr_sum>; + traffic-merge-type = ; + }; + + level1_rt1_write0: level1-rt1-write0 { + cell-index = <27>; + node-name = "level1-rt1-write0"; + parent-node = <&level2_rt1_rd_wr_sum>; + traffic-merge-type = ; + }; + }; + + level2-nodes { + level-index = <2>; + + level2_nrt0_rd_wr_sum: level2-nrt0-rd-wr-sum { + cell-index = <28>; + node-name = "level2-nrt0-rd-wr-sum"; + traffic-merge-type = ; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_sf_0_mnoc"; + }; + }; + + level2_rt0_rd_wr_sum: level2-rt0-rd-wr-sum { + cell-index = <29>; + node-name = "level2-rt0-rd-wr-sum"; + traffic-merge-type = ; + ib-bw-voting-needed; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_hf_0_mnoc"; + }; + }; + + level2_rt1_rd_wr_sum: level2-rt1-rd-wr-sum { + cell-index = <30>; + node-name = "level3-rt1-rd-wr-sum"; + traffic-merge-type = ; + + qcom,axi-port-mnoc { + cam-icc-path-names = "cam_hf_1_mnoc"; + }; + }; + }; + }; + }; + + qcom,cpas-cdm0@ac48000 { + compatible = "qcom,cam170-cpas-cdm0"; + label = "cpas-cdm"; + reg = <0x0 0xac48000 0x0 0x1000>; + reg-names = "cpas-cdm"; + reg-cam-base = <0x48000>; + interrupts = ; + interrupt-names = "cpas-cdm"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk", + "cam_cc_slow_ahb_clk_src"; + clock-rates = <0 0 0 0 0 80000000>; + src-clock-name = "cam_cc_slow_ahb_clk_src"; + operating-points-v2 = <&cpas_cdm_opp_table>; + clock-cntl-level = "svs"; + cdm-client-names = "ife0", "ife1", "ife2", + "ife3", "dualife"; + single-context-cdm; + cell-index = <0>; + status = "okay"; + + cpas_cdm_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-80000000 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + }; + + cam_cci: qcom,cci@ac4a000 { + compatible = "qcom,cci", "simple-bus"; + reg = <0x0 0xac4a000 0x0 0x4000>; + reg-names = "cci"; + reg-cam-base = <0x4a000>; + interrupts = ; + interrupt-names = "CCI"; + operating-points-v2 = <&cci_opp_table>; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CCI_CLK_SRC>, + <&camcc CAM_CC_CCI_CLK>; + clock-names = "cci_clk_src", + "cci_clk"; + clock-rates = <37500000 0>; + clock-cntl-level = "lowsvs"; + src-clock-name = "cci_clk_src"; + pctrl-idx-mapping = ; + pctrl-map-names = "m0", "m1"; + pinctrl-0 = <&cci_i2c_scl0_active &cci_i2c_sda0_active>; + pinctrl-1 = <&cci_i2c_scl0_suspend &cci_i2c_sda0_suspend>; + pinctrl-2 = <&cci_i2c_scl1_active &cci_i2c_sda1_active>; + pinctrl-3 = <&cci_i2c_scl1_suspend &cci_i2c_sda1_suspend>; + pinctrl-names = "m0_active", "m0_suspend", + "m1_active", "m1_suspend"; + cell-index = <0>; + status = "okay"; + + cci_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500000 { + opp-hz = /bits/ 64 <37500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + i2c_freq_custom_cci: qcom,i2c-custom-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <1>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "okay"; + }; + + i2c_freq_400Khz_cci: qcom,i2c-fast-mode { + hw-thigh = <38>; + hw-tlow = <56>; + hw-tsu-sto = <40>; + hw-tsu-sta = <40>; + hw-thd-dat = <22>; + hw-thd-sta = <35>; + hw-tbuf = <62>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "okay"; + }; + + i2c_freq_1Mhz_cci: qcom,i2c-fast-plus-mode { + hw-thigh = <16>; + hw-tlow = <22>; + hw-tsu-sto = <17>; + hw-tsu-sta = <18>; + hw-thd-dat = <16>; + hw-thd-sta = <15>; + hw-tbuf = <24>; + hw-scl-stretch-en = <0>; + hw-trdhld = <3>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "okay"; + }; + + i2c_freq_100Khz_cci: qcom,i2c-standard-mode { + hw-thigh = <201>; + hw-tlow = <174>; + hw-tsu-sto = <204>; + hw-tsu-sta = <231>; + hw-thd-dat = <22>; + hw-thd-sta = <162>; + hw-tbuf = <227>; + hw-scl-stretch-en = <0>; + hw-trdhld = <6>; + hw-tsp = <3>; + cci-clk-src = <37500000>; + status = "okay"; + }; + }; + + cam_jpeg_enc: qcom,jpegenc@ac4e000 { + compatible = "qcom,cam_jpeg_enc_170"; + reg = <0x0 0xac4e000 0x0 0x4000>; + reg-names = "jpege_hw"; + reg-cam-base = <0x4e000>; + interrupts = ; + interrupt-names = "jpeg"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_JPEG_CLK_SRC>, + <&camcc CAM_CC_JPEG_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk", + "cam_cc_jpeg_clk_src", + "cam_cc_jpeg_clk"; + clock-rates = <0 0 0 0 0 600000000 0>; + src-clock-name = "cam_cc_jpeg_clk_src"; + operating-points-v2 = <&jpeg_enc_opp_table>; + clock-cntl-level = "turbo"; + cell-index = <0>; + status = "okay"; + + jpeg_enc_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_jpeg_dma: qcom,jpegdma@ac52000{ + compatible = "qcom,cam_jpeg_dma_170"; + reg = <0x0 0xac52000 0x0 0x4000>; + reg-names = "jpegdma_hw"; + reg-cam-base = <0x52000>; + interrupts = ; + interrupt-names = "jpegdma"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_JPEG_CLK_SRC>, + <&camcc CAM_CC_JPEG_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk", + "cam_cc_jpeg_clk_src", + "cam_cc_jpeg_clk"; + clock-rates = <0 0 0 0 0 600000000 0>; + src-clock-name = "cam_cc_jpeg_clk_src"; + operating-points-v2 = <&jpeg_dma_opp_table>; + clock-cntl-level = "turbo"; + cell-index = <0>; + status = "okay"; + + jpeg_dma_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_csiphy0: qcom,csiphy@ac65000 { + compatible = "qcom,csiphy-v2.0.0", "qcom,csiphy"; + reg = <0x0 0x0ac65000 0x0 0x1000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy0_opp_table>; + reg-cam-base = <0x65000>; + interrupts = ; + interrupt-names = "CSIPHY0"; + csi-vdd-voltage = <1200000>; + mipi-csi-vdd-supply = <&vreg_l11a>; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>; + clock-names = "camnoc_axi_clk", + "soc_ahb_clk", + "slow_ahb_src_clk", + "cpas_ahb_clk", + "cphy_rx_clk_src", + "csiphy0_clk", + "csi0phytimer_clk_src", + "csi0phytimer_clk"; + src-clock-name = "csi0phytimer_clk_src"; + clock-cntl-level = "svs_l1", "turbo"; + clock-rates = <0 0 0 0 269333333 0 269333333 0>, + <0 0 0 0 384000000 0 269333333 0>; + cell-index = <0>; + status = "okay"; + + csiphy0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-269333333 { + opp-hz = /bits/ 64 <269333333>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-384000000 { + opp-hz = /bits/ 64 <384000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_csiphy1: qcom,csiphy@ac66000 { + compatible = "qcom,csiphy-v2.0.0", "qcom,csiphy"; + reg = <0x0 0xac66000 0x0 0x1000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy1_opp_table>; + reg-cam-base = <0x66000>; + interrupts = ; + interrupt-names = "CSIPHY1"; + csi-vdd-voltage = <1200000>; + mipi-csi-vdd-supply = <&vreg_l11a>; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>; + clock-names = "camnoc_axi_clk", + "soc_ahb_clk", + "slow_ahb_src_clk", + "cpas_ahb_clk", + "cphy_rx_clk_src", + "csiphy1_clk", + "csi1phytimer_clk_src", + "csi1phytimer_clk"; + src-clock-name = "csi1phytimer_clk_src"; + clock-cntl-level = "svs_l1", "turbo"; + clock-rates = <0 0 0 0 269333333 0 269333333 0>, + <0 0 0 0 384000000 0 269333333 0>; + cell-index = <1>; + status = "okay"; + + csiphy1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-269333333 { + opp-hz = /bits/ 64 <269333333>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-384000000 { + opp-hz = /bits/ 64 <384000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_csiphy2: qcom,csiphy@ac67000 { + compatible = "qcom,csiphy-v2.0.0", "qcom,csiphy"; + reg = <0x0 0xac67000 0x0 0x1000>; + reg-names = "csiphy"; + operating-points-v2 = <&csiphy2_opp_table>; + reg-cam-base = <0x67000>; + interrupts = ; + interrupt-names = "CSIPHY2"; + csi-vdd-voltage = <1200000>; + mipi-csi-vdd-supply = <&vreg_l11a>; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>; + clock-names = "camnoc_axi_clk", + "soc_ahb_clk", + "slow_ahb_src_clk", + "cpas_ahb_clk", + "cphy_rx_clk_src", + "csiphy2_clk", + "csi2phytimer_clk_src", + "csi2phytimer_clk"; + src-clock-name = "csi2phytimer_clk_src"; + clock-cntl-level = "svs_l1", "turbo"; + clock-rates = <0 0 0 0 269333333 0 269333333 0>, + <0 0 0 0 384000000 0 269333333 0>; + cell-index = <2>; + status = "okay"; + + csiphy2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-269333333 { + opp-hz = /bits/ 64 <269333333>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-384000000 { + opp-hz = /bits/ 64 <384000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_lrme: qcom,lrme@ac6b000 { + compatible = "qcom,lrme"; + reg = <0x0 0xac6b000 0x0 0xa00>; + reg-names = "lrme"; + reg-cam-base = <0x6b000>; + interrupts = ; + interrupt-names = "lrme"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_LRME_CLK_SRC>, + <&camcc CAM_CC_LRME_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_camnoc_axi_clk", + "cam_cc_lrme_clk_src", + "cam_cc_lrme_clk"; + clock-rates = <0 0 0 0 0 200000000 0>, + <0 0 0 0 0 216000000 0>, + <0 0 0 0 0 300000000 0>, + <0 0 0 0 0 404000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal"; + src-clock-name = "cam_cc_lrme_clk_src"; + operating-points-v2 = <&lrme_opp_table>; + cam_hw_pid = <6 10>; + cell-index = <0>; + status = "okay"; + + lrme_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-216000000 { + opp-hz = /bits/ 64 <216000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-404000000 { + opp-hz = /bits/ 64 <404000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + cam_bps: qcom,bps@0x0ac6f000 { + compatible = "qcom,cam-bps"; + reg = <0x0 0xac6f000 0x0 0x3000>; + reg-names = "bps_top"; + reg-cam-base = <0x6f000>; + power-domains = <&camcc BPS_GDSC>; + clocks = <&camcc CAM_CC_BPS_AHB_CLK>, + <&camcc CAM_CC_BPS_AREG_CLK>, + <&camcc CAM_CC_BPS_AXI_CLK>, + <&camcc CAM_CC_BPS_CLK>, + <&camcc CAM_CC_BPS_CLK_SRC>; + clock-names = "cam_cc_bps_ahb_clk", + "cam_cc_bps_areg_clk", + "cam_cc_bps_axi_clk", + "cam_cc_bps_clk", + "cam_cc_bps_clk_src"; + clock-rates = <0 0 0 0 200000000>, + <0 0 0 0 360000000>, + <0 0 0 0 432000000>, + <0 0 0 0 480000000>, + <0 0 0 0 540000000>, + <0 0 0 0 600000000>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", + "nominal", "nominal_l1", "turbo"; + src-clock-name = "cam_cc_bps_clk_src"; + operating-points-v2 = <&bps_opp_table>; + cam_hw_pid = <5 9>; + cell-index = <0>; + status = "okay"; + + bps_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-360000000 { + opp-hz = /bits/ 64 <360000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-432000000 { + opp-hz = /bits/ 64 <432000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_ipe0: qcom,ipe0@0x0ac87000 { + compatible = "qcom,cam-ipe"; + reg = <0x0 0xac87000 0x0 0x3000>; + reg-names = "ipe0_top"; + reg-cam-base = <0x87000>; + power-domains = <&camcc IPE_0_GDSC>; + clock-names = "cam_cc_ipe_0_ahb_clk", + "cam_cc_ipe_0_areg_clk", + "cam_cc_ipe_0_axi_clk", + "cam_cc_ipe_0_clk", + "cam_cc_ipe_0_clk_src"; + clocks = <&camcc CAM_CC_IPE_0_AHB_CLK>, + <&camcc CAM_CC_IPE_0_AREG_CLK>, + <&camcc CAM_CC_IPE_0_AXI_CLK>, + <&camcc CAM_CC_IPE_0_CLK>, + <&camcc CAM_CC_IPE_0_CLK_SRC>; + clock-rates = <0 0 0 0 240000000>, + <0 0 0 0 360000000>, + <0 0 0 0 432000000>, + <0 0 0 0 480000000>, + <0 0 0 0 540000000>, + <0 0 0 0 600000000>; + clock-cntl-level = "lowsvs","svs", "svs_l1", + "nominal", "nominal_l1", "turbo"; + src-clock-name = "cam_cc_ipe_0_clk_src"; + operating-points-v2 = <&ipe0_opp_table>; + cam_hw_pid = <4 8>; + cell-index = <0>; + status = "okay"; + + ipe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-360000000 { + opp-hz = /bits/ 64 <360000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-432000000 { + opp-hz = /bits/ 64 <432000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_vfe0: qcom,vfe0@acaf000 { + compatible = "qcom,vfe170"; + reg = <0x0 0xacaf000 0x0 0x4000>, + <0x0 0xac42000 0x0 0x5000>; + reg-names = "ife0", "cam_camnoc"; + reg-cam-base = <0xaf000 0x42000>; + interrupts = ; + interrupt-names = "ife0"; + power-domains = <&camcc IFE_0_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_IFE_0_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_ife_0_clk", + "cam_cc_ife_0_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_ife_0_axi_clk"; + clock-rates = <0 0 0 0 0 0 240000000 0 0>, + <0 0 0 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 432000000 0 0>, + <0 0 0 0 0 0 540000000 0 0>, + <0 0 0 0 0 0 600000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "turbo"; + src-clock-name = "cam_cc_ife_0_clk_src"; + operating-points-v2 = <&vfe0_opp_table>; + clock-names-option = "cam_cc_ife_0_dsp_clk"; + clocks-option = <&camcc CAM_CC_IFE_0_DSP_CLK>; + clock-rates-option = <600000000>; + cam_hw_pid = <1>; + clock-control-debugfs = "true"; + cell-index = <0>; + status = "okay"; + + vfe0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-360000000 { + opp-hz = /bits/ 64 <360000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-432000000 { + opp-hz = /bits/ 64 <432000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_csid0: qcom,csid0@acb3000 { + compatible = "qcom,csid170"; + reg = <0x0 0xacb3000 0x0 0x1000>; + reg-names = "csid0"; + reg-cam-base = <0xb3000>; + interrupts = ; + interrupt-names = "csid0"; + power-domains = <&camcc IFE_0_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CSID_CLK>, + <&camcc CAM_CC_IFE_0_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_IFE_0_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_ife_0_csid_clk", + "cam_cc_ife_0_csid_clk_src", + "cam_cc_ife_0_cphy_rx_clk", + "cam_cc_cphy_rx_clk_src", + "cam_cc_ife_0_clk", + "cam_cc_ife_0_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_ife_0_axi_clk"; + clock-rates = <0 0 0 0 0 0 100000000 0 0 0 240000000 0 0>, + <0 0 0 0 0 0 200000000 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 320000000 0 0 0 432000000 0 0>, + <0 0 0 0 0 0 404000000 0 0 0 540000000 0 0>, + <0 0 0 0 0 0 480000000 0 0 0 540000000 0 0>, + <0 0 0 0 0 0 540000000 0 0 0 600000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "nominal_l1", "turbo"; + operating-points-v2 = <&csid0_opp_table>; + src-clock-name = "cam_cc_ife_0_csid_clk_src"; + clock-control-debugfs = "true"; + cell-index = <0>; + status = "okay"; + + csid0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-404000000 { + opp-hz = /bits/ 64 <404000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_vfe1: qcom,vfe1@acb6000 { + compatible = "qcom,vfe170"; + reg = <0x0 0xacb6000 0x0 0x4000>, + <0x0 0xac42000 0x0 0x5000>; + reg-names = "ife1", "cam_camnoc"; + reg-cam-base = <0xb6000 0x42000>; + interrupts = ; + interrupt-names = "ife1"; + power-domains = <&camcc IFE_1_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_IFE_1_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_ife_1_clk", + "cam_cc_ife_1_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_ife_1_axi_clk"; + clock-rates = <0 0 0 0 0 0 240000000 0 0>, + <0 0 0 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 432000000 0 0>, + <0 0 0 0 0 0 540000000 0 0>, + <0 0 0 0 0 0 600000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "turbo"; + src-clock-name = "cam_cc_ife_1_clk_src"; + operating-points-v2 = <&vfe1_opp_table>; + clock-names-option = "cam_cc_ife_1_dsp_clk"; + clocks-option = <&camcc CAM_CC_IFE_1_DSP_CLK>; + clock-rates-option = <600000000>; + cam_hw_pid = <2>; + clock-control-debugfs = "true"; + cell-index = <1>; + status = "okay"; + + vfe1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-360000000 { + opp-hz = /bits/ 64 <360000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-432000000 { + opp-hz = /bits/ 64 <432000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_csid1: qcom,csid1@acba000 { + compatible = "qcom,csid170"; + reg = <0x0 0xacba000 0x0 0x1000>; + reg-names = "csid1"; + reg-cam-base = <0xba000>; + interrupts = ; + interrupt-names = "csid1"; + power-domains = <&camcc IFE_1_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CSID_CLK>, + <&camcc CAM_CC_IFE_1_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_IFE_1_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_ife_1_csid_clk", + "cam_cc_ife_1_csid_clk_src", + "cam_cc_ife_1_cphy_rx_clk", + "cam_cc_cphy_rx_clk_src", + "cam_cc_ife_1_clk", + "cam_cc_ife_1_clk_src", + "cam_cc_camnoc_axi_clk", + "cam_cc_ife_1_axi_clk"; + clock-rates = <0 0 0 0 0 0 100000000 0 0 0 240000000 0 0>, + <0 0 0 0 0 0 200000000 0 0 0 360000000 0 0>, + <0 0 0 0 0 0 320000000 0 0 0 432000000 0 0>, + <0 0 0 0 0 0 404000000 0 0 0 540000000 0 0>, + <0 0 0 0 0 0 480000000 0 0 0 540000000 0 0>, + <0 0 0 0 0 0 540000000 0 0 0 600000000 0 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "nominal_l1", "turbo"; + src-clock-name = "cam_cc_ife_1_csid_clk_src"; + operating-points-v2 = <&csid1_opp_table>; + clock-control-debugfs = "true"; + cell-index = <1>; + status = "okay"; + + csid1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-404000000 { + opp-hz = /bits/ 64 <404000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_vfe_lite: qcom,vfe-lite@acc4000 { + compatible = "qcom,vfe-lite170"; + reg = <0x0 0xacc4000 0x0 0x4000>; + reg-names = "ife-lite0"; + reg-cam-base = <0xc4000>; + interrupts = ; + interrupt-names = "ife-lite0"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_ife_lite_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_camnoc_axi_clk"; + clock-rates = <0 0 0 0 0 0 240000000 0>, + <0 0 0 0 0 0 360000000 0>, + <0 0 0 0 0 0 432000000 0>, + <0 0 0 0 0 0 540000000 0>, + <0 0 0 0 0 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "turbo"; + src-clock-name = "cam_cc_ife_lite_clk_src"; + operating-points-v2 = <&vfe_lite0_opp_table>; + cam_hw_pid = <3>; + clock-control-debugfs = "true"; + cell-index = <2>; + status = "okay"; + + vfe_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-360000000 { + opp-hz = /bits/ 64 <360000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-432000000 { + opp-hz = /bits/ 64 <432000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + cam_csid_lite: qcom,csid-lite@acc8000 { + compatible = "qcom,csid-lite170"; + reg = <0x0 0xacc8000 0x0 0x1000>; + reg-names = "csid-lite0"; + reg-cam-base = <0xc8000>; + interrupts = ; + interrupt-names = "csid-lite0"; + power-domains = <&camcc TITAN_TOP_GDSC>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_SOC_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK_SRC>, + <&camcc CAM_CC_CAMNOC_AXI_CLK>; + clock-names = "gcc_camera_ahb_clk", + "gcc_camera_hf_axi_clk", + "cam_cc_soc_ahb_clk", + "cam_cc_cpas_ahb_clk", + "cam_cc_slow_ahb_clk_src", + "cam_cc_ife_lite_csid_clk", + "cam_cc_ife_lite_csid_clk_src", + "cam_cc_ife_lite_cphy_rx_clk", + "cam_cc_cphy_rx_clk_src", + "cam_cc_ife_lite_clk", + "cam_cc_ife_lite_clk_src", + "cam_cc_camnoc_axi_clk"; + clock-rates = <0 0 0 0 0 0 100000000 0 0 0 240000000 0>, + <0 0 0 0 0 0 200000000 0 0 0 360000000 0>, + <0 0 0 0 0 0 320000000 0 0 0 432000000 0>, + <0 0 0 0 0 0 404000000 0 0 0 540000000 0>, + <0 0 0 0 0 0 480000000 0 0 0 540000000 0>, + <0 0 0 0 0 0 540000000 0 0 0 600000000 0>; + clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "nominal_l1", "turbo"; + src-clock-name = "cam_cc_ife_lite_csid_clk_src"; + operating-points-v2 = <&csid_lite0_opp_table>; + clock-control-debugfs = "true"; + cell-index = <2>; + status = "okay"; + + csid_lite0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-404000000 { + opp-hz = /bits/ 64 <404000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; + }; + + qcom,cam-cdm-intf { + compatible = "qcom,cam-cdm-intf"; + cell-index = <0>; + label = "cam-cdm-intf"; + num-hw-cdm = <1>; + cdm-client-names = "vfe", "jpegdma", + "jpegenc", "lrmecdm"; + status = "okay"; + }; + + qcom,cam-icp { + compatible = "qcom,cam-icp"; + compat-hw-name = "qcom,icp", + "qcom,ipe0", + "qcom,bps"; + num-icp = <1>; + num-ipe = <1>; + num-bps = <1>; + ipe0-mask = <0x1000>; + icp_pc_en; + status = "okay"; + }; + + cam_isp_mgr: qcom,cam-isp { + compatible = "qcom,cam-isp"; + arch-compat = "ife"; + status = "okay"; + }; + + cam_jpeg_mgr: qcom,cam-jpeg { + compatible = "qcom,cam-jpeg"; + compat-hw-name = "qcom,jpegenc", + "qcom,jpegdma"; + num-jpeg-enc = <1>; + num-jpeg-dma = <1>; + status = "okay"; + }; + + cam_lrme_mgr: qcom,cam-lrme { + compatible = "qcom,cam-lrme"; + arch-compat = "lrme"; + status = "okay"; + }; + + qcom,camera-main { + compatible = "qcom,camera_qcs615"; + status = "okay"; + }; + + qcom,cam-req-mgr { + compatible = "qcom,cam-req-mgr"; + status = "okay"; + }; + + cam_smmu: qcom,cam-smmu { + compatible = "qcom,msm-cam-smmu", "simple-bus"; + status = "okay"; + + msm-cam-icp-fw { + compatible = "qcom,msm-cam-smmu-fw-dev"; + label="icp"; + memory-region = <&pil_camera_mem>; + }; + + msm-cam-smmu-cpas-cdm { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0c00 0x0>; + cam-smmu-label = "cpas-cdm"; + + cpas_cdm_iova_mem_map: iova-mem-map { + iova-mem-region-io { + /* IO region is approximately 3.4 GB */ + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0xd8c00000>; + iova-region-id = <0x3>; + status = "okay"; + }; + }; + }; + + msm-cam-smmu-icp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0de2 0x0>, + <&apps_smmu 0x0c80 0x0>, + <&apps_smmu 0x0ca0 0x0>, + <&apps_smmu 0x0d00 0x0>, + <&apps_smmu 0x0d20 0x0>; + cam-smmu-label = "icp"; + + icp_iova_mem_map: iova-mem-map { + iova-mem-region-firmware { + /* Firmware region is 8MB */ + iova-region-name = "firmware"; + iova-region-start = <0x0>; + iova-region-len = <0x800000>; + iova-region-id = <0x0>; + status = "okay"; + }; + + iova-mem-region-io { + /* IO region is approximately 3.3 GB */ + iova-region-name = "io"; + iova-region-start = <0x10C00000>; + iova-region-len = <0xCF300000>; + iova-region-id = <0x3>; + status = "okay"; + }; + + iova-mem-qdss-region { + /* qdss region is approximately 1MB */ + iova-region-name = "qdss"; + iova-region-start = <0x10B00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x5>; + qdss-phy-addr = <0x16790000>; + status = "okay"; + }; + + iova-mem-region-secondary-heap { + /* Secondary heap region is 1MB long */ + iova-region-name = "secheap"; + iova-region-start = <0x10A00000>; + iova-region-len = <0x100000>; + iova-region-id = <0x4>; + status = "okay"; + }; + + iova-mem-region-shared { + /* Shared region is 150MB long */ + iova-region-name = "shared"; + iova-region-start = <0x7400000>; + iova-region-len = <0x9600000>; + iova-region-id = <0x1>; + iova-granularity = <0x15>; + status = "okay"; + }; + }; + }; + + msm-cam-smmu-ife { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0820 0x40>, + <&apps_smmu 0x0840 0x00>, + <&apps_smmu 0x0860 0x40>; + cam-smmu-label = "ife"; + multiple-client-devices; + com,iommu-faults = "stall-disable", "non-fatal"; + + ife_iova_mem_map: iova-mem-map { + /* IO region is approximately 3.4 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0xd8c00000>; + iova-region-id = <0x3>; + status = "okay"; + }; + }; + }; + + msm-cam-smmu-jpeg { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0xd80 0x20>, + <&apps_smmu 0xda0 0x20>; + cam-smmu-label = "jpeg"; + + jpeg_iova_mem_map: iova-mem-map { + /* IO region is approximately 3.4 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0xd8c00000>; + iova-region-id = <0x3>; + status = "okay"; + }; + }; + }; + + msm-cam-smmu-lrme { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x0cc0 0x0>, + <&apps_smmu 0x0d40 0x0>; + cam-smmu-label = "lrme"; + + lrme_iova_mem_map: iova-mem-map { + iova-mem-region-shared { + /* Shared region is 100MB long */ + iova-region-name = "shared"; + iova-region-start = <0x7400000>; + iova-region-len = <0x6400000>; + iova-region-id = <0x1>; + status = "okay"; + }; + + /* IO region is approximately 3.3 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0xd800000>; + iova-region-len = <0xd2800000>; + iova-region-id = <0x3>; + status = "okay"; + }; + }; + }; + + msm-cam-smmu-secure { + compatible = "qcom,msm-cam-smmu-cb"; + cam-smmu-label = "cam-secure"; + qcom,secure-cb; + }; + }; + + qcom,cam-sync { + compatible = "qcom,cam-sync"; + status = "okay"; + }; +}; + +&tlmm { + cam_sensor_active_rst0: cam-sensor-active-rst0 { + /* RESET */ + mux { + pins = "gpio75"; + function = "gpio"; + }; + + config { + pins = "gpio75"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst1: cam-sensor-active-rst1 { + /* RESET */ + mux { + pins = "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio29"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_rst2: cam-sensor-active-rst2 { + /* RESET */ + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_active: cam-sensor-mclk2-active { + /* MCLK2 */ + mux { + pins = "gpio30"; + function = "cam_mclk"; + }; + + config { + pins = "gpio30"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk2_suspend: cam-sensor-mclk2-suspend { + /* MCLK2 */ + mux { + pins = "gpio30"; + function = "cam_mclk"; + }; + + config { + pins = "gpio30"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_active: cam-sensor-mclk3-active { + /* MCLK3 */ + mux { + pins = "gpio28"; + function = "cam_mclk"; + }; + + config { + pins = "gpio28"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_suspend: cam-sensor-mclk3-suspend { + /* MCLK3 */ + mux { + pins = "gpio28"; + function = "cam_mclk"; + }; + + config { + pins = "gpio28"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_rst0: cam-sensor-suspend-rst0 { + /* RESET */ + mux { + pins = "gpio75"; + function = "gpio"; + }; + + config { + pins = "gpio75"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst1: cam-sensor-suspend-rst1 { + /* RESET */ + mux { + pins = "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio29"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_suspend_rst2: cam-sensor-suspend-rst2 { + /* RESET */ + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cci_i2c_scl0_active: cci-i2c-scl0-active { + mux { + /* CLK, DATA */ + pins = "gpio33"; + function = "cci_i2c"; + }; + + config { + pins = "gpio33"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl0_suspend: cci-i2c-scl0-suspend { + mux { + /* CLK, DATA */ + pins = "gpio33"; + function = "cci_i2c"; + }; + + config { + pins = "gpio33"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl1_active: cci-i2c-scl1-active { + mux { + /* CLK, DATA */ + pins = "gpio35"; + function = "cci_i2c"; + }; + + config { + pins = "gpio35"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_scl1_suspend: cci-i2c-scl1-suspend { + mux { + /* CLK, DATA */ + pins = "gpio35"; + function = "cci_i2c"; + }; + + config { + pins = "gpio35"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + + cci_i2c_sda0_active: cci-i2c-sda0-active { + mux { + /* CLK, DATA */ + pins = "gpio32"; + function = "cci_i2c"; + }; + + config { + pins = "gpio32"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda0_suspend: cci-i2c-sda0-suspend { + mux { + /* CLK, DATA */ + pins = "gpio32"; + function = "cci_i2c"; + }; + + config { + pins = "gpio32"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda1_active: cci-i2c-sda1-active { + mux { + /* CLK, DATA */ + pins = "gpio34"; + function = "cci_i2c"; + }; + + config { + pins = "gpio34"; + bias-pull-up; /* PULL UP*/ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cci_i2c_sda1_suspend: cci-i2c-sda1-suspend { + mux { + /* CLK, DATA */ + pins = "gpio34"; + function = "cci_i2c"; + }; + + config { + pins = "gpio34"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; +}; From d7fba5fde03df809e593f3e8701a0ce9d30c7d59 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:23:37 +0530 Subject: [PATCH 266/438] QCLINUX: arm64: dts: qcom: Change rb3gen2 camera firmware path update the path for the camera icp firmware. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi index 37ea48e35d09c..2fadfb9de1fee 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs6490-camera.dtsi @@ -32,7 +32,7 @@ clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal"; src-clock-name = "soc_fast_ahb"; operating-points-v2 = <&a5_opp_table>; - fw_name = "CAMERA_ICP_170.elf"; + fw_name = "qcom/qcm6490/CAMERA_ICP_170.elf"; ubwc-ipe-fetch-cfg = <0x7073 0x707b>; ubwc-ipe-write-cfg = <0x161cf 0x161ef>; ubwc-bps-fetch-cfg = <0x7073 0x707b>; From b586b9a4443e89167213d69e82d8837aa8ecf6b3 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:33:18 +0530 Subject: [PATCH 267/438] QCLINUX: arm64: dts: qcom: Change monaco camera firmware path update the path for the camera icp firmware. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/monaco-camera.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi index f72161e75f7e7..258ad08ffee2f 100644 --- a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi @@ -1463,7 +1463,7 @@ <400000000 0 600000000 0>; clock-cntl-level = "svs_l1", "nominal"; nrt-device; - fw_name = "CAMERA_ICP"; + fw_name = "qcom/qcs8300/CAMERA_ICP"; ubwc-ipe-fetch-cfg = <0x707b 0x7083>; ubwc-ipe-write-cfg = <0x161ef 0x1620f>; qos-val = <0xa0a>; From fc79f53582748872d5cb5282b40b637c83e8b4b9 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:32:20 +0530 Subject: [PATCH 268/438] QCLINUX: arm64: dts: qcom: Change lemans camera firmware path update the path for the camera icp firmware. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/lemans-camera.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi index 855d29dff618f..a207377cce6c1 100644 --- a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi @@ -1600,7 +1600,7 @@ <400000000 0 600000000 0>; clock-cntl-level = "svs_l1", "nominal"; nrt-device; - fw_name = "CAMERA_ICP"; + fw_name = "qcom/sa8775p/CAMERA_ICP"; ubwc-ipe-fetch-cfg = <0x707b 0x7083>; ubwc-ipe-write-cfg = <0x161ef 0x1620f>; qos-val = <0xa0a>; From 7ee25758f1d04d68a693a68120e16252687e1563 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:30:22 +0530 Subject: [PATCH 269/438] QCLINUX: arm64: dts: qcom: Change talos camera firmware path update the path for the camera icp firmware. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/talos-camera.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/talos-camera.dtsi b/arch/arm64/boot/dts/qcom/talos-camera.dtsi index e2daa14db1e80..5a79115547f9a 100644 --- a/arch/arm64/boot/dts/qcom/talos-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/talos-camera.dtsi @@ -43,7 +43,7 @@ clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal", "nominal_l1", "turbo"; src-clock-name = "cam_cc_icp_clk_src"; operating-points-v2 = <&a5_opp_table>; - fw_name = "CAMERA_ICP.elf"; + fw_name = "qcom/qcs615/CAMERA_ICP.elf"; ubwc-cfg = <0x73 0x1CF>; cam_hw_pid = <15>; cell-index = <0>; From f0b7b3444fd7d7cbbeb13d94886adbf864948243 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Fri, 9 Jan 2026 00:54:23 +0530 Subject: [PATCH 270/438] QCLINUX: arm64: dts: qcom: talos: add camnoc bandwidth levels Add two new AHB bandwidth levels for the camnoc path and update cam-ahb-num-cases accordingly. This ensures that the DT reflects the full set of supported interconnect bandwidth cases. Signed-off-by: Vikram Sharma --- arch/arm64/boot/dts/qcom/talos-camera.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/talos-camera.dtsi b/arch/arm64/boot/dts/qcom/talos-camera.dtsi index 5a79115547f9a..e0f59fb00a5fc 100644 --- a/arch/arm64/boot/dts/qcom/talos-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/talos-camera.dtsi @@ -134,9 +134,10 @@ "cam_hf_0_mnoc", "cam_hf_1_mnoc", "cam_sf_0_mnoc"; - cam-ahb-num-cases = <7>; + cam-ahb-num-cases = <9>; cam-ahb-bw-KBps = <0 0>, <0 76800>, <0 150000>, <0 150000>, - <0 300000>, <0 300000>, <0 300000>; + <0 300000>, <0 300000>, <0 300000>, + <0 300000>, <0 300000>; vdd-corners = Date: Fri, 23 Jan 2026 12:57:03 +0530 Subject: [PATCH 271/438] QCLINUX: arm64: dts: qcom: disabled vreg_cam1_2p8 regulator Disabled vreg_cam1_2p8 regulator to free GPIOs. Signed-off-by: Nihal Kumar Gupta Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso b/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso index 3945c77528ccb..c0fea4bb3dc23 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso +++ b/arch/arm64/boot/dts/qcom/monaco-evk-camx.dtso @@ -105,3 +105,7 @@ }; }; }; + +&vreg_cam1_2p8 { + status = "disabled"; +}; From 118b039d8cd01fb4cfbcbb127f10a0e2c8c45e76 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Thu, 29 Jan 2026 18:26:31 +0530 Subject: [PATCH 272/438] QCLINUX: arm64: dts: qcom: Enable IMX577 sensor on lemans Enable imx577 sensor on lemans boards from slot0 to slot3. Signed-off-by: Nihal Kumar Gupta --- .../dts/qcom/lemans-evk-camera-sensor.dtsi | 384 ++++++++++++++++++ 1 file changed, 384 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi index 8eb1026e7da1b..2a650bc52d1fc 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-evk-camera-sensor.dtsi @@ -205,6 +205,47 @@ status = "ok"; }; + /*cam0-cmk_imx577*/ + qcom,cam-sensor27 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <0>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam27>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 72 0>, + <&tlmm 132 0>, + <&pmm8654au_0_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <27>; + status = "ok"; + }; + eeprom_cam24: qcom,eeprom24 { compatible = "qcom,eeprom"; cam_vio-supply = <&vreg_s4a>; @@ -239,6 +280,41 @@ cell-index = <24>; status = "ok"; }; + + eeprom_cam27: qcom,eeprom27 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rst0>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rst0>; + gpios = <&tlmm 72 0>, + <&tlmm 132 0>, + <&pmm8654au_0_gpios 7 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK0", + "CAMIF_RESET0", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <27>; + status = "ok"; + }; }; &cam_cci1 { @@ -401,6 +477,160 @@ cell-index = <21>; status = "ok"; }; + + /*cam1-imx577*/ + qcom,cam-sensor26 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam26>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>, + <&tlmm 133 0>, + <&pmm8654au_0_gpios 8 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <26>; + status = "ok"; + }; + + /*cam1-cmk_imx577*/ + qcom,cam-sensor28 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam28>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>, + <&tlmm 133 0>, + <&pmm8654au_0_gpios 8 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK1", + "CAMIF_RESET1", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <28>; + status = "ok"; + }; + + eeprom_cam26: qcom,eeprom26 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>, + <&tlmm 133 0>, + <&pmm8654au_0_gpios 8 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <26>; + status = "ok"; + }; + + eeprom_cam28: qcom,eeprom28 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rst1>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rst1>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 73 0>, + <&tlmm 133 0>, + <&pmm8654au_0_gpios 8 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <28>; + status = "ok"; + }; }; &cam_cci2 { @@ -563,6 +793,83 @@ cell-index = <22>; status = "ok"; }; + + /*cam2-cmk_imx577*/ + qcom,cam-sensor29 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <2>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam29>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 74 0>, + <&tlmm 134 0>, + <&pmm8654au_0_gpios 9 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK2", + "CAMIF_RESET2", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <29>; + status = "ok"; + }; + + eeprom_cam29: qcom,eeprom29 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rst2>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rst2>; + pinctrl-names = "cam_default", "cam_suspend"; + gpios = <&tlmm 74 0>, + <&tlmm 134 0>, + <&pmm8654au_0_gpios 9 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <29>; + status = "ok"; + }; }; &cam_cci3 { @@ -725,6 +1032,83 @@ cell-index = <23>; status = "ok"; }; + + /*cam3-cmk_imx577*/ + qcom,cam-sensor30 { + compatible = "qcom,cam-sensor"; + csiphy-sd-index = <3>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_cam30>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst3>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst3>; + gpios = <&tlmm 75 0>, + <&tlmm 135 0>, + <&pmm8654au_0_gpios 10 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAM_MCLK3", + "CAMIF_RESET3", + "CAM_CUSTOM1"; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <30>; + status = "ok"; + }; + + eeprom_cam30: qcom,eeprom30 { + compatible = "qcom,eeprom"; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rst3>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rst3>; + gpios = <&tlmm 75 0>, + <&tlmm 135 0>, + <&pmm8654au_0_gpios 10 0>; + pinctrl-names = "cam_default", "cam_suspend"; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3", + "CAM_CUSTOM1"; + sensor-mode = <0>; + cci-master = <0>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + cell-index = <30>; + status = "ok"; + }; }; &soc { From 9da416f7c61b2c8509a55fc8c4cef13f4eb40f35 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Mon, 2 Feb 2026 15:46:31 +0530 Subject: [PATCH 273/438] QCLINUX: arm64: dts: qcom: Add camx overlay for talos evk Add camx overlay for talos EVK baord. Signed-off-by: Vikram Sharma --- arch/arm64/boot/dts/qcom/Makefile | 4 ++++ arch/arm64/boot/dts/qcom/talos-evk-camx.dtso | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/talos-evk-camx.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 1c854ab0054ae..63815d48e17f8 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -429,3 +429,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-camx.dtb sa8775p-ride-r3-camx-dtbs:= sa8775p-ride-r3.dtb sa8775p-ride-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3-camx.dtb + +talos-evk-camx-dtbs := talos-evk.dtb talos-evk-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-camx.dtb diff --git a/arch/arm64/boot/dts/qcom/talos-evk-camx.dtso b/arch/arm64/boot/dts/qcom/talos-evk-camx.dtso new file mode 100644 index 0000000000000..a40d8817a7a20 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-camx.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include + +#include "talos-camera.dtsi" +#include "talos-camera-sensor.dtsi" From cff584eb3fa59df53e22de30b8760aa417e5c105 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 2 Feb 2026 22:21:36 +0530 Subject: [PATCH 274/438] QCLINUX: arm64: dts: qcom: add node labels and explicit QoS flag in lemans Adds labels to cam-cpas and cam-icp nodes and changes enable-secure-qos-update from boolean to explicit. This change is required for KVM support. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/lemans-camera.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi index a207377cce6c1..d6cce86922c26 100644 --- a/arch/arm64/boot/dts/qcom/lemans-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-camera.dtsi @@ -667,7 +667,7 @@ status = "ok"; }; - qcom,cam-cpas { + cam_cpas: qcom,cam-cpas { compatible = "qcom,cam-cpas"; label = "cpas"; arch-compat = "cpas_top"; @@ -743,7 +743,7 @@ "ife5", "ife6", "ipe0", "sfe0", "sfe1", "cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2", "rt-cdm3", "icp0", "tpg17", "tpg18", "tpg19"; - enable-secure-qos-update; + enable-secure-qos-update = <1>; cell-index = <0>; status = "ok"; @@ -1114,7 +1114,7 @@ }; }; - qcom,cam-icp { + cam_icp_firmware: qcom,cam-icp { compatible = "qcom,cam-icp"; compat-hw-name = "qcom,icp", "qcom,ipe0"; num-icp = <1>; From 80f685d395d37726de450513d0418e3863ff30c6 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 2 Feb 2026 22:38:12 +0530 Subject: [PATCH 275/438] QCLINUX: arm64: dts: qcom: add node labels and explicit QoS flag in monaco Adds labels to cam-cpas and cam-icp nodes and changes enable-secure-qos-update from boolean to explicit. This change is required for KVM support. Signed-off-by: Chandan Kumar Jha --- arch/arm64/boot/dts/qcom/monaco-camera.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi index 258ad08ffee2f..8250f66c34526 100644 --- a/arch/arm64/boot/dts/qcom/monaco-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco-camera.dtsi @@ -528,7 +528,7 @@ status = "ok"; }; - qcom,cam-cpas { + cam_cpas: qcom,cam-cpas { compatible = "qcom,cam-cpas"; label = "cpas"; arch-compat = "cpas_top"; @@ -605,7 +605,7 @@ "ife5", "ife6", "ipe0", "sfe0", "sfe1", "cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2", "rt-cdm3", "icp0", "tpg13", "tpg14", "tpg15"; - enable-secure-qos-update; + enable-secure-qos-update = <1>; cell-index = <0>; status = "ok"; @@ -976,7 +976,7 @@ }; }; - qcom,cam-icp { + cam_icp_firmware: qcom,cam-icp { compatible = "qcom,cam-icp"; compat-hw-name = "qcom,icp", "qcom,ipe0"; num-icp = <1>; From 5618ef740c6cdd3743304f6a727b1558937024de Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Sat, 7 Feb 2026 15:37:33 +0530 Subject: [PATCH 276/438] QCLINUX: arm64: dts: qcom: lemans: Add CamX EL2 overlay Add camx el2 DT overlay for lemans platforms. The overlay updates the ICP firmware node with Secure SMMU SID and disables secure QoS updates for CPAS in EL2/KVM configurations. Wire up the new overlay-built DTBs in the qcom DT Makefile so the corresponding *-camx-el2.dtb targets are generated. Co-developed-by: Ignatius Michael Jihan Signed-off-by: Ignatius Michael Jihan Signed-off-by: Vikram Sharma --- arch/arm64/boot/dts/qcom/Makefile | 4 +++ arch/arm64/boot/dts/qcom/lemans-camx-el2.dtso | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/lemans-camx-el2.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 63815d48e17f8..44f8dc65362ef 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -397,6 +397,10 @@ lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb +lemans-camx-el2-dtbs := lemans-evk-el2.dtb lemans-evk-camx.dtbo lemans-camx-el2.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += lemans-camx-el2.dtb + monaco-evk-camx-dtbs := monaco-evk.dtb monaco-evk-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camx.dtb diff --git a/arch/arm64/boot/dts/qcom/lemans-camx-el2.dtso b/arch/arm64/boot/dts/qcom/lemans-camx-el2.dtso new file mode 100644 index 0000000000000..83b5605f026a8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-camx-el2.dtso @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +/ { + /* cam_cpas label -> /soc@0/qcom,cam-cpas * + fragment@0 { + target-path = "/soc@0/qcom,cam-cpas"; + __overlay__ { + enable-secure-qos-update = <0>; + }; + }; + + /* cam_icp_firmware label -> /soc@0/qcom,cam-icp */ + fragment@1 { + target-path = "/soc@0/qcom,cam-icp"; + __overlay__ { + camera-firmware { + iommus = <&apps_smmu 0x08c1 0x0400>; + }; + }; + }; +}; From 05dbe6363f42fec541fd4b2d606c2a047d70cf14 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Thu, 23 Oct 2025 12:28:39 +0530 Subject: [PATCH 277/438] QCLINUX: firmware: qcom_scm: Add new scm to update Camera QoS Add new SCM call to program secure camera qos settings. For each NIU camera driver can call this scm API which need each NIU's register offsets, value and number of registers offset that need to be programmed. Signed-off-by: Vikram Sharma --- drivers/firmware/qcom/qcom_scm.c | 45 ++++++++++++++++++++++++++ drivers/firmware/qcom/qcom_scm.h | 3 ++ include/linux/firmware/qcom/qcom_scm.h | 10 ++++++ 3 files changed, 58 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 8fbc96693a55f..8c4f4d51303b9 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2508,6 +2508,51 @@ bool qcom_scm_is_available(void) } EXPORT_SYMBOL_GPL(qcom_scm_is_available); +int qcom_scm_camera_update_camnoc_qos(uint32_t use_case_id, + uint32_t cam_qos_cnt, struct qcom_scm_camera_qos *cam_qos) +{ + int ret; + dma_addr_t payload_phys; + u32 *payload_buf = NULL; + u32 payload_size = 0; + + if ((cam_qos_cnt > QCOM_SCM_CAMERA_MAX_QOS_CNT) || (cam_qos_cnt && !cam_qos)) { + pr_err("Invalid input SmartQoS count: %d\n", cam_qos_cnt); + return -EINVAL; + } + + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_CAMERA, + .cmd = QCOM_SCM_CAMERA_UPDATE_CAMNOC_QOS, + .owner = ARM_SMCCC_OWNER_SIP, + .args[0] = use_case_id, + .args[2] = payload_size, + .arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL), + }; + + payload_size = cam_qos_cnt * sizeof(struct qcom_scm_camera_qos); + + /* fill all required qos settings */ + if (use_case_id && payload_size && cam_qos) { + payload_buf = dma_alloc_coherent(__scm->dev, + payload_size, &payload_phys, GFP_KERNEL); + if (!payload_buf) + return -ENOMEM; + + memcpy(payload_buf, cam_qos, payload_size); + desc.args[1] = payload_phys; + desc.args[2] = payload_size; + + } + ret = qcom_scm_call(__scm->dev, &desc, NULL); + + if (payload_buf) + dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_scm_camera_update_camnoc_qos); + static int qcom_scm_fill_irq_fwspec_params(struct irq_fwspec *fwspec, u32 hwirq) { if (hwirq >= GIC_SPI_BASE && hwirq <= GIC_MAX_SPI) { diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index caab80a73e17f..d8c39bfec47f7 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -175,6 +175,9 @@ int qcom_scm_shm_bridge_enable(struct device *scm_dev); #define QCOM_SCM_INTERRUPTED 1 #define QCOM_SCM_WAITQ_SLEEP 2 +#define QCOM_SCM_SVC_CAMERA 0x18 +#define QCOM_SCM_CAMERA_UPDATE_CAMNOC_QOS 0xA + static inline int qcom_scm_remap_error(int err) { switch (err) { diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 5747bd191bf15..d84b5eb6870c6 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -10,10 +10,12 @@ #include #include +#include #define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) #define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0 #define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1 +#define QCOM_SCM_CAMERA_MAX_QOS_CNT 2 #define QCOM_SCM_HDCP_MAX_REQ_CNT 5 struct qcom_scm_hdcp_req { @@ -77,6 +79,14 @@ struct qcom_scm_pas_context { bool use_tzmem; }; +struct qcom_scm_camera_qos { + u32 offset; + u32 val; +}; + +int qcom_scm_camera_update_camnoc_qos(uint32_t use_case_id, + uint32_t qos_cnt, struct qcom_scm_camera_qos *scm_buf); + struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, u32 pas_id, phys_addr_t mem_phys, From c17701785bd8e4ea8751740bc42d30a2a5fde113 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Sun, 9 Nov 2025 20:07:19 +0530 Subject: [PATCH 278/438] FROMLIST: dt-bindings: arm: Document reboot mode magic Add bindings to describe vendor-specific reboot modes. Values here correspond to valid parameters to vendor-specific reset types in PSCI SYSTEM_RESET2 call. Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-6-46e085bca4cc@oss.qualcomm.com Reviewed-by: Rob Herring (Arm) Signed-off-by: Elliot Berman Signed-off-by: Shivendra Pratap --- .../devicetree/bindings/arm/psci.yaml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml index 6e2e0c5518411..5d4368d77d07e 100644 --- a/Documentation/devicetree/bindings/arm/psci.yaml +++ b/Documentation/devicetree/bindings/arm/psci.yaml @@ -98,6 +98,27 @@ properties: [1] Kernel documentation - ARM idle states bindings Documentation/devicetree/bindings/cpu/idle-states.yaml + reboot-mode: + type: object + $ref: /schemas/power/reset/reboot-mode.yaml# + unevaluatedProperties: false + properties: + # "mode-normal" is just SYSTEM_RESET + mode-normal: false + patternProperties: + "^mode-.*$": + minItems: 1 + maxItems: 2 + description: | + Describes a vendor-specific reset type. The string after "mode-" + maps a reboot mode to the parameters in the PSCI SYSTEM_RESET2 call. + + Parameters are named mode-xxx = , where xxx + is the name of the magic reboot mode, type is the lower 31 bits + of the reset_type, and, optionally, the cookie value. If the cookie + is not provided, it is defaulted to zero. + The 31st bit (vendor-resets) will be implicitly set by the driver. + patternProperties: "^power-domain-": $ref: /schemas/power/power-domain.yaml# @@ -137,6 +158,15 @@ allOf: required: - cpu_off - cpu_on + - if: + not: + properties: + compatible: + contains: + const: arm,psci-1.0 + then: + properties: + reboot-mode: false additionalProperties: false @@ -260,4 +290,17 @@ examples: domain-idle-states = <&cluster_ret>, <&cluster_pwrdn>; }; }; + + - |+ + + // Case 5: SYSTEM_RESET2 vendor resets + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + + reboot-mode { + mode-edl = <0>; + mode-bootloader = <1 2>; + }; + }; ... From 0471448fbeaa030b614e808616cfd6138bfcd10e Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Sun, 9 Nov 2025 20:07:21 +0530 Subject: [PATCH 279/438] FROMLIST: arm64: dts: qcom: qcm6490-idp: Add PSCI SYSTEM_RESET2 types Add support for SYSTEM_RESET2 vendor-specific resets in qcm6490-idp as reboot-modes. Describe the resets: "bootloader" will cause device to reboot and stop in the bootloader's fastboot mode. "edl" will cause device to reboot into "emergency download mode", which permits loading images via the Firehose protocol. Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-8-46e085bca4cc@oss.qualcomm.com Reviewed-by: Konrad Dybcio Signed-off-by: Elliot Berman Signed-off-by: Shivendra Pratap --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 2 +- arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 6079e67ea829b..44dc8eb55a213 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -863,7 +863,7 @@ interrupts = ; }; - psci { + psci: psci { compatible = "arm,psci-1.0"; method = "smc"; diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index 089a027c57d5c..97aa905662e52 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -695,6 +695,13 @@ status = "okay"; }; +&psci { + reboot-mode { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; +}; + &qupv3_id_0 { status = "okay"; }; From b7aa921bceb7010270dd784f46c0e240063f40e1 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Sun, 9 Nov 2025 20:07:22 +0530 Subject: [PATCH 280/438] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Add PSCI SYSTEM_RESET2 types Add support for SYSTEM_RESET2 vendor-specific resets in qcs6490-rb3gen2 as reboot-modes. Describe the resets: "bootloader" will cause device to reboot and stop in the bootloader's fastboot mode. "edl" will cause device to reboot into "emergency download mode", which permits loading images via the Firehose protocol. Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-9-46e085bca4cc@oss.qualcomm.com Reviewed-by: Konrad Dybcio Signed-off-by: Elliot Berman Signed-off-by: Shivendra Pratap --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index e3d2f01881ae0..1862529815486 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -1031,6 +1031,13 @@ status = "okay"; }; +&psci { + reboot-mode { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; +}; + &qup_uart7_cts { /* * Configure a bias-bus-hold on CTS to lower power From 76610f30733850f7d6d5d6710a48abd797757df4 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Mon, 15 Dec 2025 16:29:34 +0530 Subject: [PATCH 281/438] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Adjust tsens thermal zone configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QCS6490 rb3gen2 board uses the same Qualcomm QCM6490 platform but has a different thermal junction temperature specification due to package-level differences. Update passive/hot trip thresholds to 105°C and critical trip thresholds to 115°C for various subsystem TSENS sensors. Disable CPU cooling maps for CPU TSENS since CPU thermal mitigation is handled automatically in hardware on this board. Signed-off-by: Manaf Meethalavalappu Pallikunhi Link: https://lore.kernel.org/r/20251215105934.2428987-1-manaf.pallikunhi@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 334 +++++++++++++++++++ 1 file changed, 334 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index 1862529815486..af4925ffa40c9 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -1216,6 +1216,340 @@ }; }; +&thermal_zones { + cpu0-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu1-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu2-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu3-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu4-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu5-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu6-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu7-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu8-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu9-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu10-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + cpu11-thermal { + trips { + /delete-node/ trip-point0; + /delete-node/ trip-point1; + + cpu-crit { + temperature = <115000>; + }; + }; + + /delete-node/ cooling-maps; + }; + + aoss0-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + aoss0-crit { + temperature = <115000>; + }; + }; + }; + + aoss1-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + aoss1-crit { + temperature = <115000>; + }; + }; + }; + + cpuss0-thermal { + trips { + /delete-node/ trip-point0; + + cluster0-crit { + temperature = <115000>; + }; + }; + }; + + cpuss1-thermal { + trips { + /delete-node/ trip-point0; + + cluster0-crit { + temperature = <115000>; + }; + }; + }; + + gpuss0-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + gpuss0-crit { + temperature = <115000>; + }; + }; + }; + + gpuss1-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + gpuss1-crit { + temperature = <115000>; + }; + }; + }; + + nspss0-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + nspss0-crit { + temperature = <115000>; + }; + }; + }; + + nspss1-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + nspss1-crit { + temperature = <115000>; + }; + }; + }; + + video-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + video-crit { + temperature = <115000>; + }; + }; + }; + + ddr-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + ddr-crit { + temperature = <115000>; + }; + }; + }; + + mdmss0-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + mdmss0-crit { + temperature = <115000>; + }; + }; + }; + + mdmss1-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + mdmss1-crit { + temperature = <115000>; + }; + }; + }; + + mdmss2-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + mdmss2-crit { + temperature = <115000>; + }; + }; + }; + + mdmss3-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + mdmss3-crit { + temperature = <115000>; + }; + }; + }; + + camera0-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + + camera0-crit { + temperature = <115000>; + }; + }; + }; +}; + &tlmm { gpio-reserved-ranges = <32 2>, /* ADSP */ <48 4>; /* NFC */ From ad49b2731e1f2f9925151feaa28963d7e5edbfeb Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:26 +0530 Subject: [PATCH 282/438] FROMLIST: arm64: dts: qcom: Enable cdsp qmi tmd devices for kodiak Enable cdsp cooling devices and cooling map bindings for cdsp. Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251223123227.1317244-8-gaurav.kohli@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 44dc8eb55a213..f42c5f2bc828b 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4793,6 +4793,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; usb_1: usb@a600000 { @@ -7600,12 +7608,26 @@ type = "hot"; }; + nspss0_alert1: trip-point1 { + temperature = <100000>; + hysteresis = <5000>; + type = "passive"; + }; + nspss0_crit: nspss0-crit { temperature = <110000>; hysteresis = <0>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nspss0_alert1>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nspss1-thermal { @@ -7618,12 +7640,26 @@ type = "hot"; }; + nspss1_alert1: trip-point1 { + temperature = <100000>; + hysteresis = <5000>; + type = "passive"; + }; + nspss1_crit: nspss1-crit { temperature = <110000>; hysteresis = <0>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nspss1_alert1>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; video-thermal { From e510f5a1be5582966df96a5bbd9674fa0b0281bf Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Fri, 30 Jan 2026 15:57:25 +0530 Subject: [PATCH 283/438] FROMLIST: arm64: dts: qcom: Enable lvds panel-DV215FHM-R01 for rb3gen2 industrial mezzanine Below is the routing diagram of dsi lanes from qcs6490 soc to mezzanine. DSI0 --> SW1403.4 --> LT9611uxc --> hdmi port | --> SW2700.1 --> dsi connector | --> LT9211c --> LVDS connector Disable hdmi connector for industrial mezzanine and enable LT9211c bridge and lvds panel node. LT9211c is powered by default with reset gpio connected to 117. Link: https://lore.kernel.org/r/20260130-add-lt9211c-bridge-for-rb3gen2-industrial-mezzanine-v2-1-a98714fa1531@oss.qualcomm.com Signed-off-by: Gopi Botlagunta Co-developed-by: Yi Zhang Signed-off-by: Yi Zhang --- .../qcs6490-rb3gen2-industrial-mezzanine.dtso | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso index 619a42b5ef48d..cc8ee16431679 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso @@ -8,6 +8,112 @@ #include #include +/ { + + hdmi-connector { + status = "disabled"; + }; + + panel_lvds: panel-lvds@0 { + compatible = "panel-lvds"; + data-mapping = "vesa-24"; + width-mm = <476>; + height-mm = <268>; + + status = "okay"; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <88>; + hback-porch = <148>; + hsync-len = <44>; + vfront-porch = <4>; + vback-porch = <36>; + vsync-len = <5>; + de-active = <1>; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dual-lvds-odd-pixels; + panel_in_lvds_odd: endpoint { + remote-endpoint = <<9211c_out_odd>; + }; + }; + + port@1 { + reg = <1>; + + dual-lvds-even-pixels; + panel_in_lvds_even: endpoint { + remote-endpoint = <<9211c_out_even>; + }; + + }; + }; + }; + +}; + +&i2c1 { + status = "okay"; + + lvds_bridge: lvds-bridge@29 { + compatible = "lontium,lt9211c"; + reg = <0x29>; + reset-gpios = <&tlmm 117 1>; + + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lt9211c_in: endpoint { + data-lanes = <0 1 2 3>; + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@2 { + reg = <2>; + + lt9211c_out_odd: endpoint { + remote-endpoint = <&panel_in_lvds_odd>; + }; + }; + + port@3 { + reg = <3>; + + lt9211c_out_even: endpoint { + remote-endpoint = <&panel_in_lvds_even>; + }; + }; + }; + }; + + +}; + +<9611_codec { + status = "disabled"; +}; + +&mdss_dsi0_out { + remote-endpoint = <<9211c_in>; +}; + &spi11 { #address-cells = <1>; #size-cells = <0>; From 935a74153475a9943b1ff3854e55172c917d3296 Mon Sep 17 00:00:00 2001 From: Janaki Ramaiah Thota Date: Tue, 3 Feb 2026 12:48:07 +0530 Subject: [PATCH 284/438] FROMLIST: arm64: dts: qcom: qcm6490-idp: add and enable BT node Add the PMU node for WCN6750 present on the qcm6490-idp board and assign its power outputs to the Bluetooth module. In WCN6750 module sw_ctrl and wifi-enable pins are handled in the wifi controller firmware. Therefore, it is not required to have those pins' entries in the PMU node. Link: https://lore.kernel.org/r/20260203071807.764036-1-janaki.thota@oss.qualcomm.com Reviewed-by: Konrad Dybcio Signed-off-by: Janaki Ramaiah Thota --- arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 169 +++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index 97aa905662e52..7511690cb6ae0 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -36,6 +36,7 @@ aliases { serial0 = &uart5; + serial1 = &uart7; }; pm8350c_pwm_backlight: backlight { @@ -194,6 +195,63 @@ #sound-dai-cells = <1>; }; + + wcn6750-pmu { + compatible = "qcom,wcn6750-pmu"; + pinctrl-0 = <&bt_en>; + pinctrl-names = "default"; + vddaon-supply = <&vreg_s7b_0p972>; + vddasd-supply = <&vreg_l11c_2p8>; + vddpmu-supply = <&vreg_s7b_0p972>; + vddrfa0p8-supply = <&vreg_s7b_0p972>; + vddrfa1p2-supply = <&vreg_s8b_1p272>; + vddrfa1p7-supply = <&vreg_s1b_1p872>; + vddrfa2p2-supply = <&vreg_s1c_2p19>; + + bt-enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p7: ldo7 { + regulator-name = "vreg_pmu_rfa_1p7"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; }; &apps_rsc { @@ -702,6 +760,39 @@ }; }; +&qup_uart7_cts { + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; +}; + +&qup_uart7_rts { + /* We'll drive RTS, so no pull */ + drive-strength = <2>; + bias-disable; +}; + +&qup_uart7_rx { + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module is + * in tri-state (module powered off or not driving the + * signal yet). + */ + bias-pull-up; +}; + +&qup_uart7_tx { + /* We'll drive TX, so no pull */ + drive-strength = <2>; + bias-disable; +}; + &qupv3_id_0 { status = "okay"; }; @@ -927,6 +1018,59 @@ gpio-reserved-ranges = <32 2>, /* ADSP */ <48 4>; /* NFC */ + bt_en: bt-en-state { + pins = "gpio85"; + function = "gpio"; + output-low; + bias-disable; + }; + + qup_uart7_sleep_cts: qup-uart7-sleep-cts-state { + pins = "gpio28"; + function = "gpio"; + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; + }; + + qup_uart7_sleep_rts: qup-uart7-sleep-rts-state { + pins = "gpio29"; + function = "gpio"; + /* + * Configure pull-down on RTS. As RTS is active low + * signal, pull it low to indicate the BT SoC that it + * can wakeup the system anytime from suspend state by + * pulling RX low (by sending wakeup bytes). + */ + bias-pull-down; + }; + + qup_uart7_sleep_rx: qup-uart7-sleep-rx-state { + pins = "gpio31"; + function = "gpio"; + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module + * is floating which may cause spurious wakeups. + */ + bias-pull-up; + }; + + qup_uart7_sleep_tx: qup-uart7-sleep-tx-state { + pins = "gpio30"; + function = "gpio"; + /* + * Configure pull-up on TX when it isn't actively driven + * to prevent BT SoC from receiving garbage during sleep. + */ + bias-pull-up; + }; + sd_cd: sd-cd-state { pins = "gpio91"; function = "gpio"; @@ -945,6 +1089,31 @@ status = "okay"; }; +&uart7 { + /delete-property/ interrupts; + interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 31 IRQ_TYPE_EDGE_FALLING>; + pinctrl-1 = <&qup_uart7_sleep_cts>, + <&qup_uart7_sleep_rts>, + <&qup_uart7_sleep_tx>, + <&qup_uart7_sleep_rx>; + pinctrl-names = "default", + "sleep"; + + status = "okay"; + + bluetooth: bluetooth { + compatible = "qcom,wcn6750-bt"; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + max-speed = <3200000>; + }; +}; + &ufs_mem_hc { reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>; vcc-supply = <&vreg_l7b_2p952>; From 4d3f73d45814ef510bfa9a423070e031afc17449 Mon Sep 17 00:00:00 2001 From: Sushrut Shree Trivedi Date: Thu, 12 Feb 2026 17:36:29 +0530 Subject: [PATCH 285/438] FROMLIST: arm64: dts: qcom: qcm6490-idp: Enable PCIe1 Remove PCIe1 clocks from protected-list and enable PCIe1 controller and its corresponding PHY nodes on qcm6490-idp platform. PCIe1 is used to connect NVMe based SSD's on this platform. Signed-off-by: Sushrut Shree Trivedi Link: https://lore.kernel.org/r/20260212-qcm6490-idp-v1-1-80a45bd46ac5@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 39 ++++++++++++++++++++---- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index 7511690cb6ae0..e3f79b8dde729 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -591,12 +591,7 @@ }; &gcc { - protected-clocks = ,, - , , - , , - , , - , , - , , + protected-clocks = , , ,, , , , @@ -673,6 +668,22 @@ status = "okay"; }; +&pcie1 { + perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie1_reset_n>, <&pcie1_wake_n>, <&pcie1_clkreq_n>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + status = "okay"; +}; + &pm7250b_gpios { lcd_disp_bias_en: lcd-disp-bias-en-state { pins = "gpio2"; @@ -1071,6 +1082,22 @@ bias-pull-up; }; + pcie1_reset_n: pcie1-reset-n-state { + pins = "gpio2"; + function = "gpio"; + drive-strength = <16>; + output-low; + bias-disable; + }; + + pcie1_wake_n: pcie1-wake-n-state { + pins = "gpio3"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + sd_cd: sd-cd-state { pins = "gpio91"; function = "gpio"; From dad722be41ea3dd8965e7ea059fbe85dd0006423 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Fri, 23 Jan 2026 17:42:27 +0530 Subject: [PATCH 286/438] FROMLIST: arm64: dts: qcom: kodiak: Fix PCIe1 PHY ref clock voting GCC_PCIE_CLKREF_EN controls a repeater that provides the reference clock only to the PCIe0 PHY. PCIe1 PHY receives its refclk directly from the CXO source. If the PCIe1 driver in HLOS votes for or against GCC_PCIE_CLKREF_EN, it will inadvertently modify the refclk to PCIe0 as well. Since PCIe0 is managed by WPSS while PCIe1 is managed in HLOS, there is no mechanism to coordinate these votes. As a result, HLOS may disable this repeater during suspend and cut off the PCIe0 PHY refclk while PCIe0 is still active. Replace the unused GCC_PCIE_CLKREF_EN clock entry with RPMH_CXO_CLK to reflect the actual hardware wiring and prevent unintended changes to PCIe0 clocking. Fixes: 92e0ee9f83b3 ("arm64: dts: qcom: sc7280: Add PCIe and PHY related nodes") Cc: stable@vger.kernel.org Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260123-fix_pcie1_phy_clk-v1-1-38f82ea01792@oss.qualcomm.com Signed-off-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index f42c5f2bc828b..80e9481471f24 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -2445,7 +2445,7 @@ reg = <0 0x01c0e000 0 0x1000>; clocks = <&gcc GCC_PCIE_1_AUX_CLK>, <&gcc GCC_PCIE_1_CFG_AHB_CLK>, - <&gcc GCC_PCIE_CLKREF_EN>, + <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_PCIE1_PHY_RCHNG_CLK>, <&gcc GCC_PCIE_1_PIPE_CLK>; clock-names = "aux", From 4cfec2e67245d8175699349fa654017a7aabf04c Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:23 +0530 Subject: [PATCH 287/438] FROMLIST: arm64: dts: qcom: lemans: Add PSCI SYSTEM_RESET2 types Add support for SYSTEM_RESET2 vendor-specific resets as reboot-modes in the psci node. Describe the resets: "bootloader" will cause device to reboot and stop in the bootloader's fastboot mode. "edl" will cause device to reboot into "emergency download mode", which permits loading images via the Firehose protocol. Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-10-46e085bca4cc@oss.qualcomm.com Signed-off-by: Elliot Berman Signed-off-by: Shivendra Pratap --- arch/arm64/boot/dts/qcom/lemans.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 808827b83553d..f249634a04799 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -635,6 +635,11 @@ #power-domain-cells = <0>; domain-idle-states = <&cluster_sleep_apss_rsc_pc>; }; + + reboot-mode { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; }; reserved-memory { From 7c75abd568e2982eed4f49cd570d3226b5a5a9a1 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Wed, 28 Jan 2026 17:18:50 +0530 Subject: [PATCH 288/438] FROMLIST: arm64: dts: qcom: lemans: Add eDP ref clock for eDP PHYs The eDP PHY nodes on lemans were missing the reference clock voting. This initially went unnoticed because the clock was implicitly enabled by the UFS PHY driver, and the eDP PHY happened to rely on that. After commit 77d2fa54a945 ("scsi: ufs: qcom : Refactor phy_power_on/off calls"), the UFS driver no longer keeps the reference clock enabled. As a result, the eDP PHY fails to power on. To fix this, add eDP reference clock for eDP PHYs on lemans chipset ensuring reference clock is enabled. Link: https://lore.kernel.org/r/20260128114853.2543416-3-quic_riteshk@quicinc.com Fixes: e1e3e5673f8d7 ("arm64: dts: qcom: sa8775p: add DisplayPort device nodes") Signed-off-by: Ritesh Kumar --- arch/arm64/boot/dts/qcom/lemans.dtsi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index f249634a04799..0f8643adf89b6 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -5306,9 +5306,11 @@ <0x0 0x0aec2000 0x0 0x1c8>; clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, - <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>; + <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_EDP_REF_CLKREF_EN>; clock-names = "aux", - "cfg_ahb"; + "cfg_ahb", + "ref"; #clock-cells = <1>; #phy-cells = <0>; @@ -5325,9 +5327,11 @@ <0x0 0x0aec5000 0x0 0x1c8>; clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK>, - <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>; + <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_EDP_REF_CLKREF_EN>; clock-names = "aux", - "cfg_ahb"; + "cfg_ahb", + "ref"; #clock-cells = <1>; #phy-cells = <0>; From f55c6d67d34ccdac2a462dad2becb29d84186271 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Wed, 12 Nov 2025 12:08:26 +0530 Subject: [PATCH 289/438] FROMLIST: arm64: dts: qcom: lemans-evk: Enable Bluetooth support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a WCN6855 WiFi/Bluetooth module on an M.2 card. To make Bluetooth work, we need to define the necessary device tree nodes, including UART configuration and power supplies. Since there is no standard M.2 binding in the device tree at present, the PMU is described using dedicated PMU nodes to represent the internal regulators required by the module. The module provides a 3.3V supply, which originates from the main board’s 12V rail. To represent this power hierarchy in the device tree, add a fixed 12V regulator node as the DC-IN source and link it to the 3.3V regulator node. Link: https://lore.kernel.org/all/20251112071147.1450258-2-wei.deng@oss.qualcomm.com/ Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 99 +++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 90fce947ca7e5..a227b6037b37c 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -21,6 +21,7 @@ ethernet0 = ðernet0; mmc1 = &sdhc; serial0 = &uart10; + serial1 = &uart17; }; dmic: audio-codec-0 { @@ -149,6 +150,17 @@ regulator-max-microvolt = <2950000>; }; + vreg_dcin_12v: regulator-dcin-12v { + compatible = "regulator-fixed"; + + regulator-name = "VREG_DCIN_12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + + regulator-boot-on; + regulator-always-on; + }; + vreg_sdc: regulator-vreg-sdc { compatible = "regulator-gpio"; @@ -162,6 +174,75 @@ startup-delay-us = <100>; }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + vin-supply = <&vreg_dcin_12v>; + + regulator-boot-on; + }; + + wcn6855-pmu { + compatible = "qcom,wcn6855-pmu"; + + vddio-supply = <&vreg_wcn_3p3>; + vddaon-supply = <&vreg_wcn_3p3>; + vddpmu-supply = <&vreg_wcn_3p3>; + vddpmumx-supply = <&vreg_wcn_3p3>; + vddpmucx-supply = <&vreg_wcn_3p3>; + vddrfa0p95-supply = <&vreg_wcn_3p3>; + vddrfa1p3-supply = <&vreg_wcn_3p3>; + vddrfa1p9-supply = <&vreg_wcn_3p3>; + vddpcielp3-supply = <&vreg_wcn_3p3>; + vddpcielp9-supply = <&vreg_wcn_3p3>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; }; &apps_rsc { @@ -878,6 +959,24 @@ status = "okay"; }; +&uart17 { + status = "okay"; + + bluetooth: bluetooth { + compatible = "qcom,wcn6855-bt"; + max-speed = <3200000>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +}; + &ufs_mem_hc { reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; vcc-supply = <&vreg_l8a>; From 74b63bfbf7c0cbe815376e10c6b12f3dc24b85f4 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:17 +0530 Subject: [PATCH 290/438] FROMLIST: dt-bindings: phy: describe additional regulator for Qualcomm SGMII PHY Describe the additional vdda-0p9-supply for the Qualcomm SGMII PHY. Link: https://lore.kernel.org/r/20251124-sgmiieth_serdes_regulator-v1-1-73ae8f9cbe2a@oss.qualcomm.com Signed-off-by: Mohd Ayaan Anwar --- .../devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml index 90fc8c039219c..0a1330b9118d6 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml @@ -36,6 +36,10 @@ properties: description: Phandle to a regulator that provides power to the PHY. + vdda-0p9-supply: + description: + Phandle to a 0.9V regulator supply to the PHY. + "#phy-cells": const: 0 From 2fd826cf98f269afce3e49656872cd0bbf4710bb Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:18 +0530 Subject: [PATCH 291/438] FROMLIST: arm64: dts: qcom: lemans-evk: add additional SerDes PHY regulator Add the additional 0.9V regulator for the Qualcomm SerDes PHY. Fixes: 71ee90ed1756 ("arm64: dts: qcom: lemans-evk: Enable 2.5G Ethernet interface") Link: https://lore.kernel.org/r/20251124-sgmiieth_serdes_regulator-v1-2-73ae8f9cbe2a@oss.qualcomm.com Signed-off-by: Mohd Ayaan Anwar --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index a227b6037b37c..b6403d9e5ef74 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -850,6 +850,7 @@ &serdes0 { phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; status = "okay"; }; From 8e3926cebf633b5cf335b7bdf31734c375f25255 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:19 +0530 Subject: [PATCH 292/438] FROMLIST: arm64: dts: qcom: lemans-ride-common: add additional SerDes PHY regulators Add the additional 0.9V regulators for both of the Qualcomm SerDes PHYs. Link: https://lore.kernel.org/r/20251124-sgmiieth_serdes_regulator-v1-3-73ae8f9cbe2a@oss.qualcomm.com Fixes: 5ef26fb8b3ed ("arm64: dts: qcom: sa8775p-ride: enable the SerDes PHY") Signed-off-by: Mohd Ayaan Anwar --- arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi index 8fb7d1fc6d563..e020cc85089d3 100644 --- a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi @@ -787,11 +787,15 @@ &serdes0 { phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + status = "okay"; }; &serdes1 { phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + status = "okay"; }; From 858171bb4c62256ba53e9ea500031f4b1169cbeb Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:24 +0530 Subject: [PATCH 293/438] FROMLIST: arm64: dts: qcom: Enable cdsp qmi tmd devices for lemans Enable cdsp cooling devices and thermal zone cooling map bindings for both cdsp and cdsp1. Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251223123227.1317244-6-gaurav.kohli@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/lemans.dtsi | 137 ++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 12 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 0f8643adf89b6..13de886a118fa 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -7290,6 +7290,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw0: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; nspb_noc: interconnect@2a0c0000 { @@ -7453,6 +7461,15 @@ }; }; }; + + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw1: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; remoteproc_adsp: remoteproc@30000000 { @@ -8177,7 +8194,7 @@ thermal-sensors = <&tsens2 5>; trips { - trip-point0 { + nsp_0_0_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8189,6 +8206,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_0_0_alert0>; + cooling-device = <&cdsp_sw0 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-1-0-thermal { @@ -8197,7 +8222,7 @@ thermal-sensors = <&tsens2 6>; trips { - trip-point0 { + nsp_0_1_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8209,6 +8234,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_1_0_alert0>; + cooling-device = <&cdsp_sw0 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-2-0-thermal { @@ -8217,7 +8250,7 @@ thermal-sensors = <&tsens2 7>; trips { - trip-point0 { + nsp_0_2_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8229,6 +8262,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_2_0_alert0>; + cooling-device = <&cdsp_sw0 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-1-0-0-thermal { @@ -8237,7 +8278,7 @@ thermal-sensors = <&tsens2 8>; trips { - trip-point0 { + nsp_1_0_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8249,6 +8290,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_1_0_0_alert0>; + cooling-device = <&cdsp_sw1 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-1-1-0-thermal { @@ -8257,7 +8306,7 @@ thermal-sensors = <&tsens2 9>; trips { - trip-point0 { + nsp_1_1_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8269,6 +8318,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_1_1_0_alert0>; + cooling-device = <&cdsp_sw1 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-1-2-0-thermal { @@ -8277,7 +8334,7 @@ thermal-sensors = <&tsens2 10>; trips { - trip-point0 { + nsp_1_2_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8289,6 +8346,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_1_2_0_alert0>; + cooling-device = <&cdsp_sw1 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; ddrss-0-thermal { @@ -8431,7 +8496,7 @@ thermal-sensors = <&tsens3 5>; trips { - trip-point0 { + nsp_0_0_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8443,6 +8508,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_0_1_alert0>; + cooling-device = <&cdsp_sw0 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-1-1-thermal { @@ -8451,7 +8524,7 @@ thermal-sensors = <&tsens3 6>; trips { - trip-point0 { + nsp_0_1_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8463,6 +8536,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_1_1_alert0>; + cooling-device = <&cdsp_sw0 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-2-1-thermal { @@ -8471,7 +8552,7 @@ thermal-sensors = <&tsens3 7>; trips { - trip-point0 { + nsp_0_2_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8483,6 +8564,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_2_1_alert0>; + cooling-device = <&cdsp_sw0 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-1-0-1-thermal { @@ -8491,7 +8580,7 @@ thermal-sensors = <&tsens3 8>; trips { - trip-point0 { + nsp_1_0_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8503,6 +8592,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_1_0_1_alert0>; + cooling-device = <&cdsp_sw1 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-1-1-1-thermal { @@ -8511,7 +8608,7 @@ thermal-sensors = <&tsens3 9>; trips { - trip-point0 { + nsp_1_1_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8523,6 +8620,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_1_1_1_alert0>; + cooling-device = <&cdsp_sw1 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-1-2-1-thermal { @@ -8531,7 +8636,7 @@ thermal-sensors = <&tsens3 10>; trips { - trip-point0 { + nsp_1_2_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8543,6 +8648,14 @@ type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_1_2_1_alert0>; + cooling-device = <&cdsp_sw1 + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; ddrss-1-thermal { From 926a8a1affe9cb2585d0779f2c449e8b4034a86f Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 22 Jan 2026 14:58:51 +0530 Subject: [PATCH 294/438] FROMLIST: arm64: dts: qcom: lemans-evk: Rename hd3ss3220_ instance for primary port controller Rename the hd3ss3220_ instance to improve clarity and simplify usage when adding a secondary port controller. Link: https://lore.kernel.org/r/20260122092852.887624-4-swati.agarwal@oss.qualcomm.com Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index b6403d9e5ef74..cc7fed3e3a158 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -63,7 +63,7 @@ reg = <1>; usb0_con_ss_ep: endpoint { - remote-endpoint = <&hd3ss3220_in_ep>; + remote-endpoint = <&hd3ss3220_0_in_ep>; }; }; }; @@ -603,7 +603,7 @@ port@0 { reg = <0>; - hd3ss3220_in_ep: endpoint { + hd3ss3220_0_in_ep: endpoint { remote-endpoint = <&usb0_con_ss_ep>; }; }; @@ -611,7 +611,7 @@ port@1 { reg = <1>; - hd3ss3220_out_ep: endpoint { + hd3ss3220_0_out_ep: endpoint { remote-endpoint = <&usb_0_dwc3_ss>; }; }; @@ -1004,7 +1004,7 @@ }; &usb_0_dwc3_ss { - remote-endpoint = <&hd3ss3220_out_ep>; + remote-endpoint = <&hd3ss3220_0_out_ep>; }; &usb_0_hsphy { From 3789c6ca502bb75597d8c3a3621684d6ad4b52f4 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 22 Jan 2026 14:58:52 +0530 Subject: [PATCH 295/438] FROMLIST: arm64: dts: qcom: lemans-evk: Enable secondary USB controller in host mode Enable secondary USB controller in host mode on lemans EVK Platform. Secondary USB controller is connected to a Genesys Logic USB HUB GL3590 having 4 ports. The ports of hub that are present on lemans EVK standalone board are used as follows:- 1) port-1 is connected to HD3SS3220 Type-C port controller. 2) port-4 is used for the M.2 E key on corekit. Standard core kit uses UART for Bluetooth. This port is to be used only if user optionally replaces the WiFi card with the NFA765 chip which uses USB for Bluetooth. Remaining 2 ports will become functional when the interface plus mezzanine board is stacked on top of corekit: 3) port-2 is connected to another hub which is present on the mezz through which 4 type-A ports are connected. 4) port-3 is used for the M.2 B key for a 5G card when the mezz is connected. Mark the second USB controller as host only capable and add the HD3SS3220 Type-C port controller along with Type-c connector for controlling vbus supply. Link: https://lore.kernel.org/r/20260122092852.887624-5-swati.agarwal@oss.qualcomm.com Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 208 ++++++++++++++++++++++++ 1 file changed, 208 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index cc7fed3e3a158..3a9f40a3e2a62 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -69,6 +69,45 @@ }; }; + connector-1 { + compatible = "usb-c-connector"; + label = "USB1-Type-C"; + data-role = "host"; + power-role = "source"; + + vbus-supply = <&vbus_supply_regulator_1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb1_con_ss_ep: endpoint { + remote-endpoint = <&hd3ss3220_1_in_ep>; + }; + }; + + port@1 { + reg = <1>; + + usb1_hs_in: endpoint { + remote-endpoint = <&usb_hub_2_1>; + }; + + }; + + port@2 { + reg = <2>; + + usb1_ss_in: endpoint { + remote-endpoint = <&usb_hub_3_1>; + }; + }; + }; + }; + edp0-connector { compatible = "dp-connector"; label = "EDP0"; @@ -142,6 +181,16 @@ enable-active-high; }; + vbus_supply_regulator_1: regulator-vbus-supply-1 { + compatible = "regulator-fixed"; + regulator-name = "vbus_supply_1"; + gpio = <&expander1 3 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + enable-active-high; + }; + vmmc_sdc: regulator-vmmc-sdc { compatible = "regulator-fixed"; @@ -617,6 +666,39 @@ }; }; }; + + usb-typec@47 { + compatible = "ti,hd3ss3220"; + reg = <0x47>; + + interrupts-extended = <&pmm8654au_2_gpios 6 IRQ_TYPE_EDGE_FALLING>; + + id-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&usb1_id>, <&usb1_intr>; + pinctrl-names = "default"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hd3ss3220_1_in_ep: endpoint { + remote-endpoint = <&usb1_con_ss_ep>; + }; + }; + + port@1 { + reg = <1>; + + hd3ss3220_1_out_ep: endpoint { + }; + }; + }; + }; + }; &i2c18 { @@ -780,6 +862,14 @@ bias-pull-up; power-source = <0>; }; + + usb1_intr: usb1-intr-state { + pins = "gpio6"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; }; &qup_i2c19_default { @@ -950,6 +1040,12 @@ function = "gpio"; bias-pull-up; }; + + usb1_id: usb1-id-state { + pins = "gpio51"; + function = "gpio"; + bias-pull-up; + }; }; &uart10 { @@ -1022,6 +1118,118 @@ status = "okay"; }; +&usb_1 { + dr_mode = "host"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + usb_hub_2_x: hub@1 { + compatible = "usb5e3,610"; + reg = <1>; + + peer-hub = <&usb_hub_3_x>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + usb_hub_2_1: endpoint { + remote-endpoint = <&usb1_hs_in>; + }; + }; + + /* + * Port-2 and port-3 are not connected to anything on corekit. + */ + port@2 { + reg = <2>; + + usb_hub_2_2: endpoint { + }; + }; + + port@3 { + reg = <3>; + + usb_hub_2_3: endpoint { + }; + }; + + /* + * Port-4 is connected to M.2 E key connector on corekit. + */ + port@4 { + reg = <4>; + + usb_hub_2_4: endpoint { + }; + }; + }; + }; + + usb_hub_3_x: hub@2 { + compatible = "usb5e3,625"; + reg = <2>; + + peer-hub = <&usb_hub_2_x>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + usb_hub_3_1: endpoint { + remote-endpoint = <&usb1_ss_in>; + }; + }; + + port@2 { + reg = <2>; + + usb_hub_3_2: endpoint { + }; + }; + + port@3 { + reg = <3>; + + usb_hub_3_3: endpoint { + }; + }; + + port@4 { + reg = <4>; + + usb_hub_3_4: endpoint { + }; + }; + }; + }; +}; + +&usb_1_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l6c>; + vdda33-supply = <&vreg_l9a>; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vreg_l1c>; + vdda-pll-supply = <&vreg_l7a>; + + status = "okay"; +}; + &xo_board_clk { clock-frequency = <38400000>; }; From 366b9dca16bb175832fc288a8a7d483228edb032 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Mon, 12 Jan 2026 13:05:20 +0530 Subject: [PATCH 296/438] WORKAROUND: arm64: dts: qcom: lemans-evk: Remove WCN6855 PMU node to bypass pwrseq flow There is a conflict between the current DTS configuration and the driver behavior for the WCN6855 Bluetooth path. With the PMU node in place, the driver takes the pwrseq code path unintentionally, which leads to Bluetooth failing to power up during an on -> off -> on transition. To unblock function, temporarily remove the WCN6855 PMU node so that the driver follows the non-pwrseq path and avoids the unexpected sequence. This is a TEMPORARY WORKAROUND. Once a proper M.2 binding/solution is upstreamed, will re-submit both DTS and driver changes aligned with the M.2 model. Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 73 +++---------------------- 1 file changed, 8 insertions(+), 65 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 3a9f40a3e2a62..ab4f50ac7e5e7 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -235,63 +235,6 @@ regulator-boot-on; }; - - wcn6855-pmu { - compatible = "qcom,wcn6855-pmu"; - - vddio-supply = <&vreg_wcn_3p3>; - vddaon-supply = <&vreg_wcn_3p3>; - vddpmu-supply = <&vreg_wcn_3p3>; - vddpmumx-supply = <&vreg_wcn_3p3>; - vddpmucx-supply = <&vreg_wcn_3p3>; - vddrfa0p95-supply = <&vreg_wcn_3p3>; - vddrfa1p3-supply = <&vreg_wcn_3p3>; - vddrfa1p9-supply = <&vreg_wcn_3p3>; - vddpcielp3-supply = <&vreg_wcn_3p3>; - vddpcielp9-supply = <&vreg_wcn_3p3>; - - regulators { - vreg_pmu_rfa_cmn: ldo0 { - regulator-name = "vreg_pmu_rfa_cmn"; - }; - - vreg_pmu_aon_0p59: ldo1 { - regulator-name = "vreg_pmu_aon_0p59"; - }; - - vreg_pmu_wlcx_0p8: ldo2 { - regulator-name = "vreg_pmu_wlcx_0p8"; - }; - - vreg_pmu_wlmx_0p85: ldo3 { - regulator-name = "vreg_pmu_wlmx_0p85"; - }; - - vreg_pmu_btcmx_0p85: ldo4 { - regulator-name = "vreg_pmu_btcmx_0p85"; - }; - - vreg_pmu_rfa_0p8: ldo5 { - regulator-name = "vreg_pmu_rfa_0p8"; - }; - - vreg_pmu_rfa_1p2: ldo6 { - regulator-name = "vreg_pmu_rfa_1p2"; - }; - - vreg_pmu_rfa_1p8: ldo7 { - regulator-name = "vreg_pmu_rfa_1p8"; - }; - - vreg_pmu_pcie_0p9: ldo8 { - regulator-name = "vreg_pmu_pcie_0p9"; - }; - - vreg_pmu_pcie_1p8: ldo9 { - regulator-name = "vreg_pmu_pcie_1p8"; - }; - }; - }; }; &apps_rsc { @@ -1063,14 +1006,14 @@ compatible = "qcom,wcn6855-bt"; max-speed = <3200000>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddrfacmn-supply = <&vreg_wcn_3p3>; + vddaon-supply = <&vreg_wcn_3p3>; + vddwlcx-supply = <&vreg_wcn_3p3>; + vddwlmx-supply = <&vreg_wcn_3p3>; + vddbtcmx-supply = <&vreg_wcn_3p3>; + vddrfa0p8-supply = <&vreg_wcn_3p3>; + vddrfa1p2-supply = <&vreg_wcn_3p3>; + vddrfa1p8-supply = <&vreg_wcn_3p3>; }; }; From be4eacbc18efa053464c198b7cb0e8b7eae97cb9 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 27 Jan 2026 14:01:00 +0530 Subject: [PATCH 297/438] FROMLIST: arm64: dts: qcom: lemans: disable zap-shader for EL2 configuration We don't need to use zap shader in EL2 as Linux can zap the gpu on it's own. Lets disable zap-shader for Lemans EL2 configuration. Link: https://lore.kernel.org/lkml/20260127-talos-el2-overlay-v2-1-b6a2266532c4@oss.qualcomm.com/ Signed-off-by: Mukesh Ojha --- arch/arm64/boot/dts/qcom/lemans-el2.dtso | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-el2.dtso b/arch/arm64/boot/dts/qcom/lemans-el2.dtso index ed615dce6c789..621ad930cf547 100644 --- a/arch/arm64/boot/dts/qcom/lemans-el2.dtso +++ b/arch/arm64/boot/dts/qcom/lemans-el2.dtso @@ -10,6 +10,10 @@ /dts-v1/; /plugin/; +&gpu_zap_shader { + status = "disabled"; +}; + &iris { status = "disabled"; }; From 6e98d32538f68ca38b64059319d39e3fa7f3e29e Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Wed, 4 Feb 2026 01:08:48 +0530 Subject: [PATCH 298/438] FROMLIST: arm64: dts: qcom: lemans-evk: Add Mezzanine The Mezzanine is an hardware expansion add-on board designed to be stacked on top of Lemans EVK. It has following peripherals : - 4x Type A USB ports in host mode. - TC9563 PCIe switch, which has following three downstream ports (DSP) : - 1st DSP connects M.2 E-key connector for connecting WLAN endpoints. - 2nd DSP connects M.2 B-key connector for connecting cellular modems. - 3rd DSP with support for Dual Ethernet ports. - eMMC. - Additional 2.5GbE Ethernet PHY connected to native EMAC with support for MAC Address configuration via NVMEM. - EEPROM. - LVDS Display. - 2*mini DP. Add support for following peripherals : - TC9563 PCIe Switch. - Additional 2.5GbE Ethernet Port. - EEPROM. Written with inputs from : Mohd Ayaan Anwar - Ethernet. Krishna Chaitanya Chundru - PCIe Monish Chunara - EEPROM. Signed-off-by: Umang Chheda Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260203193848.123307-2-umang.chheda@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/Makefile | 4 + .../boot/dts/qcom/lemans-evk-mezzanine.dtso | 301 ++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index f80b5d9cf1e80..79449004adfd2 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -43,6 +43,10 @@ dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera.dtb lemans-evk-el2-dtbs := lemans-evk.dtb lemans-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-el2.dtb + +lemans-evk-mezzanine-dtbs := lemans-evk.dtb lemans-evk-mezzanine.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += milos-fairphone-fp6.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso b/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso new file mode 100644 index 0000000000000..4fab96ba873c2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + model = "Qualcomm Technologies, Inc. Lemans-evk Mezzanine"; + + vreg_0p9: regulator-vreg-0p9 { + compatible = "regulator-fixed"; + regulator-name = "VREG_0P9"; + + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_3p3>; + }; + + vreg_1p8: regulator-vreg-1p8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_4p2>; + }; + + vreg_3p3: regulator-vreg-3p3 { + compatible = "regulator-fixed"; + regulator-name = "VREG_3P3"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_4p2>; + }; + + vreg_4p2: regulator-vreg-4p2 { + compatible = "regulator-fixed"; + regulator-name = "VREG_4P2"; + + regulator-min-microvolt = <4200000>; + regulator-max-microvolt = <4200000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_sys_pwr>; + }; + + vreg_sys_pwr: regulator-vreg-sys-pwr { + compatible = "regulator-fixed"; + regulator-name = "VREG_SYS_PWR"; + + regulator-min-microvolt = <24000000>; + regulator-max-microvolt = <24000000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +ðernet1 { + phy-handle = <&hsgmii_phy1>; + phy-mode = "2500base-x"; + + pinctrl-0 = <ðernet1_default>; + pinctrl-names = "default"; + + snps,mtl-rx-config = <&mtl_rx_setup1>; + snps,mtl-tx-config = <&mtl_tx_setup1>; + + nvmem-cells = <&mac_addr1>; + nvmem-cell-names = "mac-address"; + + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + hsgmii_phy1: ethernet-phy@18 { + compatible = "ethernet-phy-id004d.d101"; + reg = <0x18>; + reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <11000>; + reset-deassert-us = <70000>; + }; + }; + + mtl_rx_setup1: rx-queues-config { + snps,rx-queues-to-use = <4>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x0>; + snps,route-up; + snps,priority = <0x1>; + }; + + queue1 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x1>; + snps,route-ptp; + }; + + queue2 { + snps,avb-algorithm; + snps,map-to-dma-channel = <0x2>; + snps,route-avcp; + }; + + queue3 { + snps,avb-algorithm; + snps,map-to-dma-channel = <0x3>; + snps,priority = <0xc>; + }; + }; + + mtl_tx_setup1: tx-queues-config { + snps,tx-queues-to-use = <4>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,avb-algorithm; + snps,send_slope = <0x1000>; + snps,idle_slope = <0x1000>; + snps,high_credit = <0x3e800>; + snps,low_credit = <0xffc18000>; + }; + + queue3 { + snps,avb-algorithm; + snps,send_slope = <0x1000>; + snps,idle_slope = <0x1000>; + snps,high_credit = <0x3e800>; + snps,low_credit = <0xffc18000>; + }; + }; +}; + +&i2c18 { + #address-cells = <1>; + #size-cells = <0>; + + eeprom@52 { + compatible = "giantec,gt24c256c", "atmel,24c256"; + reg = <0x52>; + pagesize = <64>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + mac_addr1: mac-addr@0 { + reg = <0x0 0x6>; + }; + }; + }; +}; + +&pcie0 { + iommu-map = <0x0 &pcie_smmu 0x0 0x1>, + <0x100 &pcie_smmu 0x1 0x1>, + <0x208 &pcie_smmu 0x2 0x1>, + <0x210 &pcie_smmu 0x3 0x1>, + <0x218 &pcie_smmu 0x4 0x1>, + <0x300 &pcie_smmu 0x5 0x1>, + <0x400 &pcie_smmu 0x6 0x1>, + <0x500 &pcie_smmu 0x7 0x1>, + <0x501 &pcie_smmu 0x8 0x1>; +}; + +&pcieport0 { + #address-cells = <3>; + #size-cells = <2>; + + pcie@0,0 { + compatible = "pci1179,0623"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x2 0xff>; + + vddc-supply = <&vreg_0p9>; + vdd18-supply = <&vreg_1p8>; + vdd09-supply = <&vreg_0p9>; + vddio1-supply = <&vreg_1p8>; + vddio2-supply = <&vreg_1p8>; + vddio18-supply = <&vreg_1p8>; + + i2c-parent = <&i2c18 0x77>; + + resx-gpios = <&tlmm 140 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&tc9563_resx_n>; + pinctrl-names = "default"; + + pcie@1,0 { + reg = <0x20800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x3 0xff>; + }; + + pcie@2,0 { + reg = <0x21000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x4 0xff>; + }; + + pcie@3,0 { + reg = <0x21800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x5 0xff>; + + pci@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + + pci@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + }; + }; +}; + +&serdes1 { + phy-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&tlmm { + ethernet1_default: ethernet1-default-state { + ethernet1-mdc-pins { + pins = "gpio20"; + function = "emac1_mdc"; + drive-strength = <16>; + bias-pull-up; + }; + + ethernet1-mdio-pins { + pins = "gpio21"; + function = "emac1_mdio"; + drive-strength = <16>; + bias-pull-up; + }; + }; + + tc9563_resx_n: tc9563-resx-state { + pins = "gpio140"; + function = "gpio"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; +}; From a54269eed16f1febdae01fadeda3f63c208c1672 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 11 Feb 2026 13:49:19 +0530 Subject: [PATCH 299/438] PENDING: arm64: dts: qcom: Add EL2 support for Iris for lemans Add support for IRIS on lemans when Linux host running at EL2. Signed-off-by: Vikash Garodia --- arch/arm64/boot/dts/qcom/lemans-el2.dtso | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-el2.dtso b/arch/arm64/boot/dts/qcom/lemans-el2.dtso index 621ad930cf547..3efbdda9348b3 100644 --- a/arch/arm64/boot/dts/qcom/lemans-el2.dtso +++ b/arch/arm64/boot/dts/qcom/lemans-el2.dtso @@ -15,7 +15,9 @@ }; &iris { - status = "disabled"; + video-firmware { + iommus = <&apps_smmu 0x0882 0x0400>; + }; }; &remoteproc_adsp { From c9775b8386e72d723cffc3e09cf88d1438583425 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 26 Feb 2026 11:38:33 +0530 Subject: [PATCH 300/438] FROMLIST: arm64: dts: qcom: lemans-evk: Enable GPIO expander interrupt for Lemans EVK Enable PCA9538 expander as interrupt controller on Lemans EVK and configure the corresponding TLMM pins via pinctrl to operate as GPIO inputs with internal pull-ups. Link: https://lore.kernel.org/r/20260226060835.608239-2-swati.agarwal@oss.qualcomm.com Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index ab4f50ac7e5e7..76d83ad5a57ab 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -652,6 +652,11 @@ reg = <0x38>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 138 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander0_int>; + pinctrl-names = "default"; }; expander1: gpio@39 { @@ -659,6 +664,11 @@ reg = <0x39>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 19 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander1_int>; + pinctrl-names = "default"; }; expander2: gpio@3a { @@ -666,6 +676,11 @@ reg = <0x3a>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 139 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander2_int>; + pinctrl-names = "default"; }; expander3: gpio@3b { @@ -673,6 +688,11 @@ reg = <0x3b>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 39 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander3_int>; + pinctrl-names = "default"; }; eeprom@50 { @@ -919,6 +939,30 @@ }; }; + expander0_int: expander0-int-state { + pins = "gpio138"; + function = "gpio"; + bias-pull-up; + }; + + expander1_int: expander1-int-state { + pins = "gpio19"; + function = "gpio"; + bias-pull-up; + }; + + expander2_int: expander2-int-state { + pins = "gpio139"; + function = "gpio"; + bias-pull-up; + }; + + expander3_int: expander3-int-state { + pins = "gpio39"; + function = "gpio"; + bias-pull-up; + }; + pcie0_default_state: pcie0-default-state { clkreq-pins { pins = "gpio1"; From 215d72fd9282b895e90c73f1065d8ffe3affbeb5 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 26 Feb 2026 11:38:34 +0530 Subject: [PATCH 301/438] FROMLIST: arm64: dts: qcom: lemans: Add role-switch support and HS endpoint for tertiary USB controller Enable usb-role-switch for the tertiary USB controller on Lemans. Additionally, add a port node with an HS endpoint so the controller can be linked through the DT graph to the corresponding connector. Link: https://lore.kernel.org/r/20260226060835.608239-3-swati.agarwal@oss.qualcomm.com Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/lemans.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 13de886a118fa..2ad7155cc3f8a 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -4275,7 +4275,14 @@ snps,dis-u1-entry-quirk; snps,dis-u2-entry-quirk; + usb-role-switch; + status = "disabled"; + + port { + usb_2_dwc3_hs: endpoint { + }; + }; }; tcsr_mutex: hwlock@1f40000 { From a804cc6368e5b9e898f5598603a4105a921365c8 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 26 Feb 2026 11:38:35 +0530 Subject: [PATCH 302/438] FROMLIST: arm64: dts: qcom: lemans-evk: Enable the tertiary USB controller Enable the tertiary usb controller connected to micro usb port in OTG mode on Lemans EVK platform. Link: https://lore.kernel.org/r/20260226060835.608239-4-swati.agarwal@oss.qualcomm.com Reviewed-by: Konrad Dybcio Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 76d83ad5a57ab..733acc8502d0f 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -108,6 +108,25 @@ }; }; + connector-2 { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + + id-gpios = <&pmm8654au_2_gpios 11 GPIO_ACTIVE_HIGH>; + vbus-gpios = <&expander3 3 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb2_vbus>; + + pinctrl-0 = <&usb2_id>; + pinctrl-names = "default"; + + port { + usb2_con_hs_ep: endpoint { + remote-endpoint = <&usb_2_dwc3_hs>; + }; + }; + }; + edp0-connector { compatible = "dp-connector"; label = "EDP0"; @@ -172,6 +191,15 @@ }; }; + usb2_vbus: regulator-usb2-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb2_vbus"; + gpio = <&pmm8654au_1_gpios 9 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + vbus_supply_regulator_0: regulator-vbus-supply-0 { compatible = "regulator-fixed"; regulator-name = "vbus_supply_0"; @@ -833,6 +861,14 @@ bias-pull-up; power-source = <0>; }; + + usb2_id: usb2-id-state { + pins = "gpio11"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; }; &qup_i2c19_default { @@ -1217,6 +1253,22 @@ status = "okay"; }; +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3_hs { + remote-endpoint = <&usb2_con_hs_ep>; +}; + +&usb_2_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l6c>; + vdda33-supply = <&vreg_l9a>; + + status = "okay"; +}; + &xo_board_clk { clock-frequency = <38400000>; }; From febce4f7ff998ba4b363201444d324a2886639d5 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Mon, 16 Feb 2026 00:23:43 +0530 Subject: [PATCH 303/438] FROMLIST: arm64: dts: qcom: lemans-evk: Enable wakeup for primary USB controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the "wakeup-source" property to the primary port controller node so its interrupt can wake the system from low‑power states on lemans EVK platform. Link: https://lore.kernel.org/all/20260215183325.3836178-3-swati.agarwal@oss.qualcomm.com/ Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 733acc8502d0f..7f379d9b82d78 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -616,6 +616,8 @@ pinctrl-0 = <&usb_id>, <&usb0_intr_state>; pinctrl-names = "default"; + wakeup-source; + ports { #address-cells = <1>; #size-cells = <0>; From 71e567a78247e854dd478b87ec1f995d1d69f82e Mon Sep 17 00:00:00 2001 From: Mani Chandana Ballary Kuntumalla Date: Tue, 17 Feb 2026 12:44:19 +0530 Subject: [PATCH 304/438] FROMLIST: arm64: dts: qcom: lemans: add mdss1 display device nodes Add devicetree changes to enable second Mobile Display Subsystem (mdss1), Display Processing Unit(DPU), Display Port(DP) controllers and eDP PHYs on the Qualcomm Lemans platform. Signed-off-by: Mahadevan P Signed-off-by: Mani Chandana Ballary Kuntumalla Link: https://lore.kernel.org/all/20260217071420.2240380-2-mkuntuma@qti.qualcomm.com/ Signed-off-by: Yash Gupta --- arch/arm64/boot/dts/qcom/lemans.dtsi | 315 ++++++++++++++++++++++++++- 1 file changed, 313 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 2ad7155cc3f8a..b3e96bf946f77 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -7060,6 +7060,317 @@ }; }; + mdss1: display-subsystem@22000000 { + compatible = "qcom,sa8775p-mdss"; + reg = <0x0 0x22000000 0x0 0x1000>; + reg-names = "mdss"; + + interconnects = <&mmss_noc MASTER_MDP_CORE1_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_MDP_CORE1_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", + "mdp1-mem", + "cpu-cfg"; + + resets = <&dispcc1 MDSS_DISP_CC_MDSS_CORE_BCR>; + + power-domains = <&dispcc1 MDSS_DISP_CC_MDSS_CORE_GDSC>; + + clocks = <&dispcc1 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP1_HF_AXI_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_MDP_CLK>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_smmu 0x1800 0x402>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + display-controller@22001000 { + compatible = "qcom,sa8775p-dpu"; + reg = <0x0 0x22001000 0x0 0x8f000>, + <0x0 0x220b0000 0x0 0x3000>; + reg-names = "mdp", "vbif"; + + clocks = <&gcc GCC_DISP1_HF_AXI_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_MDP_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc1 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <19200000>; + + operating-points-v2 = <&mdss1_mdp_opp_table>; + power-domains = <&rpmhpd SA8775P_MMCX>; + + interrupt-parent = <&mdss1>; + interrupts = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dpu1_intf0_out: endpoint { + remote-endpoint = <&mdss1_dp0_in>; + }; + }; + + port@1 { + reg = <1>; + + dpu1_intf4_out: endpoint { + remote-endpoint = <&mdss1_dp1_in>; + }; + }; + }; + + mdss1_mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-375000000 { + opp-hz = /bits/ 64 <375000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-575000000 { + opp-hz = /bits/ 64 <575000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + required-opps = <&rpmhpd_opp_turbo_l1>; + }; + }; + }; + + mdss1_dp0_phy: phy@220c2a00 { + compatible = "qcom,sa8775p-edp-phy"; + + reg = <0x0 0x220c2a00 0x0 0x200>, + <0x0 0x220c2200 0x0 0xd0>, + <0x0 0x220c2600 0x0 0xd0>, + <0x0 0x220c2000 0x0 0x1c8>; + + clocks = <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_EDP_REF_CLKREF_EN>; + clock-names = "aux", + "cfg_ahb", + "ref"; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + mdss1_dp1_phy: phy@220c5a00 { + compatible = "qcom,sa8775p-edp-phy"; + + reg = <0x0 0x220c5a00 0x0 0x200>, + <0x0 0x220c5200 0x0 0xd0>, + <0x0 0x220c5600 0x0 0xd0>, + <0x0 0x220c5000 0x0 0x1c8>; + + clocks = <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_EDP_REF_CLKREF_EN>; + clock-names = "aux", + "cfg_ahb", + "ref"; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + mdss1_dp0: displayport-controller@22154000 { + compatible = "qcom,sa8775p-dp"; + + reg = <0x0 0x22154000 0x0 0x104>, + <0x0 0x22154200 0x0 0x0c0>, + <0x0 0x22155000 0x0 0x770>, + <0x0 0x22156000 0x0 0x09c>, + <0x0 0x22157000 0x0 0x09c>, + <0x0 0x22158000 0x0 0x09c>, + <0x0 0x22159000 0x0 0x09c>, + <0x0 0x2215a000 0x0 0x23c>, + <0x0 0x2215b000 0x0 0x23c>; + + interrupt-parent = <&mdss1>; + interrupts = <12>; + + clocks = <&dispcc1 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel", + "stream_1_pixel", + "stream_2_pixel", + "stream_3_pixel"; + assigned-clocks = <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC>; + assigned-clock-parents = <&mdss1_dp0_phy 0>, + <&mdss1_dp0_phy 1>, + <&mdss1_dp0_phy 1>, + <&mdss1_dp0_phy 1>, + <&mdss1_dp0_phy 1>; + phys = <&mdss1_dp0_phy>; + phy-names = "dp"; + + operating-points-v2 = <&mdss1_dp_opp_table>; + power-domains = <&rpmhpd SA8775P_MMCX>; + + #sound-dai-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss1_dp0_in: endpoint { + remote-endpoint = <&dpu1_intf0_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss1_dp0_out: endpoint { }; + }; + }; + + mdss1_dp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-160000000 { + opp-hz = /bits/ 64 <160000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-270000000 { + opp-hz = /bits/ 64 <270000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-810000000 { + opp-hz = /bits/ 64 <810000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + mdss1_dp1: displayport-controller@2215c000 { + compatible = "qcom,sa8775p-dp"; + + reg = <0x0 0x2215c000 0x0 0x104>, + <0x0 0x2215c200 0x0 0x0c0>, + <0x0 0x2215d000 0x0 0x770>, + <0x0 0x2215e000 0x0 0x09c>, + <0x0 0x2215f000 0x0 0x09c>, + <0x0 0x22160000 0x0 0x09c>, + <0x0 0x22161000 0x0 0x09c>, + <0x0 0x22162000 0x0 0x23c>, + <0x0 0x22163000 0x0 0x23c>; + + interrupt-parent = <&mdss1>; + interrupts = <13>; + + clocks = <&dispcc1 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel", + "stream_1_pixel"; + assigned-clocks = <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC>, + <&dispcc1 MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC>; + assigned-clock-parents = <&mdss1_dp1_phy 0>, + <&mdss1_dp1_phy 1>, + <&mdss1_dp1_phy 1>; + phys = <&mdss1_dp1_phy>; + phy-names = "dp"; + + operating-points-v2 = <&mdss1_dp_opp_table>; + power-domains = <&rpmhpd SA8775P_MMCX>; + + #sound-dai-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss1_dp1_in: endpoint { + remote-endpoint = <&dpu1_intf4_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss1_dp1_out: endpoint { }; + }; + }; + + }; + }; + dispcc1: clock-controller@22100000 { compatible = "qcom,sa8775p-dispcc1"; reg = <0x0 0x22100000 0x0 0x20000>; @@ -7067,13 +7378,13 @@ <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, - <0>, <0>, <0>, <0>, + <&mdss1_dp0_phy 0>, <&mdss1_dp0_phy 1>, + <&mdss1_dp1_phy 0>, <&mdss1_dp1_phy 1>, <0>, <0>, <0>, <0>; power-domains = <&rpmhpd SA8775P_MMCX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; - status = "disabled"; }; ethernet1: ethernet@23000000 { From 8777610b19fea686286e780a086608d32785e108 Mon Sep 17 00:00:00 2001 From: Mani Chandana Ballary Kuntumalla Date: Tue, 17 Feb 2026 12:44:20 +0530 Subject: [PATCH 305/438] FROMLIST: arm64: dts: qcom: lemans-ride: Enable mdss1 display Port This change enables DP controllers, DPTX0 and DPTX1 alongside their corresponding PHYs of mdss1 which corresponds to edp2 and edp3. Signed-off-by: Mani Chandana Ballary Kuntumalla Link: https://lore.kernel.org/all/20260217071420.2240380-3-mkuntuma@qti.qualcomm.com/ Signed-off-by: Yash Gupta --- .../boot/dts/qcom/lemans-ride-common.dtsi | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi index e020cc85089d3..c72a01fdc75de 100644 --- a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi @@ -180,6 +180,30 @@ }; }; + dp2-connector { + compatible = "dp-connector"; + label = "eDP2"; + type = "full-size"; + + port { + dp2_connector_in: endpoint { + remote-endpoint = <&mdss1_dp0_out>; + }; + }; + }; + + dp3-connector { + compatible = "dp-connector"; + label = "eDP3"; + type = "full-size"; + + port { + dp3_connector_in: endpoint { + remote-endpoint = <&mdss1_dp1_out>; + }; + }; + }; + dp-dsi0-connector { compatible = "dp-connector"; label = "DSI0"; @@ -639,6 +663,50 @@ status = "okay"; }; +&mdss1 { + status = "okay"; +}; + +&mdss1_dp0 { + pinctrl-0 = <&dp2_hot_plug_det>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&mdss1_dp0_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + remote-endpoint = <&dp2_connector_in>; +}; + +&mdss1_dp0_phy { + vdda-phy-supply = <&vreg_l1c>; + vdda-pll-supply = <&vreg_l4a>; + + status = "okay"; +}; + +&mdss1_dp1 { + pinctrl-0 = <&dp3_hot_plug_det>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&mdss1_dp1_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + remote-endpoint = <&dp3_connector_in>; +}; + +&mdss1_dp1_phy { + vdda-phy-supply = <&vreg_l1c>; + vdda-pll-supply = <&vreg_l4a>; + + status = "okay"; +}; + &pmm8654au_0_gpios { gpio-line-names = "DS_EN", "POFF_COMPLETE", @@ -820,6 +888,18 @@ bias-disable; }; + dp2_hot_plug_det: dp2-hot-plug-det-state { + pins = "gpio104"; + function = "edp2_hot"; + bias-disable; + }; + + dp3_hot_plug_det: dp3-hot-plug-det-state { + pins = "gpio103"; + function = "edp3_hot"; + bias-disable; + }; + io_expander_intr_active: io-expander-intr-active-state { pins = "gpio98"; function = "gpio"; From 2d4fec0cface9aeed412416ff19903a69b65069c Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Wed, 18 Feb 2026 20:00:07 +0530 Subject: [PATCH 306/438] FROMLIST: arm64: dts: qcom: lemans-evk: Enable mdss1 display Port This change enables DP controllers, DPTX0 and DPTX1 alongside their corresponding PHYs of mdss1 which corresponds to edp2 and edp3. Link: https://lore.kernel.org/lkml/20260219-enable-edp2-3-lemans-evk-mezzanine-v1-1-969316806538@oss.qualcomm.com/ Signed-off-by: Gopi Botlagunta --- .../boot/dts/qcom/lemans-evk-mezzanine.dtso | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso b/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso index 4fab96ba873c2..52f890fa9ab3e 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/lemans-evk-mezzanine.dtso @@ -11,6 +11,30 @@ &{/} { model = "Qualcomm Technologies, Inc. Lemans-evk Mezzanine"; + dp2-connector { + compatible = "dp-connector"; + label = "eDP2"; + type = "full-size"; + + port { + dp2_connector_in: endpoint { + remote-endpoint = <&mdss1_dp0_out>; + }; + }; + }; + + dp3-connector { + compatible = "dp-connector"; + label = "eDP3"; + type = "full-size"; + + port { + dp3_connector_in: endpoint { + remote-endpoint = <&mdss1_dp1_out>; + }; + }; + }; + vreg_0p9: regulator-vreg-0p9 { compatible = "regulator-fixed"; regulator-name = "VREG_0P9"; @@ -179,6 +203,43 @@ }; }; + +&mdss1 { + status = "okay"; +}; + +&mdss1_dp0 { + pinctrl-0 = <&dp2_hot_plug_det>; + pinctrl-names = "default"; + status = "okay"; +}; + +&mdss1_dp1 { + pinctrl-0 = <&dp3_hot_plug_det>; + pinctrl-names = "default"; + status = "okay"; +}; + +&mdss1_dp0_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + remote-endpoint = <&dp2_connector_in>; +}; + +&mdss1_dp1_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + remote-endpoint = <&dp3_connector_in>; +}; + +&mdss1_dp0_phy { + status = "okay"; +}; + +&mdss1_dp1_phy { + status = "okay"; +}; + &pcie0 { iommu-map = <0x0 &pcie_smmu 0x0 0x1>, <0x100 &pcie_smmu 0x1 0x1>, @@ -273,6 +334,18 @@ }; &tlmm { + dp2_hot_plug_det: dp2-hot-plug-det-state { + pins = "gpio104"; + function = "edp2_hot"; + bias-disable; + }; + + dp3_hot_plug_det: dp3-hot-plug-det-state { + pins = "gpio103"; + function = "edp3_hot"; + bias-disable; + }; + ethernet1_default: ethernet1-default-state { ethernet1-mdc-pins { pins = "gpio20"; From 89547a4069cc0a4b15ccc7abfb8901265e7b50f5 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:24 +0530 Subject: [PATCH 307/438] FROMLIST: arm64: dts: qcom: monaco: Add PSCI SYSTEM_RESET2 types Add support for SYSTEM_RESET2 vendor-specific resets as reboot-modes in the psci node. Describe the resets: "bootloader" will cause device to reboot and stop in the bootloader's fastboot mode. "edl" will cause device to reboot into "emergency download mode", which permits loading images via the Firehose protocol. Link: https://lore.kernel.org/r/20251109-arm-psci-system_reset2-vendor-reboots-v17-11-46e085bca4cc@oss.qualcomm.com Signed-off-by: Shivendra Pratap --- arch/arm64/boot/dts/qcom/monaco.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 5d2df4305d1c1..00d9260c37a37 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -740,6 +740,11 @@ #power-domain-cells = <0>; domain-idle-states = <&system_sleep>; }; + + reboot-mode { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; }; reserved-memory { From 77a5ced3fefaa0724590fdf8d699649f8f24d32c Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Wed, 26 Nov 2025 13:40:56 +0530 Subject: [PATCH 308/438] FROMLIST: arm64: dts: qcom: qcs8300: Add CCI definitions Qualcomm QCS8300 SoC contains three Camera Control Interface (CCI). Compared to Lemans, the key difference is in SDA/SCL GPIO assignments and number of CCIs. Link: https://lore.kernel.org/r/20251126081057.4191122-3-quic_vikramsa@quicinc.com Signed-off-by: Nihal Kumar Gupta Co-developed-by: Ravi Shankar Signed-off-by: Ravi Shankar Co-developed-by: Vishal Verma Signed-off-by: Vishal Verma Co-developed-by: Suresh Vankadara Signed-off-by: Suresh Vankadara Signed-off-by: Vikram Sharma Reviewed-by: Vladimir Zapolskiy Reviewed-by: Bryan O'Donoghue Reviewed-by: Konrad Dybcio --- arch/arm64/boot/dts/qcom/monaco.dtsi | 345 +++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 00d9260c37a37..ef9f350784652 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -5324,6 +5324,117 @@ #power-domain-cells = <1>; }; + cci0: cci@ac13000 { + compatible = "qcom,qcs8300-cci", "qcom,msm8996-cci"; + reg = <0x0 0x0ac13000 0x0 0x1000>; + + interrupts = ; + + clocks = <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CCI_0_CLK>; + clock-names = "cpas_ahb", + "cci"; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + pinctrl-0 = <&cci0_0_default &cci0_1_default>; + pinctrl-1 = <&cci0_0_sleep &cci0_1_sleep>; + pinctrl-names = "default", "sleep"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci0_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci0_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + cci1: cci@ac14000 { + compatible = "qcom,qcs8300-cci", "qcom,msm8996-cci"; + reg = <0x0 0x0ac14000 0x0 0x1000>; + + interrupts = ; + + clocks = <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CCI_1_CLK>; + clock-names = "cpas_ahb", + "cci"; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + pinctrl-0 = <&cci1_0_default &cci1_1_default>; + pinctrl-1 = <&cci1_0_sleep &cci1_1_sleep>; + pinctrl-names = "default", "sleep"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci1_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci1_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + cci2: cci@ac15000 { + compatible = "qcom,qcs8300-cci", "qcom,msm8996-cci"; + reg = <0x0 0x0ac15000 0x0 0x1000>; + + interrupts = ; + + clocks = <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CCI_2_CLK>; + clock-names = "cpas_ahb", + "cci"; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + pinctrl-0 = <&cci2_0_default &cci2_1_default>; + pinctrl-1 = <&cci2_0_sleep &cci2_1_sleep>; + pinctrl-names = "default", "sleep"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci2_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci2_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + camss: isp@ac78000 { compatible = "qcom,qcs8300-camss"; @@ -5881,6 +5992,240 @@ #interrupt-cells = <2>; wakeup-parent = <&pdc>; + cam0_avdd_2v8_en_default: cam0-avdd-2v8-en-state { + pins = "gpio73"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam0_default: cam0-default-state { + pins = "gpio67"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam1_avdd_2v8_en_default: cam1-avdd-2v8-en-state { + pins = "gpio74"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam1_default: cam1-default-state { + pins = "gpio68"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam2_avdd_2v8_en_default: cam2-avdd-2v8-en-state { + pins = "gpio75"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam2_default: cam2-default-state { + pins = "gpio69"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cci0_0_default: cci0-0-default-state { + sda-pins { + pins = "gpio57"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + scl-pins { + pins = "gpio58"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + }; + + cci0_0_sleep: cci0-0-sleep-state { + sda-pins { + pins = "gpio57"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-down; + }; + + scl-pins { + pins = "gpio58"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cci0_1_default: cci0-1-default-state { + sda-pins { + pins = "gpio29"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + scl-pins { + pins = "gpio30"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + }; + + cci0_1_sleep: cci0-1-sleep-state { + sda-pins { + pins = "gpio29"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-down; + }; + + scl-pins { + pins = "gpio30"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cci1_0_default: cci1-0-default-state { + sda-pins { + pins = "gpio59"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + scl-pins { + pins = "gpio60"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + }; + + cci1_0_sleep: cci1-0-sleep-state { + sda-pins { + pins = "gpio59"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-down; + }; + + scl-pins { + pins = "gpio60"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cci1_1_default: cci1-1-default-state { + sda-pins { + pins = "gpio31"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + scl-pins { + pins = "gpio32"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + }; + + cci1_1_sleep: cci1-1-sleep-state { + sda-pins { + pins = "gpio31"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-down; + }; + + scl-pins { + pins = "gpio32"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cci2_0_default: cci2-0-default-state { + sda-pins { + pins = "gpio61"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + scl-pins { + pins = "gpio62"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + }; + + cci2_0_sleep: cci2-0-sleep-state { + sda-pins { + pins = "gpio61"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-down; + }; + + scl-pins { + pins = "gpio62"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cci2_1_default: cci2-1-default-state { + sda-pins { + pins = "gpio54"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + scl-pins { + pins = "gpio55"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + }; + + cci2_1_sleep: cci2-1-sleep-state { + sda-pins { + pins = "gpio54"; + function = "cci_i2c_sda"; + drive-strength = <2>; + bias-pull-down; + }; + + scl-pins { + pins = "gpio55"; + function = "cci_i2c_scl"; + drive-strength = <2>; + bias-pull-down; + }; + }; + hs0_mi2s_active: hs0-mi2s-active-state { pins = "gpio106", "gpio107", "gpio108", "gpio109"; function = "hs0_mi2s"; From 33868598dc5b7dc043df8a65925e215fd865bc69 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Wed, 26 Nov 2025 13:40:57 +0530 Subject: [PATCH 309/438] FROMLIST: arm64: dts: qcom: monaco-evk-camera: Add DT overlay Monaco EVK board does not include a camera sensor in its default hardware configuration. Introducing a device tree overlay to support optional integration of the IMX577 sensor via CSIPHY1. Camera reset is handled through an I2C expander, and power is enabled via TLMM GPIO74. An example media-ctl pipeline for the imx577 is: media-ctl --reset media-ctl -V '"imx577 3-001a":0[fmt:SRGGB10/4056x3040 field:none]' media-ctl -V '"msm_csiphy1":0[fmt:SRGGB10/4056x3040]' media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]' media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]' media-ctl -l '"msm_csiphy1":1->"msm_csid0":0[1]' media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]' yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video1 Link: https://lore.kernel.org/r/20251126081057.4191122-4-quic_vikramsa@quicinc.com Signed-off-by: Nihal Kumar Gupta Co-developed-by: Ravi Shankar Signed-off-by: Ravi Shankar Co-developed-by: Vishal Verma Signed-off-by: Vishal Verma Signed-off-by: Vikram Sharma Reviewed-by: Vladimir Zapolskiy Reviewed-by: Bryan O'Donoghue --- arch/arm64/boot/dts/qcom/Makefile | 4 ++ .../dts/qcom/monaco-evk-camera-imx577.dtso | 67 +++++++++++++++++++ arch/arm64/boot/dts/qcom/monaco-evk.dts | 10 +++ 3 files changed, 81 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/monaco-evk-camera-imx577.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index f80b5d9cf1e80..4c348cf62d590 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -45,6 +45,10 @@ lemans-evk-el2-dtbs := lemans-evk.dtb lemans-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += milos-fairphone-fp6.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb + +monaco-evk-camera-imx577-dtbs := monaco-evk.dtb monaco-evk-camera-imx577.dtbo +dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camera-imx577.dtb + dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-alcatel-idol347.dtb diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-camera-imx577.dtso b/arch/arm64/boot/dts/qcom/monaco-evk-camera-imx577.dtso new file mode 100644 index 0000000000000..351eb5ee70ba8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-evk-camera-imx577.dtso @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include + +&camss { + vdda-phy-supply = <&vreg_l4a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csiphy1_ep: endpoint { + clock-lanes = <7>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&imx577_ep1>; + }; + }; + }; +}; + +&cci1 { + pinctrl-0 = <&cci1_0_default>; + pinctrl-1 = <&cci1_0_sleep>; + + status = "okay"; +}; + +&cci1_i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx577"; + reg = <0x1a>; + + reset-gpios = <&expander2 1 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam1_default>; + pinctrl-names = "default"; + + clocks = <&camcc CAM_CC_MCLK1_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK1_CLK>; + assigned-clock-rates = <24000000>; + + avdd-supply = <&vreg_cam1_2p8>; + + port { + imx577_ep1: endpoint { + link-frequencies = /bits/ 64 <600000000>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&csiphy1_ep>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 565418b86b2ad..e2aba68e5fac4 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -77,6 +77,16 @@ }; }; }; + + vreg_cam1_2p8: vreg-cam1-2p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_cam1_2p8"; + startup-delay-us = <10000>; + enable-active-high; + gpio = <&tlmm 74 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&cam1_avdd_2v8_en_default>; + pinctrl-names = "default"; + }; }; &apps_rsc { From 2d2f10c6db24c0324e3365dfab7c37210a3df9d6 Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Tue, 24 Feb 2026 23:14:59 -0800 Subject: [PATCH 310/438] FROMLIST: arm64: dts: qcom: qcs8300-ride: enable WLAN on qcs8300-ride Enable WLAN on qcs8300-ride by adding a node for the PMU module of the WCN6855 and assigning its LDO power outputs to the existing WiFi module. On the qcs8300-ride platform, the corresponding firmware and BDF are QCA6698AQ instead of WCN6855, which have been added in the 20250211 release. Link: https://lore.kernel.org/r/20260225071459.1600394-1-wei.zhang@oss.qualcomm.com Signed-off-by: Wei Zhang Reviewed-by: Konrad Dybcio --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 130 ++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index c04e0ad53eecf..2ed1015b3465a 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -36,6 +36,50 @@ }; }; + vreg_conn_1p05: regulator-conn-1p05 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p05"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + vin-supply = <&vreg_conn_1p8>; + }; + + vreg_conn_1p35: regulator-conn-1p35 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p35"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + vin-supply = <&vreg_conn_1p8>; + }; + + vreg_conn_1p8: regulator-conn-1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pmm8650au_1_gpios 4 GPIO_ACTIVE_HIGH>; + }; + + vreg_conn_1p95: regulator-conn-1p95 { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_1p95"; + regulator-min-microvolt = <1950000>; + regulator-max-microvolt = <1950000>; + vin-supply = <&vreg_conn_1p8>; + }; + + vreg_conn_pa: regulator-conn-pa { + compatible = "regulator-fixed"; + regulator-name = "vreg_conn_pa"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pmm8650au_1_gpios 6 GPIO_ACTIVE_HIGH>; + }; + regulator-usb2-vbus { compatible = "regulator-fixed"; regulator-name = "USB2_VBUS"; @@ -45,6 +89,69 @@ enable-active-high; regulator-always-on; }; + + wcn6855-pmu { + compatible = "qcom,wcn6855-pmu"; + + pinctrl-0 = <&wlan_en_state>; + pinctrl-names = "default"; + + vddio-supply = <&vreg_conn_pa>; + vddaon-supply = <&vreg_conn_1p8>; + vddpmu-supply = <&vreg_conn_pa>; + vddpmumx-supply = <&vreg_conn_1p8>; + vddpmucx-supply = <&vreg_conn_pa>; + /* WLAN rails: 1.05/1.35/1.95V (nominal 0.95/1.30/1.90V) */ + vddrfa0p95-supply = <&vreg_conn_1p05>; + vddrfa1p3-supply = <&vreg_conn_1p35>; + vddrfa1p9-supply = <&vreg_conn_1p95>; + vddpcie1p3-supply = <&vreg_conn_1p35>; + vddpcie1p9-supply = <&vreg_conn_1p95>; + + wlan-enable-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p7: ldo7 { + regulator-name = "vreg_pmu_rfa_1p7"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; }; &apps_rsc { @@ -363,6 +470,23 @@ &pcieport0 { reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; + + wifi@0 { + compatible = "pci17cb,1103"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + + qcom,calibration-variant = "QC_QCS8300_Ride"; + }; }; &pcie0_phy { @@ -503,6 +627,12 @@ function = "edp0_hot"; bias-disable; }; + + wlan_en_state: wlan-en-state { + pins = "gpio54"; + function = "gpio"; + bias-pull-down; + }; }; &uart7 { From 0960f09f95b5991fac2c2a8341a5b4b10f5c4e43 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Thu, 13 Nov 2025 18:35:19 +0530 Subject: [PATCH 311/438] FROMLIST: arm64: dts: qcom: monaco-evk: Enable Bluetooth support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a WCN6855 WiFi/Bluetooth module on an M.2 card. To make Bluetooth work, we need to define the necessary device tree nodes, including UART configuration and power supplies. Since there is no standard M.2 binding in the device tree at present, the PMU is described using dedicated PMU nodes to represent the internal regulators required by the module. The module provides a 3.3V supply, which originates from the main board’s 12V rail. To represent this power hierarchy in the device tree, add a fixed 12V regulator node as the DC-IN source and link it to the 3.3V regulator node. Link: https://lore.kernel.org/all/20251113130519.2647081-1-wei.deng@oss.qualcomm.com/ Reviewed-by: Dmitry Baryshkov Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 99 +++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index e2aba68e5fac4..833089e5f511a 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -21,6 +21,7 @@ ethernet0 = ðernet0; i2c1 = &i2c1; serial0 = &uart7; + serial1 = &uart2; }; chosen { @@ -87,6 +88,86 @@ pinctrl-0 = <&cam1_avdd_2v8_en_default>; pinctrl-names = "default"; }; + + vreg_dcin_12v: regulator-dcin-12v { + compatible = "regulator-fixed"; + + regulator-name = "VREG_DCIN_12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + + regulator-boot-on; + regulator-always-on; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + vin-supply = <&vreg_dcin_12v>; + + regulator-boot-on; + }; + + wcn6855-pmu { + compatible = "qcom,wcn6855-pmu"; + + vddio-supply = <&vreg_wcn_3p3>; + vddaon-supply = <&vreg_wcn_3p3>; + vddpmu-supply = <&vreg_wcn_3p3>; + vddpmumx-supply = <&vreg_wcn_3p3>; + vddpmucx-supply = <&vreg_wcn_3p3>; + vddrfa0p95-supply = <&vreg_wcn_3p3>; + vddrfa1p3-supply = <&vreg_wcn_3p3>; + vddrfa1p9-supply = <&vreg_wcn_3p3>; + vddpcielp3-supply = <&vreg_wcn_3p3>; + vddpcielp9-supply = <&vreg_wcn_3p3>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; }; &apps_rsc { @@ -582,6 +663,24 @@ }; }; +&uart2 { + status = "okay"; + + bluetooth: bluetooth { + compatible = "qcom,wcn6855-bt"; + max-speed = <3200000>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +}; + &uart7 { status = "okay"; }; From f8cb9f4eb0122c6b0a0fa4cac002c8a215651acd Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Thu, 13 Nov 2025 12:10:10 +0530 Subject: [PATCH 312/438] FROMLIST: arm64: dts: qcom: qcs8300-ride: Enable Bluetooth support Enable BT on qcs8300-ride by adding a BT device tree node. Since the platform uses the QCA6698 Bluetooth chip. While the QCA6698 shares the same IP core as the WCN6855, it has different RF components and RAM sizes, requiring new firmware files. Use the firmware-name property to specify the NVM and rampatch firmware to load. Link: https://lore.kernel.org/all/20251118140406.1551669-2-wei.deng@oss.qualcomm.com/ Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 2ed1015b3465a..a0ac926d2006f 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -18,6 +18,7 @@ aliases { serial0 = &uart7; mmc0 = &sdhc_1; + serial1 = &uart2; }; chosen { @@ -108,6 +109,8 @@ vddpcie1p3-supply = <&vreg_conn_1p35>; vddpcie1p9-supply = <&vreg_conn_1p95>; + + bt-enable-gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>; wlan-enable-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>; regulators { @@ -583,6 +586,13 @@ }; }; + bt_en_state: bt-en-state { + pins = "gpio55"; + function = "gpio"; + bias-pull-down; + output-low; + }; + ethernet0_default: ethernet0-default-state { ethernet0_mdc: ethernet0-mdc-pins { pins = "gpio5"; @@ -635,6 +645,25 @@ }; }; +&uart2 { + status = "okay"; + + bluetooth: bluetooth { + compatible = "qcom,wcn6855-bt"; + firmware-name = "QCA6698/hpnv21", "QCA6698/hpbtfw21.tlv"; + max-speed = <3200000>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; + }; +}; + &uart7 { status = "okay"; }; From fc406be73a17d1c7507af464f177d4180f3909ac Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Tue, 17 Feb 2026 14:39:54 +0530 Subject: [PATCH 313/438] FROMLIST: arm64: dts: qcom: qcs8300: add Display Serial Interface device nodes Add device tree nodes for the DSI0 controller with their corresponding PHY found on Qualcomm QCS8300 SoC. Link: https://lore.kernel.org/r/20260217090955.2446470-2-quic_amakhija@quicinc.com Signed-off-by: Ayushi Makhija Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio --- arch/arm64/boot/dts/qcom/monaco.dtsi | 107 ++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index ef9f350784652..2300fc3af8858 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -3,6 +3,7 @@ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ +#include #include #include #include @@ -5689,9 +5690,19 @@ reg = <0>; dpu_intf0_out: endpoint { + remote-endpoint = <&mdss_dp0_in>; }; }; + + port@1 { + reg = <1>; + + dpu_intf1_out: endpoint { + + remote-endpoint = <&mdss_dsi0_in>; + }; + }; }; mdp_opp_table: opp-table { @@ -5719,6 +5730,98 @@ }; }; + mdss_dsi0: dsi@ae94000 { + compatible = "qcom,qcs8300-dsi-ctrl", + "qcom,sa8775p-dsi-ctrl", + "qcom,mdss-dsi-ctrl"; + reg = <0x0 0x0ae94000 0x0 0x400>; + reg-names = "dsi_ctrl"; + + interrupt-parent = <&mdss>; + interrupts = <4>; + + clocks = <&dispcc MDSS_DISP_CC_MDSS_BYTE0_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_PCLK0_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_ESC0_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>; + clock-names = "byte", + "byte_intf", + "pixel", + "core", + "iface", + "bus"; + + assigned-clocks = <&dispcc MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC>, + <&dispcc MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC>; + assigned-clock-parents = <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>; + + phys = <&mdss_dsi0_phy>; + + operating-points-v2 = <&mdss_dsi_opp_table>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + + refgen-supply = <&refgen>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dsi0_in: endpoint { + + remote-endpoint = <&dpu_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dsi0_out: endpoint { + }; + }; + }; + + mdss_dsi_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-358000000 { + opp-hz = /bits/ 64 <358000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + mdss_dsi0_phy: phy@ae94400 { + compatible = "qcom,qcs8300-dsi-phy-5nm", + "qcom,sa8775p-dsi-phy-5nm"; + reg = <0x0 0x0ae94400 0x0 0x200>, + <0x0 0x0ae94600 0x0 0x280>, + <0x0 0x0ae94900 0x0 0x280>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", + "ref"; + + status = "disabled"; + }; + mdss_dp0_phy: phy@aec2a00 { compatible = "qcom,qcs8300-edp-phy", "qcom,sa8775p-edp-phy"; @@ -5846,7 +5949,9 @@ <&mdss_dp0_phy 0>, <&mdss_dp0_phy 1>, <0>, <0>, - <0>, <0>, <0>, <0>; + <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, + <0>, <0>; power-domains = <&rpmhpd RPMHPD_MMCX>; #clock-cells = <1>; #reset-cells = <1>; From 556185eae0a660cf81ae55e9cf824ffed3a1a378 Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Tue, 17 Feb 2026 14:39:55 +0530 Subject: [PATCH 314/438] FROMLIST: arm64: dts: qcom: qcs8300-ride: add anx7625 DSI to DP bridge node Add anx7625 DSI to DP bridge device node. Link: https://lore.kernel.org/r/20260217090955.2446470-3-quic_amakhija@quicinc.com Signed-off-by: Ayushi Makhija Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 179 ++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index a0ac926d2006f..ec8991923f2ab 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -25,6 +25,69 @@ stdout-path = "serial0:115200n8"; }; + vreg_1p0: regulator-vreg-1p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P0"; + + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + vin-supply = <&vreg_1p8>; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_1p8: regulator-vreg-1p8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + vin-supply = <&vreg_5p0>; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_3p0: regulator-vreg-3p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_3P0"; + + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + vin-supply = <&vreg_12p0>; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_5p0: regulator-vreg-5p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_5P0"; + + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + vin-supply = <&vreg_12p0>; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_12p0: regulator-vreg-12p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_12P0"; + + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + + regulator-always-on; + regulator-boot-on; + }; + dp0-connector { compatible = "dp-connector"; label = "DP0"; @@ -37,6 +100,18 @@ }; }; + dp-dsi0-connector { + compatible = "dp-connector"; + label = "DSI0"; + type = "full-size"; + + port { + dp_dsi0_connector_in: endpoint { + remote-endpoint = <&dsi2dp_bridge_out>; + }; + }; + }; + vreg_conn_1p05: regulator-conn-1p05 { compatible = "regulator-fixed"; regulator-name = "vreg_conn_1p05"; @@ -426,6 +501,75 @@ firmware-name = "qcom/qcs8300/a623_zap.mbn"; }; +&i2c8 { + clock-frequency = <400000>; + + status = "okay"; + + io_expander: gpio@74 { + compatible = "ti,tca9539"; + reg = <0x74>; + interrupts-extended = <&tlmm 93 IRQ_TYPE_EDGE_BOTH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reset-gpios = <&tlmm 66 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&io_expander_intr_active>, + <&io_expander_reset_active>; + pinctrl-names = "default"; + }; + + i2c-mux@70 { + compatible = "nxp,pca9543"; + reg = <0x70>; + + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + bridge@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + interrupts-extended = <&io_expander 2 IRQ_TYPE_EDGE_FALLING>; + enable-gpios = <&io_expander 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&io_expander 0 GPIO_ACTIVE_HIGH>; + vdd10-supply = <&vreg_1p0>; + vdd18-supply = <&vreg_1p8>; + vdd33-supply = <&vreg_3p0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi2dp_bridge_in: endpoint { + + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + + dsi2dp_bridge_out: endpoint { + + remote-endpoint = <&dp_dsi0_connector_in>; + }; + }; + }; + }; + }; + }; +}; + &pmm8650au_1_gpios { usb2_en: usb2-en-state { pins = "gpio7"; @@ -518,10 +662,31 @@ status = "okay"; }; +&mdss_dsi0 { + vdda-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&mdss_dsi0_phy { + vdds-supply = <&vreg_l4a>; + + status = "okay"; +}; + +&mdss_dsi0_out { + data-lanes = <0 1 2 3>; + remote-endpoint = <&dsi2dp_bridge_in>; +}; + &qupv3_id_0 { status = "okay"; }; +&qupv3_id_1 { + status = "okay"; +}; + &remoteproc_adsp { firmware-name = "qcom/qcs8300/adsp.mbn"; status = "okay"; @@ -632,6 +797,20 @@ }; }; + io_expander_reset_active: io-expander-reset-active-state { + pins = "gpio66"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + io_expander_intr_active: io-expander-intr-active-state { + pins = "gpio93"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + dp_hot_plug_det: dp-hot-plug-det-state { pins = "gpio94"; function = "edp0_hot"; From 6451c51dbd4a75fde0f3493c5a6a465f1ed73bd3 Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sun, 28 Dec 2025 19:10:38 +0530 Subject: [PATCH 315/438] FROMLIST: arm64: dts: qcom: monaco: add lt8713sx bridge with displayport Monaco-evk has LT8713sx which act as DP to 3 DP output converter. Edp PHY from monaco soc is connected to lt8713sx as input and output of lt8713sx is connected to 3 mini DP ports. Two ports are available in mainboard and one port is available on Mezz board. lt8713sx is connected to soc over i2c0 and with reset gpio connected to pin6 of ioexpander5. Enable the edp nodes from monaco and enable lontium lt8713sx bridge node. Link: https://lore.kernel.org/r/20251228-lt8713sx-bridge-linux-for-next-v3-1-3f77ad84d7d1@oss.qualcomm.com Co-developed-by: Prahlad Valluru Signed-off-by: Prahlad Valluru Signed-off-by: Vishnu Saini --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 89 +++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/monaco.dtsi | 6 ++ 2 files changed, 95 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 833089e5f511a..435291f9efb86 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -34,6 +34,30 @@ num-channels = <1>; }; + dp-connector0 { + compatible = "dp-connector"; + label = "DP"; + type = "mini"; + + port { + dp0_connector_in: endpoint { + remote-endpoint = <<8713sx_dp0_out>; + }; + }; + }; + + dp-connector1 { + compatible = "dp-connector"; + label = "DP"; + type = "mini"; + + port { + dp1_connector_in: endpoint { + remote-endpoint = <<8713sx_dp1_out>; + }; + }; + }; + max98357a: audio-codec-1 { compatible = "maxim,max98357a"; #sound-dai-cells = <0>; @@ -409,6 +433,42 @@ firmware-name = "qcom/qcs8300/a623_zap.mbn"; }; +&i2c0 { + status = "okay"; + + bridge@4f { + compatible = "lontium,lt8713sx"; + reg = <0x4f>; + reset-gpios = <&expander5 6 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lt8713sx_dp_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; + }; + }; + + port@1 { + reg = <1>; + lt8713sx_dp0_out: endpoint { + remote-endpoint = <&dp0_connector_in>; + }; + }; + + port@2 { + reg = <2>; + lt8713sx_dp1_out: endpoint { + remote-endpoint = <&dp1_connector_in>; + }; + }; + }; + }; +}; + &i2c1 { pinctrl-0 = <&qup_i2c1_default>; pinctrl-names = "default"; @@ -498,6 +558,30 @@ }; }; +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + pinctrl-0 = <&dp_hot_plug_det>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&mdss_dp0_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + remote-endpoint = <<8713sx_dp_in>; +}; + +&mdss_dp0_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l4a>; + + status = "okay"; +}; + &iris { status = "okay"; }; @@ -540,6 +624,11 @@ wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; }; +&qup_i2c0_data_clk { + drive-strength = <2>; + bias-pull-up; +}; + &qupv3_id_0 { firmware-name = "qcom/qcs8300/qupv3fw.elf"; status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 2300fc3af8858..230af3a0c1b89 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -6331,6 +6331,12 @@ }; }; + dp_hot_plug_det: dp-hot-plug-det-state { + pins = "gpio94"; + function = "edp0_hot"; + bias-disable; + }; + hs0_mi2s_active: hs0-mi2s-active-state { pins = "gpio106", "gpio107", "gpio108", "gpio109"; function = "hs0_mi2s"; From f575c607aa0cead30e8c7c55219839344d066809 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:20 +0530 Subject: [PATCH 316/438] FROMLIST: arm64: dts: qcom: monaco-evk: fix the SerDes PHY regulators The Qualcomm SerDes PHY, present on multiple boards, has two regulators providing supplies of 1.2V (L5A) and 0.9V (L4A). Update the node to reflect the same instead of incorrectly voting for only L4A. Link: https://lore.kernel.org/r/20251124-sgmiieth_serdes_regulator-v1-4-73ae8f9cbe2a@oss.qualcomm.com Fixes: 117d6bc9326b ("arm64: dts: qcom: qcs8300: Add Monaco EVK board") Signed-off-by: Mohd Ayaan Anwar --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 435291f9efb86..ace3b3e42d9ef 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -658,7 +658,8 @@ }; &serdes0 { - phy-supply = <&vreg_l4a>; + phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; status = "okay"; }; From 7553d4b810b4ad07f9020f83c70b1bfcd818b892 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:21 +0530 Subject: [PATCH 317/438] FROMLIST: arm64: dts: qcom: qcs8300-ride: add additional SerDes PHY regulator Add the additional 0.9V regulator for the Qualcomm SerDes PHY. Link: https://lore.kernel.org/r/20251124-sgmiieth_serdes_regulator-v1-5-73ae8f9cbe2a@oss.qualcomm.com Fixes: 787cb3b4c434 ("arm64: dts: qcom: qcs8300-ride: enable ethernet0") Signed-off-by: Mohd Ayaan Anwar --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index ec8991923f2ab..5866a5144457f 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -704,6 +704,8 @@ &serdes0 { phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + status = "okay"; }; From 619dba1046fb2e4cf4b0367c91cdea5d69bfd91c Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 27 Nov 2025 17:28:29 +0530 Subject: [PATCH 318/438] QCLINUX: arch: arm64: qcom: qcs8300-ride: Enable PCIe Qref regulator PCIe phy needs to be voted for QREF regulator, As the base dtsi changes are still pending we haven't posted the actual fix. Till we post actual fix to upstream, use this change as a workaround. Signed-off-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 5866a5144457f..2b9bfba793b34 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -638,7 +638,7 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l6a>; - vdda-pll-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l4a>; status = "okay"; }; From a320f6d9b40dec022116ee641d3b63f4342aa055 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 3 Dec 2025 14:13:57 +0530 Subject: [PATCH 319/438] FROMLIST: arm64: dts: qcom: Enable cdsp qmi tmd devices for monaco Enable cdsp cooling devices and thermal zone cooling map bindings for cdsp. Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/all/20251223123227.1317244-9-gaurav.kohli@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/monaco.dtsi | 92 ++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 230af3a0c1b89..7ab3feb64c85a 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -7655,6 +7655,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; }; @@ -7989,36 +7997,78 @@ thermal-sensors = <&tsens2 5>; trips { + nsp_0_0_0_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + nsp-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_0_0_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-1-0-thermal { thermal-sensors = <&tsens2 6>; trips { + nsp_0_1_0_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + nsp-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_1_0_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-2-0-thermal { thermal-sensors = <&tsens2 7>; trips { + nsp_0_2_0_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + nsp-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_2_0_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; ddrss-0-thermal { @@ -8109,36 +8159,78 @@ thermal-sensors = <&tsens3 5>; trips { + nsp_0_0_1_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + nsp-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_0_1_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-1-1-thermal { thermal-sensors = <&tsens3 6>; trips { + nsp_0_1_1_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + nsp-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_1_1_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-0-2-1-thermal { thermal-sensors = <&tsens3 7>; trips { + nsp_0_2_1_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + nsp-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&nsp_0_2_1_alert0>; + cooling-device = <&cdsp_sw + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; ddrss-1-thermal { From 813050ca720773561c806e92dc97e19fbcf7c147 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Wed, 21 Jan 2026 11:37:55 +0530 Subject: [PATCH 320/438] WORKAROUND: arm64: dts: qcom: monaco-evk: Remove WCN6855 PMU node to bypass pwrseq flow There is a conflict between the current DTS configuration and the driver behavior for the WCN6855 Bluetooth path. With the PMU node in place, the driver takes the pwrseq code path unintentionally, which leads to Bluetooth failing to power up during an on -> off -> on transition. To unblock function, temporarily remove the WCN6855 PMU node so that the driver follows the non-pwrseq path and avoids the unexpected sequence. This is a TEMPORARY WORKAROUND. Once a proper M.2 binding/solution is upstreamed, will re-submit both DTS and driver changes aligned with the M.2 model. Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 73 +++---------------------- 1 file changed, 8 insertions(+), 65 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index ace3b3e42d9ef..acf2e7c36f143 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -135,63 +135,6 @@ regulator-boot-on; }; - - wcn6855-pmu { - compatible = "qcom,wcn6855-pmu"; - - vddio-supply = <&vreg_wcn_3p3>; - vddaon-supply = <&vreg_wcn_3p3>; - vddpmu-supply = <&vreg_wcn_3p3>; - vddpmumx-supply = <&vreg_wcn_3p3>; - vddpmucx-supply = <&vreg_wcn_3p3>; - vddrfa0p95-supply = <&vreg_wcn_3p3>; - vddrfa1p3-supply = <&vreg_wcn_3p3>; - vddrfa1p9-supply = <&vreg_wcn_3p3>; - vddpcielp3-supply = <&vreg_wcn_3p3>; - vddpcielp9-supply = <&vreg_wcn_3p3>; - - regulators { - vreg_pmu_rfa_cmn: ldo0 { - regulator-name = "vreg_pmu_rfa_cmn"; - }; - - vreg_pmu_aon_0p59: ldo1 { - regulator-name = "vreg_pmu_aon_0p59"; - }; - - vreg_pmu_wlcx_0p8: ldo2 { - regulator-name = "vreg_pmu_wlcx_0p8"; - }; - - vreg_pmu_wlmx_0p85: ldo3 { - regulator-name = "vreg_pmu_wlmx_0p85"; - }; - - vreg_pmu_btcmx_0p85: ldo4 { - regulator-name = "vreg_pmu_btcmx_0p85"; - }; - - vreg_pmu_rfa_0p8: ldo5 { - regulator-name = "vreg_pmu_rfa_0p8"; - }; - - vreg_pmu_rfa_1p2: ldo6 { - regulator-name = "vreg_pmu_rfa_1p2"; - }; - - vreg_pmu_rfa_1p8: ldo7 { - regulator-name = "vreg_pmu_rfa_1p8"; - }; - - vreg_pmu_pcie_0p9: ldo8 { - regulator-name = "vreg_pmu_pcie_0p9"; - }; - - vreg_pmu_pcie_1p8: ldo9 { - regulator-name = "vreg_pmu_pcie_1p8"; - }; - }; - }; }; &apps_rsc { @@ -760,14 +703,14 @@ compatible = "qcom,wcn6855-bt"; max-speed = <3200000>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddrfacmn-supply = <&vreg_wcn_3p3>; + vddaon-supply = <&vreg_wcn_3p3>; + vddwlcx-supply = <&vreg_wcn_3p3>; + vddwlmx-supply = <&vreg_wcn_3p3>; + vddbtcmx-supply = <&vreg_wcn_3p3>; + vddrfa0p8-supply = <&vreg_wcn_3p3>; + vddrfa1p2-supply = <&vreg_wcn_3p3>; + vddrfa1p8-supply = <&vreg_wcn_3p3>; }; }; From 92c25af9bfc38e0cbe870bfbc94c283e135c41c4 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 19 Jan 2026 13:51:00 +0530 Subject: [PATCH 321/438] FROMLIST: arm64: dts: qcom: monaco: Add EL2 overlay All the Monaco IOT variants boards are using Gunyah hypervisor which means that, so far, Linux-based OS could only boot in EL1 on those devices. However, it is possible for us to boot Linux at EL2 on these devices [1]. When running under Gunyah, the remote processor firmware IOMMU streams are controlled by Gunyah. However, without Gunyah, the IOMMU is managed by the consumer of this DeviceTree. Therefore, describe the firmware streams for each remote processor. Add a EL2-specific DT overlay and apply it to Monaco IOT variant devices to create -el2.dtb for each of them alongside "normal" dtb. [1] https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi Link: https://lore.kernel.org/lkml/20260127-talos-el2-overlay-v2-2-b6a2266532c4@oss.qualcomm.com/ Signed-off-by: Mukesh Ojha --- arch/arm64/boot/dts/qcom/Makefile | 8 +++++++ arch/arm64/boot/dts/qcom/monaco-el2.dtso | 29 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/monaco-el2.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 4c348cf62d590..d92b64f5e0430 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -46,6 +46,10 @@ dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += milos-fairphone-fp6.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb +monaco-evk-el2-dtbs := monaco-evk.dtb monaco-el2.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-el2.dtb + monaco-evk-camera-imx577-dtbs := monaco-evk.dtb monaco-evk-camera-imx577.dtbo dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camera-imx577.dtb @@ -151,6 +155,10 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-rubikpi3.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb + +qcs8300-ride-el2-dtbs := qcs8300-ride.dtb monaco-el2.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb diff --git a/arch/arm64/boot/dts/qcom/monaco-el2.dtso b/arch/arm64/boot/dts/qcom/monaco-el2.dtso new file mode 100644 index 0000000000000..a7e3270f86090 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-el2.dtso @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Monaco specific modifications required to boot in EL2. + */ + +/dts-v1/; +/plugin/; + +&gpu_zap_shader { + status = "disabled"; +}; + +&iris { + status = "disabled"; +}; + +&remoteproc_adsp { + iommus = <&apps_smmu 0x2000 0x0>; +}; + +&remoteproc_cdsp { + iommus = <&apps_smmu 0x19c0 0x0400>; +}; + +&remoteproc_gpdsp { + iommus = <&apps_smmu 0x28a0 0x0>; +}; From 6203f93f8455ee8b01fcc85a8deaf9663a588d2e Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 5 Feb 2026 15:35:49 +0530 Subject: [PATCH 322/438] WORKAROUND: arm64: dts: qcom: monaco: Disable global IRQ for pcie1 Currently pcie1 global IRQ is blocking a CPU core, due to which ufs is getting blocked and failing. As workaround disable PCIe1 global IRQ for now. Signed-off-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/monaco.dtsi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 7ab3feb64c85a..9e6724eee1195 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -2482,8 +2482,7 @@ , , , - , - ; + ; interrupt-names = "msi0", "msi1", "msi2", @@ -2491,8 +2490,7 @@ "msi4", "msi5", "msi6", - "msi7", - "global"; + "msi7"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>; interrupt-map = <0 0 0 1 &intc GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, From 0e3bd9f7f1562aecac5750790aa96ad9f6d401ff Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Tue, 10 Feb 2026 16:08:21 +0530 Subject: [PATCH 323/438] FROMLIST: arm64: dts: qcom: monaco-evk: Add Mezzanine The Mezzanine is an hardware expansion add-on board designed to be stacked on top of Monaco EVK. It has following peripherals : - 4x Type A USB ports in host mode. - TC9563 PCIe switch, which has following three downstream ports (DSP) : - 1st DSP connects M.2 E-key connector for connecting WLAN endpoints. - 2nd DSP connects M.2 B-key connector for connecting cellular modems. - 3rd DSP with support for Dual Ethernet ports. - EEPROM. - LVDS Display. - 2*mini DP. Add support for following peripherals : - TC9563 PCIe Switch. - EEPROM. Written with inputs from : Krishna Chaitanya Chundru - PCIe Monish Chunara - EEPROM. Signed-off-by: Umang Chheda Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260210103821.4169-2-umang.chheda@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/Makefile | 3 + .../boot/dts/qcom/monaco-evk-mezzanine.dtso | 189 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/monaco-evk-mezzanine.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index d92b64f5e0430..c17a3bcaa8375 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -53,6 +53,9 @@ dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-el2.dtb monaco-evk-camera-imx577-dtbs := monaco-evk.dtb monaco-evk-camera-imx577.dtbo dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camera-imx577.dtb +monaco-evk-mezzanine-dtbs := monaco-evk.dtb monaco-evk-mezzanine.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-alcatel-idol347.dtb diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-mezzanine.dtso b/arch/arm64/boot/dts/qcom/monaco-evk-mezzanine.dtso new file mode 100644 index 0000000000000..701494d4dd7f0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-evk-mezzanine.dtso @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + model = "Qualcomm Technologies, Inc. Monaco-EVK Mezzanine"; + + vreg_0p9: regulator-vreg-0p9 { + compatible = "regulator-fixed"; + regulator-name = "VREG_0P9"; + + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_3p3>; + }; + + vreg_1p8: regulator-vreg-1p8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_4p2>; + }; + + vreg_3p3: regulator-vreg-3p3 { + compatible = "regulator-fixed"; + regulator-name = "VREG_3P3"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_4p2>; + }; + + vreg_4p2: regulator-vreg-4p2 { + compatible = "regulator-fixed"; + regulator-name = "VREG_4P2"; + + regulator-min-microvolt = <4200000>; + regulator-max-microvolt = <4200000>; + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vreg_sys_pwr>; + }; + + vreg_sys_pwr: regulator-vreg-sys-pwr { + compatible = "regulator-fixed"; + regulator-name = "VREG_SYS_PWR"; + + regulator-min-microvolt = <24000000>; + regulator-max-microvolt = <24000000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&i2c15 { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + eeprom1: eeprom@52 { + compatible = "giantec,gt24c256c", "atmel,24c256"; + reg = <0x52>; + pagesize = <64>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + }; + }; +}; + +&pcie0 { + iommu-map = <0x0 &pcie_smmu 0x0 0x1>, + <0x100 &pcie_smmu 0x1 0x1>, + <0x208 &pcie_smmu 0x2 0x1>, + <0x210 &pcie_smmu 0x3 0x1>, + <0x218 &pcie_smmu 0x4 0x1>, + <0x300 &pcie_smmu 0x5 0x1>, + <0x400 &pcie_smmu 0x6 0x1>, + <0x500 &pcie_smmu 0x7 0x1>, + <0x501 &pcie_smmu 0x8 0x1>; +}; + +&pcieport0 { + #address-cells = <3>; + #size-cells = <2>; + + pcie@0,0 { + compatible = "pci1179,0623"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x2 0xff>; + + vddc-supply = <&vreg_0p9>; + vdd18-supply = <&vreg_1p8>; + vdd09-supply = <&vreg_0p9>; + vddio1-supply = <&vreg_1p8>; + vddio2-supply = <&vreg_1p8>; + vddio18-supply = <&vreg_1p8>; + + i2c-parent = <&i2c15 0x77>; + + resx-gpios = <&tlmm 124 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&tc9563_resx_n>; + pinctrl-names = "default"; + + pcie@1,0 { + reg = <0x20800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x3 0xff>; + }; + + pcie@2,0 { + reg = <0x21000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x4 0xff>; + }; + + pcie@3,0 { + reg = <0x21800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x5 0xff>; + + pci@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + + pci@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + }; + }; +}; + +&tlmm { + tc9563_resx_n: tc9563-resx-state { + pins = "gpio124"; + function = "gpio"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; +}; From 4558c6cafa17e72a494e993ad1b8b2fcded8e7f0 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 12 Feb 2026 10:27:38 +0530 Subject: [PATCH 324/438] FROMLIST: arm64: dts: qcom: monaco-evk: Enable GPIO expander interrupt for Monaco EVK Enable PCA9538 expander as interrupt controller on Monaco EVK and configure the corresponding TLMM pins via pinctrl to operate as GPIO inputs with internal pull-ups. Link: https://lore.kernel.org/all/20260210155329.3044455-2-swati.agarwal@oss.qualcomm.com/ Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 77 +++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index acf2e7c36f143..006c8b8cb5876 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -456,6 +456,11 @@ reg = <0x38>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 56 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander0_int>; + pinctrl-names = "default"; }; expander1: gpio@39 { @@ -463,6 +468,11 @@ reg = <0x39>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 16 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander1_int>; + pinctrl-names = "default"; }; expander2: gpio@3a { @@ -470,6 +480,11 @@ reg = <0x3a>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 95 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander2_int>; + pinctrl-names = "default"; }; expander3: gpio@3b { @@ -477,6 +492,11 @@ reg = <0x3b>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 24 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander3_int>; + pinctrl-names = "default"; }; expander4: gpio@3c { @@ -484,6 +504,11 @@ reg = <0x3c>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 96 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander4_int>; + pinctrl-names = "default"; }; expander5: gpio@3d { @@ -491,6 +516,11 @@ reg = <0x3d>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander5_int>; + pinctrl-names = "default"; }; expander6: gpio@3e { @@ -498,6 +528,11 @@ reg = <0x3e>; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 52 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander6_int>; + pinctrl-names = "default"; }; }; @@ -619,6 +654,48 @@ &tlmm { + expander0_int: expander0-int-state { + pins = "gpio56"; + function = "gpio"; + bias-pull-up; + }; + + expander1_int: expander1-int-state { + pins = "gpio16"; + function = "gpio"; + bias-pull-up; + }; + + expander2_int: expander2-int-state { + pins = "gpio95"; + function = "gpio"; + bias-pull-up; + }; + + expander3_int: expander3-int-state { + pins = "gpio24"; + function = "gpio"; + bias-pull-up; + }; + + expander4_int: expander4-int-state { + pins = "gpio96"; + function = "gpio"; + bias-pull-up; + }; + + expander5_int: expander5-int-state { + pins = "gpio3"; + function = "gpio"; + bias-pull-up; + }; + + expander6_int: expander6-int-state { + pins = "gpio52"; + function = "gpio"; + bias-pull-up; + }; + pcie0_default_state: pcie0-default-state { wake-pins { pins = "gpio0"; From 2c38efb795e83e7a76271c3566e88f3c48912ad1 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Thu, 12 Feb 2026 10:32:48 +0530 Subject: [PATCH 325/438] FROMLIST: arm64: dts: qcom: monaco-evk: Enable the tertiary USB controller Enable the tertiary usb controller connected to micro usb port in OTG mode on Monaco EVK platform. Link: https://lore.kernel.org/all/20260210155329.3044455-3-swati.agarwal@oss.qualcomm.com/ Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 53 +++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/monaco.dtsi | 7 ++++ 2 files changed, 60 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 006c8b8cb5876..8940b0ff66bfa 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -28,6 +28,25 @@ stdout-path = "serial0:115200n8"; }; + connector-2 { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + + id-gpios = <&pmm8620au_0_gpios 9 GPIO_ACTIVE_HIGH>; + vbus-gpios = <&expander6 7 GPIO_ACTIVE_HIGH>; + vbus-supply = <&vbus_supply_regulator_2>; + + pinctrl-names = "default"; + pinctrl-0 = <&usb2_id>; + + port { + usb2_con_hs_ep: endpoint { + remote-endpoint = <&usb_2_dwc3_hs>; + }; + }; + }; + dmic: audio-codec-0 { compatible = "dmic-codec"; #sound-dai-cells = <0>; @@ -103,6 +122,15 @@ }; }; + vbus_supply_regulator_2: vbus-supply-regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "vbus_supply_2"; + gpio = <&pmm8650au_1_gpios 7 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + vreg_cam1_2p8: vreg-cam1-2p8 { compatible = "regulator-fixed"; regulator-name = "vreg_cam1_2p8"; @@ -602,6 +630,16 @@ wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; }; +&pmm8620au_0_gpios { + usb2_id: usb2-id-state { + pins = "gpio9"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; +}; + &qup_i2c0_data_clk { drive-strength = <2>; bias-pull-up; @@ -832,3 +870,18 @@ status = "okay"; }; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3_hs { + remote-endpoint = <&usb2_con_hs_ep>; +}; + +&usb_2_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l7c>; + vdda33-supply = <&vreg_l9a>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 9e6724eee1195..ec07aa88d098e 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -5236,7 +5236,14 @@ qcom,select-utmi-as-pipe-clk; wakeup-source; + usb-role-switch; + status = "disabled"; + + port { + usb_2_dwc3_hs: endpoint { + }; + }; }; iris: video-codec@aa00000 { From 68163aba1a9edb45517946562eb933484fbc9e22 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Tue, 27 Jan 2026 12:35:52 +0530 Subject: [PATCH 326/438] BACKPORT: arm64: dts: qcom: monaco-evk: Enable primary USB controller in host mode Enable primary USB controller in host mode on monaco EVK Platform. Primary USB controller is connected to a Genesys Logic USB HUB GL3590 having 4 ports. The ports of hub that are present on lemans EVK standalone board are used as follows:- 1) port-1 is connected to HD3SS3220 Type-C port controller. 2) port-4 is used for the M.2 E key on corekit. Standard core kit uses UART for Bluetooth. This port is to be used only if user optionally replaces the WiFi card with the NFA765 chip which uses USB for Bluetooth. Remaining 2 ports will become functional when the interface plus mezzanine board is stacked on top of corekit: 3) port-2 is connected to another hub which is present on the mezz through which 4 type-A ports are connected. 4) port-3 is used for the M.2 B key for a 5G card when the mezz is connected. Mark the second USB controller as host only capable and add the HD3SS3220 Type-C port controller along with Type-c connector for controlling vbus supply. In hardware, there are dip switches provided to operate between USB port 0 and port 1 for primary Type-C USB controller. By default, switches will be off operating at USB0 port. After bootup to HLOS, it will be operated in USB1 port. Added support in the software for both HS and SS switches as usb1-hs-high-gpio14 and usb1-ss-high-gpio5. Also, added bootup-high-gpio7 pin for USB1 hub reset to get detected after bootup. Link: https://lore.kernel.org/all/20260210152548.769951-1-loic.poulain@oss.qualcomm.com/ Signed-off-by: Loic Poulain Signed-off-by: Swati Agarwal --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 203 +++++++++++++++++++++++- 1 file changed, 201 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 8940b0ff66bfa..5248086304419 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -28,6 +28,45 @@ stdout-path = "serial0:115200n8"; }; + connector-1 { + compatible = "usb-c-connector"; + label = "USB1-Type-C"; + data-role = "host"; + power-role = "source"; + + vbus-supply = <&vbus_supply_regulator_1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb1_con_ss_ep: endpoint { + remote-endpoint = <&hd3ss3220_1_in_ep>; + }; + }; + + port@1 { + reg = <1>; + + usb1_hs_in: endpoint { + remote-endpoint = <&usb_hub_2_1>; + }; + + }; + + port@2 { + reg = <2>; + + usb1_ss_in: endpoint { + remote-endpoint = <&usb_hub_3_1>; + }; + }; + }; + }; + connector-2 { compatible = "gpio-usb-b-connector", "usb-b-connector"; label = "micro-USB"; @@ -122,7 +161,16 @@ }; }; - vbus_supply_regulator_2: vbus-supply-regulator-2 { + vbus_supply_regulator_1: regulator-vbus-supply-1 { + compatible = "regulator-fixed"; + regulator-name = "vbus_supply_1"; + gpio = <&expander1 3 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + + vbus_supply_regulator_2: regulator-vbus-supply-2 { compatible = "regulator-fixed"; regulator-name = "vbus_supply_2"; gpio = <&pmm8650au_1_gpios 7 GPIO_ACTIVE_HIGH>; @@ -438,6 +486,38 @@ }; }; }; + + usb-typec@47 { + compatible = "ti,hd3ss3220"; + reg = <0x47>; + + interrupts = <45 IRQ_TYPE_EDGE_FALLING>; + + id-gpios = <&tlmm 13 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&usb1_id>; + pinctrl-names = "default"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hd3ss3220_1_in_ep: endpoint { + remote-endpoint = <&usb1_con_ss_ep>; + }; + }; + + port@1 { + reg = <1>; + + hd3ss3220_1_out_ep: endpoint { + }; + }; + }; + }; }; &i2c1 { @@ -549,6 +629,13 @@ interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&expander5_int>; pinctrl-names = "default"; + + gpio5-hog { + gpio-hog; + gpios = <5 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb1-ss-high-gpio5"; + }; }; expander6: gpio@3e { @@ -561,6 +648,7 @@ interrupts-extended = <&tlmm 52 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&expander6_int>; pinctrl-names = "default"; + wakeup-source; }; }; @@ -734,6 +822,20 @@ bias-pull-up; }; + gpio7_hog: gpio7-hog { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "bootup-high-gpio7"; + }; + + gpio14_hog: gpio14-hog { + gpio-hog; + gpios = <14 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb1-hs-high-gpio14"; + }; + pcie0_default_state: pcie0-default-state { wake-pins { pins = "gpio0"; @@ -809,6 +911,12 @@ drive-strength = <2>; bias-pull-up; }; + + usb1_id: usb1-id-state { + pins = "gpio13"; + function = "gpio"; + bias-pull-up; + }; }; &uart2 { @@ -851,9 +959,100 @@ }; &usb_1 { - dr_mode = "peripheral"; + dr_mode = "host"; + + #address-cells = <1>; + #size-cells = <0>; status = "okay"; + + usb_hub_2_x: hub@1 { + compatible = "usb5e3,610"; + reg = <1>; + + peer-hub = <&usb_hub_3_x>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + usb_hub_2_1: endpoint { + remote-endpoint = <&usb1_hs_in>; + }; + }; + + /* + * Port-2 and port-3 are not connected to anything on corekit. + */ + port@2 { + reg = <2>; + + usb_hub_2_2: endpoint { + }; + }; + + port@3 { + reg = <3>; + + usb_hub_2_3: endpoint { + }; + }; + + /* + * Port-4 is connected to M.2 E key connector on corekit. + */ + port@4 { + reg = <4>; + + usb_hub_2_4: endpoint { + }; + }; + }; + }; + + usb_hub_3_x: hub@2 { + compatible = "usb5e3,625"; + reg = <2>; + + peer-hub = <&usb_hub_2_x>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + usb_hub_3_1: endpoint { + remote-endpoint = <&usb1_ss_in>; + }; + }; + + port@2 { + reg = <2>; + + usb_hub_3_2: endpoint { + }; + }; + + port@3 { + reg = <3>; + + usb_hub_3_3: endpoint { + }; + }; + + port@4 { + reg = <4>; + + usb_hub_3_4: endpoint { + }; + }; + }; + }; }; &usb_1_hsphy { From 45d7ceab97abcf856c5eea623bacdba6cb7766db Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 13 Jan 2026 19:00:16 +0530 Subject: [PATCH 327/438] QCLINUX: drivers: increase deferred probe timeout Certain drivers were failing to probe during boot because their dependencies were not ready within the default deferred probe timeout. To address this, increase the deferred probe timeout to allow dependent drivers sufficient time to register and avoid probe failures during system startup. Signed-off-by: Komal Bajaj --- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 0354f209529c6..7cbfdb3651648 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -258,7 +258,7 @@ static int deferred_devs_show(struct seq_file *s, void *data) DEFINE_SHOW_ATTRIBUTE(deferred_devs); #ifdef CONFIG_MODULES -static int driver_deferred_probe_timeout = 10; +static int driver_deferred_probe_timeout = 15; #else static int driver_deferred_probe_timeout; #endif From 44a0c379505f9f09474d3f4652f26554245c33b8 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 8 Jan 2026 09:42:56 +0530 Subject: [PATCH 328/438] QCLINUX: PCI: Disable L1ss through quirk for Qualcomm SA8775P When PCIe L1ss is enabled, WLAN functionality is completly broken. There are some connectivity issues in this platform mostly with CLKREQ# pin. Disable L1ss as workaround untill actual issue get resolved. Signed-off-by: Krishna Chaitanya Chundru --- drivers/pci/quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 48946cca4be72..61d4aeed4d29f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2538,6 +2538,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PASEMI, 0xa002, quirk_disable_aspm_l0s_l1); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1); +static void quirk_disable_aspm_l1ss(struct pci_dev *dev) +{ + pci_disable_link_state(dev, PCIE_LINK_STATE_L1_1 | PCIE_LINK_STATE_L1_2); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QCOM, 0x1103, quirk_disable_aspm_l1ss); + /* * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain * Link bit cleared after starting the link retrain process to allow this From 5cd7edbc4947e34e65f0882764c6839ddebe1691 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 4 Feb 2026 21:40:53 +0530 Subject: [PATCH 329/438] WORKAROUND: arm64: dts: qcom: lemans: Disable global IRQ for pcie1 Currently pcie1 global IRQ is blocking a CPU core, due to which ufs is getting blocked and failing. As workaround disable PCIe1 global IRQ for now. Signed-off-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/lemans.dtsi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 808827b83553d..27edb48d3e3bf 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -8797,8 +8797,7 @@ , , , - , - ; + ; interrupt-names = "msi0", "msi1", "msi2", @@ -8806,8 +8805,7 @@ "msi4", "msi5", "msi6", - "msi7", - "global"; + "msi7"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>; interrupt-map = <0 0 0 1 &intc GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, From 391703930140852d7ad9feb73520c05a66107eb6 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 7 Feb 2026 17:55:39 +0530 Subject: [PATCH 330/438] WORKAROUND: scsi: ufs: core: Set uic_cmd_timeout to max It is obsrved that qcs9100-ride fails to boot intermittently due to ufs cmd timeouts. The timeout happens as the ufs threaded-irq fails to schedule within the default UIC_CMD_TIMEOUT_DEFAULT (500 msec) due to console logs spewing at the same moment. Increase timeout to max for now to UIC_CMD_TIMEOUT_MAX (5000 msecs) to allow ufs cmd sequences to complete. Signed-off-by: Shiraz Hashim --- drivers/ufs/core/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 847b55789bb87..36a573cfd96f2 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -119,7 +119,7 @@ static bool is_mcq_supported(struct ufs_hba *hba) module_param(use_mcq_mode, bool, 0644); MODULE_PARM_DESC(use_mcq_mode, "Control MCQ mode for controllers starting from UFSHCI 4.0. 1 - enable MCQ, 0 - disable MCQ. MCQ is enabled by default"); -static unsigned int uic_cmd_timeout = UIC_CMD_TIMEOUT_DEFAULT; +static unsigned int uic_cmd_timeout = UIC_CMD_TIMEOUT_MAX; static int uic_cmd_timeout_set(const char *val, const struct kernel_param *kp) { From ed409b323c0df3031e1ff3caba659ad0b8cfcc9a Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:20 +0530 Subject: [PATCH 331/438] FROMLIST: thermal: Add Remote Proc cooling driver Add a new generic driver for thermal cooling devices that control remote processors (modem, DSP, etc.) through various communication channels. This driver provides an abstraction layer between the thermal subsystem and vendor-specific remote processor communication mechanisms. Suggested-by: Amit Kucheria Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251223123227.1317244-2-gaurav.kohli@oss.qualcomm.com --- MAINTAINERS | 8 ++ drivers/thermal/Kconfig | 11 ++ drivers/thermal/Makefile | 2 + drivers/thermal/remoteproc_cooling.c | 154 +++++++++++++++++++++++++++ include/linux/remoteproc_cooling.h | 52 +++++++++ 5 files changed, 227 insertions(+) create mode 100644 drivers/thermal/remoteproc_cooling.c create mode 100644 include/linux/remoteproc_cooling.h diff --git a/MAINTAINERS b/MAINTAINERS index 55af015174a54..abf2a0b9e72d1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -26258,6 +26258,14 @@ F: drivers/thermal/cpufreq_cooling.c F: drivers/thermal/cpuidle_cooling.c F: include/linux/cpu_cooling.h +THERMAL/REMOTEPROC_COOLING +M: Gaurav Kohli +L: linux-pm@vger.kernel.org +S: Supported +F: drivers/thermal/remoteproc_cooling.c +F: include/linux/remoteproc_cooling.h + + THERMAL/POWER_ALLOCATOR M: Lukasz Luba L: linux-pm@vger.kernel.org diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index b10080d618604..31e92be343871 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -229,6 +229,17 @@ config PCIE_THERMAL If you want this support, you should say Y here. + +config REMOTEPROC_THERMAL + bool "Remote processor cooling support" + help + This implements a generic cooling mechanism for remote processors + (modem, DSP, etc.) that allows vendor-specific implementations to + register thermal cooling devices and provide callbacks for thermal + mitigation. + + If you want this support, you should say Y here. + config THERMAL_EMULATION bool "Thermal emulation mode support" help diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index bb21e7ea7fc6b..ae747dde54feb 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -34,6 +34,8 @@ thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o thermal_sys-$(CONFIG_PCIE_THERMAL) += pcie_cooling.o +thermal_sys-$(CONFIG_REMOTEPROC_THERMAL) += remoteproc_cooling.o + obj-$(CONFIG_K3_THERMAL) += k3_bandgap.o k3_j72xx_bandgap.o # platform thermal drivers obj-y += broadcom/ diff --git a/drivers/thermal/remoteproc_cooling.c b/drivers/thermal/remoteproc_cooling.c new file mode 100644 index 0000000000000..a1f948cbde0fe --- /dev/null +++ b/drivers/thermal/remoteproc_cooling.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Remote Processor Cooling Device + * + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define REMOTEPROC_PREFIX "rproc_" + +struct remoteproc_cooling_ops { + int (*get_max_level)(void *devdata, unsigned long *level); + int (*get_cur_level)(void *devdata, unsigned long *level); + int (*set_cur_level)(void *devdata, unsigned long level); +}; + +/** + * struct remoteproc_cdev - Remote processor cooling device + * @cdev: Thermal cooling device handle + * @ops: Vendor-specific operation callbacks + * @devdata: Private data for vendor implementation + * @np: Device tree node associated with this cooling device + * @lock: Mutex to protect cooling device operations + */ +struct remoteproc_cdev { + struct thermal_cooling_device *cdev; + const struct remoteproc_cooling_ops *ops; + void *devdata; + struct device_node *np; + struct mutex lock; +}; + + +/* Thermal cooling device callbacks */ + +static int remoteproc_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct remoteproc_cdev *rproc_cdev = cdev->devdata; + int ret; + + if (!rproc_cdev || !rproc_cdev->ops) + return -EINVAL; + + mutex_lock(&rproc_cdev->lock); + ret = rproc_cdev->ops->get_max_level(rproc_cdev->devdata, state); + mutex_unlock(&rproc_cdev->lock); + + return ret; +} + +static int remoteproc_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct remoteproc_cdev *rproc_cdev = cdev->devdata; + int ret; + + if (!rproc_cdev || !rproc_cdev->ops) + return -EINVAL; + + mutex_lock(&rproc_cdev->lock); + ret = rproc_cdev->ops->get_cur_level(rproc_cdev->devdata, state); + mutex_unlock(&rproc_cdev->lock); + + return ret; +} + +static int remoteproc_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct remoteproc_cdev *rproc_cdev = cdev->devdata; + int ret; + + if (!rproc_cdev || !rproc_cdev->ops) + return -EINVAL; + + mutex_lock(&rproc_cdev->lock); + ret = rproc_cdev->ops->set_cur_level(rproc_cdev->devdata, state); + mutex_unlock(&rproc_cdev->lock); + + return ret; +} + +static const struct thermal_cooling_device_ops remoteproc_cooling_ops = { + .get_max_state = remoteproc_get_max_state, + .get_cur_state = remoteproc_get_cur_state, + .set_cur_state = remoteproc_set_cur_state, +}; + +struct remoteproc_cdev * +remoteproc_cooling_register(struct device_node *np, + const char *name, const struct remoteproc_cooling_ops *ops, + void *devdata) +{ + struct remoteproc_cdev *rproc_cdev; + struct thermal_cooling_device *cdev; + int ret; + + if (!name || !ops) { + return ERR_PTR(-EINVAL); + } + + rproc_cdev = kzalloc(sizeof(*rproc_cdev), GFP_KERNEL); + if (!rproc_cdev) + return ERR_PTR(-ENOMEM); + + rproc_cdev->ops = ops; + rproc_cdev->devdata = devdata; + rproc_cdev->np = np; + mutex_init(&rproc_cdev->lock); + + char *rproc_name __free(kfree) = + kasprintf(GFP_KERNEL, REMOTEPROC_PREFIX "%s", name); + /* Register with thermal framework */ + if (np) { + cdev = thermal_of_cooling_device_register(np, rproc_name, rproc_cdev, + &remoteproc_cooling_ops); + } + + if (IS_ERR(cdev)) { + ret = PTR_ERR(cdev); + goto free_rproc_cdev; + } + + rproc_cdev->cdev = cdev; + + return rproc_cdev; + +free_rproc_cdev: + kfree(rproc_cdev); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(remoteproc_cooling_register); + +void remoteproc_cooling_unregister(struct remoteproc_cdev *rproc_cdev) +{ + if (!rproc_cdev) + return; + + thermal_cooling_device_unregister(rproc_cdev->cdev); + mutex_destroy(&rproc_cdev->lock); + kfree(rproc_cdev); +} +EXPORT_SYMBOL_GPL(remoteproc_cooling_unregister); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Remote Processor Cooling Device"); diff --git a/include/linux/remoteproc_cooling.h b/include/linux/remoteproc_cooling.h new file mode 100644 index 0000000000000..ef94019d220de --- /dev/null +++ b/include/linux/remoteproc_cooling.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Remote Processor Cooling Device + * + * Copyright (c) 2025, Qualcomm Innovation Center + */ + +#ifndef __REMOTEPROC_COOLING_H__ +#define __REMOTEPROC_COOLING_H__ + +#include + +struct device; +struct device_node; + +struct remoteproc_cooling_ops { + int (*get_max_level)(void *devdata, unsigned long *level); + int (*get_cur_level)(void *devdata, unsigned long *level); + int (*set_cur_level)(void *devdata, unsigned long level); +}; + +struct remoteproc_cdev; + +#ifdef CONFIG_REMOTEPROC_THERMAL + +struct remoteproc_cdev * +remoteproc_cooling_register(struct device_node *np, + const char *name, + const struct remoteproc_cooling_ops *ops, + void *devdata); + +void remoteproc_cooling_unregister(struct remoteproc_cdev *rproc_cdev); + +#else /* !CONFIG_REMOTEPROC_THERMAL */ + +static inline struct remoteproc_cdev * +remoteproc_cooling_register(struct device_node *np, + const char *name, + const struct remoteproc_cooling_ops *ops, + void *devdata) +{ + return ERR_PTR(-EINVAL); +} + +static inline void +remoteproc_cooling_unregister(struct remoteproc_cdev *rproc_cdev) +{ +} + +#endif /* CONFIG_REMOTEPROC_THERMAL */ + +#endif /* __REMOTEPROC_COOLING_H__ */ From 7ed5b26208dff1fc25e53332daf4f8b311aa1d75 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:22 +0530 Subject: [PATCH 332/438] FROMLIST: dt-bindings: thermal: Add qcom,qmi-cooling yaml bindings The cooling subnode of a remoteproc represents a client of the Thermal Mitigation Device QMI service running on it. Each subnode of the cooling node represents a single control exposed by the service. Add maintainer name also and update this binding for cdsp substem. Co-developed-by: Casey Connolly Signed-off-by: Gaurav Kohli Signed-off-by: Casey Connolly Link: https://lore.kernel.org/r/20251223123227.1317244-4-gaurav.kohli@oss.qualcomm.com --- .../bindings/remoteproc/qcom,pas-common.yaml | 6 ++ .../bindings/thermal/qcom,qmi-cooling.yaml | 99 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/qcom,qmi-cooling.yaml diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml index 68c17bf18987c..6a736161d5aed 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml @@ -80,6 +80,12 @@ properties: and devices related to the ADSP. unevaluatedProperties: false + cooling: + $ref: /schemas/thermal/qcom,qmi-cooling.yaml# + description: + Cooling subnode which represents the cooling devices exposed by the Modem. + unevaluatedProperties: false + required: - clocks - clock-names diff --git a/Documentation/devicetree/bindings/thermal/qcom,qmi-cooling.yaml b/Documentation/devicetree/bindings/thermal/qcom,qmi-cooling.yaml new file mode 100644 index 0000000000000..90b46712d2412 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/qcom,qmi-cooling.yaml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2023 (c), Linaro Limited + +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/qcom,qmi-cooling.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QMI based thermal mitigation (TMD) cooling devices. + +maintainers: + - Caleb Connolly + - Gaurav Kohli + +description: + Qualcomm QMI-based TMD cooling devices are used to mitigate thermal conditions + across multiple remote subsystems. These devices operate based on junction temperature + sensors (TSENS) associated with thermal zones for each subsystem. + + Each subnode corresponds to a control interface for a single instance of the TMD + service running on a remote subsystem. + +definitions: + tmd: + type: object + description: | + A single Thermal Mitigation Device exposed by a remote subsystem. + properties: + label: + maxItems: 1 + "#cooling-cells": + $ref: /schemas/thermal/thermal-cooling-devices.yaml#/properties/#cooling-cells + phandle: true + + required: + - label + - "#cooling-cells" + + additionalProperties: false + +properties: + compatible: + enum: + - qcom,qmi-cooling-modem + - qcom,qmi-cooling-cdsp + + vdd: + $ref: "#/definitions/tmd" + description: + Modem processor temperature TMD + properties: + label: + const: modem + +required: + - compatible + +allOf: + - if: + properties: + compatible: + contains: + const: qcom,qmi-cooling-cdsp + then: + properties: + cdsp_sw: + $ref: "#/definitions/tmd" + description: + CDSP software TMD + properties: + label: + const: cdsp_sw + +unevaluatedProperties: false + +examples: + - | + remoteproc-cdsp { + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + + cdsp_sw0: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; + }; + + remoteproc-cdsp1 { + cooling { + compatible = "qcom,qmi-cooling-cdsp1"; + + cdsp_sw1: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; + }; +... From 74537a2f6688dda96a14b453163498d5f9062aec Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Tue, 23 Dec 2025 18:02:23 +0530 Subject: [PATCH 333/438] FROMLIST: thermal: qcom: add qmi-cooling driver The Thermal Mitigation Device (TMD) service exposes various platform specific thermal mitigations available on remote subsystems (ie the modem and cdsp). The service is exposed via the QMI messaging interface, usually over the QRTR transport. Qualcomm QMI-based TMD cooling devices are used to mitigate thermal conditions across multiple remote subsystems. These devices operate based on junction temperature sensors (TSENS) associated with thermal zones for each subsystem. Co-developed-by: Gaurav Kohli Signed-off-by: Casey Connolly Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251223123227.1317244-5-gaurav.kohli@oss.qualcomm.com --- drivers/soc/qcom/Kconfig | 13 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/qmi-cooling.c | 498 +++++++++++++++++++++++++++++++++ drivers/soc/qcom/qmi-cooling.h | 428 ++++++++++++++++++++++++++++ 4 files changed, 940 insertions(+) create mode 100644 drivers/soc/qcom/qmi-cooling.c create mode 100644 drivers/soc/qcom/qmi-cooling.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 2caadbbcf8307..905a24b42fe69 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -124,6 +124,19 @@ config QCOM_PMIC_GLINK Say yes here to support USB-C and battery status on modern Qualcomm platforms. +config QCOM_QMI_COOLING + tristate "Qualcomm QMI cooling drivers" + depends on QCOM_RPROC_COMMON + depends on ARCH_QCOM || COMPILE_TEST + select QCOM_QMI_HELPERS + help + This enables the remote subsystem cooling devices. These cooling + devices will be used by Qualcomm chipset to place various remote + subsystem mitigations like remote processor passive mitigation, + remote subsystem voltage restriction at low temperatures etc. + The QMI cooling device will interface with remote subsystem + using Qualcomm remoteproc interface. + config QCOM_QMI_HELPERS tristate depends on NET diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index b7f1d2a573674..b6728f54944b1 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink_altmode.o obj-$(CONFIG_QCOM_PMIC_PDCHARGER_ULOG) += pmic_pdcharger_ulog.o CFLAGS_pmic_pdcharger_ulog.o := -I$(src) +obj-$(CONFIG_QCOM_QMI_COOLING) += qmi-cooling.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 diff --git a/drivers/soc/qcom/qmi-cooling.c b/drivers/soc/qcom/qmi-cooling.c new file mode 100644 index 0000000000000..1a6afcb96bf69 --- /dev/null +++ b/drivers/soc/qcom/qmi-cooling.c @@ -0,0 +1,498 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017, The Linux Foundation + * Copyright (c) 2025, Linaro Limited + * + * QMI Thermal Mitigation Device (TMD) client driver. + * This driver provides an in-kernel client to handle hot and cold thermal + * mitigations for remote subsystems (modem and DSPs) running the TMD service. + * It doesn't implement any handling of reports from remote subsystems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qmi-cooling.h" + +#define MODEM0_INSTANCE_ID 0x0 +#define ADSP_INSTANCE_ID 0x1 +#define CDSP_INSTANCE_ID 0x43 +#define SLPI_INSTANCE_ID 0x53 + +#define QMI_TMD_RESP_TIMEOUT msecs_to_jiffies(100) + +/** + * struct qmi_tmd_client - TMD client state + * @dev: Device associated with this client + * @name: Friendly name for the remote TMD service + * @handle: QMI connection handle + * @mutex: Lock to synchronise QMI communication + * @id: The QMI TMD service instance ID + * @cdev_list: The list of cooling devices (controls) enabled for this instance + * @svc_arrive_work: Work item for initialising the client when the TMD service + * starts. + * @connection_active: Whether or not we're connected to the QMI TMD service + */ +struct qmi_tmd_client { + struct device *dev; + const char *name; + struct qmi_handle handle; + struct mutex mutex; + u32 id; + struct list_head cdev_list; + struct work_struct svc_arrive_work; + bool connection_active; +}; + +/** + * struct qmi_tmd - A TMD cooling device + * @np: OF node associated with this control + * @type: The control type (exposed via sysfs) + * @qmi_name: The common name of this control shared by the remote subsystem + * @rproc_cdev: Remote processor cooling device handle + * @cur_state: The current cooling/warming/mitigation state + * @max_state: The maximum state + * @client: The TMD client instance this control is associated with + */ +struct qmi_tmd { + struct device_node *np; + const char *type; + char qmi_name[QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1]; + struct list_head node; + struct remoteproc_cdev *rproc_cdev; + unsigned int cur_state; + unsigned int max_state; + struct qmi_tmd_client *client; +}; + +/** + * struct qmi_instance_id - QMI instance match data + * @id: The QMI instance ID + * @name: Friendly name for this instance + */ +struct qmi_instance_data { + u32 id; + const char *name; +}; + +/* Notify the remote subsystem of the requested cooling state */ +static int qmi_tmd_send_state_request(struct qmi_tmd *tmd) +{ + struct tmd_set_mitigation_level_resp_msg_v01 tmd_resp = { 0 }; + struct tmd_set_mitigation_level_req_msg_v01 req = { 0 }; + struct qmi_tmd_client *client; + struct qmi_txn txn; + int ret = 0; + + client = tmd->client; + + guard(mutex)(&client->mutex); + + /* + * This function is called by qmi_set_cur_state() which does not know if + * the QMI service is actually online. If it isn't then we noop here. + * The state is cached in tmd->cur_state and will be broadcast via + * qmi_tmd_init_control() when the service comes up. + */ + if (!client->connection_active) + return 0; + + strscpy(req.mitigation_dev_id.mitigation_dev_id, tmd->qmi_name, + QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1); + req.mitigation_level = tmd->cur_state; + + ret = qmi_txn_init(&client->handle, &txn, + tmd_set_mitigation_level_resp_msg_v01_ei, &tmd_resp); + if (ret < 0) { + dev_err(client->dev, "qmi set state %d txn init failed for %s ret %d\n", + tmd->cur_state, tmd->type, ret); + return ret; + } + + ret = qmi_send_request(&client->handle, NULL, &txn, + QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01, + TMD_SET_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN, + tmd_set_mitigation_level_req_msg_v01_ei, &req); + if (ret < 0) { + dev_err(client->dev, "qmi set state %d txn send failed for %s ret %d\n", + tmd->cur_state, tmd->type, ret); + qmi_txn_cancel(&txn); + return ret; + } + + ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TIMEOUT); + if (ret < 0) { + dev_err(client->dev, "qmi set state %d txn wait failed for %s ret %d\n", + tmd->cur_state, tmd->type, ret); + return ret; + } + + if (tmd_resp.resp.result != QMI_RESULT_SUCCESS_V01) { + ret = -tmd_resp.resp.result; + dev_err(client->dev, "qmi set state %d NOT success for %s ret %d\n", + tmd->cur_state, tmd->type, ret); + return ret; + } + + dev_dbg(client->dev, "Requested state %d/%d for %s\n", tmd->cur_state, + tmd->max_state, tmd->type); + + return 0; +} + +static int qmi_get_max_level(void *devdata, unsigned long *level) +{ + struct qmi_tmd *tmd = devdata; + + if (!tmd) + return -EINVAL; + + *level = tmd->max_state; + + return 0; +} + +static int qmi_get_cur_level(void *devdata, unsigned long *level) +{ + struct qmi_tmd *tmd = devdata; + + if (!tmd) + return -EINVAL; + + *level = tmd->cur_state; + + return 0; +} + +static int qmi_set_cur_level(void *devdata, unsigned long level) +{ + struct qmi_tmd *tmd = devdata; + + if (!tmd) + return -EINVAL; + + if (level > tmd->max_state) + return -EINVAL; + + if (tmd->cur_state == level) + return 0; + + tmd->cur_state = level; + + return qmi_tmd_send_state_request(tmd); +} + +static const struct remoteproc_cooling_ops qmi_rproc_ops = { + .get_max_level = qmi_get_max_level, + .get_cur_level = qmi_get_cur_level, + .set_cur_level = qmi_set_cur_level, +}; + +static int qmi_register_cooling_device(struct qmi_tmd *tmd) +{ + struct remoteproc_cdev *rproc_cdev; + + rproc_cdev = remoteproc_cooling_register(tmd->np, + tmd->type, + &qmi_rproc_ops, + tmd); + + if (IS_ERR(rproc_cdev)) + return dev_err_probe(tmd->client->dev, PTR_ERR(rproc_cdev), + "Failed to register cooling device %s\n", + tmd->qmi_name); + + tmd->rproc_cdev = rproc_cdev; + return 0; +} + +/* + * Init a single TMD control by registering a cooling device for it, or + * synchronising state with the remote subsystem if recovering from a service + * restart. This is called when the TMD service starts up. + */ +static int qmi_tmd_init_control(struct qmi_tmd_client *client, const char *label, + u8 max_state) +{ + struct qmi_tmd *tmd = NULL; + + list_for_each_entry(tmd, &client->cdev_list, node) + if (!strncasecmp(tmd->qmi_name, label, + QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1)) + goto found; + + dev_dbg(client->dev, + "TMD '%s' available in firmware but not specified in DT\n", + label); + return 0; + +found: + tmd->max_state = max_state; + /* + * If the cooling device already exists then the QMI service went away and + * came back. So just make sure the current cooling device state is + * reflected on the remote side and then return. + */ + if (tmd->rproc_cdev) + return qmi_tmd_send_state_request(tmd); + + return qmi_register_cooling_device(tmd); +} + +/* + * When the QMI service starts up on a remote subsystem this function will fetch + * the list of TMDs on the subsystem, match it to the TMDs specified in devicetree + * and call qmi_tmd_init_control() for each + */ +static void qmi_tmd_svc_arrive(struct work_struct *work) +{ + struct qmi_tmd_client *client = + container_of(work, struct qmi_tmd_client, svc_arrive_work); + + struct tmd_get_mitigation_device_list_req_msg_v01 req = { 0 }; + struct tmd_get_mitigation_device_list_resp_msg_v01 *resp __free(kfree); + int ret = 0, i; + struct qmi_txn txn; + + /* resp struct is 1.1kB, allocate it on the heap. */ + resp = kzalloc(sizeof(*resp), GFP_KERNEL); + if (!resp) + return; + + /* Get a list of TMDs supported by the remoteproc */ + scoped_guard(mutex, &client->mutex) { + ret = qmi_txn_init(&client->handle, &txn, + tmd_get_mitigation_device_list_resp_msg_v01_ei, resp); + if (ret < 0) { + dev_err(client->dev, + "Transaction init error for instance_id: %#x ret %d\n", + client->id, ret); + return; + } + + ret = qmi_send_request(&client->handle, NULL, &txn, + QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01, + TMD_GET_MITIGATION_DEVICE_LIST_REQ_MSG_V01_MAX_MSG_LEN, + tmd_get_mitigation_device_list_req_msg_v01_ei, &req); + if (ret < 0) { + qmi_txn_cancel(&txn); + return; + } + + ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TIMEOUT); + if (ret < 0) { + dev_err(client->dev, "Transaction wait error for client %#x ret:%d\n", + client->id, ret); + return; + } + if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { + ret = resp->resp.result; + dev_err(client->dev, "Failed to get device list for client %#x ret:%d\n", + client->id, ret); + return; + } + + client->connection_active = true; + } + + for (i = 0; i < resp->mitigation_device_list_len; i++) { + struct tmd_mitigation_dev_list_type_v01 *device = + &resp->mitigation_device_list[i]; + + ret = qmi_tmd_init_control(client, + device->mitigation_dev_id.mitigation_dev_id, + device->max_mitigation_level); + if (ret) + break; + } +} + +static void thermal_qmi_net_reset(struct qmi_handle *qmi) +{ + struct qmi_tmd_client *client = container_of(qmi, struct qmi_tmd_client, handle); + struct qmi_tmd *tmd = NULL; + + list_for_each_entry(tmd, &client->cdev_list, node) { + qmi_tmd_send_state_request(tmd); + } +} + +static void thermal_qmi_del_server(struct qmi_handle *qmi, struct qmi_service *service) +{ + struct qmi_tmd_client *client = container_of(qmi, struct qmi_tmd_client, handle); + + scoped_guard(mutex, &client->mutex) + client->connection_active = false; +} + +static int thermal_qmi_new_server(struct qmi_handle *qmi, struct qmi_service *service) +{ + struct qmi_tmd_client *client = container_of(qmi, struct qmi_tmd_client, handle); + struct sockaddr_qrtr sq = { AF_QIPCRTR, service->node, service->port }; + + scoped_guard(mutex, &client->mutex) + kernel_connect(qmi->sock, (struct sockaddr_unsized *)&sq, sizeof(sq), 0); + + queue_work(system_highpri_wq, &client->svc_arrive_work); + + return 0; +} + +static struct qmi_ops thermal_qmi_event_ops = { + .new_server = thermal_qmi_new_server, + .del_server = thermal_qmi_del_server, + .net_reset = thermal_qmi_net_reset, +}; + +static void qmi_tmd_cleanup(struct qmi_tmd_client *client) +{ + struct qmi_tmd *tmd, *c_next; + + guard(mutex)(&client->mutex); + + client->connection_active = false; + + qmi_handle_release(&client->handle); + cancel_work(&client->svc_arrive_work); + list_for_each_entry_safe(tmd, c_next, &client->cdev_list, node) { + if (tmd->rproc_cdev) + remoteproc_cooling_unregister(tmd->rproc_cdev); + + list_del(&tmd->node); + } +} + +/* Parse the controls and allocate a qmi_tmd for each of them */ +static int qmi_tmd_alloc_cdevs(struct qmi_tmd_client *client) +{ + struct device *dev = client->dev; + struct qmi_tmd *tmd; + struct device_node *subnode, *node = dev->of_node; + int ret; + + for_each_available_child_of_node(node, subnode) { + const char *name; + + tmd = devm_kzalloc(dev, sizeof(*tmd), GFP_KERNEL); + if (!tmd) + return dev_err_probe(client->dev, -ENOMEM, + "Couldn't allocate tmd\n"); + + tmd->type = devm_kasprintf(client->dev, GFP_KERNEL, "%s:%s", + client->name, subnode->name); + if (!tmd->type) + return dev_err_probe(dev, -ENOMEM, + "Couldn't allocate cooling device name\n"); + + if (of_property_read_string(subnode, "label", &name)) { + return dev_err_probe(client->dev, -EINVAL, + "Failed to parse dev name for %s\n", + subnode->name); + } + + ret = strscpy(tmd->qmi_name, name, + QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1); + if (ret == -E2BIG) { + return dev_err_probe(dev, -EINVAL, "TMD label %s is too long\n", + name); + } + + tmd->client = client; + tmd->np = subnode; + tmd->cur_state = 0; + list_add(&tmd->node, &client->cdev_list); + } + + if (list_empty(&client->cdev_list)) + return dev_err_probe(client->dev, -EINVAL, + "No cooling devices specified for client %s (%#x)\n", + client->name, client->id); + + return 0; +} + +static int qmi_tmd_client_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct qmi_tmd_client *client; + const struct qmi_instance_data *match; + int ret; + client = devm_kzalloc(dev, sizeof(*client), GFP_KERNEL); + if (!client) + return -ENOMEM; + + client->dev = dev; + + match = of_device_get_match_data(dev); + if (!match) + return dev_err_probe(dev, -EINVAL, "No match data\n"); + + client->id = match->id; + client->name = match->name; + + mutex_init(&client->mutex); + INIT_LIST_HEAD(&client->cdev_list); + INIT_WORK(&client->svc_arrive_work, qmi_tmd_svc_arrive); + + ret = qmi_tmd_alloc_cdevs(client); + if (ret) + return ret; + + platform_set_drvdata(pdev, client); + + ret = qmi_handle_init(&client->handle, + TMD_GET_MITIGATION_DEVICE_LIST_RESP_MSG_V01_MAX_MSG_LEN, + &thermal_qmi_event_ops, NULL); + if (ret < 0) + return dev_err_probe(client->dev, ret, "QMI handle init failed for client %#x\n", + client->id); + + ret = qmi_add_lookup(&client->handle, TMD_SERVICE_ID_V01, TMD_SERVICE_VERS_V01, + client->id); + if (ret < 0) { + qmi_handle_release(&client->handle); + return dev_err_probe(client->dev, ret, "QMI register failed for client 0x%x\n", + client->id); + } + + return 0; +} + +static void qmi_tmd_client_remove(struct platform_device *pdev) +{ + struct qmi_tmd_client *client = platform_get_drvdata(pdev); + + qmi_tmd_cleanup(client); +} + +static const struct of_device_id qmi_tmd_device_table[] = { + { + .compatible = "qcom,qmi-cooling-cdsp", + .data = &((struct qmi_instance_data) { CDSP_INSTANCE_ID, "cdsp" }), + }, + {} +}; +MODULE_DEVICE_TABLE(of, qmi_tmd_device_table); + +static struct platform_driver qmi_tmd_device_driver = { + .probe = qmi_tmd_client_probe, + .remove = qmi_tmd_client_remove, + .driver = { + .name = "qcom-qmi-cooling", + .of_match_table = qmi_tmd_device_table, + }, +}; + +module_platform_driver(qmi_tmd_device_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm QMI Thermal Mitigation Device driver"); diff --git a/drivers/soc/qcom/qmi-cooling.h b/drivers/soc/qcom/qmi-cooling.h new file mode 100644 index 0000000000000..f46b827b4ce64 --- /dev/null +++ b/drivers/soc/qcom/qmi-cooling.h @@ -0,0 +1,428 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2017, The Linux Foundation + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef __QCOM_COOLING_H__ +#define __QCOM_COOLING_H__ + +#include + +#define TMD_SERVICE_ID_V01 0x18 +#define TMD_SERVICE_VERS_V01 0x01 + +#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_RESP_V01 0x0020 +#define QMI_TMD_GET_MITIGATION_LEVEL_REQ_V01 0x0022 +#define QMI_TMD_GET_SUPPORTED_MSGS_REQ_V01 0x001E +#define QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01 0x0021 +#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0023 +#define QMI_TMD_GET_SUPPORTED_MSGS_RESP_V01 0x001E +#define QMI_TMD_SET_MITIGATION_LEVEL_RESP_V01 0x0021 +#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0024 +#define QMI_TMD_MITIGATION_LEVEL_REPORT_IND_V01 0x0025 +#define QMI_TMD_GET_MITIGATION_LEVEL_RESP_V01 0x0022 +#define QMI_TMD_GET_SUPPORTED_FIELDS_REQ_V01 0x001F +#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01 0x0020 +#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0023 +#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0024 +#define QMI_TMD_GET_SUPPORTED_FIELDS_RESP_V01 0x001F + +#define QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 32 +#define QMI_TMD_MITIGATION_DEV_LIST_MAX_V01 32 + +struct tmd_mitigation_dev_id_type_v01 { + char mitigation_dev_id[QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1]; +}; + +static const struct qmi_elem_info tmd_mitigation_dev_id_type_v01_ei[] = { + { + .data_type = QMI_STRING, + .elem_len = QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1, + .elem_size = sizeof(char), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct tmd_mitigation_dev_id_type_v01, + mitigation_dev_id), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_mitigation_dev_list_type_v01 { + struct tmd_mitigation_dev_id_type_v01 mitigation_dev_id; + uint8_t max_mitigation_level; +}; + +static const struct qmi_elem_info tmd_mitigation_dev_list_type_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct tmd_mitigation_dev_list_type_v01, + mitigation_dev_id), + .ei_array = tmd_mitigation_dev_id_type_v01_ei, + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct tmd_mitigation_dev_list_type_v01, + max_mitigation_level), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_get_mitigation_device_list_req_msg_v01 { + char placeholder; +}; + +#define TMD_GET_MITIGATION_DEVICE_LIST_REQ_MSG_V01_MAX_MSG_LEN 0 +const struct qmi_elem_info tmd_get_mitigation_device_list_req_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_get_mitigation_device_list_resp_msg_v01 { + struct qmi_response_type_v01 resp; + uint8_t mitigation_device_list_valid; + uint32_t mitigation_device_list_len; + struct tmd_mitigation_dev_list_type_v01 + mitigation_device_list[QMI_TMD_MITIGATION_DEV_LIST_MAX_V01]; +}; + +#define TMD_GET_MITIGATION_DEVICE_LIST_RESP_MSG_V01_MAX_MSG_LEN 1099 +static const struct qmi_elem_info tmd_get_mitigation_device_list_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct tmd_get_mitigation_device_list_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct tmd_get_mitigation_device_list_resp_msg_v01, + mitigation_device_list_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct tmd_get_mitigation_device_list_resp_msg_v01, + mitigation_device_list_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_TMD_MITIGATION_DEV_LIST_MAX_V01, + .elem_size = sizeof(struct tmd_mitigation_dev_list_type_v01), + .array_type = VAR_LEN_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct tmd_get_mitigation_device_list_resp_msg_v01, + mitigation_device_list), + .ei_array = tmd_mitigation_dev_list_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_set_mitigation_level_req_msg_v01 { + struct tmd_mitigation_dev_id_type_v01 mitigation_dev_id; + uint8_t mitigation_level; +}; + +#define TMD_SET_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 40 +static const struct qmi_elem_info tmd_set_mitigation_level_req_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct tmd_set_mitigation_level_req_msg_v01, + mitigation_dev_id), + .ei_array = tmd_mitigation_dev_id_type_v01_ei, + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct tmd_set_mitigation_level_req_msg_v01, + mitigation_level), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_set_mitigation_level_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define TMD_SET_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7 +static const struct qmi_elem_info tmd_set_mitigation_level_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct tmd_set_mitigation_level_resp_msg_v01, resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_get_mitigation_level_req_msg_v01 { + struct tmd_mitigation_dev_id_type_v01 mitigation_device; +}; +#define TMD_GET_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 36 + +static const struct qmi_elem_info tmd_get_mitigation_level_req_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct tmd_get_mitigation_level_req_msg_v01, + mitigation_device), + .ei_array = tmd_mitigation_dev_id_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_get_mitigation_level_resp_msg_v01 { + struct qmi_response_type_v01 resp; + uint8_t current_mitigation_level_valid; + uint8_t current_mitigation_level; + uint8_t requested_mitigation_level_valid; + uint8_t requested_mitigation_level; +}; + +#define TMD_GET_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 15 +static const struct qmi_elem_info tmd_get_mitigation_level_resp_msg_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct tmd_get_mitigation_level_resp_msg_v01, resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct tmd_get_mitigation_level_resp_msg_v01, + current_mitigation_level_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct tmd_get_mitigation_level_resp_msg_v01, + current_mitigation_level), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct tmd_get_mitigation_level_resp_msg_v01, + requested_mitigation_level_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct tmd_get_mitigation_level_resp_msg_v01, + requested_mitigation_level), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct tmd_register_notification_mitigation_level_req_msg_v01 { + struct tmd_mitigation_dev_id_type_v01 mitigation_device; +}; + +#define TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 36 +static const struct qmi_elem_info + tmd_register_notification_mitigation_level_req_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof( + struct tmd_register_notification_mitigation_level_req_msg_v01, + mitigation_device), + .ei_array = tmd_mitigation_dev_id_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, + }; + +struct tmd_register_notification_mitigation_level_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7 +static const struct qmi_elem_info + tmd_register_notification_mitigation_level_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof( + struct tmd_register_notification_mitigation_level_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, + }; + +struct tmd_deregister_notification_mitigation_level_req_msg_v01 { + struct tmd_mitigation_dev_id_type_v01 mitigation_device; +}; + +#define TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 36 +static const struct qmi_elem_info + tmd_deregister_notification_mitigation_level_req_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof( + struct tmd_deregister_notification_mitigation_level_req_msg_v01, + mitigation_device), + .ei_array = tmd_mitigation_dev_id_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, + }; + +struct tmd_deregister_notification_mitigation_level_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7 +static const struct qmi_elem_info + tmd_deregister_notification_mitigation_level_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof( + struct tmd_deregister_notification_mitigation_level_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, + }; + +struct tmd_mitigation_level_report_ind_msg_v01 { + struct tmd_mitigation_dev_id_type_v01 mitigation_device; + uint8_t current_mitigation_level; +}; + +#define TMD_MITIGATION_LEVEL_REPORT_IND_MSG_V01_MAX_MSG_LEN 40 +static const struct qmi_elem_info tmd_mitigation_level_report_ind_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct tmd_mitigation_level_report_ind_msg_v01, + mitigation_device), + .ei_array = tmd_mitigation_dev_id_type_v01_ei, + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct tmd_mitigation_level_report_ind_msg_v01, + current_mitigation_level), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +#endif /* __QMI_COOLING_INTERNAL_H__ */ From c6bfd53058dd772e3311ed5ea7cafefeacf47612 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 19 Feb 2026 18:53:26 +0530 Subject: [PATCH 334/438] FROMLIST: dt-bindings: arm: qcom: Document Glymur SoC and board Document Glymur SoC bindings and Compute Reference Device (CRD) board id Link: https://lore.kernel.org/all/20260219-upstream_v3_glymur_introduction-v8-0-8ce4e489ebb6@oss.qualcomm.com/ Signed-off-by: Pankaj Patil Acked-by: Krzysztof Kozlowski Signed-off-by: Pradyot Kumar Nayak --- Documentation/devicetree/bindings/arm/qcom.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index d48c625d3fc42..34a19e6645569 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -61,6 +61,11 @@ properties: - qcom,apq8084-sbc - const: qcom,apq8084 + - items: + - enum: + - qcom,glymur-crd + - const: qcom,glymur + - items: - enum: - fairphone,fp6 From 18c1cca5edcd6872ce9175e05dbc70bc4bfa64da Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 19 Feb 2026 18:53:28 +0530 Subject: [PATCH 335/438] FROMLIST: arm64: dts: qcom: Introduce Glymur base dtsi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce the base device tree support for Glymur – Qualcomm's next-generation compute SoC. The new glymur.dtsi describes the core SoC components, including: - CPUs and CPU topology - Interrupt controller and TLMM - GCC,DISPCC and RPMHCC clock controllers - Reserved memory and interconnects - APPS and PCIe SMMU and firmware SCM - Watchdog, RPMHPD, APPS RSC and SRAM - PSCI and PMU nodes - QUPv3 serial engines - CPU power domains and idle states, plus SCMI/ SRAM pieces for CPU DVFS - PDP0 mailbox, IPCC and AOSS - Display clock controller - SPMI PMIC arbiter with SPMI0/1/2 buses - SMP2P nodes - TSENS and thermal zones (8 instances, 92 sensors) Add dtsi files for PMH0101, PMK8850, PMCX0102, SMB2370, PMH0104, PMH0110, PMIC's along with temp-alarm and GPIO nodes needed on Glymur Enabled PCIe controllers and associated PHY to support boot to shell with nvme storage, List of PCIe instances enabled: - PCIe3b - PCIe4 - PCIe5 - PCIe6 Link: https://lore.kernel.org/all/20260219-upstream_v3_glymur_introduction-v8-0-8ce4e489ebb6@oss.qualcomm.com/ Co-developed-by: Raviteja Laggyshetty Signed-off-by: Raviteja Laggyshetty Co-developed-by: Jyothi Kumar Seerapu Signed-off-by: Jyothi Kumar Seerapu Co-developed-by: Maulik Shah Signed-off-by: Maulik Shah Co-developed-by: Sibi Sankar Signed-off-by: Sibi Sankar Co-developed-by: Taniya Das Signed-off-by: Taniya Das Co-developed-by: Kamal Wadhwa Signed-off-by: Kamal Wadhwa Co-developed-by: Qiang Yu Signed-off-by: Qiang Yu Co-developed-by: Abel Vesa Signed-off-by: Abel Vesa Co-developed-by: Manaf Meethalavalappu Pallikunhi Signed-off-by: Manaf Meethalavalappu Pallikunhi Co-developed-by: Jishnu Prakash Signed-off-by: Jishnu Prakash Reviewed-by: Konrad Dybcio Signed-off-by: Pankaj Patil Reviewed-by: Dmitry Baryshkov Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 5913 ++++++++++++++++++ arch/arm64/boot/dts/qcom/pmcx0102.dtsi | 187 + arch/arm64/boot/dts/qcom/pmh0101.dtsi | 68 + arch/arm64/boot/dts/qcom/pmh0104-glymur.dtsi | 144 + arch/arm64/boot/dts/qcom/pmh0110-glymur.dtsi | 144 + arch/arm64/boot/dts/qcom/pmk8850.dtsi | 70 + arch/arm64/boot/dts/qcom/smb2370.dtsi | 45 + 7 files changed, 6571 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/glymur.dtsi create mode 100644 arch/arm64/boot/dts/qcom/pmcx0102.dtsi create mode 100644 arch/arm64/boot/dts/qcom/pmh0101.dtsi create mode 100644 arch/arm64/boot/dts/qcom/pmh0104-glymur.dtsi create mode 100644 arch/arm64/boot/dts/qcom/pmh0110-glymur.dtsi create mode 100644 arch/arm64/boot/dts/qcom/pmk8850.dtsi create mode 100644 arch/arm64/boot/dts/qcom/smb2370.dtsi diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi new file mode 100644 index 0000000000000..e269cec7942c8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -0,0 +1,5913 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "glymur-ipcc.h" + +/ { + interrupt-parent = <&intc>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x0>; + enable-method = "psci"; + power-domains = <&cpu_pd0>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + + l2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu1: cpu@100 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x100>; + enable-method = "psci"; + power-domains = <&cpu_pd1>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x200>; + enable-method = "psci"; + power-domains = <&cpu_pd2>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + }; + + cpu3: cpu@300 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x300>; + enable-method = "psci"; + power-domains = <&cpu_pd3>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + }; + + cpu4: cpu@400 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x400>; + enable-method = "psci"; + power-domains = <&cpu_pd4>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + }; + + cpu5: cpu@500 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x500>; + enable-method = "psci"; + power-domains = <&cpu_pd5>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + }; + + cpu6: cpu@10000 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10000>; + enable-method = "psci"; + power-domains = <&cpu_pd6>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_1>; + + l2_1: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu7: cpu@10100 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10100>; + enable-method = "psci"; + power-domains = <&cpu_pd7>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_1>; + }; + + cpu8: cpu@10200 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10200>; + enable-method = "psci"; + power-domains = <&cpu_pd8>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_1>; + }; + + cpu9: cpu@10300 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10300>; + enable-method = "psci"; + power-domains = <&cpu_pd9>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_1>; + }; + + cpu10: cpu@10400 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10400>; + enable-method = "psci"; + power-domains = <&cpu_pd10>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_1>; + }; + + cpu11: cpu@10500 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10500>; + enable-method = "psci"; + power-domains = <&cpu_pd11>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_1>; + }; + + cpu12: cpu@20000 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x20000>; + enable-method = "psci"; + power-domains = <&cpu_pd12>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_2>; + + l2_2: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu13: cpu@20100 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x20100>; + enable-method = "psci"; + power-domains = <&cpu_pd13>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_2>; + }; + + cpu14: cpu@20200 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x20200>; + enable-method = "psci"; + power-domains = <&cpu_pd14>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_2>; + }; + + cpu15: cpu@20300 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x20300>; + enable-method = "psci"; + power-domains = <&cpu_pd15>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_2>; + }; + + cpu16: cpu@20400 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x20400>; + enable-method = "psci"; + power-domains = <&cpu_pd16>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_2>; + }; + + cpu17: cpu@20500 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x20500>; + enable-method = "psci"; + power-domains = <&cpu_pd17>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_2>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + + core2 { + cpu = <&cpu2>; + }; + + core3 { + cpu = <&cpu3>; + }; + + core4 { + cpu = <&cpu4>; + }; + + core5 { + cpu = <&cpu5>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu6>; + }; + + core1 { + cpu = <&cpu7>; + }; + + core2 { + cpu = <&cpu8>; + }; + + core3 { + cpu = <&cpu9>; + }; + + core4 { + cpu = <&cpu10>; + }; + + core5 { + cpu = <&cpu11>; + }; + }; + + cluster2 { + core0 { + cpu = <&cpu12>; + }; + + core1 { + cpu = <&cpu13>; + }; + + core2 { + cpu = <&cpu14>; + }; + + core3 { + cpu = <&cpu15>; + }; + + core4 { + cpu = <&cpu16>; + }; + + core5 { + cpu = <&cpu17>; + }; + }; + }; + + idle-states { + entry-method = "psci"; + + cpu_c4: cpu-sleep-0 { + compatible = "arm,idle-state"; + idle-state-name = "ret"; + arm,psci-suspend-param = <0x00000004>; + entry-latency-us = <180>; + exit-latency-us = <320>; + min-residency-us = <1000>; + }; + }; + + domain-idle-states { + cluster_cl5: cluster-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x01000054>; + entry-latency-us = <2000>; + exit-latency-us = <2000>; + min-residency-us = <9000>; + }; + + domain_ss3: domain-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x0200c354>; + entry-latency-us = <2800>; + exit-latency-us = <4400>; + min-residency-us = <10150>; + }; + }; + }; + + firmware { + scm: scm { + compatible = "qcom,scm-glymur", "qcom,scm"; + qcom,dload-mode = <&tcsr 0x4000>; + interconnects = <&aggre2_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + }; + + scmi { + compatible = "arm,scmi"; + mboxes = <&pdp0_mbox 0>, <&pdp0_mbox 1>; + mbox-names = "tx", "rx"; + shmem = <&cpu_scp_lpri1>, <&cpu_scp_lpri0>; + + #address-cells = <1>; + #size-cells = <0>; + + scmi_perf: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + }; + }; + + clk_virt: interconnect-0 { + compatible = "qcom,glymur-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect-1 { + compatible = "qcom,glymur-mc-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + + cpu_pd0: power-domain-cpu0 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd1: power-domain-cpu1 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd2: power-domain-cpu2 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd3: power-domain-cpu3 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd4: power-domain-cpu4 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd5: power-domain-cpu5 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd6: power-domain-cpu6 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd7: power-domain-cpu7 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd8: power-domain-cpu8 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd9: power-domain-cpu9 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd10: power-domain-cpu10 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd11: power-domain-cpu11 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd12: power-domain-cpu12 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd13: power-domain-cpu13 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd14: power-domain-cpu14 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd15: power-domain-cpu15 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd16: power-domain-cpu16 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cpu_pd17: power-domain-cpu17 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&cpu_c4>; + }; + + cluster0_pd: power-domain-cpu-cluster0 { + #power-domain-cells = <0>; + power-domains = <&system_pd>; + domain-idle-states = <&cluster_cl5>; + }; + + cluster1_pd: power-domain-cpu-cluster1 { + #power-domain-cells = <0>; + power-domains = <&system_pd>; + domain-idle-states = <&cluster_cl5>; + }; + + cluster2_pd: power-domain-cpu-cluster2 { + #power-domain-cells = <0>; + power-domains = <&system_pd>; + domain-idle-states = <&cluster_cl5>; + }; + + system_pd: power-domain-system { + #power-domain-cells = <0>; + domain-idle-states = <&domain_ss3>; + }; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + pdp_mem: pdp@81400000 { + reg = <0x0 0x81400000 0x0 0x100000>; + no-map; + }; + + aop_cmd_db_mem: aop-cmd-db@81c60000 { + compatible = "qcom,cmd-db"; + reg = <0x0 0x81c60000 0x0 0x20000>; + no-map; + }; + + pdp_ns_shared_mem: pdp-ns-shared@81e00000 { + reg = <0x0 0x81e00000 0x0 0x200000>; + no-map; + }; + + oobdaretag_mem: oobdaretag@86e10000 { + reg = <0x0 0x86e10000 0x0 0x360000>; + no-map; + }; + + oob_secure_mem: oob-secure@87170000 { + reg = <0x0 0x87170000 0x0 0xbc0000>; + no-map; + }; + + oobdtbqc_mem: oobdtbqc@87d30000 { + reg = <0x0 0x87d30000 0x0 0x20000>; + no-map; + }; + + oobdtboem_mem: oobdtboem@87d50000 { + reg = <0x0 0x87d50000 0x0 0x20000>; + no-map; + }; + + oob_nonsecure_mem: oob-nonsecure@87e00000 { + reg = <0x0 0x87e00000 0x0 0xc00000>; + no-map; + }; + + spss_region_mem: spss@88a00000 { + reg = <0x0 0x88a00000 0x0 0x400000>; + no-map; + }; + + soccpdtb_mem: soccpdtb@892e0000 { + reg = <0x0 0x892e0000 0x0 0x20000>; + no-map; + }; + + soccp_mem: soccp@89300000 { + reg = <0x0 0x89300000 0x0 0x400000>; + no-map; + }; + + cvp_mem: cvp@89700000 { + reg = <0x0 0x89700000 0x0 0x700000>; + no-map; + }; + + adspslpi_mem: adspslpi@89e00000 { + reg = <0x0 0x89e00000 0x0 0x3a00000>; + no-map; + }; + + q6_adsp_dtb_mem: q6-adsp-dtb@8d800000 { + reg = <0x0 0x8d800000 0x0 0x80000>; + no-map; + }; + + cdsp_mem: cdsp@8d900000 { + reg = <0x0 0x8d900000 0x0 0x4000000>; + no-map; + }; + + q6_cdsp_dtb_mem: q6-cdsp-dtb@91900000 { + reg = <0x0 0x91900000 0x0 0x80000>; + no-map; + }; + + gpu_microcode_mem: gpu-microcode@919fe000 { + reg = <0x0 0x919fe000 0x0 0x2000>; + no-map; + }; + + camera_mem: camera@91a00000 { + reg = <0x0 0x91a00000 0x0 0x800000>; + no-map; + }; + + av1_encoder_mem: av1-encoder@92200000 { + reg = <0x0 0x92200000 0x0 0x700000>; + no-map; + }; + + video_mem: video@92900000 { + reg = <0x0 0x92900000 0x0 0xc00000>; + no-map; + }; + + smem_mem: smem@ffe00000 { + compatible = "qcom,smem"; + reg = <0x0 0xffe00000 0x0 0x200000>; + hwlocks = <&tcsr_mutex 3>; + no-map; + }; + }; + + smp2p-adsp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_LPASS IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <443>, <429>; + qcom,local-pid = <0>; + qcom,remote-pid = <2>; + + smp2p_adsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_adsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-cdsp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_CDSP IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <94>, <432>; + qcom,local-pid = <0>; + qcom,remote-pid = <5>; + + smp2p_cdsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_cdsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-soccp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <617>, <616>; + qcom,local-pid = <0>; + qcom,remote-pid = <19>; + + soccp_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + soccp_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + soc: soc@0 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x0 0x100 0x0>; + dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>; + + gcc: clock-controller@100000 { + compatible = "qcom,glymur-gcc"; + reg = <0x0 0x00100000 0x0 0x1f9000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, /* Board XO source */ + <&rpmhcc RPMH_CXO_CLK_A>, /* Board XO_A source */ + <&sleep_clk>, /* Sleep */ + <0>, /* USB 0 Phy DP0 GMUX */ + <0>, /* USB 0 Phy DP1 GMUX */ + <0>, /* USB 0 Phy PCIE PIPEGMUX */ + <0>, /* USB 0 Phy PIPEGMUX */ + <0>, /* USB 0 Phy SYS PCIE PIPEGMUX */ + <0>, /* USB 1 Phy DP0 GMUX 2 */ + <0>, /* USB 1 Phy DP1 GMUX 2 */ + <0>, /* USB 1 Phy PCIE PIPEGMUX */ + <0>, /* USB 1 Phy PIPEGMUX */ + <0>, /* USB 1 Phy SYS PCIE PIPEGMUX */ + <0>, /* USB 2 Phy DP0 GMUX 2 */ + <0>, /* USB 2 Phy DP1 GMUX 2 */ + <0>, /* USB 2 Phy PCIE PIPEGMUX */ + <0>, /* USB 2 Phy PIPEGMUX */ + <0>, /* USB 2 Phy SYS PCIE PIPEGMUX */ + <0>, /* PCIe 3a */ + <&pcie3b_phy>, /* PCIe 3b */ + <&pcie4_phy>, /* PCIe 4 */ + <&pcie5_phy>, /* PCIe 5 */ + <&pcie6_phy>, /* PCIe 6 */ + <0>, /* QUSB4 0 PHY RX 0 */ + <0>, /* QUSB4 0 PHY RX 1 */ + <0>, /* QUSB4 1 PHY RX 0 */ + <0>, /* QUSB4 1 PHY RX 1 */ + <0>, /* QUSB4 2 PHY RX 0 */ + <0>, /* QUSB4 2 PHY RX 1 */ + <0>, /* UFS PHY RX Symbol 0 */ + <0>, /* UFS PHY RX Symbol 1 */ + <0>, /* UFS PHY TX Symbol 0 */ + <0>, /* USB3 PHY 0 */ + <0>, /* USB3 PHY 1 */ + <0>, /* USB3 PHY 2 */ + <0>, /* USB3 UNI PHY pipe 0 */ + <0>, /* USB3 UNI PHY pipe 1 */ + <0>, /* USB4 PHY 0 pcie pipe */ + <0>, /* USB4 PHY 0 Max pipe */ + <0>, /* USB4 PHY 1 pcie pipe */ + <0>, /* USB4 PHY 1 Max pipe */ + <0>, /* USB4 PHY 2 pcie */ + <0>; /* USB4 PHY 2 Max */ + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + gpi_dma2: dma-controller@800000 { + compatible = "qcom,glymur-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00800000 0x0 0x60000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + dma-channels = <16>; + dma-channel-mask = <0x3f>; + #dma-cells = <3>; + iommus = <&apps_smmu 0xd76 0x0>; + }; + + qupv3_2: geniqup@8c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x008c0000 0x0 0x3000>; + clocks = <&gcc GCC_QUPV3_WRAP_2_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + iommus = <&apps_smmu 0xd63 0x0>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c16: i2c@880000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00880000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, + <&gpi_dma2 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c16_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi16: spi@880000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00880000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, + <&gpi_dma2 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi16_data_clk>, <&qup_spi16_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c17: i2c@884000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00884000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, + <&gpi_dma2 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c17_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi17: spi@884000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00884000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, + <&gpi_dma2 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi17_data_clk>, <&qup_spi17_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c18: i2c@888000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00888000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, + <&gpi_dma2 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c18_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi18: spi@888000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00888000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, + <&gpi_dma2 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi18_data_clk>, <&qup_spi18_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c19: i2c@88c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0088c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, + <&gpi_dma2 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c19_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi19: spi@88c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0088c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, + <&gpi_dma2 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi19_data_clk>, <&qup_spi19_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart19: serial@88c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x0088c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart19_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c20: i2c@890000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00890000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, + <&gpi_dma2 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c20_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi20: spi@890000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00890000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>, + <&gpi_dma2 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi20_data_clk>, <&qup_spi20_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c21: i2c@894000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00894000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>, + <&gpi_dma2 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c21_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi21: spi@894000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00894000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>, + <&gpi_dma2 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi21_data_clk>, <&qup_spi21_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart21: serial@894000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x00894000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart21_default>; + pinctrl-names = "default"; + }; + + i2c22: i2c@898000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00898000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 6 QCOM_GPI_I2C>, + <&gpi_dma2 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c22_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi22: spi@898000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00898000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>, + <&gpi_dma2 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi22_data_clk>, <&qup_spi22_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart22: serial@898000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00898000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart22_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c23: i2c@89c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0089c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S7_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 7 QCOM_GPI_I2C>, + <&gpi_dma2 1 7 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c23_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi23: spi@89c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0089c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP2_S7_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma2 0 7 QCOM_GPI_SPI>, + <&gpi_dma2 1 7 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi23_data_clk>, <&qup_spi23_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + gpi_dma1: dma-controller@a00000 { + compatible = "qcom,glymur-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00a00000 0x0 0x60000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + dma-channels = <16>; + dma-channel-mask = <0x3f>; + #dma-cells = <3>; + iommus = <&apps_smmu 0xcb6 0x0>; + }; + + qupv3_1: geniqup@ac0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x00ac0000 0x0 0x3000>; + clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + iommus = <&apps_smmu 0xca3 0x0>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c8: i2c@a80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a80000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, + <&gpi_dma1 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c8_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi8: spi@a80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a80000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, + <&gpi_dma1 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c9: i2c@a84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a84000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, + <&gpi_dma1 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c9_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi9: spi@a84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a84000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, + <&gpi_dma1 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c10: i2c@a88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, + <&gpi_dma1 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c10_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi10: spi@a88000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, + <&gpi_dma1 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c11: i2c@a8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, + <&gpi_dma1 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c11_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi11: spi@a8c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, + <&gpi_dma1 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi11_data_clk>, <&qup_spi11_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c12: i2c@a90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a90000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, + <&gpi_dma1 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c12_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi12: spi@a90000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a90000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, + <&gpi_dma1 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi12_data_clk>, <&qup_spi12_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c13: i2c@a94000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a94000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, + <&gpi_dma1 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c13_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi13: spi@a94000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a94000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, + <&gpi_dma1 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi13_data_clk>, <&qup_spi13_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c14: i2c@a98000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a98000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, + <&gpi_dma1 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c14_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi14: spi@a98000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a98000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, + <&gpi_dma1 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi14_data_clk>, <&qup_spi14_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart14: serial@a98000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a98000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart14_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c15: i2c@a9c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a9c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>, + <&gpi_dma1 1 7 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c15_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi15: spi@a9c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a9c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma1 0 7 QCOM_GPI_SPI>, + <&gpi_dma1 1 7 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi15_data_clk>, <&qup_spi15_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + gpi_dma0: dma-controller@b00000 { + compatible = "qcom,glymur-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00b00000 0x0 0x60000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + dma-channels = <16>; + dma-channel-mask = <0x3f>; + #dma-cells = <3>; + iommus = <&apps_smmu 0xd36 0x0>; + }; + + qupv3_0: geniqup@bc0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x00bc0000 0x0 0x3000>; + clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + iommus = <&apps_smmu 0xd23 0x0>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c0: i2c@b80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b80000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>, + <&gpi_dma0 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c0_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi0: spi@b80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b80000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>, + <&gpi_dma0 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c1: i2c@b84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b84000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>, + <&gpi_dma0 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c1_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi1: spi@b84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b84000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>, + <&gpi_dma0 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi1_data_clk>, <&qup_spi1_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c2: i2c@b88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>, + <&gpi_dma0 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c2_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi2: spi@b88000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>, + <&gpi_dma0 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart2: serial@b88000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00b88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart2_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c3: i2c@b8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b8c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>, + <&gpi_dma0 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c3_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi3: spi@b8c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b8c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>, + <&gpi_dma0 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c4: i2c@b90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b90000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>, + <&gpi_dma0 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c4_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi4: spi@b90000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b90000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>, + <&gpi_dma0 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c5: i2c@b94000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b94000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>, + <&gpi_dma0 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c5_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi5: spi@b94000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b94000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>, + <&gpi_dma0 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi5_data_clk>, <&qup_spi5_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c6: i2c@b98000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b98000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>, + <&gpi_dma0 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c6_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi6: spi@b98000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b98000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>, + <&gpi_dma0 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c7: i2c@b9c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00b9c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>, + <&gpi_dma0 1 7 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_i2c7_data_clk>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi7: spi@b9c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00b9c000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre3_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + dmas = <&gpi_dma0 0 7 QCOM_GPI_SPI>, + <&gpi_dma0 1 7 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&qup_spi7_data_clk>, <&qup_spi7_cs>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + cnoc_main: interconnect@1500000 { + compatible = "qcom,glymur-cnoc-main"; + reg = <0x0 0x01500000 0x0 0x17080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + config_noc: interconnect@1600000 { + compatible = "qcom,glymur-cnoc-cfg"; + reg = <0x0 0x01600000 0x0 0x6600>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + system_noc: interconnect@1680000 { + compatible = "qcom,glymur-system-noc"; + reg = <0x0 0x01680000 0x0 0x1c080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + pcie_west_anoc: interconnect@16c0000 { + compatible = "qcom,glymur-pcie-west-anoc"; + reg = <0x0 0x016c0000 0x0 0xf580>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_NOC_PCIE_3A_WEST_SF_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_3B_WEST_SF_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_4_WEST_SF_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_6_WEST_SF_AXI_CLK>; + }; + + pcie_east_anoc: interconnect@16d0000 { + compatible = "qcom,glymur-pcie-east-anoc"; + reg = <0x0 0x016d0000 0x0 0xf300>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_NOC_PCIE_5_EAST_SF_AXI_CLK>; + }; + + aggre1_noc: interconnect@16e0000 { + compatible = "qcom,glymur-aggre1-noc"; + reg = <0x0 0x016e0000 0x0 0x14400>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + aggre2_noc: interconnect@1720000 { + compatible = "qcom,glymur-aggre2-noc"; + reg = <0x0 0x01720000 0x0 0x14400>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_USB3_TERT_AXI_CLK>, + <&gcc GCC_AGGRE_USB4_2_AXI_CLK>, + <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>; + }; + + aggre3_noc: interconnect@1700000 { + compatible = "qcom,glymur-aggre3-noc"; + reg = <0x0 0x01700000 0x0 0x1d400>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + aggre4_noc: interconnect@1740000 { + compatible = "qcom,glymur-aggre4-noc"; + reg = <0x0 0x01740000 0x0 0x14400>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&gcc GCC_AGGRE_USB4_0_AXI_CLK>, + <&gcc GCC_AGGRE_USB4_1_AXI_CLK>; + }; + + mmss_noc: interconnect@1780000 { + compatible = "qcom,glymur-mmss-noc"; + reg = <0x0 0x01780000 0x0 0x5b800>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + pcie_east_slv_noc: interconnect@1900000 { + compatible = "qcom,glymur-pcie-east-slv-noc"; + reg = <0x0 0x01900000 0x0 0xe080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + pcie_west_slv_noc: interconnect@1920000 { + compatible = "qcom,glymur-pcie-west-slv-noc"; + reg = <0x0 0x01920000 0x0 0xf180>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + pcie4: pci@1bf0000 { + device_type = "pci"; + compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100"; + reg = <0x0 0x01bf0000 0x0 0x3000>, + <0x0 0x78000000 0x0 0xf20>, + <0x0 0x78000f40 0x0 0xa8>, + <0x0 0x78001000 0x0 0x4000>, + <0x0 0x78005000 0x0 0x100000>, + <0x0 0x01bf3000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x78105000 0x0 0x100000>, + <0x02000000 0x0 0x78205000 0x0 0x78205000 0x0 0x1dfb000>, + <0x03000000 0x7 0x80000000 0x7 0x80000000 0x0 0x20000000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <4>; + num-lanes = <2>; + + operating-points-v2 = <&pcie4_opp_table>; + + msi-map = <0x0 &gic_its 0xc0000 0x10000>; + iommu-map = <0x0 &pcie_smmu 0x40000 0x10000>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 513 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 514 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 515 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 516 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_4_AUX_CLK>, + <&gcc GCC_PCIE_4_CFG_AHB_CLK>, + <&gcc GCC_PCIE_4_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_4_SLV_AXI_CLK>, + <&gcc GCC_PCIE_4_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_4_WEST_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr"; + + assigned-clocks = <&gcc GCC_PCIE_4_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_west_anoc MASTER_PCIE_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &pcie_west_slv_noc SLAVE_PCIE_4 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + resets = <&gcc GCC_PCIE_4_BCR>, + <&gcc GCC_PCIE_4_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_4_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55>; + + status = "disabled"; + + pcie4_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + }; + + pcie4_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie4_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie4_phy: phy@1bf6000 { + compatible = "qcom,glymur-qmp-gen4x2-pcie-phy"; + reg = <0x0 0x01bf6000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_PHY_4_AUX_CLK>, + <&gcc GCC_PCIE_4_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_2_CLKREF_EN>, + <&gcc GCC_PCIE_4_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_4_PIPE_CLK>, + <&gcc GCC_PCIE_4_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + resets = <&gcc GCC_PCIE_4_PHY_BCR>, + <&gcc GCC_PCIE_4_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + assigned-clocks = <&gcc GCC_PCIE_4_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + power-domains = <&gcc GCC_PCIE_4_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie4_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie5: pci@1b40000 { + device_type = "pci"; + compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100"; + reg = <0x0 0x01b40000 0x0 0x3000>, + <0x0 0x7a000000 0x0 0xf20>, + <0x0 0x7a000f40 0x0 0xa8>, + <0x0 0x7a001000 0x0 0x4000>, + <0x0 0x7a100000 0x0 0x100000>, + <0x0 0x01b43000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x7a200000 0x0 0x100000>, + <0x02000000 0x0 0x7a300000 0x0 0x7a300000 0x0 0x3d00000>, + <0x03000000 0x7 0xa0000000 0x7 0xa0000000 0x0 0x40000000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <5>; + num-lanes = <4>; + + operating-points-v2 = <&pcie5_opp_table>; + + msi-map = <0x0 &gic_its 0xd0000 0x10000>; + iommu-map = <0x0 &pcie_smmu 0x50000 0x10000>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 526 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 428 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 429 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 435 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_5_AUX_CLK>, + <&gcc GCC_PCIE_5_CFG_AHB_CLK>, + <&gcc GCC_PCIE_5_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_5_SLV_AXI_CLK>, + <&gcc GCC_PCIE_5_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_5_EAST_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr"; + + assigned-clocks = <&gcc GCC_PCIE_5_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_east_anoc MASTER_PCIE_5 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &pcie_east_slv_noc SLAVE_PCIE_5 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + resets = <&gcc GCC_PCIE_5_BCR>, + <&gcc GCC_PCIE_5_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_5_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>; + eq-presets-32gts = /bits/ 8 <0x55 0x55 0x55 0x55>; + + status = "disabled"; + + pcie5_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 1 x4 */ + opp-10000000-1 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 3 x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 4 x4 */ + opp-64000000-4 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + + /* GEN 5 x4 */ + opp-128000000-5 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <15753000 1>; + opp-level = <5>; + }; + }; + + pcie5_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie5_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie5_phy: phy@1b50000 { + compatible = "qcom,glymur-qmp-gen5x4-pcie-phy"; + reg = <0x0 0x01b50000 0x0 0x10000>; + + clocks = <&gcc GCC_PCIE_PHY_5_AUX_CLK>, + <&gcc GCC_PCIE_5_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_1_CLKREF_EN>, + <&gcc GCC_PCIE_5_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_5_PIPE_CLK>, + <&gcc GCC_PCIE_5_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + resets = <&gcc GCC_PCIE_5_PHY_BCR>, + <&gcc GCC_PCIE_5_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + assigned-clocks = <&gcc GCC_PCIE_5_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + power-domains = <&gcc GCC_PCIE_5_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie5_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie6: pci@1c00000 { + device_type = "pci"; + compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100"; + reg = <0x0 0x01c00000 0x0 0x3000>, + <0x0 0x7e000000 0x0 0xf20>, + <0x0 0x7e000f40 0x0 0xa8>, + <0x0 0x7e001000 0x0 0x4000>, + <0x0 0x7e100000 0x0 0x100000>, + <0x0 0x01c03000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x7e200000 0x0 0x100000>, + <0x02000000 0x0 0x7e300000 0x0 0x7e300000 0x0 0x1d00000>, + <0x03000000 0x7 0xe0000000 0x7 0xe0000000 0x0 0x20000000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <6>; + num-lanes = <2>; + + operating-points-v2 = <&pcie6_opp_table>; + + msi-map = <0x0 &gic_its 0xe0000 0x10000>; + iommu-map = <0x0 &pcie_smmu 0x60000 0x10000>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 472 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 473 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 474 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 475 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_6_AUX_CLK>, + <&gcc GCC_PCIE_6_CFG_AHB_CLK>, + <&gcc GCC_PCIE_6_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_6_SLV_AXI_CLK>, + <&gcc GCC_PCIE_6_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_6_WEST_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr"; + + assigned-clocks = <&gcc GCC_PCIE_6_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_west_anoc MASTER_PCIE_6 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &pcie_west_slv_noc SLAVE_PCIE_6 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + resets = <&gcc GCC_PCIE_6_BCR>, + <&gcc GCC_PCIE_6_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_6_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55>; + + status = "disabled"; + + pcie6_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + }; + + pcie6_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie6_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie6_phy: phy@1c06000 { + compatible = "qcom,glymur-qmp-gen4x2-pcie-phy"; + reg = <0x0 0x01c06000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_PHY_6_AUX_CLK>, + <&gcc GCC_PCIE_6_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_4_CLKREF_EN>, + <&gcc GCC_PCIE_6_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_6_PIPE_CLK>, + <&gcc GCC_PCIE_6_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + resets = <&gcc GCC_PCIE_6_PHY_BCR>, + <&gcc GCC_PCIE_6_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + assigned-clocks = <&gcc GCC_PCIE_6_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + power-domains = <&gcc GCC_PCIE_6_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie6_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie3b: pci@1b80000 { + device_type = "pci"; + compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100"; + reg = <0x0 0x01b80000 0x0 0x3000>, + <0x0 0x74000000 0x0 0xf20>, + <0x0 0x74000f40 0x0 0xa8>, + <0x0 0x74001000 0x0 0x4000>, + <0x0 0x74100000 0x0 0x100000>, + <0x0 0x01b83000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x74200000 0x0 0x100000>, + <0x02000000 0x0 0x74300000 0x0 0x74300000 0x0 0x3d00000>, + <0x03000000 0x7 0x40000000 0x7 0x40000000 0x0 0x40000000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <7>; + num-lanes = <4>; + + operating-points-v2 = <&pcie3b_opp_table>; + + msi-map = <0x0 &gic_its 0xf0000 0x10000>; + iommu-map = <0x0 &pcie_smmu 0x70000 0x10000>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 831 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 832 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 833 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 834 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_3B_AUX_CLK>, + <&gcc GCC_PCIE_3B_CFG_AHB_CLK>, + <&gcc GCC_PCIE_3B_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_3B_SLV_AXI_CLK>, + <&gcc GCC_PCIE_3B_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_3B_WEST_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr"; + + assigned-clocks = <&gcc GCC_PCIE_3B_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_west_anoc MASTER_PCIE_3B QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &pcie_west_slv_noc SLAVE_PCIE_3B QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + resets = <&gcc GCC_PCIE_3B_BCR>, + <&gcc GCC_PCIE_3B_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_3B_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>; + eq-presets-32gts = /bits/ 8 <0x55 0x55 0x55 0x55>; + + status = "disabled"; + + pcie3b_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 1 x4 */ + opp-10000000-1 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 3 x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 4 x4 */ + opp-64000000-4 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + + /* GEN 5 x4 */ + opp-128000000-5 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <15753000 1>; + opp-level = <5>; + }; + }; + + pcie3b_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie3b_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie3b_phy: phy@f10000 { + compatible = "qcom,glymur-qmp-gen5x4-pcie-phy"; + reg = <0x0 0x00f10000 0x0 0x10000>; + + clocks = <&gcc GCC_PCIE_PHY_3B_AUX_CLK>, + <&gcc GCC_PCIE_3B_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_3_CLKREF_EN>, + <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3B_PIPE_CLK>, + <&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + resets = <&gcc GCC_PCIE_3B_PHY_BCR>, + <&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + assigned-clocks = <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + power-domains = <&gcc GCC_PCIE_3B_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie3b_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + tcsr_mutex: hwlock@1f40000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x0 0x01f40000 0x0 0x20000>; + + #hwlock-cells = <1>; + }; + + tcsr: clock-controller@1fd5000 { + compatible = "qcom,glymur-tcsr", + "syscon"; + reg = <0x0 0x1fd5000 0x0 0x21000>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + hsc_noc: interconnect@2000000 { + compatible = "qcom,glymur-hscnoc"; + reg = <0x0 0x02000000 0x0 0x93a080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + ipcc: mailbox@3e04000 { + compatible = "qcom,glymur-ipcc", "qcom,ipcc"; + reg = <0x0 0x03e04000 0x0 0x1000>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <3>; + + #mbox-cells = <2>; + }; + + lpass_lpiaon_noc: interconnect@7400000 { + compatible = "qcom,glymur-lpass-lpiaon-noc"; + reg = <0x0 0x07400000 0x0 0x19080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + lpass_lpicx_noc: interconnect@7420000 { + compatible = "qcom,glymur-lpass-lpicx-noc"; + reg = <0x0 0x07420000 0x0 0x44080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + lpass_ag_noc: interconnect@7e40000 { + compatible = "qcom,glymur-lpass-ag-noc"; + reg = <0x0 0x07e40000 0x0 0xe080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + dispcc: clock-controller@af00000 { + compatible = "qcom,glymur-dispcc"; + reg = <0x0 0x0af00000 0x0 0x20000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&sleep_clk>, + <0>, /* dp0 */ + <0>, + <0>, /* dp1 */ + <0>, + <0>, /* dp2 */ + <0>, + <0>, /* dp3 */ + <0>, + <0>, /* dsi0 */ + <0>, + <0>, /* dsi1 */ + <0>, + <0>, + <0>, + <0>, + <0>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + pdc: interrupt-controller@b220000 { + compatible = "qcom,glymur-pdc", "qcom,pdc"; + reg = <0x0 0x0b220000 0x0 0x10000>; + qcom,pdc-ranges = <0 745 51>, + <51 527 47>, + <98 609 32>, + <130 717 12>, + <142 251 5>, + <147 796 16>, + <171 4104 36>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; + }; + + tsens0: thermal-sensor@c22c000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22c000 0x0 0x1000>, + <0x0 0x0c222000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <13>; + + #thermal-sensor-cells = <1>; + }; + + tsens1: thermal-sensor@c22d000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22d000 0x0 0x1000>, + <0x0 0x0c223000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <9>; + + #thermal-sensor-cells = <1>; + }; + + tsens2: thermal-sensor@c22e000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22e000 0x0 0x1000>, + <0x0 0x0c224000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <13>; + + #thermal-sensor-cells = <1>; + }; + + tsens3: thermal-sensor@c22f000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22f000 0x0 0x1000>, + <0x0 0x0c225000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <8>; + + #thermal-sensor-cells = <1>; + }; + + tsens4: thermal-sensor@c230000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c230000 0x0 0x1000>, + <0x0 0x0c226000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <13>; + + #thermal-sensor-cells = <1>; + }; + + tsens5: thermal-sensor@c231000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c231000 0x0 0x1000>, + <0x0 0x0c227000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <8>; + + #thermal-sensor-cells = <1>; + }; + + tsens6: thermal-sensor@c232000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c232000 0x0 0x1000>, + <0x0 0x0c228000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <13>; + + #thermal-sensor-cells = <1>; + }; + + tsens7: thermal-sensor@c233000 { + compatible = "qcom,glymur-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c233000 0x0 0x1000>, + <0x0 0x0c229000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "uplow", + "critical"; + + #qcom,sensors = <15>; + + #thermal-sensor-cells = <1>; + }; + + aoss_qmp: power-management@c300000 { + compatible = "qcom,glymur-aoss-qmp", "qcom,aoss-qmp"; + reg = <0x0 0x0c300000 0x0 0x400>; + interrupt-parent = <&ipcc>; + interrupts-extended = <&ipcc IPCC_MPROC_AOP IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_MPROC_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>; + + #clock-cells = <0>; + }; + + sram@c30f000 { + compatible = "qcom,rpmh-stats"; + reg = <0x0 0x0c30f000 0x0 0x400>; + }; + + arbiter@c400000 { + compatible = "qcom,glymur-spmi-pmic-arb"; + reg = <0x0 0x0c400000 0x0 0x3000>, + <0x0 0x0c900000 0x0 0x400000>, + <0x0 0x0c4c0000 0x0 0x400000>, + <0x0 0x0c403000 0x0 0x8000>; + reg-names = "core", + "chnls", + "obsrvr", + "chnl_map"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + qcom,channel = <0>; + qcom,ee = <0>; + + spmi_bus0: spmi@c426000 { + reg = <0x0 0x0c426000 0x0 0x4000>, + <0x0 0x0c8c0000 0x0 0x10000>, + <0x0 0x0c42a000 0x0 0x8000>; + reg-names = "cnfg", + "intr", + "chnl_owner"; + interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + #address-cells = <2>; + #size-cells = <0>; + }; + + spmi_bus1: spmi@c437000 { + reg = <0x0 0x0c437000 0x0 0x4000>, + <0x0 0x0c8d0000 0x0 0x10000>, + <0x0 0x0c43b000 0x0 0x8000>; + reg-names = "cnfg", + "intr", + "chnl_owner"; + interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + #address-cells = <2>; + #size-cells = <0>; + }; + + spmi_bus2: spmi@c48000 { + reg = <0x0 0x0c448000 0x0 0x4000>, + <0x0 0x0c8e0000 0x0 0x10000>, + <0x0 0x0c44c000 0x0 0x8000>; + reg-names = "cnfg", + "intr", + "chnl_owner"; + interrupts-extended = <&pdc 72 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + #address-cells = <2>; + #size-cells = <0>; + }; + }; + + tlmm: pinctrl@f100000 { + compatible = "qcom,glymur-tlmm"; + reg = <0x0 0x0f100000 0x0 0xf00000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 249>; + wakeup-parent = <&pdc>; + + qup_i2c0_data_clk: qup-i2c0-data-clk-state { + /* SDA, SCL */ + pins = "gpio0", "gpio1"; + function = "qup0_se0"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c1_data_clk: qup-i2c1-data-clk-state { + /* SDA, SCL */ + pins = "gpio4", "gpio5"; + function = "qup0_se1"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c2_data_clk: qup-i2c2-data-clk-state { + /* SDA, SCL */ + pins = "gpio8", "gpio9"; + function = "qup0_se2"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c3_data_clk: qup-i2c3-data-clk-state { + /* SDA, SCL */ + pins = "gpio12", "gpio13"; + function = "qup0_se3"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c4_data_clk: qup-i2c4-data-clk-state { + /* SDA, SCL */ + pins = "gpio16", "gpio17"; + function = "qup0_se4"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c5_data_clk: qup-i2c5-data-clk-state { + /* SDA, SCL */ + pins = "gpio20", "gpio21"; + function = "qup0_se5"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c6_data_clk: qup-i2c6-data-clk-state { + /* SDA, SCL */ + pins = "gpio6", "gpio7"; + function = "qup0_se6"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c7_data_clk: qup-i2c7-data-clk-state { + /* SDA, SCL */ + pins = "gpio14", "gpio15"; + function = "qup0_se7"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c8_data_clk: qup-i2c8-data-clk-state { + /* SDA, SCL */ + pins = "gpio32", "gpio33"; + function = "qup1_se0"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c9_data_clk: qup-i2c9-data-clk-state { + /* SDA, SCL */ + pins = "gpio36", "gpio37"; + function = "qup1_se1"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c10_data_clk: qup-i2c10-data-clk-state { + /* SDA, SCL */ + pins = "gpio40", "gpio41"; + function = "qup1_se2"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c11_data_clk: qup-i2c11-data-clk-state { + /* SDA, SCL */ + pins = "gpio44", "gpio45"; + function = "qup1_se3"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c12_data_clk: qup-i2c12-data-clk-state { + /* SDA, SCL */ + pins = "gpio48", "gpio49"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c13_data_clk: qup-i2c13-data-clk-state { + /* SDA, SCL */ + pins = "gpio52", "gpio53"; + function = "qup1_se5"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c14_data_clk: qup-i2c14-data-clk-state { + /* SDA, SCL */ + pins = "gpio56", "gpio57"; + function = "qup1_se6"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c15_data_clk: qup-i2c15-data-clk-state { + /* SDA, SCL */ + pins = "gpio54", "gpio55"; + function = "qup1_se7"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c16_data_clk: qup-i2c16-data-clk-state { + /* SDA, SCL */ + pins = "gpio64", "gpio65"; + function = "qup2_se0"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c17_data_clk: qup-i2c17-data-clk-state { + /* SDA, SCL */ + pins = "gpio68", "gpio69"; + function = "qup2_se1"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c18_data_clk: qup-i2c18-data-clk-state { + /* SDA, SCL */ + pins = "gpio72", "gpio73"; + function = "qup2_se2"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c19_data_clk: qup-i2c19-data-clk-state { + /* SDA, SCL */ + pins = "gpio76", "gpio77"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c20_data_clk: qup-i2c20-data-clk-state { + /* SDA, SCL */ + pins = "gpio80", "gpio81"; + function = "qup2_se4"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c21_data_clk: qup-i2c21-data-clk-state { + /* SDA, SCL */ + pins = "gpio84", "gpio85"; + function = "qup2_se5"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c22_data_clk: qup-i2c22-data-clk-state { + /* SDA, SCL */ + pins = "gpio88", "gpio89"; + function = "qup2_se6"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_i2c23_data_clk: qup-i2c23-data-clk-state { + /* SDA, SCL */ + pins = "gpio80", "gpio81"; + function = "qup2_se7"; + drive-strength = <2>; + bias-pull-up = <2200>; + }; + + qup_spi0_cs: qup-spi0-cs-state { + pins = "gpio3"; + function = "qup0_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi0_data_clk: qup-spi0-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio0", "gpio1", "gpio2"; + function = "qup0_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi1_cs: qup-spi1-cs-state { + pins = "gpio7"; + function = "qup0_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi1_data_clk: qup-spi1-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio4", "gpio5", "gpio6"; + function = "qup0_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi2_cs: qup-spi2-cs-state { + pins = "gpio11"; + function = "qup0_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi2_data_clk: qup-spi2-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio8", "gpio9", "gpio10"; + function = "qup0_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi3_cs: qup-spi3-cs-state { + pins = "gpio15"; + function = "qup0_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi3_data_clk: qup-spi3-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio12", "gpio13", "gpio14"; + function = "qup0_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi4_cs: qup-spi4-cs-state { + pins = "gpio19"; + function = "qup0_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi4_data_clk: qup-spi4-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio16", "gpio17", "gpio18"; + function = "qup0_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi5_cs: qup-spi5-cs-state { + pins = "gpio23"; + function = "qup0_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi5_data_clk: qup-spi5-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio20", "gpio21", "gpio22"; + function = "qup0_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi6_cs: qup-spi6-cs-state { + pins = "gpio5"; + function = "qup0_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi6_data_clk: qup-spi6-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio6", "gpio7", "gpio4"; + function = "qup0_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi7_cs: qup-spi7-cs-state { + pins = "gpio13"; + function = "qup0_se7"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi7_data_clk: qup-spi7-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio14", "gpio15", "gpio12"; + function = "qup0_se7"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi8_cs: qup-spi8-cs-state { + pins = "gpio35"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi8_data_clk: qup-spi8-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio32", "gpio33", "gpio34"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi9_cs: qup-spi9-cs-state { + pins = "gpio39"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi9_data_clk: qup-spi9-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio36", "gpio37", "gpio38"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi10_cs: qup-spi10-cs-state { + pins = "gpio43"; + function = "qup1_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi10_data_clk: qup-spi10-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio40", "gpio41", "gpio42"; + function = "qup1_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi11_cs: qup-spi11-cs-state { + pins = "gpio47"; + function = "qup1_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi11_data_clk: qup-spi11-data-clk-state { + pins = "gpio44", "gpio45", "gpio46"; + function = "qup1_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi12_cs: qup-spi12-cs-state { + pins = "gpio51"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi12_data_clk: qup-spi12-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio48", "gpio49", "gpio50"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi13_cs: qup-spi13-cs-state { + pins = "gpio55"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi13_data_clk: qup-spi13-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio52", "gpio53", "gpio54"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi14_cs: qup-spi14-cs-state { + pins = "gpio59"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi14_data_clk: qup-spi14-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio56", "gpio57", "gpio58"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi15_cs: qup-spi15-cs-state { + pins = "gpio53"; + function = "qup1_se7"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi15_data_clk: qup-spi15-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio54", "gpio55", "gpio52"; + function = "qup1_se7"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi16_cs: qup-spi16-cs-state { + pins = "gpio67"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi16_data_clk: qup-spi16-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio64", "gpio65", "gpio66"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi17_cs: qup-spi17-cs-state { + pins = "gpio71"; + function = "qup2_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi17_data_clk: qup-spi17-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio68", "gpio69", "gpio70"; + function = "qup2_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi18_cs: qup-spi18-cs-state { + pins = "gpio75"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi18_data_clk: qup-spi18-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio72", "gpio73", "gpio74"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi19_cs: qup-spi19-cs-state { + pins = "gpio79"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi19_data_clk: qup-spi19-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio76", "gpio77", "gpio78"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi20_cs: qup-spi20-cs-state { + pins = "gpio83"; + function = "qup2_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi20_data_clk: qup-spi20-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio80", "gpio81", "gpio82"; + function = "qup2_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi21_cs: qup-spi21-cs-state { + pins = "gpio87"; + function = "qup2_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi21_data_clk: qup-spi21-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio84", "gpio85", "gpio86"; + function = "qup2_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi22_cs: qup-spi22-cs-state { + pins = "gpio91"; + function = "qup2_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi22_data_clk: qup-spi22-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio88", "gpio89", "gpio90"; + function = "qup2_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi23_cs: qup-spi23-cs-state { + pins = "gpio83"; + function = "qup2_se7"; + drive-strength = <6>; + bias-disable; + }; + + qup_spi23_data_clk: qup-spi23-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio80", "gpio81", "gpio82"; + function = "qup2_se7"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart2_default: qup-uart2-default-state { + tx-pins { + pins = "gpio10"; + function = "qup0_se2"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio11"; + function = "qup0_se2"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart14_default: qup-uart14-default-state { + cts-pins { + pins = "gpio56"; + function = "qup1_se6"; + drive-strength = <2>; + bias-disable; + }; + + rts-pins { + pins = "gpio57"; + function = "qup1_se6"; + drive-strength = <2>; + bias-disable; + }; + + tx-pins { + pins = "gpio58"; + function = "qup1_se6"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio59"; + function = "qup1_se6"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart19_default: qup-uart19-default-state { + cts-pins { + pins = "gpio76"; + function = "qup2_se3"; + drive-strength = <2>; + bias-disable; + }; + + rts-pins { + pins = "gpio77"; + function = "qup2_se3"; + drive-strength = <2>; + bias-disable; + }; + + tx-pins { + pins = "gpio78"; + function = "qup2_se3"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio79"; + function = "qup2_se3"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart21_default: qup-uart21-default-state { + tx-pins { + pins = "gpio86"; + function = "qup2_se5"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio87"; + function = "qup2_se5"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart22_default: qup-uart22-default-state { + tx-pins { + pins = "gpio90"; + function = "qup2_se6"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio91"; + function = "qup2_se6"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + apps_smmu: iommu@15000000 { + compatible = "qcom,glymur-smmu-500", + "qcom,smmu-500", + "arm,mmu-500"; + reg = <0x0 0x15000000 0x0 0x100000>; + + #iommu-cells = <2>; + #global-interrupts = <1>; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + + dma-coherent; + }; + + pcie_smmu: iommu@15480000 { + compatible = "arm,smmu-v3"; + reg = <0x0 0x15480000 0x0 0x20000>; + interrupts = , + , + ; + interrupt-names = "eventq", "cmdq-sync", "gerror"; + dma-coherent; + #iommu-cells = <1>; + }; + + intc: interrupt-controller@17000000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x17000000 0x0 0x10000>, + <0x0 0x17080000 0x0 0x480000>; + + interrupts = ; + + #interrupt-cells = <3>; + interrupt-controller; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic_its: msi-controller@17040000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x17040000 0x0 0x40000>; + + msi-controller; + #msi-cells = <1>; + }; + }; + + watchdog@17600000 { + compatible = "qcom,apss-wdt-glymur", "qcom,kpss-wdt"; + reg = <0x0 0x17600000 0x0 0x1000>; + clocks = <&sleep_clk>; + interrupts = ; + }; + + pdp0_mbox: mailbox@17610000 { + compatible = "qcom,glymur-cpucp-mbox", "qcom,x1e80100-cpucp-mbox"; + reg = <0x0 0x17610000 0 0x8000>, <0 0x19980000 0 0x8000>; + interrupts = ; + #mbox-cells = <1>; + }; + + timer@17810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x17810000 0x0 0x1000>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x0 0x20000000>; + + frame@17811000 { + reg = <0x0 0x17811000 0x1000>, + <0x0 0x17812000 0x1000>; + + interrupts = , + ; + + frame-number = <0>; + }; + + frame@17813000 { + reg = <0x0 0x17813000 0x1000>; + + interrupts = ; + + frame-number = <1>; + + status = "disabled"; + }; + + frame@17815000 { + reg = <0x0 0x17815000 0x1000>; + + interrupts = ; + + frame-number = <2>; + + status = "disabled"; + }; + + frame@17817000 { + reg = <0x0 0x17817000 0x1000>; + + interrupts = ; + + frame-number = <3>; + + status = "disabled"; + }; + + frame@17819000 { + reg = <0x0 0x17819000 0x1000>; + + interrupts = ; + + frame-number = <4>; + + status = "disabled"; + }; + + frame@1781b000 { + reg = <0x0 0x1781b000 0x1000>; + + interrupts = ; + + frame-number = <5>; + + status = "disabled"; + }; + + frame@1781d000 { + reg = <0x0 0x1781d000 0x1000>; + + interrupts = ; + + frame-number = <6>; + + status = "disabled"; + }; + }; + + apps_rsc: rsc@18900000 { + compatible = "qcom,rpmh-rsc"; + label = "apps_rsc"; + reg = <0x0 0x18900000 0x0 0x10000>, + <0x0 0x18910000 0x0 0x10000>, + <0x0 0x18920000 0x0 0x10000>; + reg-names = "drv-0", + "drv-1", + "drv-2"; + interrupts = , + , + ; + qcom,tcs-offset = <0xd00>; + qcom,drv-id = <2>; + qcom,tcs-config = , + , + , + ; + power-domains = <&system_pd>; + + apps_bcm_voter: bcm-voter { + compatible = "qcom,bcm-voter"; + }; + + rpmhcc: clock-controller { + compatible = "qcom,glymur-rpmh-clk"; + + clocks = <&xo_board>; + clock-names = "xo"; + + #clock-cells = <1>; + }; + + rpmhpd: power-controller { + compatible = "qcom,glymur-rpmhpd"; + + operating-points-v2 = <&rpmhpd_opp_table>; + + #power-domain-cells = <1>; + + rpmhpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmhpd_opp_ret: opp-16 { + opp-level = ; + }; + + rpmhpd_opp_min_svs: opp-48 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_d2: opp-52 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_d1: opp-56 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_d0: opp-60 { + opp-level = ; + }; + + rpmhpd_opp_low_svs: opp-64 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_l1: opp-80 { + opp-level = ; + }; + + rpmhpd_opp_svs: opp-128 { + opp-level = ; + }; + + rpmhpd_opp_svs_l0: opp-144 { + opp-level = ; + }; + + rpmhpd_opp_svs_l1: opp-192 { + opp-level = ; + }; + + rpmhpd_opp_nom: opp-256 { + opp-level = ; + }; + + rpmhpd_opp_nom_l1: opp-320 { + opp-level = ; + }; + + rpmhpd_opp_nom_l2: opp-336 { + opp-level = ; + }; + + rpmhpd_opp_turbo: opp-384 { + opp-level = ; + }; + + rpmhpd_opp_turbo_l1: opp-416 { + opp-level = ; + }; + }; + }; + }; + + nsi_noc: interconnect@1d600000 { + compatible = "qcom,glymur-nsinoc"; + reg = <0x0 0x1d600000 0x0 0x14080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + oobm_ss_noc: interconnect@1f300000 { + compatible = "qcom,glymur-oobm-ss-noc"; + reg = <0x0 0x1f300000 0x0 0x49a00>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + system-cache-controller@20400000 { + compatible = "qcom,glymur-llcc"; + reg = <0x0 0x21800000 0x0 0x100000>, + <0x0 0x21a00000 0x0 0x100000>, + <0x0 0x21c00000 0x0 0x100000>, + <0x0 0x21e00000 0x0 0x100000>, + <0x0 0x22800000 0x0 0x100000>, + <0x0 0x22a00000 0x0 0x100000>, + <0x0 0x22c00000 0x0 0x100000>, + <0x0 0x22e00000 0x0 0x100000>, + <0x0 0x23800000 0x0 0x100000>, + <0x0 0x23a00000 0x0 0x100000>, + <0x0 0x23c00000 0x0 0x100000>, + <0x0 0x23e00000 0x0 0x100000>, + <0x0 0x20400000 0x0 0x100000>, + <0x0 0x20600000 0x0 0x100000>; + reg-names = "llcc0_base", + "llcc1_base", + "llcc2_base", + "llcc3_base", + "llcc4_base", + "llcc5_base", + "llcc6_base", + "llcc7_base", + "llcc8_base", + "llcc9_base", + "llcc10_base", + "llcc11_base", + "llcc_broadcast_base", + "llcc_broadcast_and_base"; + + interrupts = ; + }; + + nsp_noc: interconnect@320c0000 { + compatible = "qcom,glymur-nsp-noc"; + reg = <0x0 0x320c0000 0x0 0x21280>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + imem: sram@81e08000 { + compatible = "mmio-sram"; + reg = <0x0 0x81e08600 0x0 0x300>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x81e08600 0x300>; + + cpu_scp_lpri0: scp-sram-section@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x180>; + }; + + cpu_scp_lpri1: scp-sram-section@180 { + compatible = "arm,scmi-shmem"; + reg = <0x180 0x180>; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + , + ; + }; + + thermal_zones: thermal-zones { + aoss-0-thermal { + thermal-sensors = <&tsens0 0>; + + trips { + aoss-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-0-0-thermal { + thermal-sensors = <&tsens0 1>; + + trips { + cpu-0-0-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-0-1-thermal { + thermal-sensors = <&tsens0 2>; + + trips { + cpu-0-0-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-1-0-thermal { + thermal-sensors = <&tsens0 3>; + + trips { + cpu-0-1-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-1-1-thermal { + thermal-sensors = <&tsens0 4>; + + trips { + cpu-0-1-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-2-0-thermal { + thermal-sensors = <&tsens0 5>; + + trips { + cpu-0-2-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-2-1-thermal { + thermal-sensors = <&tsens0 6>; + + trips { + cpu-0-2-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-3-0-thermal { + thermal-sensors = <&tsens0 7>; + + trips { + cpu-0-3-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-3-1-thermal { + thermal-sensors = <&tsens0 8>; + + trips { + cpu-0-3-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-4-0-thermal { + thermal-sensors = <&tsens0 9>; + + trips { + cpu-0-4-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-4-1-thermal { + thermal-sensors = <&tsens0 10>; + + trips { + cpu-0-4-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-5-0-thermal { + thermal-sensors = <&tsens0 11>; + + trips { + cpu-0-5-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-5-1-thermal { + thermal-sensors = <&tsens0 12>; + + trips { + cpu-0-5-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-1-thermal { + thermal-sensors = <&tsens1 0>; + + trips { + aoss-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpullc-0-0-thermal { + thermal-sensors = <&tsens1 1>; + + trips { + cpullc-0-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpullc-0-1-thermal { + thermal-sensors = <&tsens1 2>; + + trips { + cpullc-0-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-0-0-thermal { + thermal-sensors = <&tsens1 3>; + + trips { + qmx-0-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-0-1-thermal { + thermal-sensors = <&tsens1 4>; + + trips { + qmx-0-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-0-2-thermal { + thermal-sensors = <&tsens1 5>; + + trips { + qmx-0-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddr-0-thermal { + thermal-sensors = <&tsens1 6>; + + trips { + ddr-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + video-0-thermal { + thermal-sensors = <&tsens1 7>; + + trips { + video-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + video-1-thermal { + thermal-sensors = <&tsens1 8>; + + trips { + video-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-2-thermal { + thermal-sensors = <&tsens2 0>; + + trips { + aoss-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-0-0-thermal { + thermal-sensors = <&tsens2 1>; + + trips { + cpu-1-0-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-0-1-thermal { + thermal-sensors = <&tsens2 2>; + + trips { + cpu-1-0-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-1-0-thermal { + thermal-sensors = <&tsens2 3>; + + trips { + cpu-1-1-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-1-1-thermal { + thermal-sensors = <&tsens2 4>; + + trips { + cpu-1-1-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-2-0-thermal { + thermal-sensors = <&tsens2 5>; + + trips { + cpu-1-2-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-2-1-thermal { + thermal-sensors = <&tsens2 6>; + + trips { + cpu-1-2-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-3-0-thermal { + thermal-sensors = <&tsens2 7>; + + trips { + cpu-1-3-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-3-1-thermal { + thermal-sensors = <&tsens2 8>; + + trips { + cpu-1-3-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-4-0-thermal { + thermal-sensors = <&tsens2 9>; + + trips { + cpu-1-4-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-4-1-thermal { + thermal-sensors = <&tsens2 10>; + + trips { + cpu-1-4-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-5-0-thermal { + thermal-sensors = <&tsens2 11>; + + trips { + cpu-1-5-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-5-1-thermal { + thermal-sensors = <&tsens2 12>; + + trips { + cpu-1-5-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-3-thermal { + thermal-sensors = <&tsens3 0>; + + trips { + aoss-3-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpullc-1-0-thermal { + thermal-sensors = <&tsens3 1>; + + trips { + cpullc-1-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpullc-1-1-thermal { + thermal-sensors = <&tsens3 2>; + + trips { + cpullc-1-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-1-0-thermal { + thermal-sensors = <&tsens3 3>; + + trips { + qmx-1-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-1-1-thermal { + thermal-sensors = <&tsens3 4>; + + trips { + qmx-1-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-1-2-thermal { + thermal-sensors = <&tsens3 5>; + + trips { + qmx-1-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-1-3-thermal { + thermal-sensors = <&tsens3 6>; + + trips { + qmx-1-3-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-1-4-thermal { + thermal-sensors = <&tsens3 7>; + + trips { + qmx-1-4-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-4-thermal { + thermal-sensors = <&tsens4 0>; + + trips { + aoss-4-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-0-0-thermal { + thermal-sensors = <&tsens4 1>; + + trips { + cpu-2-0-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-0-1-thermal { + thermal-sensors = <&tsens4 2>; + + trips { + cpu-2-0-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-1-0-thermal { + thermal-sensors = <&tsens4 3>; + + trips { + cpu-2-1-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-1-1-thermal { + thermal-sensors = <&tsens4 4>; + + trips { + cpu-2-1-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-2-0-thermal { + thermal-sensors = <&tsens4 5>; + + trips { + cpu-2-2-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-2-1-thermal { + thermal-sensors = <&tsens4 6>; + + trips { + cpu-2-2-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-3-0-thermal { + thermal-sensors = <&tsens4 7>; + + trips { + cpu-2-3-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-3-1-thermal { + thermal-sensors = <&tsens4 8>; + + trips { + cpu-2-3-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-4-0-thermal { + thermal-sensors = <&tsens4 9>; + + trips { + cpu-2-4-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-4-1-thermal { + thermal-sensors = <&tsens4 10>; + + trips { + cpu-2-4-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-5-0-thermal { + thermal-sensors = <&tsens4 11>; + + trips { + cpu-2-5-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-2-5-1-thermal { + thermal-sensors = <&tsens4 12>; + + trips { + cpu-2-5-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-5-thermal { + thermal-sensors = <&tsens5 0>; + + trips { + aoss-5-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpullc-2-0-thermal { + thermal-sensors = <&tsens5 1>; + + trips { + cpullc-2-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpuillc-2-1-thermal { + thermal-sensors = <&tsens5 2>; + + trips { + cpullc-2-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-2-0-thermal { + thermal-sensors = <&tsens5 3>; + + trips { + qmx-2-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-2-1-thermal { + thermal-sensors = <&tsens5 4>; + + trips { + qmx-2-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-2-2-thermal { + thermal-sensors = <&tsens5 5>; + + trips { + qmx-2-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-2-3-thermal { + thermal-sensors = <&tsens5 6>; + + trips { + qmx-2-3-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + qmx-2-4-thermal { + thermal-sensors = <&tsens5 7>; + + trips { + qmx-2-4-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-6-thermal { + thermal-sensors = <&tsens6 0>; + + trips { + aoss-6-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphvx-0-thermal { + thermal-sensors = <&tsens6 1>; + + trips { + nsphvx-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphvx-1-thermal { + thermal-sensors = <&tsens6 2>; + + trips { + nsphvx-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphvx-2-thermal { + thermal-sensors = <&tsens6 3>; + + trips { + nsphvx-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphvx-3-thermal { + thermal-sensors = <&tsens6 4>; + + trips { + nsphvx-3-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphmx-0-thermal { + thermal-sensors = <&tsens6 5>; + + trips { + nsphmx-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphmx-1-thermal { + thermal-sensors = <&tsens6 6>; + + trips { + nsphmx-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphmx-2-thermal { + thermal-sensors = <&tsens6 7>; + + trips { + nsphmx-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsphmx-3-thermal { + thermal-sensors = <&tsens6 8>; + + trips { + nsphmx-3-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + camera-0-thermal { + thermal-sensors = <&tsens6 9>; + + trips { + camera-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + camera-1-thermal { + thermal-sensors = <&tsens6 10>; + + trips { + camera-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddr-1-thermal { + thermal-sensors = <&tsens6 11>; + + trips { + ddr-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddr-2-thermal { + thermal-sensors = <&tsens6 12>; + + trips { + ddr-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-7-thermal { + thermal-sensors = <&tsens7 0>; + + trips { + aoss-7-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-0-0-thermal { + thermal-sensors = <&tsens7 1>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-0-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-0-1-thermal { + thermal-sensors = <&tsens7 2>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-0-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-0-2-thermal { + thermal-sensors = <&tsens7 3>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-0-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-1-0-thermal { + thermal-sensors = <&tsens7 4>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-1-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-1-1-thermal { + thermal-sensors = <&tsens7 5>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-1-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-1-2-thermal { + thermal-sensors = <&tsens7 6>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-1-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-2-0-thermal { + thermal-sensors = <&tsens7 7>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-2-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-2-1-thermal { + thermal-sensors = <&tsens7 8>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-2-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-2-2-thermal { + thermal-sensors = <&tsens7 9>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-2-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-3-0-thermal { + thermal-sensors = <&tsens7 10>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-3-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-3-1-thermal { + thermal-sensors = <&tsens7 11>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-3-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpu-3-2-thermal { + thermal-sensors = <&tsens7 12>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-3-2-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-0-thermal { + thermal-sensors = <&tsens7 13>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-0-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-1-thermal { + thermal-sensors = <&tsens7 14>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpuss-1-critical { + temperature = <115000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmcx0102.dtsi b/arch/arm64/boot/dts/qcom/pmcx0102.dtsi new file mode 100644 index 0000000000000..c3ccd2b756099 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmcx0102.dtsi @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +/ { + thermal-zones { + pmcx0102-c0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmcx0102_c_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmcx0102-c1-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmcx0102_c_e1_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmcx0102-d0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmcx0102_d_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmcx0102-d1-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmcx0102_d_e1_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus0 { + pmcx0102_c_e0: pmic@2 { + compatible = "qcom,pmcx0102", "qcom,spmi-pmic"; + reg = <0x2 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmcx0102_c_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmcx0102_c_e0_gpios: gpio@8800 { + compatible = "qcom,pmcx0102-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmcx0102_c_e0_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pmcx0102_d_e0: pmic@3 { + compatible = "qcom,pmcx0102", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmcx0102_d_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x3 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmcx0102_d_e0_gpios: gpio@8800 { + compatible = "qcom,pmcx0102-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmcx0102_d_e0_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +&spmi_bus1 { + pmcx0102_c_e1: pmic@2 { + compatible = "qcom,pmcx0102", "qcom,spmi-pmic"; + reg = <0x2 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmcx0102_c_e1_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmcx0102_c_e1_gpios: gpio@8800 { + compatible = "qcom,pmcx0102-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmcx0102_c_e1_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pmcx0102_d_e1: pmic@3 { + compatible = "qcom,pmcx0102", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmcx0102_d_e1_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x3 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmcx0102_d_e1_gpios: gpio@8800 { + compatible = "qcom,pmcx0102-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmcx0102_d_e1_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmh0101.dtsi b/arch/arm64/boot/dts/qcom/pmh0101.dtsi new file mode 100644 index 0000000000000..b1ec413259583 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmh0101.dtsi @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +/ { + thermal-zones { + pmh0101-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0101_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus0 { + pmic@1 { + compatible = "qcom,pmh0101", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0101_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0101_gpios: gpio@8800 { + compatible = "qcom,pmh0101-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0101_gpios 0 0 18>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pmh0101_flash: led-controller@ee00 { + compatible = "qcom,pmh0101-flash-led", "qcom,spmi-flash-led"; + reg = <0xee00>; + status = "disabled"; + }; + + pmh0101_pwm: pwm { + compatible = "qcom,pmh0101-pwm", "qcom,pm8350c-pwm"; + #pwm-cells = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmh0104-glymur.dtsi b/arch/arm64/boot/dts/qcom/pmh0104-glymur.dtsi new file mode 100644 index 0000000000000..d89cceda53a3f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmh0104-glymur.dtsi @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +/{ + thermal_zones { + pmh0104-i0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0104_i_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmh0104-j0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0104_j_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmh0104-l1-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0104_l_e1_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus0 { + pmh0104_i_e0: pmic@8 { + compatible = "qcom,pmh0104", "qcom,spmi-pmic"; + reg = <0x8 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0104_i_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x8 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0104_i_e0_gpios: gpio@8800 { + compatible = "qcom,pmh0104-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0104_i_e0_gpios 0 0 8>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pmh0104_j_e0: pmic@9 { + compatible = "qcom,pmh0104", "qcom,spmi-pmic"; + reg = <0x9 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0104_j_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x9 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0104_j_e0_gpios: gpio@8800 { + compatible = "qcom,pmh0104-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0104_j_e0_gpios 0 0 8>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +&spmi_bus1 { + pmh0104_l_e1: pmic@b { + compatible = "qcom,pmh0104", "qcom,spmi-pmic"; + reg = <0xb SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0104_l_e1_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0xb 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0104_l_e1_gpios: gpio@8800 { + compatible = "qcom,pmh0104-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0104_l_e1_gpios 0 0 8>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmh0110-glymur.dtsi b/arch/arm64/boot/dts/qcom/pmh0110-glymur.dtsi new file mode 100644 index 0000000000000..7655bc0303482 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmh0110-glymur.dtsi @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +/ { + thermal-zones { + pmh0110-f0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0110_f_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmh0110-f1-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0110_f_e1_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + pmh0110-h0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmh0110_h_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus0 { + pmh0110_f_e0: pmic@5 { + compatible = "qcom,pmh0110", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0110_f_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x5 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0110_f_e0_gpios: gpio@8800 { + compatible = "qcom,pmh0110-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0110_f_e0_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pmh0110_h_e0: pmic@7 { + compatible = "qcom,pmh0110", "qcom,spmi-pmic"; + reg = <0x7 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0110_h_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x7 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0110_h_e0_gpios: gpio@8800 { + compatible = "qcom,pmh0110-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0110_h_e0_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +&spmi_bus1 { + pmh0110_f_e1: pmic@5 { + compatible = "qcom,pmh0110", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0110_f_e1_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x5 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0110_f_e1_gpios: gpio@8800 { + compatible = "qcom,pmh0110-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0110_f_e1_gpios 0 0 14>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmk8850.dtsi b/arch/arm64/boot/dts/qcom/pmk8850.dtsi new file mode 100644 index 0000000000000..c7ba72fd48bc8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmk8850.dtsi @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +&spmi_bus0 { + pmic@0 { + compatible = "qcom,pmk8850", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmk8850_pon: pon@1300 { + compatible = "qcom,pmk8350-pon"; + reg = <0x1300>, + <0x800>; + reg-names = "hlos", + "pbs"; + + pon_pwrkey: pwrkey { + compatible = "qcom,pmk8350-pwrkey"; + interrupts = <0x0 0x13 0x7 IRQ_TYPE_EDGE_BOTH>; + linux,code = ; + }; + + pon_resin: resin { + compatible = "qcom,pmk8350-resin"; + interrupts = <0x0 0x13 0x6 IRQ_TYPE_EDGE_BOTH>; + status = "disabled"; + }; + }; + + pmk8850_gpios: gpio@b800 { + compatible = "qcom,pmk8850-gpio", "qcom,spmi-gpio"; + reg = <0xb800>; + gpio-controller; + gpio-ranges = <&pmk8850_gpios 0 0 8>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pmk8850_rtc: rtc@6100 { + compatible = "qcom,pmk8350-rtc"; + reg = <0x6100>, + <0x6200>; + reg-names = "rtc", + "alarm"; + interrupts = <0x0 0x62 0x1 IRQ_TYPE_EDGE_RISING>; + }; + + pmk8850_sdam_2: nvram@7100 { + compatible = "qcom,spmi-sdam"; + reg = <0x7100>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x7100 0x100>; + + reboot_reason: reboot-reason@48 { + reg = <0x48 0x1>; + bits = <1 7>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/smb2370.dtsi b/arch/arm64/boot/dts/qcom/smb2370.dtsi new file mode 100644 index 0000000000000..80f3fdae57050 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/smb2370.dtsi @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +&spmi_bus2 { + smb2370_j_e2: pmic@9 { + compatible = "qcom,smb2370", "qcom,spmi-pmic"; + reg = <0x9 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + smb2370_j_e2_eusb2_repeater: phy@fd00 { + compatible = "qcom,smb2370-eusb2-repeater"; + reg = <0xfd00>; + #phy-cells = <0>; + }; + }; + + smb2370_k_e2: pmic@a { + compatible = "qcom,smb2370", "qcom,spmi-pmic"; + reg = <0xa SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + smb2370_k_e2_eusb2_repeater: phy@fd00 { + compatible = "qcom,smb2370-eusb2-repeater"; + reg = <0xfd00>; + #phy-cells = <0>; + }; + }; + + smb2370_l_e2: pmic@b { + compatible = "qcom,smb2370", "qcom,spmi-pmic"; + reg = <0xb SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + smb2370_l_e2_eusb2_repeater: phy@fd00 { + compatible = "qcom,smb2370-eusb2-repeater"; + reg = <0xfd00>; + #phy-cells = <0>; + }; + }; +}; From 20d8c919dc705fc164b03502c65460f4420f8abc Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 19 Feb 2026 18:53:29 +0530 Subject: [PATCH 336/438] FROMLIST: arm64: dts: qcom: glymur: Enable Glymur CRD board support Add initial device tree support for the Glymur Compute Reference Device(CRD) board, with this board dts glymur crd can boot to shell with rootfs on nvme and uart21 as serial console Features enabled are: - Board and sleep clocks - Volume up/down keys - Regulators 0 - 4 - Power supplies and sideband signals (PERST, WAKE, CLKREQ) for PCIe3b/4/5/6 controllers and PHYs Link: https://lore.kernel.org/all/20260219-upstream_v3_glymur_introduction-v8-0-8ce4e489ebb6@oss.qualcomm.com/ Co-developed-by: Kamal Wadhwa Signed-off-by: Kamal Wadhwa Co-developed-by: Qiang Yu Signed-off-by: Qiang Yu Co-developed-by: Sibi Sankar Signed-off-by: Sibi Sankar Co-developed-by: Jyothi Kumar Seerapu Signed-off-by: Jyothi Kumar Seerapu Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Pankaj Patil Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/glymur-crd.dts | 598 ++++++++++++++++++++++++ 2 files changed, 599 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/glymur-crd.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index f80b5d9cf1e80..317af937d038f 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -13,6 +13,7 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8039-t2.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8094-sony-xperia-kitakami-karin_windy.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb +dtb-$(CONFIG_ARCH_QCOM) += glymur-crd.dtb dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-rdp432-c2.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-tplink-archer-ax55-v1.dtb diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts new file mode 100644 index 0000000000000..8779453190122 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -0,0 +1,598 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include "glymur.dtsi" +#include "pmcx0102.dtsi" /* SPMI0: SID-2/3 SPMI1: SID-2/3 */ +#include "pmh0101.dtsi" /* SPMI0: SID-1 */ +#include "pmh0110-glymur.dtsi" /* SPMI0: SID-5/7 SPMI1: SID-5 */ +#include "pmh0104-glymur.dtsi" /* SPMI0: SID-8/9 SPMI1: SID-11 */ +#include "pmk8850.dtsi" /* SPMI0: SID-0 */ +#include "smb2370.dtsi" /* SPMI2: SID-9/10/11 */ + +/ { + model = "Qualcomm Technologies, Inc. Glymur CRD"; + compatible = "qcom,glymur-crd", "qcom,glymur"; + + aliases { + serial0 = &uart21; + serial1 = &uart14; + i2c0 = &i2c0; + i2c1 = &i2c4; + i2c2 = &i2c5; + spi0 = &spi18; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&key_vol_up_default>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = ; + gpios = <&pmh0101_gpios 6 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0101_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_nvmesec: regulator-nvmesec { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_SEC_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0110_f_e1_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_sec_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wlan: regulator-wlan { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WLAN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 94 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wlan_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wwan: regulator-wwan { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WWAN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 246 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wwan_reg_en>; + pinctrl-names = "default"; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_bob1_e0: bob1 { + regulator-name = "vreg_bob1_e0"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <4224000>; + regulator-initial-mode = ; + }; + + vreg_bob2_e0: bob2 { + regulator-name = "vreg_bob2_e0"; + regulator-min-microvolt = <2540000>; + regulator-max-microvolt = <3600000>; + regulator-initial-mode = ; + }; + + vreg_l1b_e0_1p8: ldo1 { + regulator-name = "vreg_l1b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l2b_e0_2p9: ldo2 { + regulator-name = "vreg_l2b_e0_2p9"; + regulator-min-microvolt = <2904000>; + regulator-max-microvolt = <2904000>; + regulator-initial-mode = ; + }; + + vreg_l7b_e0_2p79: ldo7 { + regulator-name = "vreg_l7b_e0_2p79"; + regulator-min-microvolt = <2790000>; + regulator-max-microvolt = <2792000>; + regulator-initial-mode = ; + }; + + vreg_l8b_e0_1p50: ldo8 { + regulator-name = "vreg_l8b_e0_1p50"; + regulator-min-microvolt = <1504000>; + regulator-max-microvolt = <1504000>; + regulator-initial-mode = ; + }; + + vreg_l9b_e0_2p7: ldo9 { + regulator-name = "vreg_l9b_e0_2p7"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2704000>; + regulator-initial-mode = ; + }; + + vreg_l10b_e0_1p8: ldo10 { + regulator-name = "vreg_l10b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l11b_e0_1p2: ldo11 { + regulator-name = "vreg_l11b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + + vreg_l12b_e0_1p14: ldo12 { + regulator-name = "vreg_l12b_e0_1p14"; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1144000>; + regulator-initial-mode = ; + }; + + vreg_l15b_e0_1p8: ldo15 { + regulator-name = "vreg_l15b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l17b_e0_2p4: ldo17 { + regulator-name = "vreg_l17b_e0_2p4"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <2700000>; + regulator-initial-mode = ; + }; + + vreg_l18b_e0_1p2: ldo18 { + regulator-name = "vreg_l18b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + }; + + regulators-1 { + compatible = "qcom,pmcx0102-rpmh-regulators"; + qcom,pmic-id = "C_E1"; + + vreg_l1c_e1_0p82: ldo1 { + regulator-name = "vreg_l1c_e1_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = ; + }; + + vreg_l2c_e1_1p14: ldo2 { + regulator-name = "vreg_l2c_e1_1p14"; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1144000>; + regulator-initial-mode = ; + }; + + vreg_l3c_e1_0p89: ldo3 { + regulator-name = "vreg_l3c_e1_0p89"; + regulator-min-microvolt = <890000>; + regulator-max-microvolt = <980000>; + regulator-initial-mode = ; + }; + + vreg_l4c_e1_0p72: ldo4 { + regulator-name = "vreg_l4c_e1_0p72"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <720000>; + regulator-initial-mode = ; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s7f_e0_1p32: smps7 { + regulator-name = "vreg_s7f_e0_1p32"; + regulator-min-microvolt = <1320000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = ; + }; + + vreg_s8f_e0_0p95: smps8 { + regulator-name = "vreg_s8f_e0_0p95"; + regulator-min-microvolt = <952000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + + vreg_s9f_e0_1p9: smps9 { + regulator-name = "vreg_s9f_e0_1p9"; + regulator-min-microvolt = <1900000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + }; + + vreg_l2f_e0_0p82: ldo2 { + regulator-name = "vreg_l2f_e0_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = ; + }; + + vreg_l3f_e0_0p72: ldo3 { + regulator-name = "vreg_l3f_e0_0p72"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <720000>; + regulator-initial-mode = ; + }; + + vreg_l4f_e0_0p3: ldo4 { + regulator-name = "vreg_l4f_e0_0p3"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E1"; + + vreg_s7f_e1_0p3: smps7 { + regulator-name = "vreg_s7f_e1_0p3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + + vreg_l1f_e1_0p82: ldo1 { + regulator-name = "vreg_l1f_e1_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = ; + }; + + vreg_l2f_e1_0p83: ldo2 { + regulator-name = "vreg_l2f_e1_0p83"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = ; + }; + + vreg_l4f_e1_1p08: ldo4 { + regulator-name = "vreg_l4f_e1_1p08"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1320000>; + regulator-initial-mode = ; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h_e0_0p89: ldo1 { + regulator-name = "vreg_l1h_e0_0p89"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = ; + }; + + vreg_l2h_e0_0p72: ldo2 { + regulator-name = "vreg_l2h_e0_0p72"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = ; + }; + + vreg_l3h_e0_0p32: ldo3 { + regulator-name = "vreg_l3h_e0_0p32"; + regulator-min-microvolt = <320000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + }; + + vreg_l4h_e0_1p2: ldo4 { + regulator-name = "vreg_l4h_e0_1p2"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1320000>; + regulator-initial-mode = ; + }; + }; +}; + +&pcie3b { + vddpe-3v3-supply = <&vreg_nvmesec>; + + pinctrl-0 = <&pcie3b_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie3b_phy { + vdda-phy-supply = <&vreg_l3c_e1_0p89>; + vdda-pll-supply = <&vreg_l2c_e1_1p14>; + + status = "okay"; +}; + +&pcie3b_port0 { + reset-gpios = <&tlmm 155 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 157 GPIO_ACTIVE_LOW>; +}; + +&pcie4 { + vddpe-3v3-supply = <&vreg_wlan>; + + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p82>; + vdda-pll-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; +}; + +&pcie5 { + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l2f_e0_0p82>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; +}; + +&pcie6 { + vddpe-3v3-supply = <&vreg_wwan>; + + pinctrl-0 = <&pcie6_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie6_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p82>; + vdda-pll-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; + +&pcie6_port0 { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; +}; + +&pmh0101_gpios { + nvme_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmh0110_f_e1_gpios { + nvme_sec_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmh0101_gpios { + key_vol_up_default: key-vol-up-default-state { + pins = "gpio6"; + function = "normal"; + output-disable; + bias-pull-up; + }; +}; + +&pmk8850_rtc { + qcom,no-alarm; +}; + +&pon_resin { + linux,code = ; + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ + <10 2>, /* OOB UART */ + <44 4>; /* Security SPI (TPM) */ + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie5_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie6_default: pcie6-default-state { + clkreq-n-pins { + pins = "gpio150"; + function = "pcie6_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio149"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio151"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie3b_default: pcie3b-default-state { + clkreq-n-pins { + pins = "gpio156"; + function = "pcie3b_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio155"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio157"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + wlan_reg_en: wlan-reg-en-state { + pins = "gpio94"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wwan_reg_en: wwan-reg-en-state { + pins = "gpio246"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; From dde9348c42285ebfd4dc3a2778c7228042670f28 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Mon, 23 Feb 2026 17:37:44 +0200 Subject: [PATCH 337/438] FROMLIST: arm64: dts: qcom: glymur: Add USB related nodes The Glymur USB system contains 3 USB type C ports, 1 USB multiport controller and a USB 2.0 only controller. This encompasses 5 SS USB QMP PHYs (3 combo and 2 uni) and 6 M31 eUSB2 PHYs. All controllers are SNPS DWC3 based, so describe them as flattened DWC3 QCOM nodes. Link: https://lore.kernel.org/linux-arm-msm/20260223-dts-qcom-glymur-add-usb-support-v2-1-f4e0f38db21d@oss.qualcomm.com/ Signed-off-by: Wesley Cheng Co-developed-by: Abel Vesa Signed-off-by: Abel Vesa Tested-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 691 ++++++++++++++++++++++++++- 1 file changed, 686 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index e269cec7942c8..2aa9af8c96ce6 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -750,11 +750,11 @@ <0>, /* UFS PHY RX Symbol 0 */ <0>, /* UFS PHY RX Symbol 1 */ <0>, /* UFS PHY TX Symbol 0 */ - <0>, /* USB3 PHY 0 */ - <0>, /* USB3 PHY 1 */ - <0>, /* USB3 PHY 2 */ - <0>, /* USB3 UNI PHY pipe 0 */ - <0>, /* USB3 UNI PHY pipe 1 */ + <&usb_0_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_2_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_mp_qmpphy0 QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_mp_qmpphy1 QMP_USB43DP_USB3_PIPE_CLK>, <0>, /* USB4 PHY 0 pcie pipe */ <0>, /* USB4 PHY 0 Max pipe */ <0>, /* USB4 PHY 1 pcie pipe */ @@ -2264,6 +2264,254 @@ }; }; + usb_hs_phy: phy@fa0000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + reg = <0x0 0x00fa0000 0x0 0x154>; + #phy-cells = <0>; + + clocks = <&tcsr TCSR_USB2_1_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_USB20_HS_BCR>; + + status = "disabled"; + }; + + usb_mp_hsphy0: phy@fa1000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0x0 0x00fa1000 0x0 0x29c>; + #phy-cells = <0>; + + clocks = <&tcsr TCSR_USB2_1_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_HS0_MP_BCR>; + + status = "disabled"; + }; + + usb_mp_hsphy1: phy@fa2000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0x0 0x00fa2000 0x0 0x29c>; + #phy-cells = <0>; + + clocks = <&tcsr TCSR_USB2_2_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_HS1_MP_BCR>; + + status = "disabled"; + }; + + usb_mp_qmpphy0: phy@fa3000 { + compatible = "qcom,glymur-qmp-usb3-uni-phy"; + reg = <0x0 0x00fa3000 0x0 0x2000>; + + clocks = <&gcc GCC_USB3_MP_PHY_AUX_CLK>, + <&tcsr TCSR_USB3_0_CLKREF_EN>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_MP_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_MP_PHY_PIPE_0_CLK>; + clock-names = "aux", + "clkref", + "ref", + "com_aux", + "pipe"; + + power-domains = <&gcc GCC_USB3_MP_SS0_PHY_GDSC>; + + resets = <&gcc GCC_USB3_MP_SS0_PHY_BCR>, + <&gcc GCC_USB3UNIPHY_PHY_MP0_BCR>; + reset-names = "phy", + "phy_phy"; + + clock-output-names = "usb3_uni_phy_0_pipe_clk_src"; + #clock-cells = <0>; + #phy-cells = <0>; + + status = "disabled"; + }; + + usb_mp_qmpphy1: phy@fa5000 { + compatible = "qcom,glymur-qmp-usb3-uni-phy"; + reg = <0x0 0x00fa5000 0x0 0x2000>; + + clocks = <&gcc GCC_USB3_MP_PHY_AUX_CLK>, + <&tcsr TCSR_USB3_1_CLKREF_EN>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_MP_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_MP_PHY_PIPE_1_CLK>; + clock-names = "aux", + "clkref", + "ref", + "com_aux", + "pipe"; + + power-domains = <&gcc GCC_USB3_MP_SS1_PHY_GDSC>; + + resets = <&gcc GCC_USB3_MP_SS1_PHY_BCR>, + <&gcc GCC_USB3UNIPHY_PHY_MP1_BCR>; + reset-names = "phy", + "phy_phy"; + + clock-output-names = "usb3_uni_phy_1_pipe_clk_src"; + + #clock-cells = <0>; + #phy-cells = <0>; + + status = "disabled"; + }; + + usb_0_hsphy: phy@fd3000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0x0 0x00fd3000 0x0 0x29c>; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + + status = "disabled"; + }; + + usb_0_qmpphy: phy@fd5000 { + compatible = "qcom,glymur-qmp-usb3-dp-phy"; + reg = <0x0 0x00fd5000 0x0 0x8000>; + + clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "com_aux", + "usb3_pipe"; + + resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, + <&gcc GCC_USB3PHY_PHY_PRIM_BCR>; + + reset-names = "phy", + "common"; + + power-domains = <&gcc GCC_USB_0_PHY_GDSC>; + + #clock-cells = <1>; + #phy-cells = <1>; + + mode-switch; + orientation-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_0_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_0_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb_0_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb_dp_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + usb_1_hsphy: phy@fdd000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0x0 0x00fdd000 0x0 0x29c>; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + + status = "disabled"; + }; + + usb_1_qmpphy: phy@fde000 { + compatible = "qcom,glymur-qmp-usb3-dp-phy"; + reg = <0x0 0x00fde000 0x0 0x8000>; + + clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>, + <&tcsr TCSR_USB4_1_CLKREF_EN>; + clock-names = "aux", + "ref", + "com_aux", + "usb3_pipe", + "clkref"; + + power-domains = <&gcc GCC_USB_1_PHY_GDSC>; + + resets = <&gcc GCC_USB3_PHY_SEC_BCR>, + <&gcc GCC_USB3PHY_PHY_SEC_BCR>; + reset-names = "phy", + "common"; + + #clock-cells = <1>; + #phy-cells = <1>; + + mode-switch; + orientation-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_1_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb_1_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb_1_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + cnoc_main: interconnect@1500000 { compatible = "qcom,glymur-cnoc-main"; reg = <0x0 0x01500000 0x0 0x17080>; @@ -3367,6 +3615,439 @@ #interconnect-cells = <2>; }; + usb_2_hsphy: phy@88e0000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0x0 0x088e0000 0x0 0x29c>; + #phy-cells = <0>; + + clocks = <&tcsr TCSR_USB2_4_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_TERT_BCR>; + + status = "disabled"; + }; + + usb_2_qmpphy: phy@88e1000 { + compatible = "qcom,glymur-qmp-usb3-dp-phy"; + reg = <0x0 0x088e1000 0x0 0x8000>; + + clocks = <&gcc GCC_USB3_TERT_PHY_AUX_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_TERT_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>, + <&tcsr TCSR_USB4_2_CLKREF_EN>; + clock-names = "aux", + "ref", + "com_aux", + "usb3_pipe", + "clkref"; + + power-domains = <&gcc GCC_USB_2_PHY_GDSC>; + + resets = <&gcc GCC_USB3_PHY_TERT_BCR>, + <&gcc GCC_USB3PHY_PHY_TERT_BCR>; + reset-names = "phy", + "common"; + + #clock-cells = <1>; + #phy-cells = <1>; + + mode-switch; + orientation-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_2_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_2_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb_2_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb_2_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + usb_0: usb@a600000 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a600000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_SLEEP_CLK>, + <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_AHB_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi", + "noc_aggr_north", + "noc_aggr_south"; + + interrupts-extended = <&intc GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 90 IRQ_TYPE_EDGE_BOTH>, + <&pdc 60 IRQ_TYPE_EDGE_BOTH>, + <&pdc 17 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "ss_phy_irq"; + + power-domains = <&gcc GCC_USB30_PRIM_GDSC>; + resets = <&gcc GCC_USB30_PRIM_BCR>; + + iommus = <&apps_smmu 0x1420 0x0>; + phys = <&usb_0_hsphy>, + <&usb_0_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,has-lpm-erratum; + tx-fifo-resize; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + + usb-role-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_0_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_0_dwc3_ss: endpoint { + remote-endpoint = <&usb_0_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + usb_1: usb@a800000 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a800000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>, + <&gcc GCC_USB30_SEC_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&gcc GCC_USB30_SEC_SLEEP_CLK>, + <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_AHB_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi", + "noc_aggr_north", + "noc_aggr_south"; + + interrupts-extended = <&intc GIC_SPI 875 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 88 IRQ_TYPE_EDGE_BOTH>, + <&pdc 87 IRQ_TYPE_EDGE_BOTH>, + <&pdc 76 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "ss_phy_irq"; + + resets = <&gcc GCC_USB30_SEC_BCR>; + power-domains = <&gcc GCC_USB30_SEC_GDSC>; + + iommus = <&apps_smmu 0x1460 0x0>; + + phys = <&usb_1_hsphy>, + <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,has-lpm-erratum; + tx-fifo-resize; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_1_dwc3_ss: endpoint { + remote-endpoint = <&usb_1_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + usb_2: usb@a000000 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a000000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_TERT_AXI_CLK>, + <&gcc GCC_USB30_TERT_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_TERT_AXI_CLK>, + <&gcc GCC_USB30_TERT_SLEEP_CLK>, + <&gcc GCC_USB30_TERT_MOCK_UTMI_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_AHB_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi", + "noc_aggr_north", + "noc_aggr_south"; + + interrupts-extended = <&intc GIC_SPI 871 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 89 IRQ_TYPE_EDGE_BOTH>, + <&pdc 81 IRQ_TYPE_EDGE_BOTH>, + <&pdc 75 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "ss_phy_irq"; + + resets = <&gcc GCC_USB30_TERT_BCR>; + power-domains = <&gcc GCC_USB30_TERT_GDSC>; + + iommus = <&apps_smmu 0x420 0x0>; + + phys = <&usb_2_hsphy>, + <&usb_2_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,has-lpm-erratum; + tx-fifo-resize; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_2_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_2_dwc3_ss: endpoint { + remote-endpoint = <&usb_2_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + usb_hs: usb@a2f8800 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a200000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB2_PRIM_AXI_CLK>, + <&gcc GCC_USB20_MASTER_CLK>, + <&gcc GCC_AGGRE_USB2_PRIM_AXI_CLK>, + <&gcc GCC_USB20_SLEEP_CLK>, + <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_AHB_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi", + "noc_aggr_north", + "noc_aggr_south"; + + assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 92 IRQ_TYPE_EDGE_BOTH>, + <&pdc 57 IRQ_TYPE_EDGE_BOTH>, + <&intc GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "hs_phy_irq"; + + resets = <&gcc GCC_USB20_PRIM_BCR>; + + power-domains = <&gcc GCC_USB20_PRIM_GDSC>; + required-opps = <&rpmhpd_opp_nom>; + + iommus = <&apps_smmu 0x0ce0 0x0>; + + interconnects = <&aggre3_noc MASTER_USB2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", + "apps-usb"; + + phys = <&usb_hs_phy>; + phy-names = "usb2-phy"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,has-lpm-erratum; + tx-fifo-resize; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + + dr_mode = "host"; + + maximum-speed = "high-speed"; + + status = "disabled"; + }; + + usb_mp: usb@a400000 { + compatible = "qcom,glymur-dwc3-mp", "qcom,snps-dwc3"; + reg = <0x0 0x0a400000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_MP_AXI_CLK>, + <&gcc GCC_USB30_MP_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_MP_AXI_CLK>, + <&gcc GCC_USB30_MP_SLEEP_CLK>, + <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_AHB_CLK>, + <&gcc GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi", + "noc_aggr_north", + "noc_aggr_south"; + + interrupts-extended = <&intc GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 12 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 11 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 14 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 13 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 78 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 77 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dwc_usb3", + "pwr_event_1", + "pwr_event_2", + "hs_phy_1", + "hs_phy_2", + "dp_hs_phy_1", + "dm_hs_phy_1", + "dp_hs_phy_2", + "dm_hs_phy_2", + "ss_phy_1", + "ss_phy_2"; + + resets = <&gcc GCC_USB30_MP_BCR>; + power-domains = <&gcc GCC_USB30_MP_GDSC>; + + iommus = <&apps_smmu 0xda0 0x0>; + + phys = <&usb_mp_hsphy0>, + <&usb_mp_qmpphy0>, + <&usb_mp_hsphy1>, + <&usb_mp_qmpphy1>; + phy-names = "usb2-0", + "usb3-0", + "usb2-1", + "usb3-1"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,has-lpm-erratum; + tx-fifo-resize; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + + dr_mode = "host"; + + status = "disabled"; + }; + + dispcc: clock-controller@af00000 { compatible = "qcom,glymur-dispcc"; reg = <0x0 0x0af00000 0x0 0x20000>; From 7234e3d81fbf3aef7d3f24406d81959b2632e077 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Mon, 23 Feb 2026 17:37:45 +0200 Subject: [PATCH 338/438] FROMLIST: arm64: dts: qcom: glymur-crd: Enable USB support The Qualcomm Glymur Compute Reference Device comes with 3 Type-C ports, one USB Type-A, and a fingerprint reader connected over USB. Each of these 3 Type-C ports are connected to one of the USB combo PHYs and one of the M31 eUSB2 PHYs. The Type-A is connected to the USB Multi-port controller via one of the M31 eUSB2 PHYs and one USB3 UNI PHY. The fingerprint reader is connected to the USB_2 controller. All M31 eUSB2 PHYs have associated eUSB2 to USB 2.0 repeaters, which are either part of SMB2370 PMICs or dedicated NXP PTN3222. So enable all needed controllers, PHYs and repeaters, while describing their supplies. Also describe the PMIC glink graph for Type-C connectors. Link: https://lore.kernel.org/linux-arm-msm/20260223-dts-qcom-glymur-add-usb-support-v2-1-f4e0f38db21d@oss.qualcomm.com/ Signed-off-by: Wesley Cheng Co-developed-by: Abel Vesa Signed-off-by: Abel Vesa Tested-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 286 ++++++++++++++++++++++++ 1 file changed, 286 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 8779453190122..02e9520028a41 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -60,6 +60,97 @@ }; }; + pmic-glink { + compatible = "qcom,glymur-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>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_0_qmpphy_out>; + }; + }; + }; + }; + + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in1: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in1: endpoint { + remote-endpoint = <&usb_1_qmpphy_out>; + }; + }; + }; + }; + + connector@2 { + compatible = "usb-c-connector"; + reg = <2>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in2: endpoint { + remote-endpoint = <&usb_2_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in2: endpoint { + remote-endpoint = <&usb_2_qmpphy_out>; + }; + }; + }; + }; + }; + vreg_nvme: regulator-nvme { compatible = "regulator-fixed"; @@ -367,6 +458,48 @@ }; }; +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; + + ptn3222_0: redriver@43 { + compatible = "nxp,ptn3222"; + reg = <0x43>; + + reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_1p50>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; + + ptn3222_1: redriver@4f { + compatible = "nxp,ptn3222"; + reg = <0x4f>; + + reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_1p50>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; + + ptn3222_2: redriver@47 { + compatible = "nxp,ptn3222"; + reg = <0x47>; + + reset-gpios = <&tlmm 9 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_1p50>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; +}; + &pcie3b { vddpe-3v3-supply = <&vreg_nvmesec>; @@ -485,6 +618,21 @@ status = "okay"; }; +&smb2370_j_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_2p79>; +}; + +&smb2370_k_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_2p79>; +}; + +&smb2370_l_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_2p79>; +}; + &tlmm { gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ <10 2>, /* OOB UART */ @@ -596,3 +744,141 @@ bias-disable; }; }; + +&usb_0 { + status = "okay"; +}; + +&usb_0_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_0_hsphy { + vdd-supply = <&vreg_l3f_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_j_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_0_qmpphy { + vdda-phy-supply = <&vreg_l4h_e0_1p2>; + vdda-pll-supply = <&vreg_l3f_e0_0p72>; + refgen-supply = <&vreg_l2f_e0_0p82>; + + status = "okay"; +}; + +&usb_0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in1>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l3f_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_k_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vreg_l4h_e0_1p2>; + vdda-pll-supply = <&vreg_l1h_e0_0p89>; + refgen-supply = <&vreg_l2f_e0_0p82>; + + status = "okay"; +}; + +&usb_1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in1>; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in2>; +}; + +&usb_2_hsphy { + vdd-supply = <&vreg_l4c_e1_0p72>; + vdda12-supply = <&vreg_l4f_e1_1p08>; + + phys = <&smb2370_l_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_2_qmpphy { + vdda-phy-supply = <&vreg_l4f_e1_1p08>; + vdda-pll-supply = <&vreg_l4c_e1_0p72>; + refgen-supply = <&vreg_l1c_e1_0p82>; + + status = "okay"; +}; + +&usb_2_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in2>; +}; + +&usb_hs { + status = "okay"; +}; + +&usb_hs_phy { + vdd-supply = <&vreg_l2h_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&ptn3222_2>; + + status = "okay"; +}; + +&usb_mp { + status = "okay"; +}; + +&usb_mp_hsphy0 { + vdd-supply = <&vreg_l2h_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&ptn3222_0>; + + status = "okay"; +}; + +&usb_mp_hsphy1 { + vdd-supply = <&vreg_l2h_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&ptn3222_1>; + + status = "okay"; +}; + +&usb_mp_qmpphy0 { + vdda-phy-supply = <&vreg_l4h_e0_1p2>; + vdda-pll-supply = <&vreg_l2h_e0_0p72>; + refgen-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; + +&usb_mp_qmpphy1 { + vdda-phy-supply = <&vreg_l4h_e0_1p2>; + vdda-pll-supply = <&vreg_l2h_e0_0p72>; + refgen-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; From 4b1c187492a403a75bd798e7ca58b0d1d610f58d Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Tue, 10 Feb 2026 23:37:59 +0530 Subject: [PATCH 339/438] FROMLIST: arm64: dts: qcom: glymur: Add ADSP and CDSP for Glymur SoC Add remoteproc PAS loader for ADSP and CDSP with its fastrpc nodes. Link: https://lore.kernel.org/lkml/20260129001358.770053-5-sibi.sankar@oss.qualcomm.com/ Signed-off-by: Sibi Sankar Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 286 +++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 2aa9af8c96ce6..451b642e99549 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -3594,6 +3594,122 @@ #mbox-cells = <2>; }; + remoteproc_adsp: remoteproc@6800000 { + compatible = "qcom,glymur-adsp-pas", "qcom,sm8550-adsp-pas"; + reg = <0x0 0x06800000 0x0 0x10000>; + + iommus = <&apps_smmu 0x1000 0x0>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", + "lmx"; + + memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + remoteproc_adsp_glink: glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <2>; + + label = "lpass"; + + fastrpc { + compatible = "qcom,glymur-fastrpc", "qcom,kaanapali-fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + + iommus = <&apps_smmu 0x1003 0x80>, + <&apps_smmu 0x1043 0x20>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + + iommus = <&apps_smmu 0x1004 0x80>, + <&apps_smmu 0x1044 0x20>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + + iommus = <&apps_smmu 0x1005 0x80>, + <&apps_smmu 0x1045 0x20>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + + iommus = <&apps_smmu 0x1006 0x80>, + <&apps_smmu 0x1046 0x20>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + + iommus = <&apps_smmu 0x1007 0x40>, + <&apps_smmu 0x1067 0x0>, + <&apps_smmu 0x1087 0x0>; + dma-coherent; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + + iommus = <&apps_smmu 0x1008 0x80>, + <&apps_smmu 0x1048 0x20>; + dma-coherent; + }; + }; + }; + }; + lpass_lpiaon_noc: interconnect@7400000 { compatible = "qcom,glymur-lpass-lpiaon-noc"; reg = <0x0 0x07400000 0x0 0x19080>; @@ -5373,6 +5489,176 @@ #interconnect-cells = <2>; }; + remoteproc_cdsp: remoteproc@32300000 { + compatible = "qcom,glymur-cdsp-pas", "qcom,sm8550-cdsp-pas"; + reg = <0x0 0x32300000 0x0 0x10000>; + + iommus = <&apps_smmu 0x2000 0x400>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_NSP>; + power-domain-names = "cx", + "mxc", + "nsp"; + + memory-region = <&cdsp_mem>, <&q6_cdsp_dtb_mem>; + qcom,qmp = <&aoss_qmp>; + qcom,smem-states = <&smp2p_cdsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + qcom,remote-pid = <5>; + label = "cdsp"; + + fastrpc { + compatible = "qcom,glymur-fastrpc", "qcom,kaanapali-fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + + iommus = <&apps_smmu 0x2001 0x440>, + <&apps_smmu 0x1961 0x0>, + <&apps_smmu 0x19c1 0x0>; + dma-coherent; + }; + + compute-cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + + iommus = <&apps_smmu 0x2002 0x440>, + <&apps_smmu 0x1962 0x0>, + <&apps_smmu 0x19c2 0x0>; + dma-coherent; + }; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + + iommus = <&apps_smmu 0x2003 0x440>, + <&apps_smmu 0x1963 0x0>, + <&apps_smmu 0x19c3 0x0>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + + iommus = <&apps_smmu 0x2004 0x440>, + <&apps_smmu 0x1964 0x0>, + <&apps_smmu 0x19c4 0x0>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + + iommus = <&apps_smmu 0x2005 0x440>, + <&apps_smmu 0x1965 0x0>, + <&apps_smmu 0x19c5 0x0>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + + iommus = <&apps_smmu 0x2006 0x440>, + <&apps_smmu 0x1966 0x0>, + <&apps_smmu 0x19c6 0x0>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + + iommus = <&apps_smmu 0x2007 0x440>, + <&apps_smmu 0x1967 0x0>, + <&apps_smmu 0x19c7 0x0>; + dma-coherent; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + + iommus = <&apps_smmu 0x2008 0x440>, + <&apps_smmu 0x1968 0x0>, + <&apps_smmu 0x19c8 0x0>; + dma-coherent; + }; + + /* note: compute-cb@9 is secure */ + + compute-cb@10 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <10>; + + iommus = <&apps_smmu 0x200c 0x440>, + <&apps_smmu 0x196c 0x0>, + <&apps_smmu 0x19cc 0x0>; + dma-coherent; + }; + + compute-cb@11 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <11>; + + iommus = <&apps_smmu 0x200d 0x440>, + <&apps_smmu 0x196d 0x0>, + <&apps_smmu 0x19cd 0x0>; + dma-coherent; + }; + + compute-cb@12 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <12>; + + iommus = <&apps_smmu 0x200e 0x440>, + <&apps_smmu 0x196e 0x0>, + <&apps_smmu 0x19ce 0x0>; + dma-coherent; + }; + }; + }; + }; + imem: sram@81e08000 { compatible = "mmio-sram"; reg = <0x0 0x81e08600 0x0 0x300>; From 3807f257242266658c041bdcc80576a767f584eb Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Tue, 10 Feb 2026 23:40:07 +0530 Subject: [PATCH 340/438] FROMLIST: arm64: dts: qcom: glymur-crd: Enable ADSP and CDSP Enable ADSP and CDSP on Glymur CRD board. Link: https://lore.kernel.org/lkml/20260129001358.770053-6-sibi.sankar@oss.qualcomm.com/ Signed-off-by: Sibi Sankar Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 02e9520028a41..b98f28ba482b7 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -633,6 +633,20 @@ vdd3-supply = <&vreg_l7b_e0_2p79>; }; +&remoteproc_adsp { + firmware-name = "qcom/glymur/adsp.mbn", + "qcom/glymur/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/glymur/cdsp.mbn", + "qcom/glymur/cdsp_dtb.mbn"; + + status = "okay"; +}; + &tlmm { gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ <10 2>, /* OOB UART */ From 8656c31b65551f0550199cd4711e277b22869c77 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 25 Feb 2026 15:54:41 +0530 Subject: [PATCH 341/438] PENDING: arm64: dts: qcom: glymur: Describe display related nodes The MDSS (Mobile Display SubSystem) on Glymur comes with 4 DisplayPort controllers. Describe them along with display controller and the eDP PHY. Then, attach the combo PHYs link and vco_div clocks to the Display clock controller and link up the PHYs and DP endpoints in the graph. Signed-off-by: Abel Vesa Signed-off-by: Abel Vesa Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 431 ++++++++++++++++++++++++++- 1 file changed, 423 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 451b642e99549..99c2f725edf6b 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -2434,6 +2434,7 @@ reg = <2>; usb_dp_qmpphy_dp_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; }; }; }; @@ -2507,10 +2508,32 @@ reg = <2>; usb_1_qmpphy_dp_in: endpoint { + remote-endpoint = <&mdss_dp1_out>; }; }; }; }; + mdss_dp3_phy: phy@faac00 { + compatible = "qcom,glymur-dp-phy"; + reg = <0 0x00faac00 0 0x1d0>, + <0 0x00faa400 0 0x128>, + <0 0x00faa800 0 0x128>, + <0 0x00faa000 0 0x358>; + + clocks = <&dispcc DISP_CC_MDSS_DPTX3_AUX_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&tcsr TCSR_EDP_CLKREF_EN>; + clock-names = "aux", + "cfg_ahb", + "ref"; + + power-domains = <&rpmhpd RPMHPD_MX>; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; cnoc_main: interconnect@1500000 { compatible = "qcom,glymur-cnoc-main"; @@ -3799,6 +3822,7 @@ reg = <2>; usb_2_qmpphy_dp_in: endpoint { + remote-endpoint = <&mdss_dp2_out>; }; }; }; @@ -4163,20 +4187,411 @@ status = "disabled"; }; + mdss: display-subsystem@ae00000 { + compatible = "qcom,glymur-mdss"; + reg = <0x0 0x0ae00000 0x0 0x1000>; + reg-names = "mdss"; + + interrupts = ; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>; + + resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; + + interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", + "cpu-cfg"; + + power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>; + + iommus = <&apps_smmu 0x1de0 0x2>; + + interrupt-controller; + #interrupt-cells = <1>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdss_mdp: display-controller@ae01000 { + compatible = "qcom,glymur-dpu"; + reg = <0 0x0ae01000 0 0x93000>, + <0 0x0aeb0000 0 0x2008>; + reg-names = "mdp", + "vbif"; + + interrupts-extended = <&mdss 0>; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + + operating-points-v2 = <&mdp_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dpu_intf0_out: endpoint { + remote-endpoint = <&mdss_dp0_in>; + }; + }; + + port@4 { + reg = <4>; + + mdss_intf4_out: endpoint { + remote-endpoint = <&mdss_dp1_in>; + }; + }; + + port@5 { + reg = <5>; + + mdss_intf5_out: endpoint { + remote-endpoint = <&mdss_dp3_in>; + }; + }; + + port@6 { + reg = <6>; + + mdss_intf6_out: endpoint { + remote-endpoint = <&mdss_dp2_in>; + }; + }; + }; + + mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-205000000 { + opp-hz = /bits/ 64 <205000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-337000000 { + opp-hz = /bits/ 64 <337000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-417000000 { + opp-hz = /bits/ 64 <417000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-532000000 { + opp-hz = /bits/ 64 <532000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + }; + }; + + mdss_dp0: displayport-controller@af54000 { + compatible = "qcom,glymur-dp"; + reg = <0x0 0xaf54000 0x0 0x104>, + <0x0 0xaf54200 0x0 0xc0>, + <0x0 0xaf55000 0x0 0x770>, + <0x0 0xaf56000 0x0 0x9c>, + <0x0 0xaf57000 0x0 0x9c>; + + interrupts-extended = <&mdss 12>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_LINK_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL0_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL1_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>; + assigned-clock-parents = <&usb_0_qmpphy QMP_USB43DP_DP_LINK_CLK>, + <&usb_0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; + + operating-points-v2 = <&mdss_dp0_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&usb_0_qmpphy QMP_USB43DP_DP_PHY>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dp0_in: endpoint { + remote-endpoint = <&dpu_intf0_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp0_out: endpoint { + remote-endpoint = <&usb_dp_qmpphy_dp_in>; + }; + }; + }; + + mdss_dp0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-192000000 { + opp-hz = /bits/ 64 <192000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + }; + + opp-270000000 { + opp-hz = /bits/ 64 <270000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-810000000 { + opp-hz = /bits/ 64 <810000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + mdss_dp1: displayport-controller@af5c000 { + compatible = "qcom,glymur-dp"; + reg = <0x0 0xaf5c000 0x0 0x104>, + <0x0 0xaf5c200 0x0 0xc0>, + <0x0 0xaf5d000 0x0 0x770>, + <0x0 0xaf5e000 0x0 0x9c>, + <0x0 0xaf5f000 0x0 0x9c>; + + interrupts-extended = <&mdss 13>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_DPTX1_AUX_CLK>, + <&dispcc DISP_CC_MDSS_DPTX1_LINK_CLK>, + <&dispcc DISP_CC_MDSS_DPTX1_LINK_INTF_CLK>, + <&dispcc DISP_CC_MDSS_DPTX1_PIXEL0_CLK>, + <&dispcc DISP_CC_MDSS_DPTX1_PIXEL1_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX1_LINK_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC>; + assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, + <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; + + operating-points-v2 = <&mdss_dp0_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dp1_in: endpoint { + remote-endpoint = <&mdss_intf4_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp1_out: endpoint { + remote-endpoint = <&usb_1_qmpphy_dp_in>; + }; + }; + }; + }; + + mdss_dp2: displayport-controller@af64000 { + compatible = "qcom,glymur-dp"; + reg = <0x0 0x0af64000 0x0 0x104>, + <0x0 0x0af64200 0x0 0xc0>, + <0x0 0x0af65000 0x0 0x770>, + <0x0 0x0af66000 0x0 0x9c>, + <0x0 0x0af67000 0x0 0x9c>; + + interrupts-extended = <&mdss 14>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_DPTX2_AUX_CLK>, + <&dispcc DISP_CC_MDSS_DPTX2_LINK_CLK>, + <&dispcc DISP_CC_MDSS_DPTX2_LINK_INTF_CLK>, + <&dispcc DISP_CC_MDSS_DPTX2_PIXEL0_CLK>, + <&dispcc DISP_CC_MDSS_DPTX2_PIXEL1_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX2_LINK_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC>; + assigned-clock-parents = <&usb_2_qmpphy QMP_USB43DP_DP_LINK_CLK>, + <&usb_2_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_2_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; + + operating-points-v2 = <&mdss_dp0_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&usb_2_qmpphy QMP_USB43DP_DP_PHY>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdss_dp2_in: endpoint { + remote-endpoint = <&mdss_intf6_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp2_out: endpoint { + remote-endpoint = <&usb_2_qmpphy_dp_in>; + }; + }; + }; + }; + + mdss_dp3: displayport-controller@af6c000 { + compatible = "qcom,glymur-dp"; + reg = <0 0x0af6c000 0 0x200>, + <0 0x0af6c200 0 0x200>, + <0 0x0af6d000 0 0xc00>, + <0 0x0af6e000 0 0x400>, + <0 0x0af6f000 0 0x400>; + + interrupts-extended = <&mdss 15>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_DPTX3_AUX_CLK>, + <&dispcc DISP_CC_MDSS_DPTX3_LINK_CLK>, + <&dispcc DISP_CC_MDSS_DPTX3_LINK_INTF_CLK>, + <&dispcc DISP_CC_MDSS_DPTX3_PIXEL0_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX3_LINK_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC>; + assigned-clock-parents = <&mdss_dp3_phy 0>, + <&mdss_dp3_phy 1>; + + operating-points-v2 = <&mdss_dp0_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&mdss_dp3_phy>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dp3_in: endpoint { + remote-endpoint = <&mdss_intf5_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp3_out: endpoint { + }; + }; + }; + }; + }; dispcc: clock-controller@af00000 { compatible = "qcom,glymur-dispcc"; reg = <0x0 0x0af00000 0x0 0x20000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, - <0>, /* dp0 */ - <0>, - <0>, /* dp1 */ - <0>, - <0>, /* dp2 */ - <0>, - <0>, /* dp3 */ - <0>, + <&usb_0_qmpphy QMP_USB43DP_DP_LINK_CLK>, /* dp0 */ + <&usb_0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, /* dp1 */ + <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_2_qmpphy QMP_USB43DP_DP_LINK_CLK>, /* dp2 */ + <&usb_2_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&mdss_dp3_phy 0>, /* dp3 */ + <&mdss_dp3_phy 1>, <0>, /* dsi0 */ <0>, <0>, /* dsi1 */ From 6cb6f15a055e061766b3b96eaa4fb1bc20c36654 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 27 Jan 2026 18:04:09 +0530 Subject: [PATCH 342/438] PENDING: arm64: dts: qcom: glymur-crd: Enable eDP display support Enable the MDSS (Mobile Display SubSystem) along with the 3rd DisplayPort controller and its PHY in order to bring support for the panel on Glymur CRD platform. Also describe the voltage regulator needed by the eDP panel. Signed-off-by: Abel Vesa Signed-off-by: Pankaj Patil Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index b98f28ba482b7..8767431055038 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -151,6 +151,22 @@ }; }; + vreg_edp_3p3: regulator-edp-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + vreg_nvme: regulator-nvme { compatible = "regulator-fixed"; @@ -500,6 +516,47 @@ }; }; +&mdss { + status = "okay"; +}; + +&mdss_dp3 { + /delete-property/ #sound-dai-cells; + + status = "okay"; + + aux-bus { + panel { + compatible = "samsung,atna60cl08", "samsung,atna33xc20"; + enable-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_3p3>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; +}; + +&mdss_dp3_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l2f_e1_0p83>; + vdda-pll-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; + &pcie3b { vddpe-3v3-supply = <&vreg_nvmesec>; @@ -652,6 +709,20 @@ <10 2>, /* OOB UART */ <44 4>; /* Security SPI (TPM) */ + edp_bl_en: edp-bl-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + edp_reg_en: edp-reg-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + pcie4_default: pcie4-default-state { clkreq-n-pins { pins = "gpio147"; From e8e87444d324ac75b26d5f7bd5c5d338f2a91f78 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 1 Oct 2025 12:00:56 +0300 Subject: [PATCH 343/438] PENDING: arm64: dts: qcom: glymur-crd: Enable keyboard, trackpad and touchscreen Enable keyboard, trackpad and touchscreen Signed-off-by: Abel Vesa Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 117 ++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 8767431055038..23d21481f9261 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -5,6 +5,8 @@ /dts-v1/; +#include + #include "glymur.dtsi" #include "pmcx0102.dtsi" /* SPMI0: SID-2/3 SPMI1: SID-2/3 */ #include "pmh0101.dtsi" /* SPMI0: SID-1 */ @@ -167,6 +169,23 @@ regulator-boot-on; }; + vreg_misc_3p3: regulator-misc-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_MISC_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0110_f_e0_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&misc_3p3_reg_en>; + + regulator-boot-on; + regulator-always-on; + }; + vreg_nvme: regulator-nvme { compatible = "regulator-fixed"; @@ -474,6 +493,44 @@ }; }; +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + touchpad@2c { + compatible = "hid-over-i2c"; + reg = <0x2c>; + + hid-descr-addr = <0x20>; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0_1p8>; + + pinctrl-0 = <&tpad_default>; + pinctrl-names = "default"; + + wakeup-source; + }; + + keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0_1p8>; + + pinctrl-0 = <&kybd_default>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + &i2c5 { clock-frequency = <400000>; @@ -516,6 +573,26 @@ }; }; +&i2c8 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@38 { + compatible = "hid-over-i2c"; + reg = <0x38>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0_1p8>; + + pinctrl-0 = <&ts0_default>; + pinctrl-names = "default"; + }; +}; + &mdss { status = "okay"; }; @@ -666,6 +743,19 @@ }; }; +&pmh0110_f_e0_gpios { + misc_3p3_reg_en: misc-3p3-reg-en-state { + pins = "gpio6"; + function = "normal"; + bias-disable; + input-disable; + output-enable; + drive-push-pull; + power-source = <1>; /* 1.8 V */ + qcom,drive-strength = ; + }; +}; + &pmk8850_rtc { qcom,no-alarm; }; @@ -746,6 +836,33 @@ }; }; + kybd_default: kybd-default-state { + pins = "gpio67"; + function = "gpio"; + bias-disable; + }; + + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; + bias-disable; + }; + + ts0_default: ts0-default-state { + int-n-pins { + pins = "gpio51"; + function = "gpio"; + bias-disable; + }; + + reset-n-pins { + pins = "gpio48"; + function = "gpio"; + output-high; + drive-strength = <16>; + }; + }; + pcie5_default: pcie5-default-state { clkreq-n-pins { pins = "gpio153"; From d38230f9b6bb8e0cade9d7a82adfe543081d064a Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 25 Feb 2026 18:16:38 +0530 Subject: [PATCH 344/438] FROMLIST: arm64: dts: qcom: Add support for MM clock controllers for Glymur Add the device nodes for the multimedia clock controllers videocc, gpucc and gxclkctl. Link: https://lore.kernel.org/r/20260220-glymur_mmcc_dt_config-v1-1-e0e2f43a32af@oss.qualcomm.com Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 99c2f725edf6b..9978ad1c177e7 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -5,7 +5,10 @@ #include #include +#include #include +#include +#include #include #include #include @@ -3606,6 +3609,30 @@ #interconnect-cells = <2>; }; + gxclkctl: clock-controller@3d64000 { + compatible = "qcom,glymur-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc GPU_CC_CX_GDSC>; + + #power-domain-cells = <1>; + }; + + + gpucc: clock-controller@3d90000 { + compatible = "qcom,glymur-gpucc"; + reg = <0x0 0x03d90000 0x0 0x9800>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + power-domains = <&rpmhpd RPMHPD_MX>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; ipcc: mailbox@3e04000 { compatible = "qcom,glymur-ipcc", "qcom,ipcc"; reg = <0x0 0x03e04000 0x0 0x1000>; @@ -4579,6 +4606,22 @@ }; }; + videocc: clock-controller@0aaf0000 { + compatible = "qcom,glymur-videocc"; + reg = <0x0 0x0aaf0000 0x0 0x10000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + dispcc: clock-controller@af00000 { compatible = "qcom,glymur-dispcc"; reg = <0x0 0x0af00000 0x0 0x20000>; From 1dbea33915357b226a2eedfcbc6bcc448ae38b0d Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Wed, 25 Feb 2026 18:34:51 +0530 Subject: [PATCH 345/438] PENDING: arm64: dts: qcom: Add Glymur GPU support The Adreno X2 series GPU present in Glymur SoC belongs to the A8x family. It is a new HW IP with architectural improvements as well as different set of hw configs like GMEM, num SPs, Caches sizes etc. Add the GPU and GMU nodes to describe this hardware. Signed-off-by: Akhil P Oommen Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 168 +++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 9978ad1c177e7..5ad1aac6fc4ab 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -3621,6 +3621,174 @@ }; + gpu: gpu@3d00000 { + compatible = "qcom,adreno-44070001", "qcom,adreno"; + reg = <0x0 0x03d00000 0x0 0x40000>, + <0x0 0x03d9e000 0x0 0x2000>, + <0x0 0x03d61000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + + interrupts = ; + + iommus = <&adreno_smmu 0 0x0>, + <&adreno_smmu 1 0x0>; + + operating-points-v2 = <&gpu_opp_table>; + + qcom,gmu = <&gmu>; + #cooling-cells = <2>; + + interconnects = <&hsc_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2-adreno", + "operating-points-v2"; + + opp-310000000 { + opp-hz = /bits/ 64 <310000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + }; + + opp-410000000 { + opp-hz = /bits/ 64 <410000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + }; + + opp-572000000 { + opp-hz = /bits/ 64 <572000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0xe02d5ffd>; + }; + + opp-760000000 { + opp-hz = /bits/ 64 <760000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0xc0285ffd>; + }; + + opp-820000000 { + opp-hz = /bits/ 64 <820000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0xa82e5ffd>; + }; + + opp-915000000 { + opp-hz = /bits/ 64 <915000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0x882d5ffd>; + }; + + opp-1070000000 { + opp-hz = /bits/ 64 <1070000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0x882b5ffd>; + }; + + opp-1185000000 { + opp-hz = /bits/ 64 <1185000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0x882a5ffd>; + }; + + opp-1350000000 { + opp-hz = /bits/ 64 <1350000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0x882a5ffd>; + }; + + opp-1550000000 { + opp-hz = /bits/ 64 <1550000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0xa8295ffd>; + }; + + opp-1700000000 { + opp-hz = /bits/ 64 <1700000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0x88295ffd>; + }; + + opp-1850000000 { + opp-hz = /bits/ 64 <1850000000>; + opp-level = ; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0x88285ffd>; + }; + }; + }; + + gmu: gmu@3d6a000 { + compatible = "qcom,adreno-gmu-x285.1", "qcom,adreno-gmu"; + + reg = <0x0 0x03d37000 0x0 0x68000>; + reg-names = "gmu"; + + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + + clocks = <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_GPU_GEMNOC_GFX_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>; + clock-names = "ahb", + "gmu", + "cxo", + "memnoc", + "hub"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>, <&gpucc GPU_CC_CX_GDSC>; + //<&gxclkctl GX_CLKCTL_GX_GDSC>; TODO: + power-domain-names = "cx", + "gx"; + + iommus = <&adreno_smmu 5 0x0>; + + qcom,qmp = <&aoss_qmp>; + + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-575000000 { + opp-hz = /bits/ 64 <575000000>; + opp-level = ; + }; + + opp-700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-level = ; + }; + + opp-725000000 { + opp-hz = /bits/ 64 <725000000>; + opp-level = ; + }; + + opp-750000000 { + opp-hz = /bits/ 64 <750000000>; + opp-level = ; + }; + }; + }; + gpucc: clock-controller@3d90000 { compatible = "qcom,glymur-gpucc"; reg = <0x0 0x03d90000 0x0 0x9800>; From 2692838fec06db58afc14733eeb7796d2dcd4042 Mon Sep 17 00:00:00 2001 From: Pradyot Kumar Nayak Date: Wed, 25 Feb 2026 18:38:32 +0530 Subject: [PATCH 346/438] PENDING: arm64: dts: qcom: glymur: Add GPU smmu nodes Add the nodes to describe GPU smmu Signed-off-by: Rajendra Nayak Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 5ad1aac6fc4ab..dd1052e787f72 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -3801,6 +3801,46 @@ #reset-cells = <1>; #power-domain-cells = <1>; }; + + adreno_smmu: iommu@3da0000 { + compatible = "qcom,glymur-smmu-500", "qcom,adreno-smmu", + "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x03da0000 0x0 0x40000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + clocks = <&gpucc GPU_CC_GPU_SMMU_VOTE_CLK>; + clock-names = "hlos"; + power-domains = <&gpucc GPU_CC_CX_GDSC>; + interconnects = <&hsc_noc MASTER_GPU_TCU &mc_virt SLAVE_EBI1>; + dma-coherent; + }; + ipcc: mailbox@3e04000 { compatible = "qcom,glymur-ipcc", "qcom,ipcc"; reg = <0x0 0x03e04000 0x0 0x1000>; From d8110faa39a5a30e5b050e663d435832f7e2c9d8 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 12 Feb 2026 06:15:50 +0530 Subject: [PATCH 347/438] PENDING: arm64: dts: glymur: Add LPASS macro codecs and pinctrl Add LPASS macro codecs and LPASS TLMM pin controller on Qualcomm glymur. for proper sound support. Also add GPR(Generic Pack router) node along with APM(Audio Process Manager) and PRM(Proxy resource Manager) audio services. Signed-off-by: Mohammad Rafi Shaik Signed-off-by: Srinivas Kandagatla Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 263 +++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index dd1052e787f72..7ad5dd7337e05 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include #include #include "glymur-ipcc.h" @@ -3965,6 +3967,267 @@ dma-coherent; }; }; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = ; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = ; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1004 0x80>, + <&apps_smmu 0x1061 0x20>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; + }; + }; + + lpass_vamacro: codec@7660000 { + compatible = "qcom,glymur-lpass-va-macro", "qcom,sm8550-lpass-va-macro"; + reg = <0 0x07660000 0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "mclk", + "macro", + "dcodec"; + + #clock-cells = <0>; + clock-output-names = "fsgen"; + #sound-dai-cells = <1>; + }; + + lpass_wsamacro: codec@6c90000 { + compatible = "qcom,glymur-lpass-wsa-macro", "qcom,sm8550-lpass-wsa-macro"; + reg = <0 0x06c90000 0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_WSA_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_vamacro>; + clock-names = "mclk", + "macro", + "dcodec", + "fsgen"; + + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + sound-name-prefix = "WSA"; + }; + + swr0: soundwire@6c80000 { + compatible = "qcom,soundwire-v3.1.0"; + reg = <0 0x06c80000 0 0x10000>; + interrupts = ; + clocks = <&lpass_wsamacro>; + clock-names = "iface"; + label = "WSA"; + + pinctrl-0 = <&wsa_swr_active>; + pinctrl-names = "default"; + + qcom,ports-block-pack-mode = /bits/ 8 <0x00 0x01 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x01 0x01 0x00 0x00 0x01 0x01>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff 0x18 0x18 0xff 0xff>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0xff 0xff 0x06 0x0d 0x0 0x19 0x06 0x06>; + qcom,ports-offset2 = /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-sinterval = /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0xc8 0xff 0xff 0xff 0xff 0x0f 0x0f 0x31f 0x31f 0x0f 0x0f >; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff 0xf 0xf 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff 0x0f 0x0f 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + lpass_wsa2macro: codec@6cb0000 { + compatible = "qcom,glymur-lpass-wsa-macro", "qcom,sm8550-lpass-wsa-macro"; + reg = <0 0x06cb0000 0 0x1000>; + clocks = <&q6prmcc LPASS_CLK_ID_WSA2_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_vamacro>; + clock-names = "mclk", + "macro", + "dcodec", + "fsgen"; + + #clock-cells = <0>; + clock-output-names = "wsa2-mclk"; + #sound-dai-cells = <1>; + sound-name-prefix = "WSA2"; + }; + + swr3: soundwire@6ca0000 { + compatible = "qcom,soundwire-v3.1.0"; + reg = <0 0x06ca0000 0 0x10000>; + interrupts = ; + clocks = <&lpass_wsa2macro>; + clock-names = "iface"; + label = "WSA2"; + + pinctrl-0 = <&wsa2_swr_active>; + pinctrl-names = "default"; + + qcom,ports-block-pack-mode = /bits/ 8 <0x00 0x01 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x01 0x01 0x00 0x00 0x01 0x01>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff 0x18 0x18 0xff 0xff>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0xff 0xff 0x06 0x0d 0x0 0x19 0x06 0x06>; + qcom,ports-offset2 = /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-sinterval = /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0xc8 0xff 0xff 0xff 0xff 0x0f 0x0f 0x31f 0x31f 0x0f 0x0f >; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff 0xf 0xf 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0xff 0x0f 0x0f 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + lpass_tlmm: pinctrl@6e80000 { + compatible = "qcom,glymur-lpass-lpi-pinctrl", "qcom,sm8650-lpass-lpi-pinctrl"; + reg = <0 0x07760000 0 0x20000>; + + clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "core", "audio"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&lpass_tlmm 0 0 23>; + + tx_swr_active: tx-swr-active-state { + clk-pins { + pins = "gpio0"; + function = "swr_tx_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio1", "gpio2"; + function = "swr_tx_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + + rx_swr_active: rx-swr-active-state { + clk-pins { + pins = "gpio3"; + function = "swr_rx_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio4", "gpio5"; + function = "swr_rx_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + + dmic01_default: dmic01-default-state { + clk-pins { + pins = "gpio6"; + function = "dmic1_clk"; + drive-strength = <8>; + output-high; + }; + + data-pins { + pins = "gpio7"; + function = "dmic1_data"; + drive-strength = <8>; + input-enable; + }; + }; + + dmic23_default: dmic23-default-state { + clk-pins { + pins = "gpio8"; + function = "dmic2_clk"; + drive-strength = <8>; + output-high; + }; + + data-pins { + pins = "gpio9"; + function = "dmic2_data"; + drive-strength = <8>; + input-enable; + }; + }; + + wsa_swr_active: wsa-swr-active-state { + clk-pins { + pins = "gpio10"; + function = "wsa_swr_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio11"; + function = "wsa_swr_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; + }; + + wsa2_swr_active: wsa2-swr-active-state { + clk-pins { + pins = "gpio15"; + function = "wsa2_swr_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + data-pins { + pins = "gpio16"; + function = "wsa2_swr_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; }; }; From c7a5b3de4d7c7dfb280e08defa71597f80241e42 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 19 Feb 2026 14:53:58 +0530 Subject: [PATCH 348/438] PENDING: arm64: dts: qcom: glymur-crd: add Audio sound card node Add the sound card of Glymur-crd board with the routing for Speakers. Add device nodes for the sound support with WSA884x smart speakers and playback via speakers and recording via DMIC microphones. Co-developed-by: Mohammad Rafi Shaik Signed-off-by: Mohammad Rafi Shaik Tested-by: Mohammad Rafi Shaik Signed-off-by: Srinivas Kandagatla Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 110 ++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 23d21481f9261..d1d641d54d6df 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -247,6 +247,54 @@ pinctrl-0 = <&wwan_reg_en>; pinctrl-names = "default"; }; + + sound { + compatible = "qcom,glymur-sndcard"; + model = "GLYMUR-CRD"; + audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT", + "TweeterLeft IN", "WSA WSA_SPK2 OUT", + "WooferRight IN", "WSA2 WSA_SPK2 OUT", + "TweeterRight IN", "WSA2 WSA_SPK2 OUT", + "VA DMIC0", "vdd-micb", + "VA DMIC1", "vdd-micb", + "VA DMIC2", "vdd-micb", + "VA DMIC3", "vdd-micb"; + + wsa-dai-link { + link-name = "WSA Playback"; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + codec { + sound-dai = <&left_woofer>, <&left_tweeter>, + <&swr0 0>, <&lpass_wsamacro 0>, + <&right_woofer>, <&right_tweeter>, + <&swr3 0>, <&lpass_wsa2macro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; }; &apps_rsc { @@ -634,6 +682,12 @@ status = "okay"; }; +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + qcom,dmic-sample-rate = <4800000>; +}; + &pcie3b { vddpe-3v3-supply = <&vreg_nvmesec>; @@ -780,6 +834,62 @@ vdd3-supply = <&vreg_l7b_e0_2p79>; }; +&swr0 { + status = "okay"; + + /* WSA8845, Left Woofer */ + left_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferLeft"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, Left Tweeter */ + left_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterLeft"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&swr3 { + status = "okay"; + + /* WSA8845, Right Woofer */ + right_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferRight"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, Right Tweeter */ + right_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterRight"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + &remoteproc_adsp { firmware-name = "qcom/glymur/adsp.mbn", "qcom/glymur/adsp_dtb.mbn"; From fa8e4bd8e93b66bde8ee455bcd3bf09c35606f12 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Thu, 12 Feb 2026 14:30:53 +0800 Subject: [PATCH 349/438] WORKAROUND: arm64: dts: qcom: glymur: Add refgen and qref supplies for PCIe PHY on Glymur Add refgen and qref power supplies in each pcie phy devicetree node. For some instance, refgen and qref may share LDOs with phy LDOs, so add additional power supplies. Signed-off-by: Qiang Yu --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index d1d641d54d6df..08867176cc3bd 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -700,6 +700,10 @@ &pcie3b_phy { vdda-phy-supply = <&vreg_l3c_e1_0p89>; vdda-pll-supply = <&vreg_l2c_e1_1p14>; + vdda-qref-supply = <&vreg_l1f_e1_0p82>; + vdda-qref2-supply = <&vreg_l2f_e1_0p83>; + vdda-refgen0p9-supply = <&vreg_l1c_e1_0p82>; + vdda-refgen1p2-supply = <&vreg_l4f_e1_1p08>; status = "okay"; }; @@ -722,6 +726,8 @@ vdda-phy-supply = <&vreg_l1c_e1_0p82>; vdda-pll-supply = <&vreg_l4f_e1_1p08>; + vdda-qref-supply = <&vreg_l1f_e1_0p82>; + vdda-qref2-supply = <&vreg_l2f_e1_0p83>; status = "okay"; }; @@ -743,6 +749,7 @@ vdda-phy-supply = <&vreg_l2f_e0_0p82>; vdda-pll-supply = <&vreg_l4h_e0_1p2>; + vdda-qref-supply = <&vreg_l3f_e0_0p72>; status = "okay"; }; @@ -764,6 +771,8 @@ vdda-phy-supply = <&vreg_l1c_e1_0p82>; vdda-pll-supply = <&vreg_l4f_e1_1p08>; + vdda-qref-supply = <&vreg_l1f_e1_0p82>; + vdda-qref2-supply = <&vreg_l2f_e1_0p83>; status = "okay"; }; From c29b2a8795e0f64836ca9314837d167013d0699e Mon Sep 17 00:00:00 2001 From: Anandu Krishnan E Date: Thu, 26 Feb 2026 21:26:47 +0530 Subject: [PATCH 350/438] FROMLIST: misc: fastrpc: Add reference counting for fastrpc_user structure Add reference counting using kref to the fastrpc_user structure to prevent use-after-free issues when contexts are freed from workqueue after device release. The issue occurs when fastrpc_device_release() frees the user structure while invoke contexts are still pending in the workqueue. When the workqueue later calls fastrpc_context_free(), it attempts to access buf->fl->cctx in fastrpc_buf_free(), leading to a use-after-free: pc : fastrpc_buf_free+0x38/0x80 [fastrpc] lr : fastrpc_context_free+0xa8/0x1b0 [fastrpc] ... fastrpc_context_free+0xa8/0x1b0 [fastrpc] fastrpc_context_put_wq+0x78/0xa0 [fastrpc] process_one_work+0x180/0x450 worker_thread+0x26c/0x388 Implement proper reference counting to fix this: - Initialize kref in fastrpc_device_open() - Take a reference in fastrpc_context_alloc() for each context - Release the reference in fastrpc_context_free() when context is freed - Release the initial reference in fastrpc_device_release() This ensures the user structure remains valid as long as there are contexts holding references to it, preventing the race condition. Link: https://lore.kernel.org/all/20260226151121.818852-1-anandu.e@oss.qualcomm.com/ Signed-off-by: Anandu Krishnan E --- drivers/misc/fastrpc.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 158514d72f8b9..50bd47d09eeef 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -328,6 +328,8 @@ struct fastrpc_user { spinlock_t lock; /* lock for allocations */ struct mutex mutex; + /* Reference count */ + struct kref refcount; }; /* Extract SMMU PA from consolidated IOVA */ @@ -515,15 +517,36 @@ static void fastrpc_channel_ctx_put(struct fastrpc_channel_ctx *cctx) kref_put(&cctx->refcount, fastrpc_channel_ctx_free); } +static void fastrpc_user_free(struct kref *ref) +{ + struct fastrpc_user *fl = container_of(ref, struct fastrpc_user, refcount); + + fastrpc_channel_ctx_put(fl->cctx); + mutex_destroy(&fl->mutex); + kfree(fl); +} + +static void fastrpc_user_get(struct fastrpc_user *fl) +{ + kref_get(&fl->refcount); +} + +static void fastrpc_user_put(struct fastrpc_user *fl) +{ + kref_put(&fl->refcount, fastrpc_user_free); +} + static void fastrpc_context_free(struct kref *ref) { struct fastrpc_invoke_ctx *ctx; struct fastrpc_channel_ctx *cctx; + struct fastrpc_user *fl; unsigned long flags; int i; ctx = container_of(ref, struct fastrpc_invoke_ctx, refcount); cctx = ctx->cctx; + fl = ctx->fl; for (i = 0; i < ctx->nbufs; i++) fastrpc_map_put(ctx->maps[i]); @@ -539,6 +562,8 @@ static void fastrpc_context_free(struct kref *ref) kfree(ctx->olaps); kfree(ctx); + /* Release the reference taken in fastrpc_context_alloc() */ + fastrpc_user_put(fl); fastrpc_channel_ctx_put(cctx); } @@ -646,6 +671,8 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( /* Released in fastrpc_context_put() */ fastrpc_channel_ctx_get(cctx); + /* Take a reference to user, released in fastrpc_context_free() */ + fastrpc_user_get(user); ctx->sc = sc; ctx->retval = -1; @@ -676,6 +703,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( spin_lock(&user->lock); list_del(&ctx->node); spin_unlock(&user->lock); + fastrpc_user_put(user); fastrpc_channel_ctx_put(cctx); kfree(ctx->maps); kfree(ctx->olaps); @@ -1700,11 +1728,9 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) } fastrpc_session_free(cctx, fl->sctx); - fastrpc_channel_ctx_put(cctx); - - mutex_destroy(&fl->mutex); - kfree(fl); file->private_data = NULL; + /* Release the reference taken in fastrpc_device_open */ + fastrpc_user_put(fl); return 0; } @@ -1748,6 +1774,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) spin_lock_irqsave(&cctx->lock, flags); list_add_tail(&fl->user, &cctx->users); spin_unlock_irqrestore(&cctx->lock, flags); + kref_init(&fl->refcount); return 0; } From 89a06f69fe17da9f1405ebce66e6c2add141e0d7 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 27 Jan 2026 16:08:45 +0530 Subject: [PATCH 351/438] soc: qcom: smp2p: Add irqchip state support A remoteproc booted during earlier boot stages such as UEFI or the bootloader, may need to be attached to without restarting the remoteproc hardware. To do this the remoteproc will need to check the ready and handover states in smp2p without an interrupt notification. Create qcom_smp2p_start_in() to initialize the shadow state without notifying clients because these early events happened in the past. Add support for the .irq_get_irqchip_state callback so remoteproc can read the current state of the fatal, ready and handover bits. Signed-off-by: Chris Lew Link: https://lore.kernel.org/r/20260127-smp2pv2-v3-1-4060b859b1e2@oss.qualcomm.com Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/smp2p.c | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index cb515c2340c10..c27ffb44b8253 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -222,6 +222,39 @@ static void qcom_smp2p_negotiate(struct qcom_smp2p *smp2p) } } +static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p) +{ + unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND]; + unsigned int pid = smp2p->remote_pid; + char buf[SMP2P_MAX_ENTRY_NAME]; + struct smp2p_smem_item *in; + struct smp2p_entry *entry; + size_t size; + int i; + + in = qcom_smem_get(pid, smem_id, &size); + if (IS_ERR(in)) + return; + + smp2p->in = in; + + /* Check if version is initialized by the remote. */ + if (in->version == 0) + return; + + for (i = smp2p->valid_entries; i < in->valid_entries; i++) { + list_for_each_entry(entry, &smp2p->inbound, node) { + memcpy(buf, in->entries[i].name, sizeof(buf)); + if (!strcmp(buf, entry->name)) { + entry->value = &in->entries[i].value; + entry->last_value = readl(entry->value); + break; + } + } + } + smp2p->valid_entries = i; +} + static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) { struct smp2p_smem_item *in; @@ -368,12 +401,31 @@ static void smp2p_irq_print_chip(struct irq_data *irqd, struct seq_file *p) seq_printf(p, "%8s", dev_name(entry->smp2p->dev)); } +static int smp2p_irq_get_irqchip_state(struct irq_data *irqd, enum irqchip_irq_state which, + bool *state) +{ + struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd); + u32 val; + + if (which != IRQCHIP_STATE_LINE_LEVEL) + return -EINVAL; + + if (!entry->value) + return -ENODEV; + + val = readl(entry->value); + *state = !!(val & BIT(irqd_to_hwirq(irqd))); + + return 0; +} + static struct irq_chip smp2p_irq_chip = { .name = "smp2p", .irq_mask = smp2p_mask_irq, .irq_unmask = smp2p_unmask_irq, .irq_set_type = smp2p_set_irq_type, .irq_print_chip = smp2p_irq_print_chip, + .irq_get_irqchip_state = smp2p_irq_get_irqchip_state, }; static int smp2p_irq_map(struct irq_domain *d, @@ -618,6 +670,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev) } } + /* Check inbound entries in the case of early boot processor */ + qcom_smp2p_start_in(smp2p); + /* Kick the outgoing edge after allocating entries */ qcom_smp2p_kick(smp2p); From 73687ff277f7bc7f9ebbd3ca9733db6eb9f623b2 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 27 Jan 2026 16:08:46 +0530 Subject: [PATCH 352/438] soc: qcom: smp2p: Add support for smp2p v2 smp2p v2 adds support for allowing remote processors to write outbound smp2p items without completing the feature negotiation. This is required for processors that start before linux to write out signals like error and clock ready and unblock their bootup. If a remote processor only supports v1, smp2p can version down by mirroring the peer version during the negotiation stage. When using smp2p version 2, the remote does not wait for the ssr ack before setting the items. To accommodate this, set the last_value of all the entries to 0 when SSR is detected. This forces smp2p to detect the new values written by the remote. Because the SSR ack is skipped, the down transition of bits is missed in smp2p version 2. Signed-off-by: Chris Lew Link: https://lore.kernel.org/r/20260127-smp2pv2-v3-2-4060b859b1e2@oss.qualcomm.com Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/smp2p.c | 48 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index c27ffb44b8253..af0ceeaf6e073 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -36,6 +36,10 @@ * The driver uses the Linux GPIO and interrupt framework to expose a virtual * GPIO for each outbound entry and a virtual interrupt controller for each * inbound entry. + * + * V2 of SMP2P allows remote processors to write to outbound smp2p items before + * the full smp2p connection is negotiated. This is important for processors + * started before linux runs. */ #define SMP2P_MAX_ENTRY 16 @@ -47,11 +51,12 @@ #define SMP2P_MAGIC 0x504d5324 #define SMP2P_ALL_FEATURES SMP2P_FEATURE_SSR_ACK +#define MAX_VERSION 2 /** * struct smp2p_smem_item - in memory communication structure * @magic: magic number - * @version: version - must be 1 + * @version: version * @features: features flag - currently unused * @local_pid: processor id of sending end * @remote_pid: processor id of receiving end @@ -180,14 +185,22 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) static bool qcom_smp2p_check_ssr(struct qcom_smp2p *smp2p) { struct smp2p_smem_item *in = smp2p->in; + struct smp2p_entry *entry; + bool restart_done; bool restart; if (!smp2p->ssr_ack_enabled) return false; - restart = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT); + restart_done = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT); + restart = restart_done != smp2p->ssr_ack; + list_for_each_entry(entry, &smp2p->inbound, node) { + if (!entry->value) + continue; + entry->last_value = 0; + } - return restart != smp2p->ssr_ack; + return restart; } static void qcom_smp2p_do_ssr_ack(struct qcom_smp2p *smp2p) @@ -219,9 +232,26 @@ static void qcom_smp2p_negotiate(struct qcom_smp2p *smp2p) smp2p->negotiation_done = true; trace_smp2p_negotiate(smp2p->dev, out->features); + } else if (in->version && in->version < out->version) { + out->version = in->version; + qcom_smp2p_kick(smp2p); } } +static int qcom_smp2p_in_version(struct qcom_smp2p *smp2p) +{ + unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND]; + unsigned int pid = smp2p->remote_pid; + struct smp2p_smem_item *in; + size_t size; + + in = qcom_smem_get(pid, smem_id, &size); + if (IS_ERR(in)) + return 0; + + return in->version; +} + static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p) { unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND]; @@ -516,6 +546,7 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p) struct smp2p_smem_item *out; unsigned smem_id = smp2p->smem_items[SMP2P_OUTBOUND]; unsigned pid = smp2p->remote_pid; + u8 in_version; int ret; ret = qcom_smem_alloc(pid, smem_id, sizeof(*out)); @@ -537,12 +568,21 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p) out->valid_entries = 0; out->features = SMP2P_ALL_FEATURES; + in_version = qcom_smp2p_in_version(smp2p); + if (in_version > MAX_VERSION) { + dev_err(smp2p->dev, "Unsupported smp2p version %d\n", in_version); + return -EINVAL; + } + /* * Make sure the rest of the header is written before we validate the * item by writing a valid version number. */ wmb(); - out->version = 1; + if (in_version && in_version <= 2) + out->version = in_version; + else + out->version = 2; qcom_smp2p_kick(smp2p); From 0b822e26e8504392b11cf044b773f4ab494bb9fa Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 8 Jan 2026 15:21:50 +0100 Subject: [PATCH 353/438] soc: qcom: smem: Expose DDR data from SMEM Most modern Qualcomm platforms (>= SM8150) expose information about the DDR memory present on the system via SMEM. Details from this information is used in various scenarios, such as multimedia drivers configuring the hardware based on the "Highest Bank address Bit" (hbb), or the list of valid frequencies in validation scenarios... Add support for parsing v3-v7 version of the structs. Unforunately, they are not versioned, so some elbow grease is necessary to determine which one is present. See for reference: ver 3: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/1d11897d2cfcc7b85f28ff74c445018dbbecac7a ver 4: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/f6e9aa549260bbc0bdcb156c2b05f48dc5963203 ver 5: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/617d3297abe8b1b8dd3de3d1dd69c3961e6f343f ver 5 with 6regions: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/d770e009f9bae58d56d926f7490bbfb45af8341f ver 6: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/62659b557fdb1551b20fae8073d1d701dfa8a62e ver 7: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/734d95599c5ebb1ca0d4e1639142e65c590532b7 Reviewed-by: Bjorn Andersson Signed-off-by: Konrad Dybcio Tested-by: Neil Armstrong # on SM8650-HDK Link: https://lore.kernel.org/r/20260108-topic-smem_dramc-v3-1-6b64df58a017@oss.qualcomm.com --- drivers/soc/qcom/Makefile | 3 +- drivers/soc/qcom/smem.c | 14 +- drivers/soc/qcom/smem.h | 9 + drivers/soc/qcom/smem_dramc.c | 408 ++++++++++++++++++++++++++++++++++ include/linux/soc/qcom/smem.h | 4 + 5 files changed, 436 insertions(+), 2 deletions(-) create mode 100644 drivers/soc/qcom/smem.h create mode 100644 drivers/soc/qcom/smem_dramc.c diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index b7f1d2a573674..798643be3590c 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -23,7 +23,8 @@ obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o qcom_rpmh-y += rpmh-rsc.o qcom_rpmh-y += rpmh.o obj-$(CONFIG_QCOM_SMD_RPM) += rpm-proc.o smd-rpm.o -obj-$(CONFIG_QCOM_SMEM) += smem.o +qcom_smem-y += smem.o smem_dramc.o +obj-$(CONFIG_QCOM_SMEM) += qcom_smem.o obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o CFLAGS_smp2p.o := -I$(src) obj-$(CONFIG_QCOM_SMP2P) += smp2p.o diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index d5c94b47f431f..7e05e0555dcb4 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -4,6 +4,7 @@ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -16,6 +17,8 @@ #include #include +#include "smem.h" + /* * The Qualcomm shared memory system is a allocate only heap structure that * consists of one of more memory areas that can be accessed by the processors @@ -284,6 +287,8 @@ struct qcom_smem { struct smem_partition global_partition; struct smem_partition partitions[SMEM_HOST_COUNT]; + struct dentry *debugfs_dir; + unsigned num_regions; struct smem_region regions[] __counted_by(num_regions); }; @@ -1236,17 +1241,24 @@ static int qcom_smem_probe(struct platform_device *pdev) __smem = smem; + smem->debugfs_dir = smem_dram_parse(smem->dev); + smem->socinfo = platform_device_register_data(&pdev->dev, "qcom-socinfo", PLATFORM_DEVID_NONE, NULL, 0); - if (IS_ERR(smem->socinfo)) + if (IS_ERR(smem->socinfo)) { + debugfs_remove_recursive(smem->debugfs_dir); + dev_dbg(&pdev->dev, "failed to register socinfo device\n"); + } return 0; } static void qcom_smem_remove(struct platform_device *pdev) { + debugfs_remove_recursive(__smem->debugfs_dir); + platform_device_unregister(__smem->socinfo); /* Set to -EPROBE_DEFER to signal unprobed state */ diff --git a/drivers/soc/qcom/smem.h b/drivers/soc/qcom/smem.h new file mode 100644 index 0000000000000..8bf3f606e1ae8 --- /dev/null +++ b/drivers/soc/qcom/smem.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __QCOM_SMEM_INTERNAL__ +#define __QCOM_SMEM_INTERNAL__ + +#include + +struct dentry *smem_dram_parse(struct device *dev); + +#endif diff --git a/drivers/soc/qcom/smem_dramc.c b/drivers/soc/qcom/smem_dramc.c new file mode 100644 index 0000000000000..017bb894a91b6 --- /dev/null +++ b/drivers/soc/qcom/smem_dramc.c @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smem.h" + +#define SMEM_DDR_INFO_ID 603 + +#define MAX_DDR_FREQ_NUM_V3 13 +#define MAX_DDR_FREQ_NUM_V5 14 + +#define MAX_CHAN_NUM 8 +#define MAX_RANK_NUM 2 + +#define DDR_HBB_MIN 13 +#define DDR_HBB_MAX 19 + +#define MAX_SHUB_ENTRIES 8 + +static struct smem_dram *__dram; + +enum ddr_info_version { + INFO_UNKNOWN, + INFO_V3, + INFO_V3_WITH_14_FREQS, + INFO_V4, + INFO_V5, + INFO_V5_WITH_6_REGIONS, + INFO_V6, /* INFO_V6 seems to only have shipped with 6 DDR regions, unlike V7 */ + INFO_V7, + INFO_V7_WITH_6_REGIONS, +}; + +struct smem_dram { + unsigned long frequencies[MAX_DDR_FREQ_NUM_V5]; + u32 num_frequencies; + u8 hbb; +}; + +enum ddr_type { + DDR_TYPE_NODDR = 0, + DDR_TYPE_LPDDR1 = 1, + DDR_TYPE_LPDDR2 = 2, + DDR_TYPE_PCDDR2 = 3, + DDR_TYPE_PCDDR3 = 4, + DDR_TYPE_LPDDR3 = 5, + DDR_TYPE_LPDDR4 = 6, + DDR_TYPE_LPDDR4X = 7, + DDR_TYPE_LPDDR5 = 8, + DDR_TYPE_LPDDR5X = 9, +}; + +/* The data structures below are NOT __packed on purpose! */ + +/* Structs used across multiple versions */ +struct ddr_part_details { + __le16 revision_id1; + __le16 revision_id2; + __le16 width; + __le16 density; +}; + +struct ddr_freq_table { + u32 freq_khz; + u8 enabled; +}; + +/* V3 */ +struct ddr_freq_plan_v3 { + struct ddr_freq_table ddr_freq[MAX_DDR_FREQ_NUM_V3]; /* NOTE: some have 14 like v5 */ + u8 num_ddr_freqs; + phys_addr_t clk_period_address; +}; + +struct ddr_details_v3 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v3 ddr_freq_tbl; + u8 num_channels; +}; + +/* V4 */ +struct ddr_details_v4 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v3 ddr_freq_tbl; + u8 num_channels; + u8 num_ranks[MAX_CHAN_NUM]; + u8 highest_bank_addr_bit[MAX_CHAN_NUM][MAX_RANK_NUM]; +}; + +/* V5 */ +struct shub_freq_table { + u8 enable; + u32 freq_khz; +}; + +struct shub_freq_plan_entry { + u8 num_shub_freqs; + struct shub_freq_table shub_freq[MAX_SHUB_ENTRIES]; +}; + +struct ddr_xbl2quantum_smem_data { + phys_addr_t ssr_cookie_addr; + u32 reserved[10]; +}; + +struct ddr_freq_plan_v5 { + struct ddr_freq_table ddr_freq[MAX_DDR_FREQ_NUM_V5]; + u8 num_ddr_freqs; + phys_addr_t clk_period_address; + u32 max_nom_ddr_freq; +}; + +struct ddr_region_v5 { + u64 start_address; + u64 size; + u64 mem_controller_address; + u32 granule_size; /* MiB */ + u8 ddr_rank; +#define DDR_RANK_0 BIT(0) +#define DDR_RANK_1 BIT(1) + u8 segments_start_index; + u64 segments_start_offset; +}; + +struct ddr_regions_v5 { + u32 ddr_region_num; /* We expect this to always be 4 or 6 */ + u64 ddr_rank0_size; + u64 ddr_rank1_size; + u64 ddr_cs0_start_addr; + u64 ddr_cs1_start_addr; + u32 highest_bank_addr_bit; + struct ddr_region_v5 ddr_region[] __counted_by(ddr_region_num); +}; + +struct ddr_details_v5 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v5 ddr_freq_tbl; + u8 num_channels; + u8 _padding; + struct ddr_regions_v5 ddr_regions; +}; + +/* V6 */ +struct ddr_misc_info_v6 { + u32 dsf_version; + u32 reserved[10]; +}; + +/* V7 */ +struct ddr_details_v7 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v5 ddr_freq_tbl; + u8 num_channels; + u8 sct_config; + struct ddr_regions_v5 ddr_regions; +}; + +/** + * qcom_smem_dram_get_hbb(): Get the Highest bank address bit + * + * Context: Check qcom_smem_is_available() before calling this function. + * Because __dram * is initialized by smem_dram_parse(), which is in turn + * called from * qcom_smem_probe(), __dram will only be NULL if the data + * couldn't have been found/interpreted correctly. + * + * Return: 0 on success, -ENODATA on failure. + */ +int qcom_smem_dram_get_hbb(void) +{ + int hbb; + + if (!__dram) + return -ENODATA; + + hbb = __dram->hbb; + if (hbb == 0) + return -ENODATA; + else if (hbb < DDR_HBB_MIN || hbb > DDR_HBB_MAX) + return -EINVAL; + + return hbb; +} +EXPORT_SYMBOL_GPL(qcom_smem_dram_get_hbb); + +static void smem_dram_parse_v3_data(struct smem_dram *dram, void *data, bool additional_freq_entry) +{ + /* This may be 13 or 14 */ + int num_freq_entries = MAX_DDR_FREQ_NUM_V3; + struct ddr_details_v3 *details = data; + + if (additional_freq_entry) + num_freq_entries++; + + for (int i = 0; i < num_freq_entries; i++) { + struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz; + } +} + +static void smem_dram_parse_v4_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v4 *details = data; + + /* Rank 0 channel 0 entry holds the correct value */ + dram->hbb = details->highest_bank_addr_bit[0][0]; + + for (int i = 0; i < MAX_DDR_FREQ_NUM_V3; i++) { + struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz; + } +} + +static void smem_dram_parse_v5_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v5 *details = data; + struct ddr_regions_v5 *region = &details->ddr_regions; + + dram->hbb = region[0].highest_bank_addr_bit; + + for (int i = 0; i < MAX_DDR_FREQ_NUM_V5; i++) { + struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz; + } +} + +static void smem_dram_parse_v7_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v7 *details = data; + struct ddr_regions_v5 *region = &details->ddr_regions; + + dram->hbb = region[0].highest_bank_addr_bit; + + for (int i = 0; i < MAX_DDR_FREQ_NUM_V5; i++) { + struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz; + } +} + +/* The structure contains no version field, so we have to perform some guesswork.. */ +static int smem_dram_infer_struct_version(size_t size) +{ + /* Some early versions provided less bytes of less useful data */ + if (size < sizeof(struct ddr_details_v3)) + return -EINVAL; + + if (size == sizeof(struct ddr_details_v3)) + return INFO_V3; + + if (size == sizeof(struct ddr_details_v3) + + sizeof(struct ddr_freq_table)) + return INFO_V3_WITH_14_FREQS; + + if (size == sizeof(struct ddr_details_v4)) + return INFO_V4; + + if (size == sizeof(struct ddr_details_v5) + + 4 * sizeof(struct ddr_region_v5)) + return INFO_V5; + + if (size == sizeof(struct ddr_details_v5) + + 4 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_xbl2quantum_smem_data) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V5; + + if (size == sizeof(struct ddr_details_v5) + + 6 * sizeof(struct ddr_region_v5)) + return INFO_V5_WITH_6_REGIONS; + + if (size == sizeof(struct ddr_details_v5) + + 6 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_xbl2quantum_smem_data) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V5_WITH_6_REGIONS; + + if (size == sizeof(struct ddr_details_v5) + + 6 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_misc_info_v6) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V6; + + if (size == sizeof(struct ddr_details_v7) + + 4 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_misc_info_v6) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V7; + + if (size == sizeof(struct ddr_details_v7) + + 6 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_misc_info_v6) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V7_WITH_6_REGIONS; + + return INFO_UNKNOWN; +} + +static int smem_dram_frequencies_show(struct seq_file *s, void *unused) +{ + struct smem_dram *dram = s->private; + + for (int i = 0; i < dram->num_frequencies; i++) + seq_printf(s, "%lu\n", dram->frequencies[i]); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(smem_dram_frequencies); + +static int smem_hbb_show(struct seq_file *s, void *unused) +{ + struct smem_dram *dram = s->private; + + if (!dram->hbb) + return -EINVAL; + + seq_printf(s, "%d\n", dram->hbb); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(smem_hbb); + +struct dentry *smem_dram_parse(struct device *dev) +{ + struct dentry *debugfs_dir; + enum ddr_info_version ver; + struct smem_dram *dram; + size_t actual_size; + void *data = NULL; + + /* No need to check qcom_smem_is_available(), this func is called by the SMEM driver */ + data = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_DDR_INFO_ID, &actual_size); + if (IS_ERR_OR_NULL(data)) + return ERR_PTR(-ENODATA); + + ver = smem_dram_infer_struct_version(actual_size); + if (ver < 0) { + /* Some SoCs don't provide data that's useful for us */ + return ERR_PTR(-ENODATA); + } else if (ver == INFO_UNKNOWN) { + /* In other cases, we may not have added support for a newer struct revision */ + pr_err("Found an unknown type of DRAM info struct (size = %zu)\n", actual_size); + return ERR_PTR(-EINVAL); + } + + dram = devm_kzalloc(dev, sizeof(*dram), GFP_KERNEL); + if (!dram) + return ERR_PTR(-ENOMEM); + + switch (ver) { + case INFO_V3: + smem_dram_parse_v3_data(dram, data, false); + break; + case INFO_V3_WITH_14_FREQS: + smem_dram_parse_v3_data(dram, data, true); + break; + case INFO_V4: + smem_dram_parse_v4_data(dram, data); + break; + case INFO_V5: + case INFO_V5_WITH_6_REGIONS: + case INFO_V6: + smem_dram_parse_v5_data(dram, data); + break; + case INFO_V7: + case INFO_V7_WITH_6_REGIONS: + smem_dram_parse_v7_data(dram, data); + break; + default: + return ERR_PTR(-EINVAL); + } + + /* Both the entry and its parent dir will be cleaned up by debugfs_remove_recursive */ + debugfs_dir = debugfs_create_dir("qcom_smem", NULL); + debugfs_create_file("dram_frequencies", 0444, debugfs_dir, dram, + &smem_dram_frequencies_fops); + debugfs_create_file("hbb", 0444, debugfs_dir, dram, &smem_hbb_fops); + + /* If there was no failure so far, assign the global variable */ + __dram = dram; + + return debugfs_dir; +} diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h index f946e3beca215..223cd5090a2a8 100644 --- a/include/linux/soc/qcom/smem.h +++ b/include/linux/soc/qcom/smem.h @@ -2,6 +2,8 @@ #ifndef __QCOM_SMEM_H__ #define __QCOM_SMEM_H__ +#include + #define QCOM_SMEM_HOST_ANY -1 bool qcom_smem_is_available(void); @@ -17,4 +19,6 @@ int qcom_smem_get_feature_code(u32 *code); int qcom_smem_bust_hwspin_lock_by_host(unsigned int host); +int qcom_smem_dram_get_hbb(void); + #endif From 64d75f7e2a793b65d86fd9b35f8d4c40595ba799 Mon Sep 17 00:00:00 2001 From: Vishnu Santhosh Date: Thu, 5 Feb 2026 13:51:31 +0530 Subject: [PATCH 354/438] FROMLIST: net: qrtr: Expand control port access to root When qrtr is loaded as module, qrtr-ns runs from SELinux kmod_t domain. On targets using upstream SELinux policies, this domain does not receive CAP_NET_ADMIN, which prevents it from binding control port even though qrtr-ns is a trusted system component. Granting kmod_t the CAP_NET_ADMIN capability in policy is possible, but not desirable, as kmod_t is not expected to perform networking operations and widening its capability set is discouraged. To address this in a contained way within qrtr, extend the control port permission check to allow binding when either: - the process has CAP_NET_ADMIN, or - the process belongs to GLOBAL_ROOT_GID (root-equivalent tasks) This permits qrtr-ns to successfully bind its control port in kmod_t restricted environments without broadening SELinux capability assignments. Link: https://lore.kernel.org/r/20260205-qrtr-control-port-access-permission-v1-1-e900039e92d5@oss.qualcomm.com Co-developed-by: Deepak Kumar Singh Signed-off-by: Deepak Kumar Singh Signed-off-by: Vishnu Santhosh --- net/qrtr/af_qrtr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c index 55fd2dd375886..60e98a2f4bcb0 100644 --- a/net/qrtr/af_qrtr.c +++ b/net/qrtr/af_qrtr.c @@ -8,6 +8,7 @@ #include #include /* For TIOCINQ/OUTQ */ #include +#include #include #include @@ -738,7 +739,8 @@ static int qrtr_port_assign(struct qrtr_sock *ipc, int *port) if (!*port) { rc = xa_alloc(&qrtr_ports, port, ipc, QRTR_EPH_PORT_RANGE, GFP_KERNEL); - } else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) { + } else if (*port < QRTR_MIN_EPH_SOCKET && !(capable(CAP_NET_ADMIN) || + in_egroup_p(GLOBAL_ROOT_GID))) { rc = -EACCES; } else if (*port == QRTR_PORT_CTRL) { rc = xa_insert(&qrtr_ports, 0, ipc, GFP_KERNEL); From 3f29c36e143a36ad317d6b44b514aab2594f3555 Mon Sep 17 00:00:00 2001 From: Shivnandan Kumar Date: Fri, 27 Feb 2026 16:40:51 +0530 Subject: [PATCH 355/438] FROMLIST: soc: qcom: icc-bwmon: Update zone1_thres_count to 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce zone1_thres_count from 16 to 3 so the driver can lower the bus vote after 3 sample windows instead of waiting for 16. The previous 16‑window delay (~64 ms) is too long at higher FPS workloads, causing delayed decision making and measurable power regression. Empirical tuning showed that lower values (e.g., 2) made bwmon behavior jittery, while higher values (4–6) were stable but less responsive and reduced power savings. A value of 3 provided the best balance: responsive enough for timely power reduction while maintaining stable bwmon operation. Significant power savings were observed across multiple use cases when reducing the threshold from 16 to 3: USECASE zone1_thres_count=16 zone1_thres_count=3 4K video playback 236.15 mA 203.15 mA Sleep 7mA 6.9mA Display (idle display) 71.95mA 67.11mA Link: https://lore.kernel.org/r/20260227111051.1789439-1-pussin@qti.qualcomm.com Signed-off-by: Shivnandan Kumar Signed-off-by: Pushpendra Singh --- drivers/soc/qcom/icc-bwmon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c index 597f9025e4228..e46975da7dba6 100644 --- a/drivers/soc/qcom/icc-bwmon.c +++ b/drivers/soc/qcom/icc-bwmon.c @@ -830,7 +830,7 @@ static const struct icc_bwmon_data msm8998_bwmon_data = { static const struct icc_bwmon_data sdm845_cpu_bwmon_data = { .sample_ms = 4, .count_unit_kb = 64, - .zone1_thres_count = 16, + .zone1_thres_count = 3, .zone3_thres_count = 1, .quirks = BWMON_HAS_GLOBAL_IRQ, .regmap_fields = sdm845_cpu_bwmon_reg_fields, @@ -849,7 +849,7 @@ static const struct icc_bwmon_data sdm845_llcc_bwmon_data = { static const struct icc_bwmon_data sc7280_llcc_bwmon_data = { .sample_ms = 4, .count_unit_kb = 64, - .zone1_thres_count = 16, + .zone1_thres_count = 3, .zone3_thres_count = 1, .quirks = BWMON_NEEDS_FORCE_CLEAR, .regmap_fields = sdm845_llcc_bwmon_reg_fields, From b1899a76f7c358555a04023f7e1f142cbb6cf2ff Mon Sep 17 00:00:00 2001 From: Hrishabh Rajput Date: Tue, 18 Nov 2025 10:40:56 +0000 Subject: [PATCH 356/438] FROMLIST: firmware: qcom: scm: Register gunyah watchdog device To restrict Gunyah watchdog initialization to Qualcomm platforms running under the Gunyah Hypervisor, register the watchdog device in the QCOM SCM driver. When Gunyah is not present or Gunyah emulates MMIO-based watchdog, we expect Qualcomm watchdog or ARM SBSA watchdog device to be present in the devicetree. First, we make sure we're running under the Gunyah Hypervisor. Then we move to check if any of the above mentioned watchdog device nodes are present, if not then we proceed to register the SMC-based Gunyah watchdog device. Link: https://lore.kernel.org/all/20251118-gunyah_watchdog-v8-1-e5de12e2eef5@oss.qualcomm.com/ Reviewed-by: Dmitry Baryshkov Tested-by: Shivendra Pratap Tested-by: Neil Armstrong Signed-off-by: Hrishabh Rajput --- drivers/firmware/qcom/qcom_scm.c | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 8fbc96693a55f..1611e1ab3a31a 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2467,6 +2467,56 @@ int qcom_scm_qtee_callback_response(phys_addr_t buf, size_t buf_size, } EXPORT_SYMBOL(qcom_scm_qtee_callback_response); +static void qcom_scm_gunyah_wdt_free(void *data) +{ + struct platform_device *gunyah_wdt_dev = data; + + platform_device_unregister(gunyah_wdt_dev); +} + +static void qcom_scm_gunyah_wdt_init(struct qcom_scm *scm) +{ + struct platform_device *gunyah_wdt_dev; + struct device_node *np; + bool of_wdt_available; + int i; + static const uuid_t gunyah_uuid = UUID_INIT(0xc1d58fcd, 0xa453, 0x5fdb, + 0x92, 0x65, 0xce, 0x36, + 0x67, 0x3d, 0x5f, 0x14); + static const char * const of_wdt_compatible[] = { + "qcom,kpss-wdt", + "arm,sbsa-gwdt", + }; + + /* Bail out if we are not running under Gunyah */ + if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) || + !arm_smccc_hypervisor_has_uuid(&gunyah_uuid)) + return; + + /* + * Gunyah emulates either of Qualcomm watchdog or ARM SBSA watchdog on + * newer platforms. Bail out if we find them in the devicetree. + */ + for (i = 0; i < ARRAY_SIZE(of_wdt_compatible); i++) { + np = of_find_compatible_node(NULL, NULL, of_wdt_compatible[i]); + of_wdt_available = of_device_is_available(np); + of_node_put(np); + if (of_wdt_available) + return; + } + + gunyah_wdt_dev = platform_device_register_simple("gunyah-wdt", -1, + NULL, 0); + if (IS_ERR(gunyah_wdt_dev)) { + dev_err(scm->dev, "Failed to register Gunyah watchdog device: %ld\n", + PTR_ERR(gunyah_wdt_dev)); + return; + } + + devm_add_action_or_reset(scm->dev, qcom_scm_gunyah_wdt_free, + gunyah_wdt_dev); +} + static void qcom_scm_qtee_free(void *data) { struct platform_device *qtee_dev = data; @@ -2811,6 +2861,9 @@ static int qcom_scm_probe(struct platform_device *pdev) /* Initialize the QTEE object interface. */ qcom_scm_qtee_init(scm); + /* Initialize the Gunyah watchdog platform device. */ + qcom_scm_gunyah_wdt_init(scm); + return 0; } From 8d2e9b38958235c0291cd2e127585d4af93bc9c2 Mon Sep 17 00:00:00 2001 From: Hrishabh Rajput Date: Tue, 18 Nov 2025 10:40:57 +0000 Subject: [PATCH 357/438] FROMLIST: watchdog: Add driver for Gunyah Watchdog On Qualcomm SoCs running under the Gunyah hypervisor, access to watchdog through MMIO is not available on all platforms. Depending on the hypervisor configuration, the watchdog is either fully emulated or exposed via ARM's SMC Calling Conventions (SMCCC) through the Vendor Specific Hypervisor Service Calls space. Add driver to support the SMC-based watchdog provided by the Gunyah Hypervisor. Device registration is done in the QCOM SCM driver after checks to restrict the watchdog initialization to Qualcomm devices running under Gunyah. Gunyah watchdog is not a hardware but an SMC-based vendor-specific hypervisor interface provided by the Gunyah hypervisor. The design involving QCOM SCM driver for registering the platform device has been devised to avoid adding non-hardware nodes to devicetree. Link: https://lore.kernel.org/all/20251118-gunyah_watchdog-v8-2-e5de12e2eef5@oss.qualcomm.com/ Tested-by: Shivendra Pratap Tested-by: Neil Armstrong Signed-off-by: Hrishabh Rajput --- MAINTAINERS | 1 + drivers/watchdog/Kconfig | 13 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/gunyah_wdt.c | 261 ++++++++++++++++++++++++++++++++++ 4 files changed, 276 insertions(+) create mode 100644 drivers/watchdog/gunyah_wdt.c diff --git a/MAINTAINERS b/MAINTAINERS index 55af015174a54..8699187bc4bd0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3328,6 +3328,7 @@ F: arch/arm64/boot/dts/qcom/ F: drivers/bus/qcom* F: drivers/firmware/qcom/ F: drivers/soc/qcom/ +F: drivers/watchdog/gunyah_wdt.c F: include/dt-bindings/arm/qcom,ids.h F: include/dt-bindings/firmware/qcom,scm.h F: include/dt-bindings/soc/qcom* diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index dc78729ba2a5d..5f1dfb6ac41bf 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -2354,4 +2354,17 @@ config KEEMBAY_WATCHDOG To compile this driver as a module, choose M here: the module will be called keembay_wdt. +config GUNYAH_WATCHDOG + tristate "Qualcomm Gunyah Watchdog" + depends on ARCH_QCOM || COMPILE_TEST + depends on HAVE_ARM_SMCCC + select WATCHDOG_CORE + help + Say Y here to include support for watchdog timer provided by the + Gunyah hypervisor. The driver uses ARM SMC Calling Convention (SMCCC) + to interact with Gunyah Watchdog. + + To compile this driver as a module, choose M here: the + module will be called gunyah_wdt. + endif # WATCHDOG diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index d2fb16b9f9ce7..4d1547702ef03 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -103,6 +103,7 @@ obj-$(CONFIG_MSC313E_WATCHDOG) += msc313e_wdt.o obj-$(CONFIG_APPLE_WATCHDOG) += apple_wdt.o obj-$(CONFIG_SUNPLUS_WATCHDOG) += sunplus_wdt.o obj-$(CONFIG_MARVELL_GTI_WDT) += marvell_gti_wdt.o +obj-$(CONFIG_GUNYAH_WATCHDOG) += gunyah_wdt.o # X86 (i386 + ia64 + x86_64) Architecture obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o diff --git a/drivers/watchdog/gunyah_wdt.c b/drivers/watchdog/gunyah_wdt.c new file mode 100644 index 0000000000000..49dfef459e847 --- /dev/null +++ b/drivers/watchdog/gunyah_wdt.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GUNYAH_WDT_SMCCC_CALL_VAL(func_id) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32,\ + ARM_SMCCC_OWNER_VENDOR_HYP, func_id) + +/* SMCCC function IDs for watchdog operations */ +#define GUNYAH_WDT_CONTROL GUNYAH_WDT_SMCCC_CALL_VAL(0x0005) +#define GUNYAH_WDT_STATUS GUNYAH_WDT_SMCCC_CALL_VAL(0x0006) +#define GUNYAH_WDT_PING GUNYAH_WDT_SMCCC_CALL_VAL(0x0007) +#define GUNYAH_WDT_SET_TIME GUNYAH_WDT_SMCCC_CALL_VAL(0x0008) + +/* + * Control values for GUNYAH_WDT_CONTROL. + * Bit 0 is used to enable or disable the watchdog. If this bit is set, + * then the watchdog is enabled and vice versa. + * Bit 1 should always be set to 1 as this bit is reserved in Gunyah and + * it's expected to be 1. + */ +#define WDT_CTRL_ENABLE (BIT(1) | BIT(0)) +#define WDT_CTRL_DISABLE BIT(1) + +enum gunyah_error { + GUNYAH_ERROR_OK = 0, + GUNYAH_ERROR_UNIMPLEMENTED = -1, + GUNYAH_ERROR_ARG_INVAL = 1, +}; + +/** + * gunyah_error_remap() - Remap Gunyah hypervisor errors into a Linux error code + * @gunyah_error: Gunyah hypercall return value + */ +static inline int gunyah_error_remap(enum gunyah_error gunyah_error) +{ + switch (gunyah_error) { + case GUNYAH_ERROR_OK: + return 0; + case GUNYAH_ERROR_UNIMPLEMENTED: + return -EOPNOTSUPP; + default: + return -EINVAL; + } +} + +static int gunyah_wdt_call(unsigned long func_id, unsigned long arg1, + unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(func_id, arg1, arg2, &res); + return gunyah_error_remap(res.a0); +} + +static int gunyah_wdt_start(struct watchdog_device *wdd) +{ + unsigned int timeout_ms; + struct device *dev = wdd->parent; + int ret; + + ret = gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_DISABLE, 0); + if (ret && watchdog_active(wdd)) { + dev_err(dev, "%s: Failed to stop gunyah wdt %d\n", __func__, ret); + return ret; + } + + timeout_ms = wdd->timeout * 1000; + ret = gunyah_wdt_call(GUNYAH_WDT_SET_TIME, timeout_ms, timeout_ms); + if (ret) { + dev_err(dev, "%s: Failed to set timeout for gunyah wdt %d\n", + __func__, ret); + return ret; + } + + ret = gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_ENABLE, 0); + if (ret) + dev_err(dev, "%s: Failed to start gunyah wdt %d\n", __func__, ret); + + return ret; +} + +static int gunyah_wdt_stop(struct watchdog_device *wdd) +{ + return gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_DISABLE, 0); +} + +static int gunyah_wdt_ping(struct watchdog_device *wdd) +{ + return gunyah_wdt_call(GUNYAH_WDT_PING, 0, 0); +} + +static int gunyah_wdt_set_timeout(struct watchdog_device *wdd, + unsigned int timeout_sec) +{ + wdd->timeout = timeout_sec; + + if (watchdog_active(wdd)) + return gunyah_wdt_start(wdd); + + return 0; +} + +static int gunyah_wdt_get_time_since_last_ping(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(GUNYAH_WDT_STATUS, 0, 0, &res); + if (res.a0) + return gunyah_error_remap(res.a0); + + return res.a2 / 1000; +} + +static unsigned int gunyah_wdt_get_timeleft(struct watchdog_device *wdd) +{ + int seconds_since_last_ping; + + seconds_since_last_ping = gunyah_wdt_get_time_since_last_ping(); + if (seconds_since_last_ping < 0 || + seconds_since_last_ping > wdd->timeout) + return 0; + + return wdd->timeout - seconds_since_last_ping; +} + +static int gunyah_wdt_restart(struct watchdog_device *wdd, + unsigned long action, void *data) +{ + /* Set timeout to 1ms and send a ping */ + gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_DISABLE, 0); + gunyah_wdt_call(GUNYAH_WDT_SET_TIME, 1, 1); + gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_ENABLE, 0); + gunyah_wdt_call(GUNYAH_WDT_PING, 0, 0); + + /* Wait to make sure reset occurs */ + mdelay(100); + + return 0; +} + +static const struct watchdog_info gunyah_wdt_info = { + .identity = "Gunyah Watchdog", + .options = WDIOF_SETTIMEOUT + | WDIOF_KEEPALIVEPING + | WDIOF_MAGICCLOSE, +}; + +static const struct watchdog_ops gunyah_wdt_ops = { + .owner = THIS_MODULE, + .start = gunyah_wdt_start, + .stop = gunyah_wdt_stop, + .ping = gunyah_wdt_ping, + .set_timeout = gunyah_wdt_set_timeout, + .get_timeleft = gunyah_wdt_get_timeleft, + .restart = gunyah_wdt_restart +}; + +static int gunyah_wdt_probe(struct platform_device *pdev) +{ + struct watchdog_device *wdd; + struct device *dev = &pdev->dev; + int ret; + + ret = gunyah_wdt_call(GUNYAH_WDT_STATUS, 0, 0); + if (ret == -EOPNOTSUPP) + return -ENODEV; + + if (ret) + return dev_err_probe(dev, ret, "status check failed\n"); + + wdd = devm_kzalloc(dev, sizeof(*wdd), GFP_KERNEL); + if (!wdd) + return -ENOMEM; + + wdd->info = &gunyah_wdt_info; + wdd->ops = &gunyah_wdt_ops; + wdd->parent = dev; + + /* + * Although Gunyah expects 16-bit unsigned int values as timeout values + * in milliseconds, values above 0x8000 are reserved. This limits the + * max timeout value to 32 seconds. + */ + wdd->max_timeout = 32; /* seconds */ + wdd->min_timeout = 1; /* seconds */ + wdd->timeout = wdd->max_timeout; + + gunyah_wdt_stop(wdd); + platform_set_drvdata(pdev, wdd); + watchdog_set_restart_priority(wdd, 0); + + return devm_watchdog_register_device(dev, wdd); +} + +static void gunyah_wdt_remove(struct platform_device *pdev) +{ + struct watchdog_device *wdd = platform_get_drvdata(pdev); + + gunyah_wdt_stop(wdd); +} + +static int gunyah_wdt_suspend(struct device *dev) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + + if (watchdog_active(wdd)) + gunyah_wdt_stop(wdd); + + return 0; +} + +static int gunyah_wdt_resume(struct device *dev) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + + if (watchdog_active(wdd)) + gunyah_wdt_start(wdd); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(gunyah_wdt_pm_ops, gunyah_wdt_suspend, gunyah_wdt_resume); + +/* + * Gunyah watchdog is a vendor-specific hypervisor interface provided by the + * Gunyah hypervisor. Using QCOM SCM driver to detect Gunyah watchdog SMCCC + * hypervisor service and register platform device when the service is available + * allows this driver to operate independently of the devicetree and avoids + * adding the non-hardware nodes to the devicetree. + */ +static const struct platform_device_id gunyah_wdt_id[] = { + { .name = "gunyah-wdt" }, + {} +}; +MODULE_DEVICE_TABLE(platform, gunyah_wdt_id); + +static struct platform_driver gunyah_wdt_driver = { + .driver = { + .name = "gunyah-wdt", + .pm = pm_sleep_ptr(&gunyah_wdt_pm_ops), + }, + .id_table = gunyah_wdt_id, + .probe = gunyah_wdt_probe, + .remove = gunyah_wdt_remove, +}; + +module_platform_driver(gunyah_wdt_driver); + +MODULE_DESCRIPTION("Gunyah Watchdog Driver"); +MODULE_LICENSE("GPL"); From 97705ad448ee822520ccb69db325d6a3914848cc Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 2 Feb 2026 16:06:40 +0530 Subject: [PATCH 358/438] FROMLIST: soc: qcom: pd-mapper: Fix element length in servreg_loc_pfr_req_ei It looks element length declared in servreg_loc_pfr_req_ei for reason not matching servreg_loc_pfr_req's reason field due which we could observe decoding error on PD crash. qmi_decode_string_elem: String len 81 >= Max Len 65 Fix this by matching with servreg_loc_pfr_req's reason field. Cc: stable@vger.kernel.org Fixes: 1ebcde047c54 ("soc: qcom: add pd-mapper implementation") Reviewed-by: Dmitry Baryshkov Co-developed-by: Gokul Krishnakumar Signed-off-by: Gokul Krishnakumar Signed-off-by: Mukesh Ojha Signed-off-by: Xin Liu Link: https://lore.kernel.org/all/20260202103641.3003867-1-mukesh.ojha@oss.qualcomm.com/ --- drivers/soc/qcom/pdr_internal.h | 2 +- drivers/soc/qcom/qcom_pdr_msg.c | 2 +- include/linux/soc/qcom/pdr.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/pdr_internal.h b/drivers/soc/qcom/pdr_internal.h index 039508c1bbf7d..047c0160b6178 100644 --- a/drivers/soc/qcom/pdr_internal.h +++ b/drivers/soc/qcom/pdr_internal.h @@ -84,7 +84,7 @@ struct servreg_set_ack_resp { struct servreg_loc_pfr_req { char service[SERVREG_NAME_LENGTH + 1]; - char reason[257]; + char reason[SERVREG_PFR_LENGTH + 1]; }; struct servreg_loc_pfr_resp { diff --git a/drivers/soc/qcom/qcom_pdr_msg.c b/drivers/soc/qcom/qcom_pdr_msg.c index ca98932140d87..02022b11ecf05 100644 --- a/drivers/soc/qcom/qcom_pdr_msg.c +++ b/drivers/soc/qcom/qcom_pdr_msg.c @@ -325,7 +325,7 @@ const struct qmi_elem_info servreg_loc_pfr_req_ei[] = { }, { .data_type = QMI_STRING, - .elem_len = SERVREG_NAME_LENGTH + 1, + .elem_len = SERVREG_PFR_LENGTH + 1, .elem_size = sizeof(char), .array_type = VAR_LEN_ARRAY, .tlv_type = 0x02, diff --git a/include/linux/soc/qcom/pdr.h b/include/linux/soc/qcom/pdr.h index 83a8ea612e69a..2b7691e47c2a9 100644 --- a/include/linux/soc/qcom/pdr.h +++ b/include/linux/soc/qcom/pdr.h @@ -5,6 +5,7 @@ #include #define SERVREG_NAME_LENGTH 64 +#define SERVREG_PFR_LENGTH 256 struct pdr_service; struct pdr_handle; From c793ce5e280bffeca61ab6cdf9ef058c3ad92a99 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 2 Feb 2026 16:06:41 +0530 Subject: [PATCH 359/438] FROMLIST: soc: qcom: qmi: Print error codes in failure paths Few error paths in the qmi_interface module log a failure message but do not include the actual error code. Include the error value in the log so debugging failures becomes easier. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mukesh Ojha Signed-off-by: Xin Liu Link: https://lore.kernel.org/all/20260202103641.3003867-2-mukesh.ojha@oss.qualcomm.com/ --- drivers/soc/qcom/qmi_interface.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c index 16e2e24b60968..974ed2b3d611d 100644 --- a/drivers/soc/qcom/qmi_interface.c +++ b/drivers/soc/qcom/qmi_interface.c @@ -321,7 +321,7 @@ int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, mutex_lock(&qmi->txn_lock); ret = idr_alloc_cyclic(&qmi->txns, txn, 0, U16_MAX, GFP_KERNEL); if (ret < 0) - pr_err("failed to allocate transaction id\n"); + pr_err("failed to allocate transaction id: %d\n", ret); txn->id = ret; mutex_unlock(&qmi->txn_lock); @@ -413,7 +413,7 @@ static void qmi_invoke_handler(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, ret = qmi_decode_message(buf, len, handler->ei, dest); if (ret < 0) - pr_err("failed to decode incoming message\n"); + pr_err("failed to decode incoming message: %d\n", ret); else handler->fn(qmi, sq, txn, dest); @@ -502,7 +502,7 @@ static void qmi_handle_message(struct qmi_handle *qmi, if (txn->dest && txn->ei) { ret = qmi_decode_message(buf, len, txn->ei, txn->dest); if (ret < 0) - pr_err("failed to decode incoming message\n"); + pr_err("failed to decode incoming message: %d\n", ret); txn->result = ret; complete(&txn->completion); @@ -661,8 +661,8 @@ int qmi_handle_init(struct qmi_handle *qmi, size_t recv_buf_size, if (PTR_ERR(qmi->sock) == -EAFNOSUPPORT) { ret = -EPROBE_DEFER; } else { - pr_err("failed to create QMI socket\n"); ret = PTR_ERR(qmi->sock); + pr_err("failed to create QMI socket: %d\n", ret); } goto err_destroy_wq; } @@ -766,7 +766,7 @@ static ssize_t qmi_send_message(struct qmi_handle *qmi, if (qmi->sock) { ret = kernel_sendmsg(qmi->sock, &msghdr, &iv, 1, len); if (ret < 0) - pr_err("failed to send QMI message\n"); + pr_err("failed to send QMI message: %d\n", ret); } else { ret = -EPIPE; } From c48e3c41dd69003de5abfadfb66d2754ede45ac0 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 11 Dec 2025 11:41:01 -0800 Subject: [PATCH 360/438] FROMLIST: dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Add Glymur compatible Define a Glymur compatible string for the QMP combo PHY, along with resource requirements. Acked-by: Rob Herring (Arm) Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-1-42133596bda0@oss.qualcomm.com/ From f38e6d5c792a15b30de964edc493d059ad71c2c5 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 11 Dec 2025 11:47:27 -0800 Subject: [PATCH 361/438] FROMLIST: dt-bindings: phy: qcom-m31-eusb2: Add Glymur compatible Add the Glymur compatible to the M31 eUSB2 PHY, and use the SM8750 as the fallback. Signed-off-by: Wesley Cheng Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-3-42133596bda0@oss.qualcomm.com/ From cc2e94b33461862ee5e6594eb16f6aa8f1c6aceb Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:35 +0530 Subject: [PATCH 362/438] usb: misc: onboard_usb_hub: Add Genesys Logic GL3590 hub support Add support for the GL3590 4 ports USB3.2 hub. This allows to control its reset pins with a gpio. Signed-off-by: Swati Agarwal --- drivers/usb/misc/onboard_usb_dev.c | 1 + drivers/usb/misc/onboard_usb_dev.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c index ba37eb99efbaf..b52dafeefcda9 100644 --- a/drivers/usb/misc/onboard_usb_dev.c +++ b/drivers/usb/misc/onboard_usb_dev.c @@ -661,6 +661,7 @@ static const struct usb_device_id onboard_dev_id_table[] = { { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 HUB */ + { USB_DEVICE(VENDOR_ID_GENESYS, 0x0625) }, /* Genesys Logic GL3590 USB 3.2 HUB */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 HUB */ diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h index 1a1e86e60e042..978acc662ce41 100644 --- a/drivers/usb/misc/onboard_usb_dev.h +++ b/drivers/usb/misc/onboard_usb_dev.h @@ -147,6 +147,7 @@ static const struct of_device_id onboard_dev_match[] = { { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, }, { .compatible = "usb5e3,610", .data = &genesys_gl852g_data, }, { .compatible = "usb5e3,620", .data = &genesys_gl852g_data, }, + { .compatible = "usb5e3,625", .data = &genesys_gl852g_data, }, { .compatible = "usb5e3,626", .data = &genesys_gl852g_data, }, { .compatible = "usbbda,179", .data = &realtek_rtl8188etv_data, }, { .compatible = "usbbda,411", .data = &realtek_rts5411_data, }, From 8b065550dc1cd2fe225b6f62d8fa980e7c5aa87f Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:34 +0530 Subject: [PATCH 363/438] dt-bindings: usb: Add binding for Genesys Logic GL3590 hub Add the binding for the USB3.2 Genesys Logic GL3590 hub. Signed-off-by: Swati Agarwal --- .../devicetree/bindings/usb/genesys,gl850g.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml index 9a94b2a74a1eb..a184e1074c7c4 100644 --- a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml +++ b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml @@ -15,6 +15,7 @@ properties: - usb5e3,608 - usb5e3,610 - usb5e3,620 + - usb5e3,625 - usb5e3,626 reg: true @@ -69,6 +70,17 @@ allOf: peer-hub: true vdd-supply: true + - if: + properties: + compatible: + contains: + enum: + - usb5e3,625 + then: + properties: + peer-hub: true + vdd-supply: false + unevaluatedProperties: false examples: From c6471c8611a6aa9ff31a902ef37d3f9ca3938c3c Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:22 -0800 Subject: [PATCH 364/438] FROMLIST: dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Qualcomm Embedded USB Debugger (EUD) can intercept one or two independent High-Speed UTMI paths, depending on the SoC. Each path is distinct with its own HS-PHY interface, connector/controller wiring, and UTMI routing behavior. The EUD hardware sits between the USB2 PHY and the USB controller on each path. The existing binding models only a single UTMI path and does not provide a way to associate the required High-Speed USB PHY. EUD relies on the HS-PHY on the selected UTMI path for link signalling and correct operation of the hardware. Historically, EUD has worked on platforms that use a single UTMI path because the USB controller maintains ownership of the PHY during enumeration and normal operation. This implicit relationship allowed EUD to function even though the dependency on the PHY was not described in the binding. However, this behavior is not guaranteed by hardware. The current binding description is not sufficient for SoCs that expose two independent UTMI paths, where the PHY association and port wiring must be explicitly described. Introduce per-path eud-path child nodes so each UTMI path can describe its HS-PHY, port connections, and the role‑switching capability of its associated USB port. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-2-elson.serrao@oss.qualcomm.com/ --- .../bindings/soc/qcom/qcom,eud.yaml | 100 +++++++++++++----- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml index 84218636c0d8d..0507252dbf27e 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml @@ -10,8 +10,11 @@ maintainers: - Souradeep Chowdhury description: - This binding is used to describe the Qualcomm Embedded USB Debugger, which is - mini USB-hub implemented on chip to support USB-based debug capabilities. + This binding describes the Qualcomm Embedded USB Debugger (EUD), an on-chip + mini USB hub that enables USB-based debug capabilities. The EUD block is + positioned between the High-Speed USB PHY and the USB controller, where it + intercepts the UTMI interface to support debug and bypass modes. EUD can be + supported on up to two High-Speed USB ports. properties: compatible: @@ -29,26 +32,62 @@ properties: description: EUD interrupt maxItems: 1 - ports: - $ref: /schemas/graph.yaml#/properties/ports + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^eud-path@[0-1]$": + type: object description: - These ports is to be attached to the endpoint of the DWC3 controller node - and type C connector node. The controller has the "usb-role-switch" - property. + Represents one High-Speed UTMI path that EUD intercepts. This node models + the physical data path intercepted by EUD and provides graph endpoints to + link the USB controller and the external connector associated with this path. properties: - port@0: - $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the DWC3 controller. + reg: + maxItems: 1 + description: Path number + + phys: + maxItems: 1 + description: High-Speed USB PHY associated with this data path. + + usb-role-switch: + type: boolean + description: + Set this property if the USB port on this path is role switch capable. + In device role, debug mode inserts the EUD hub into the UTMI path. In + host role, the EUD hub is bypassed and UTMI traffic flows directly + between the PHY and the USB controller. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: + These ports are to be attached to the endpoint of the USB controller node + and USB connector node. + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the USB controller. - port@1: - $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the type C connector. + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the USB connector. + + required: + - reg + - phys + - ports + + additionalProperties: false required: - compatible - reg - - ports additionalProperties: false @@ -58,21 +97,30 @@ examples: compatible = "qcom,sc7280-eud", "qcom,eud"; reg = <0x88e0000 0x2000>, <0x88e2000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + eud-path@0 { + reg = <0>; + phys = <&usb_1_hsphy>; + usb-role-switch; - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - eud_ep: endpoint { - remote-endpoint = <&usb2_role_switch>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + eud_ep: endpoint { + remote-endpoint = <&usb2_role_switch>; + }; }; - }; - port@1 { - reg = <1>; - eud_con: endpoint { - remote-endpoint = <&con_eud>; + port@1 { + reg = <1>; + eud_con: endpoint { + remote-endpoint = <&con_eud>; + }; }; }; }; From 1fa01a19f261eda06af16ca1f1d5b398acd89748 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:23 -0800 Subject: [PATCH 365/438] FROMLIST: usb: misc: qcom_eud: add sysfs attribute for port selection EUD can be mapped to either the primary USB port or the secondary USB port depending on the value of the EUD_PORT_SEL register. Add a 'port' sysfs attribute to allow userspace to select which port EUD should operate on and update the ABI documentation. This is needed for systems with dual USB ports where EUD needs to be accessible on either port depending on the system configuration and use case. Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-3-elson.serrao@oss.qualcomm.com/ --- Documentation/ABI/testing/sysfs-driver-eud | 16 ++++++++ drivers/usb/misc/qcom_eud.c | 43 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud index 2bab0db2d2f0f..67223f73ee606 100644 --- a/Documentation/ABI/testing/sysfs-driver-eud +++ b/Documentation/ABI/testing/sysfs-driver-eud @@ -7,3 +7,19 @@ Description: EUD based on a 1 or a 0 value. By enabling EUD, the user is able to activate the mini-usb hub of EUD for debug and trace capabilities. + +What: /sys/bus/platform/drivers/qcom_eud/.../port +Date: January 2026 +Contact: Elson Serrao +Description: + Selects which USB port the Embedded USB Debugger (EUD) + is mapped to on platforms providing multiple High-Speed + USB ports. + + Valid values: + 0 - Primary USB port + 1 - Secondary USB port + + The attribute is writable only while EUD is disabled. + Reading the attribute returns the currently selected + USB port number. diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 926419ca560fc..1a136f8f1ae52 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -23,8 +23,11 @@ #define EUD_REG_VBUS_INT_CLR 0x0080 #define EUD_REG_CSR_EUD_EN 0x1014 #define EUD_REG_SW_ATTACH_DET 0x1018 +#define EUD_REG_PORT_SEL 0x1028 #define EUD_REG_EUD_EN2 0x0000 +#define EUD_MAX_PORTS 2 + #define EUD_ENABLE BIT(0) #define EUD_INT_PET_EUD BIT(0) #define EUD_INT_VBUS BIT(2) @@ -40,6 +43,7 @@ struct eud_chip { int irq; bool enabled; bool usb_attached; + u8 port_idx; }; static int enable_eud(struct eud_chip *priv) @@ -104,8 +108,47 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR_RW(enable); +static ssize_t port_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct eud_chip *chip = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%u\n", chip->port_idx); +} + +static ssize_t port_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct eud_chip *chip = dev_get_drvdata(dev); + u8 port; + int ret; + + ret = kstrtou8(buf, 0, &port); + if (ret) + return ret; + + /* Only port 0 and port 1 are valid */ + if (port >= EUD_MAX_PORTS) + return -EINVAL; + + /* Port selection must be done before enabling EUD */ + if (chip->enabled) { + dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); + return -EBUSY; + } + + writel(port, chip->base + EUD_REG_PORT_SEL); + chip->port_idx = port; + + return count; +} + +static DEVICE_ATTR_RW(port); + static struct attribute *eud_attrs[] = { &dev_attr_enable.attr, + &dev_attr_port.attr, NULL, }; ATTRIBUTE_GROUPS(eud); From 6ae596966375fadb03b48dd2c0905be75a639984 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:24 -0800 Subject: [PATCH 366/438] FROMLIST: usb: misc: qcom_eud: add per-path High-Speed PHY control EUD hardware can support multiple High-Speed USB paths, each routed through its own PHY. The active path is selected in hardware via the EUD_PORT_SEL register. As a High-Speed hub, EUD requires access to the High-Speed PHY associated with the active UTMI path. To support this multi-path capability, the driver must manage PHY resources on a per-path basis, ensuring that the PHY for the currently selected path is properly initialized and powered. This patch restructures the driver to implement per-path PHY management. The driver now powers the appropriate PHY based on the selected and enabled UTMI path, ensuring correct operation when EUD is enabled. Supporting this requires describing the available UTMI paths and their corresponding PHYs in Device Tree. This updates DT requirements and is not backward compatible with older DTs that lacked this description. Historically, EUD appeared to work on single-path systems because the USB controller kept the PHY initialized. However, EUD is designed to operate independently of the USB controller and therefore requires explicit PHY control. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-4-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 130 +++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 1a136f8f1ae52..5cebb64f4a672 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -34,26 +35,96 @@ #define EUD_INT_SAFE_MODE BIT(4) #define EUD_INT_ALL (EUD_INT_VBUS | EUD_INT_SAFE_MODE) +struct eud_path { + struct eud_chip *chip; + struct phy *phy; + u8 num; +}; + struct eud_chip { struct device *dev; struct usb_role_switch *role_sw; void __iomem *base; + struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; + bool phy_enabled; u8 port_idx; }; +static int eud_phy_enable(struct eud_chip *chip) +{ + struct eud_path *path; + struct phy *phy; + int ret; + + if (chip->phy_enabled) + return 0; + + path = chip->paths[chip->port_idx]; + if (!path || !path->phy) { + dev_err(chip->dev, "No PHY configured for port %u\n", chip->port_idx); + return -ENODEV; + } + + phy = path->phy; + + ret = phy_init(phy); + if (ret) { + dev_err(chip->dev, "Failed to initialize USB2 PHY for port %u: %d\n", + chip->port_idx, ret); + return ret; + } + + ret = phy_power_on(phy); + if (ret) { + dev_err(chip->dev, "Failed to power on USB2 PHY for port %u: %d\n", + chip->port_idx, ret); + phy_exit(phy); + return ret; + } + + chip->phy_enabled = true; + + return 0; +} + +static void eud_phy_disable(struct eud_chip *chip) +{ + struct eud_path *path; + struct phy *phy; + + if (!chip->phy_enabled) + return; + + path = chip->paths[chip->port_idx]; + if (!path || !path->phy) + return; + + phy = path->phy; + + phy_power_off(phy); + phy_exit(phy); + chip->phy_enabled = false; +} + static int enable_eud(struct eud_chip *priv) { int ret; - ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + ret = eud_phy_enable(priv); if (ret) return ret; + ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + if (ret) { + eud_phy_disable(priv); + return ret; + } + writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN); writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); @@ -70,6 +141,8 @@ static int disable_eud(struct eud_chip *priv) return ret; writel(0, priv->base + EUD_REG_CSR_EUD_EN); + eud_phy_disable(priv); + return 0; } @@ -132,6 +205,12 @@ static ssize_t port_store(struct device *dev, if (port >= EUD_MAX_PORTS) return -EINVAL; + /* Check if the corresponding path is available */ + if (!chip->paths[port]) { + dev_err(chip->dev, "EUD not supported on selected port\n"); + return -EOPNOTSUPP; + } + /* Port selection must be done before enabling EUD */ if (chip->enabled) { dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); @@ -231,8 +310,45 @@ static void eud_role_switch_release(void *data) usb_role_switch_put(chip->role_sw); } +static int eud_init_path(struct eud_chip *chip, struct device_node *np) +{ + struct eud_path *path; + u32 path_num; + int ret; + + ret = of_property_read_u32(np, "reg", &path_num); + if (ret) { + dev_err(chip->dev, "Missing 'reg' property in path node\n"); + return ret; + } + + if (path_num >= EUD_MAX_PORTS) { + dev_err(chip->dev, "Invalid path number: %u (max %d)\n", + path_num, EUD_MAX_PORTS - 1); + return -EINVAL; + } + + path = devm_kzalloc(chip->dev, sizeof(*path), GFP_KERNEL); + if (!path) + return -ENOMEM; + + path->chip = chip; + path->num = path_num; + + path->phy = devm_of_phy_get(chip->dev, np, NULL); + if (IS_ERR(path->phy)) + return dev_err_probe(chip->dev, PTR_ERR(path->phy), + "Failed to get PHY for path %d\n", path_num); + + chip->paths[path_num] = path; + + return 0; +} + static int eud_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; + struct device_node *child; struct eud_chip *chip; struct resource *res; int ret; @@ -252,6 +368,18 @@ static int eud_probe(struct platform_device *pdev) if (ret) return ret; + for_each_child_of_node(np, child) { + ret = eud_init_path(chip, child); + if (ret) { + of_node_put(child); + return ret; + } + } + + /* Primary path is mandatory. Secondary is optional */ + if (!chip->paths[0]) + return -ENODEV; + chip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chip->base)) return PTR_ERR(chip->base); From 93814670f87c5b431e3dbc5504505c67892206fb Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:25 -0800 Subject: [PATCH 367/438] FROMLIST: usb: misc: qcom_eud: add per-path role switch support The EUD hardware can support multiple High-Speed USB paths, each connected to different USB controllers. The current implementation uses a single chip-level role switch, which cannot properly handle multi-path configurations where each path needs independent role management. Since EUD is physically present between the USB connector and the controller, it should also relay the role change requests from the connector. Restructure the driver to support per-path role switches and remove the chip-level role switch. Additionally, as EUD need not modify the USB role upon enabling, remove the unnecessary role switch call from enable_eud(). Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-5-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 80 ++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 5cebb64f4a672..a58022f50484f 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -38,12 +38,15 @@ struct eud_path { struct eud_chip *chip; struct phy *phy; + struct usb_role_switch *controller_sw; + struct usb_role_switch *eud_sw; + enum usb_role curr_role; + char name[16]; u8 num; }; struct eud_chip { struct device *dev; - struct usb_role_switch *role_sw; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; @@ -129,7 +132,7 @@ static int enable_eud(struct eud_chip *priv) writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); - return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE); + return 0; } static int disable_eud(struct eud_chip *priv) @@ -287,15 +290,21 @@ static irqreturn_t handle_eud_irq(int irq, void *data) static irqreturn_t handle_eud_irq_thread(int irq, void *data) { struct eud_chip *chip = data; + struct eud_path *path; int ret; + path = chip->paths[chip->port_idx]; + if (!path || !path->controller_sw) + goto clear_irq; + if (chip->usb_attached) - ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_DEVICE); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_HOST); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); if (ret) dev_err(chip->dev, "failed to set role switch\n"); +clear_irq: /* set and clear vbus_int_clr[0] to clear interrupt */ writel(BIT(0), chip->base + EUD_REG_VBUS_INT_CLR); writel(0, chip->base + EUD_REG_VBUS_INT_CLR); @@ -303,15 +312,45 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) return IRQ_HANDLED; } +static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role) +{ + struct eud_path *path = usb_role_switch_get_drvdata(sw); + int ret; + + /* Forward the role request to the USB controller */ + ret = usb_role_switch_set_role(path->controller_sw, role); + if (ret) { + dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n", + usb_role_string(role), path->num, ret); + return ret; + } + + path->curr_role = role; + + return 0; +} + static void eud_role_switch_release(void *data) { struct eud_chip *chip = data; + int i; - usb_role_switch_put(chip->role_sw); + for (i = 0; i < EUD_MAX_PORTS; i++) { + struct eud_path *path = chip->paths[i]; + + if (!path) + continue; + + if (path->eud_sw) + usb_role_switch_unregister(path->eud_sw); + if (path->controller_sw) + usb_role_switch_put(path->controller_sw); + } } static int eud_init_path(struct eud_chip *chip, struct device_node *np) { + struct usb_role_switch_desc role_sw_desc = {}; struct eud_path *path; u32 path_num; int ret; @@ -342,6 +381,32 @@ static int eud_init_path(struct eud_chip *chip, struct device_node *np) chip->paths[path_num] = path; + path->curr_role = USB_ROLE_NONE; + + if (!of_property_read_bool(np, "usb-role-switch")) + return 0; + + /* Fetch the USB controller's role switch */ + path->controller_sw = fwnode_usb_role_switch_get(of_fwnode_handle(np)); + if (IS_ERR(path->controller_sw)) + return dev_err_probe(chip->dev, PTR_ERR(path->controller_sw), + "Failed to get controller role switch for path %d\n", + path_num); + + /* Create a role switch */ + role_sw_desc.fwnode = of_fwnode_handle(np); + role_sw_desc.set = eud_role_switch_set; + role_sw_desc.driver_data = path; + snprintf(path->name, sizeof(path->name), "eud-path%u", path_num); + role_sw_desc.name = path->name; + + path->eud_sw = usb_role_switch_register(chip->dev, &role_sw_desc); + if (IS_ERR(path->eud_sw)) { + dev_err(chip->dev, "Failed to register EUD role switch for path %d: %ld\n", + path_num, PTR_ERR(path->eud_sw)); + return PTR_ERR(path->eud_sw); + } + return 0; } @@ -359,11 +424,6 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; - chip->role_sw = usb_role_switch_get(&pdev->dev); - if (IS_ERR(chip->role_sw)) - return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), - "failed to get role switch\n"); - ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From c52030819d59d6ca0706b1c0e0bce8fec831e990 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:26 -0800 Subject: [PATCH 368/438] FROMLIST: usb: misc: qcom_eud: improve enable_store API Currently enable_store() allows operations irrespective of the EUD state, which can result in redundant operations. Avoid this by adding duplicate state checks to skip requests when EUD is already in the desired state. Additionally, improve error handling with explicit logging to provide better feedback. Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-6-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index a58022f50484f..0ea6491f963ce 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -168,18 +168,27 @@ static ssize_t enable_store(struct device *dev, if (kstrtobool(buf, &enable)) return -EINVAL; + /* Skip operation if already in desired state */ + if (chip->enabled == enable) + return count; + if (enable) { ret = enable_eud(chip); - if (!ret) - chip->enabled = enable; - else - disable_eud(chip); - + if (ret) { + dev_err(chip->dev, "failed to enable eud\n"); + return ret; + } } else { ret = disable_eud(chip); + if (ret) { + dev_err(chip->dev, "failed to disable eud\n"); + return ret; + } } - return ret < 0 ? ret : count; + chip->enabled = enable; + + return count; } static DEVICE_ATTR_RW(enable); From d08159955128bdfd387288e289054f442055b9e0 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:27 -0800 Subject: [PATCH 369/438] FROMLIST: usb: misc: qcom_eud: add host mode coordination EUD functions by presenting itself as a USB device to the host PC for debugging, making it incompatible in USB host mode configurations. Enabling EUD, when in host mode can also cause the USB controller to misbehave as the EUD hub can only have one upstream facing port. Handle below two scenarios to prevent these conflicts: 1. Prevent user from enabling EUD via sysfs when the USB port is in host mode. 2. Automatically disable EUD when USB port switches to host mode and re-enable it when exiting host mode. This ensures consistent state management without creating conflicts between the EUD debug hub and the USB controller. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-7-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 79 ++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 0ea6491f963ce..3f1cc7ea2a6ae 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -49,12 +49,15 @@ struct eud_chip { struct device *dev; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; + /* serializes EUD control operations */ + struct mutex state_lock; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; bool phy_enabled; + bool eud_disabled_for_host; u8 port_idx; }; @@ -162,32 +165,66 @@ static ssize_t enable_store(struct device *dev, const char *buf, size_t count) { struct eud_chip *chip = dev_get_drvdata(dev); + struct eud_path *path; bool enable; int ret; if (kstrtobool(buf, &enable)) return -EINVAL; + mutex_lock(&chip->state_lock); + /* Skip operation if already in desired state */ - if (chip->enabled == enable) + if (chip->enabled == enable) { + mutex_unlock(&chip->state_lock); return count; + } + + /* + * Handle double-disable scenario: User is disabling EUD that was already + * disabled due to host mode. Since the hardware is already disabled, we + * only need to clear the host-disabled flag to prevent unwanted re-enabling + * when exiting host mode. This respects the user's explicit disable request. + */ + if (!enable && chip->eud_disabled_for_host) { + chip->eud_disabled_for_host = false; + chip->enabled = false; + mutex_unlock(&chip->state_lock); + return count; + } if (enable) { + /* + * EUD functions by presenting itself as a USB device to the host PC for + * debugging, making it incompatible in USB host mode configuration. + * Prevent enabling EUD in this configuration to avoid hardware conflicts. + */ + path = chip->paths[chip->port_idx]; + if (path && path->curr_role == USB_ROLE_HOST) { + dev_err(chip->dev, "EUD not usable in host mode configuration\n"); + mutex_unlock(&chip->state_lock); + return -EBUSY; + } + ret = enable_eud(chip); if (ret) { dev_err(chip->dev, "failed to enable eud\n"); + mutex_unlock(&chip->state_lock); return ret; } } else { ret = disable_eud(chip); if (ret) { dev_err(chip->dev, "failed to disable eud\n"); + mutex_unlock(&chip->state_lock); return ret; } } chip->enabled = enable; + mutex_unlock(&chip->state_lock); + return count; } @@ -324,18 +361,56 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role) { struct eud_path *path = usb_role_switch_get_drvdata(sw); + struct eud_chip *chip = path->chip; int ret; + mutex_lock(&chip->state_lock); + + /* + * EUD must be disabled when USB operates in host mode. EUD functions by + * presenting itself as a USB device to the host PC for debugging, making + * it incompatible in host mode configuration. + * + * chip->enabled preserves user's sysfs configuration and is not modified + * during host mode transitions to maintain user intent. + */ + + /* Only act if EUD is enabled and this is the active path */ + if (chip->enabled && path->num == chip->port_idx) { + if (role == USB_ROLE_HOST && !chip->eud_disabled_for_host) { + ret = disable_eud(chip); + if (ret) { + dev_err(chip->dev, "Failed to disable EUD for host mode: %d\n", + ret); + mutex_unlock(&chip->state_lock); + return ret; + } + chip->eud_disabled_for_host = true; + } else if (role != USB_ROLE_HOST && chip->eud_disabled_for_host) { + ret = enable_eud(chip); + if (ret) { + dev_err(chip->dev, "Failed to re-enable EUD after host mode: %d\n", + ret); + mutex_unlock(&chip->state_lock); + return ret; + } + chip->eud_disabled_for_host = false; + } + } + /* Forward the role request to the USB controller */ ret = usb_role_switch_set_role(path->controller_sw, role); if (ret) { dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n", usb_role_string(role), path->num, ret); + mutex_unlock(&chip->state_lock); return ret; } path->curr_role = role; + mutex_unlock(&chip->state_lock); + return 0; } @@ -433,6 +508,8 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; + mutex_init(&chip->state_lock); + ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From 64a83b467c4098c5bd524aae26bf6bbab3edc35e Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:28 -0800 Subject: [PATCH 370/438] FROMLIST: usb: misc: qcom_eud: fix virtual attach/detach event handling EUD provides virtual USB attach/detach events to simulate cable plug/unplug while maintaining the physical debug connection. However, the current implementation incorrectly sets the USB role to HOST on virtual detach, which doesn't represent the disconnected state. Fix the virtual detach handling by setting the USB role to NONE instead of HOST, correctly representing the disconnected state. Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio https://lore.kernel.org/linux-usb/20260126233830.2193816-8-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 3f1cc7ea2a6ae..60f566427abe2 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -343,10 +343,26 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) if (!path || !path->controller_sw) goto clear_irq; + /* + * EUD virtual attach/detach event handling for low power debugging: + * + * When EUD is enabled in debug mode, the device remains physically + * connected to the PC throughout the debug session, keeping the USB + * controller active. This prevents testing of low power scenarios that + * require USB disconnection. + * + * EUD solves this by providing virtual USB attach/detach events while + * maintaining the physical connection. These events are triggered from + * the Host PC via the enumerated EUD control interface and delivered + * to the EUD driver as interrupts. + * + * These notifications are forwarded to the USB controller through role + * switch framework. + */ if (chip->usb_attached) ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_NONE); if (ret) dev_err(chip->dev, "failed to set role switch\n"); From cf045b3fd46dfa242988d3f7ebd3d643fe88b550 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:29 -0800 Subject: [PATCH 371/438] FROMLIST: arm64: dts: qcom: kodiak: Align EUD node with binding The EUD node does not match the current binding and maps USB endpoints to the secondary controller. This SoC supports EUD only on the primary High-Speed USB path. The binding also requires a per-path PHY reference. Model the primary UTMI path as a child node with the required PHY and an empty ports graph. Leave endpoint mapping to board DTS files, and remove the secondary mapping and associated ports so the description conforms to the binding. Signed-off-by: Elson Serrao iLink: https://lore.kernel.org/linux-usb/20260126233830.2193816-9-elson.serrao@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 33 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 6079e67ea829b..5d40ffb06e4b7 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4294,12 +4294,6 @@ phy-names = "usb2-phy"; maximum-speed = "high-speed"; usb-role-switch; - - port { - usb2_role_switch: endpoint { - remote-endpoint = <&eud_ep>; - }; - }; }; qspi: spi@88dc000 { @@ -4623,16 +4617,29 @@ <0 0x88e2000 0 0x1000>; interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; - ports { - #address-cells = <1>; - #size-cells = <0>; + eud0: eud-path@0 { + reg = <0>; + phys = <&usb_1_hsphy>; - port@0 { - reg = <0>; - eud_ep: endpoint { - remote-endpoint = <&usb2_role_switch>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + eud_usb0: endpoint { + }; + }; + + port@1 { + reg = <1>; + eud_con0: endpoint { + }; }; }; }; From 0168a4cc6044d9efd23f49565c99f97ab36ad543 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:30 -0800 Subject: [PATCH 372/438] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality On this board, EUD resides on the primary High-Speed USB data path between the connector and the DWC3 controller. Update the device tree connections to correctly map the connector and controller endpoints, and describe role-switch capability on the EUD primary path. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-10-elson.serrao@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index e3d2f01881ae0..293c390094051 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -194,7 +194,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con0>; }; }; @@ -1304,13 +1304,29 @@ }; &usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; + remote-endpoint = <&eud_usb0>; }; &usb_1_dwc3_ss { remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; }; +&eud_con0 { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&eud_usb0 { + remote-endpoint = <&usb_1_dwc3_hs>; +}; + +&eud { + status = "okay"; +}; + +&eud0 { + usb-role-switch; +}; + &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; From 6f0f9bc95cab570b64b2bfe415003af6596343eb Mon Sep 17 00:00:00 2001 From: Jan Remmet Date: Fri, 23 Jan 2026 15:52:37 +0100 Subject: [PATCH 373/438] FROMLIST: usb: typec: hd3ss3220: Enable VBUS based on role state For systems where the ID pin isn't available as gpio use the ATTACHED_STATE register instead to control vbus. >From the datasheet: "This is an additional method to communicate attach other than the ID pin. These bits can be read by the application to determine what was attached." Use this method if id-gpios property is not set, but the connector node has vbus-supply defined. Check regulator state as peripheral and detach can disable vbus. Signed-off-by: Jan Remmet From 9ea5ee5acfdb279407267ae4697bcc1e415fcb22 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Mon, 16 Feb 2026 01:35:33 +0530 Subject: [PATCH 374/438] FROMLIST: usb: typec: hd3ss3220: Add wakeup support from system suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HD3SS3220's interrupt is disabled during system suspend, so a USB‑C cable connect/attach event cannot wake the system. This prevents resume from low‑power modes when the port controller is expected to act as a wakeup source. Add wakeup support by: - Initialize the device as wakeup‑capable. - Enable the HD3SS3220 IRQ as a wakeup interrupt. - Add suspend/resume callbacks to enable or disable the IRQ for wakeup depending on the device's wakeup configuration. With this, USB‑C cable insertion correctly wakes the system from suspend. Link: https://lore.kernel.org/all/20260215183325.3836178-2-swati.agarwal@oss.qualcomm.com/ Signed-off-by: Swati Agarwal --- drivers/usb/typec/hd3ss3220.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index 3e39b800e6b5f..b56df9349f89b 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -501,6 +501,11 @@ static int hd3ss3220_probe(struct i2c_client *client) if (hd3ss3220->poll) schedule_delayed_work(&hd3ss3220->output_poll_work, HZ); + if (client->irq && device_property_read_bool(hd3ss3220->dev, "wakeup-source")) { + device_init_wakeup(&client->dev, true); + enable_irq_wake(client->irq); + } + dev_info(&client->dev, "probed revision=0x%x\n", ret); return 0; @@ -525,6 +530,35 @@ static void hd3ss3220_remove(struct i2c_client *client) usb_role_switch_put(hd3ss3220->role_sw); } +static int __maybe_unused hd3ss3220_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(client->irq); + else + disable_irq(client->irq); + + return 0; +} + +static int __maybe_unused hd3ss3220_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(client->irq); + else + enable_irq(client->irq); + + return 0; +} + +static const struct dev_pm_ops hd3ss3220_pm_ops = { + .suspend = hd3ss3220_suspend, + .resume = hd3ss3220_resume, +}; + static const struct of_device_id dev_ids[] = { { .compatible = "ti,hd3ss3220"}, {} @@ -535,6 +569,7 @@ static struct i2c_driver hd3ss3220_driver = { .driver = { .name = "hd3ss3220", .of_match_table = dev_ids, + .pm = &hd3ss3220_pm_ops, }, .probe = hd3ss3220_probe, .remove = hd3ss3220_remove, From 2fde4f1e98f68786ecaf2f501158ed809df4fb7d Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Fri, 20 Feb 2026 16:01:25 +0530 Subject: [PATCH 375/438] Revert "FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality" This reverts commit e65028c6aae9f531066bdfc487454ed45e0834a9. Issue is observed with this commit e65028c6aae9f531066bdfc487454ed45e0834a9 leading to crash, with following call stack [ 19.706310][ T73] Call trace: [ 19.706312][ T73] usb_role_switch_unregister+0x28/0x70 (P) [ 19.706319][ T73] eud_role_switch_release+0x30/0x78 [qcom_eud] [ 19.884972][ T73] devm_action_release+0x1c/0x30 [ 19.884981][ T73] release_nodes+0x70/0x120 [ 19.884987][ T73] devres_release_all+0x98/0xf0 [ 19.884995][ T73] device_unbind_cleanup+0x20/0x98 [ 19.885000][ T73] really_probe+0x184/0x3f0 [ 19.885005][ T73] __driver_probe_device+0x88/0x190 [ 19.885010][ T73] driver_probe_device+0x44/0x120 [ 19.885015][ T73] __device_attach_driver+0xc4/0x178 [ 19.885020][ T73] bus_for_each_drv+0x90/0xf8 [ 19.885027][ T73] __device_attach+0xa8/0x1d8 [ 19.885032][ T73] device_initial_probe+0x58/0x68 [ 19.885037][ T73] bus_probe_device+0x40/0xb8 [ 19.885041][ T73] deferred_probe_work_func+0xbc/0x128 [ 19.885046][ T73] process_one_work+0x180/0x450 [ 19.885055][ T73] worker_thread+0x26c/0x388 [ 19.885062][ T73] kthread+0x120/0x140 [ 19.885068][ T73] ret_from_fork+0x10/0x20 [ 19.885079][ T73] Code: f9000bf3 aa0003f3 b140041f 54000168 (390c901f) [ 19.885083][ T73] ---[ end trace 0000000000000000 ]--- [ 19.885088][ T73] Kernel panic - not syncing: Oops: Fatal exception [ 19.885091][ T73] SMP: stopping secondary CPUs Revert commit for now. Signed-off-by: Salendarsingh Gaud --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index 293c390094051..e3d2f01881ae0 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -194,7 +194,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&eud_con0>; + remote-endpoint = <&usb_1_dwc3_hs>; }; }; @@ -1304,29 +1304,13 @@ }; &usb_1_dwc3_hs { - remote-endpoint = <&eud_usb0>; + remote-endpoint = <&pmic_glink_hs_in>; }; &usb_1_dwc3_ss { remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; }; -&eud_con0 { - remote-endpoint = <&pmic_glink_hs_in>; -}; - -&eud_usb0 { - remote-endpoint = <&usb_1_dwc3_hs>; -}; - -&eud { - status = "okay"; -}; - -&eud0 { - usb-role-switch; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; From 9f9b6184b76f8a3c677ec883872fc61eaa908c6a Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Fri, 20 Feb 2026 16:02:45 +0530 Subject: [PATCH 376/438] Revert "FROMLIST: arm64: dts: qcom: kodiak: Align EUD node with binding" This reverts commit 09ed0b6ddc99b87f0fb3141a9c4d55f015329c5c. Issue is observed with this commit 09ed0b6ddc99b87f0fb3141a9c4d55f015329c5c leading to crash, with following call stack [ 19.706310][ T73] Call trace: [ 19.706312][ T73] usb_role_switch_unregister+0x28/0x70 (P) [ 19.706319][ T73] eud_role_switch_release+0x30/0x78 [qcom_eud] [ 19.884972][ T73] devm_action_release+0x1c/0x30 [ 19.884981][ T73] release_nodes+0x70/0x120 [ 19.884987][ T73] devres_release_all+0x98/0xf0 [ 19.884995][ T73] device_unbind_cleanup+0x20/0x98 [ 19.885000][ T73] really_probe+0x184/0x3f0 [ 19.885005][ T73] __driver_probe_device+0x88/0x190 [ 19.885010][ T73] driver_probe_device+0x44/0x120 [ 19.885015][ T73] __device_attach_driver+0xc4/0x178 [ 19.885020][ T73] bus_for_each_drv+0x90/0xf8 [ 19.885027][ T73] __device_attach+0xa8/0x1d8 [ 19.885032][ T73] device_initial_probe+0x58/0x68 [ 19.885037][ T73] bus_probe_device+0x40/0xb8 [ 19.885041][ T73] deferred_probe_work_func+0xbc/0x128 [ 19.885046][ T73] process_one_work+0x180/0x450 [ 19.885055][ T73] worker_thread+0x26c/0x388 [ 19.885062][ T73] kthread+0x120/0x140 [ 19.885068][ T73] ret_from_fork+0x10/0x20 [ 19.885079][ T73] Code: f9000bf3 aa0003f3 b140041f 54000168 (390c901f) [ 19.885083][ T73] ---[ end trace 0000000000000000 ]--- [ 19.885088][ T73] Kernel panic - not syncing: Oops: Fatal exception [ 19.885091][ T73] SMP: stopping secondary CPUs Revert commit for now. Signed-off-by: Salendarsingh Gaud --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 33 +++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 5d40ffb06e4b7..6079e67ea829b 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4294,6 +4294,12 @@ phy-names = "usb2-phy"; maximum-speed = "high-speed"; usb-role-switch; + + port { + usb2_role_switch: endpoint { + remote-endpoint = <&eud_ep>; + }; + }; }; qspi: spi@88dc000 { @@ -4617,29 +4623,16 @@ <0 0x88e2000 0 0x1000>; interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - eud0: eud-path@0 { - reg = <0>; - phys = <&usb_1_hsphy>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - eud_usb0: endpoint { - }; - }; + ports { + #address-cells = <1>; + #size-cells = <0>; - port@1 { - reg = <1>; - eud_con0: endpoint { - }; + port@0 { + reg = <0>; + eud_ep: endpoint { + remote-endpoint = <&usb2_role_switch>; }; }; }; From b73508024fa0445c2697a961e5750653df8f01fc Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 12:34:25 +0000 Subject: [PATCH 377/438] FROMLIST: dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema Add a base schema initially compatible with x1e80100 to describe MIPI CSI2 PHY devices. The hardware can support both C-PHY and D-PHY modes. The CSIPHY devices have their own pinouts on the SoC as well as their own individual voltage rails. The need to model voltage rails on a per-PHY basis leads us to define CSIPHY devices as individual nodes. Two nice outcomes in terms of schema and DT arise from this change. 1. The ability to define on a per-PHY basis voltage rails. 2. The ability to require those voltage. We have had a complete bodge upstream for this where a single set of voltage rail for all CSIPHYs has been buried inside of CAMSS. Much like the I2C bus which is dedicated to Camera sensors - the CCI bus in CAMSS parlance, the CSIPHY devices should be individually modelled. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-csi2-phy-v3-1-11e608759410@linaro.org/ --- .../bindings/phy/qcom,x1e80100-csi2-phy.yaml | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml new file mode 100644 index 0000000000000..c937d26ccbda9 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/qcom,x1e80100-csi2-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm CSI2 PHY + +maintainers: + - Bryan O'Donoghue + +description: + Qualcomm MIPI CSI2 C-PHY/D-PHY combination PHY. Connects MIPI CSI2 sensors + to Qualcomm's Camera CSI Decoder. The PHY supports both C-PHY and D-PHY + modes. + +properties: + compatible: + const: qcom,x1e80100-csi2-phy + + reg: + maxItems: 1 + + "#phy-cells": + const: 1 + + clocks: + maxItems: 4 + + clock-names: + items: + - const: csiphy + - const: csiphy_timer + - const: camnoc_axi + - const: cpas_ahb + + interrupts: + maxItems: 1 + + operating-points-v2: + maxItems: 1 + + power-domains: + maxItems: 1 + + vdda-0p8-supply: + description: Phandle to a 0.8V regulator supply to a PHY. + + vdda-1p2-supply: + description: Phandle to 1.2V regulator supply to a PHY. + +required: + - compatible + - reg + - "#phy-cells" + - clocks + - clock-names + - interrupts + - operating-points-v2 + - power-domains + - vdda-0p8-supply + - vdda-1p2-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + csiphy@ace4000 { + compatible = "qcom,x1e80100-csi2-phy"; + reg = <0x0ace4000 0x2000>; + #phy-cells = <1>; + + clocks = <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "csiphy", + "csiphy_timer", + "camnoc_axi", + "cpas_ahb"; + + operating-points-v2 = <&csiphy_opp_table>; + + interrupts = ; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + vdda-0p8-supply = <&vreg_l2c_0p8>; + vdda-1p2-supply = <&vreg_l1c_1p2>; + }; + + csiphy_opp_table: opp-table-csiphy { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; From d62da0ca45326d839cb0e01af02663112731744a Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 12:34:26 +0000 Subject: [PATCH 378/438] FROMLIST: phy: qcom-mipi-csi2: Add a CSI2 MIPI DPHY driver Add a new MIPI CSI2 driver in DPHY mode initially. The entire set of existing CAMSS CSI PHY init sequences are imported in order to save time and effort in later patches. The following devices are supported in this drop: "qcom,x1e80100-csi2-phy" In-line with other PHY drivers the process node is included in the name. At the moment we follow the assignment of lane positions - the bitmap of physical input lanes to logical lane numbers as a linear list per the existing DPHY @lanes data-member. This is fine for us in upstream at the moment since we also map the lanes contiguously but, our hardware can support different lane mappings so we should in the future extend out the DPHY structure to capture the mapping. The Qualcomm 3PH class of PHYs can do both DPHY and CPHY mode. For now only DPHY is supported. In porting some of the logic over from camss-csiphy*.c to here its also possible to rationalise some of the code. In particular use of regulator_bulk and clk_bulk as well as dropping the seemingly useless and unused interrupt handler. The PHY sequences and a lot of the logic that goes with them are well proven in CAMSS and mature so the main thing to watch out for here is how to get the right sequencing of regulators, clocks and register-writes. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-csi2-phy-v3-2-11e608759410@linaro.org/ --- MAINTAINERS | 11 + drivers/phy/qualcomm/Kconfig | 13 + drivers/phy/qualcomm/Makefile | 5 + .../qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 384 ++++++++++++++++++ .../phy/qualcomm/phy-qcom-mipi-csi2-core.c | 307 ++++++++++++++ drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 102 +++++ 6 files changed, 822 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c create mode 100644 drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c create mode 100644 drivers/phy/qualcomm/phy-qcom-mipi-csi2.h diff --git a/MAINTAINERS b/MAINTAINERS index 55af015174a54..8c316044e8a28 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21804,6 +21804,17 @@ S: Maintained F: Documentation/devicetree/bindings/media/qcom,*-iris.yaml F: drivers/media/platform/qcom/iris/ +QUALCOMM MIPI CSI2 PHY DRIVER +M: Bryan O'Donoghue +L: linux-phy@lists.infradead.org +L: linux-media@vger.kernel.org +L: linux-arm-msm@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/phy/qcom,*-csi2-phy.yaml +F: drivers/phy/qualcomm/phy-qcom-mipi-csi2*.c +F: drivers/phy/qualcomm/phy-qcom-mipi-csi2*.h +F: include/dt-bindings/phy/phy-qcom-mipi-csi2* + QUALCOMM NAND CONTROLLER DRIVER M: Manivannan Sadhasivam L: linux-mtd@lists.infradead.org diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 60a0ead127fa9..ea33025a40fd0 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -28,6 +28,19 @@ config PHY_QCOM_EDP Enable this driver to support the Qualcomm eDP PHY found in various Qualcomm chipsets. +config PHY_QCOM_MIPI_CSI2 + tristate "Qualcomm MIPI CSI2 PHY driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on OF + depends on COMMON_CLK + select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + help + Enable this to support the MIPI CSI2 PHY driver found in various + Qualcomm chipsets. This PHY is used to connect MIPI CSI2 + camera sensors to the CSI Decoder in the Qualcomm Camera Subsystem + CAMSS. + config PHY_QCOM_IPQ4019_USB tristate "Qualcomm IPQ4019 USB PHY driver" depends on OF && (ARCH_QCOM || COMPILE_TEST) diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index b71a6a0bed3f1..382cb594b06b6 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -6,6 +6,11 @@ obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o obj-$(CONFIG_PHY_QCOM_M31_USB) += phy-qcom-m31.o obj-$(CONFIG_PHY_QCOM_M31_EUSB) += phy-qcom-m31-eusb2.o + +phy-qcom-mipi-csi2-objs += phy-qcom-mipi-csi2-core.o \ + phy-qcom-mipi-csi2-3ph-dphy.o +obj-$(CONFIG_PHY_QCOM_MIPI_CSI2) += phy-qcom-mipi-csi2.o + obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o phy-qcom-qmp-usbc.o diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c new file mode 100644 index 0000000000000..f9f3451e9a5e1 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-phy_qcom_mipi_csi2-3ph-1-0.c + * + * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v1.0 + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2016-2025 Linaro Ltd. + */ + +#include +#include +#include +#include + +#include "phy-qcom-mipi-csi2.h" + +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(offset, n) ((offset) + 0x4 * (n)) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET BIT(0) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE BIT(7) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL10_IRQ_CLEAR_CMD BIT(0) +#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, n) ((offset) + 0xb0 + 0x4 * (n)) + +/* + * 3 phase CSI has 19 common status regs with only 0-10 being used + * and 11-18 being reserved. + */ +#define CSI_COMMON_STATUS_NUM 11 +/* + * There are a number of common control registers + * The offset to clear the CSIPHY IRQ status starts @ 22 + * So to clear CSI_COMMON_STATUS0 this is CSI_COMMON_CONTROL22, STATUS1 is + * CONTROL23 and so on + */ +#define CSI_CTRL_STATUS_INDEX 22 + +/* + * There are 43 COMMON_CTRL registers with regs after # 33 being reserved + */ +#define CSI_CTRL_MAX 33 + +#define CSIPHY_DEFAULT_PARAMS 0 +#define CSIPHY_LANE_ENABLE 1 +#define CSIPHY_SETTLE_CNT_LOWER_BYTE 2 +#define CSIPHY_SETTLE_CNT_HIGHER_BYTE 3 +#define CSIPHY_DNP_PARAMS 4 +#define CSIPHY_2PH_REGS 5 +#define CSIPHY_3PH_REGS 6 +#define CSIPHY_SKEW_CAL 7 + +/* 4nm 2PH v 2.1.2 2p5Gbps 4 lane DPHY mode */ +static const struct +mipi_csi2phy_lane_regs lane_regs_x1e80100[] = { + /* Power up lanes 2ph mode */ + {.reg_addr = 0x1014, .reg_data = 0xD5, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x101C, .reg_data = 0x7A, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x1018, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + + {.reg_addr = 0x0094, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x00A0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0090, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0098, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0094, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0030, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0000, .reg_data = 0x8E, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0038, .reg_data = 0xFE, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x002C, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0034, .reg_data = 0x0F, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x001C, .reg_data = 0x0A, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0014, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x003C, .reg_data = 0xB8, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0004, .reg_data = 0x0C, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0020, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0008, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {.reg_addr = 0x0010, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0094, .reg_data = 0xD7, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x005C, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0060, .reg_data = 0xBD, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0064, .reg_data = 0x7F, .param_type = CSIPHY_SKEW_CAL}, + + {.reg_addr = 0x0E94, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0EA0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E90, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E98, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E94, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E30, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E28, .reg_data = 0x04, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E00, .reg_data = 0x80, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E0C, .reg_data = 0xFF, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E38, .reg_data = 0x1F, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E2C, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E34, .reg_data = 0x0F, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E1C, .reg_data = 0x0A, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E14, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E3C, .reg_data = 0xB8, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E04, .reg_data = 0x0C, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E20, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0E08, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {.reg_addr = 0x0E10, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, + + {.reg_addr = 0x0494, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x04A0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0490, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0498, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0494, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0430, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0400, .reg_data = 0x8E, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0438, .reg_data = 0xFE, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x042C, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0434, .reg_data = 0x0F, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x041C, .reg_data = 0x0A, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0414, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x043C, .reg_data = 0xB8, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0404, .reg_data = 0x0C, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0420, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0408, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {.reg_addr = 0x0410, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0494, .reg_data = 0xD7, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x045C, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0460, .reg_data = 0xBD, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0464, .reg_data = 0x7F, .param_type = CSIPHY_SKEW_CAL}, + + {.reg_addr = 0x0894, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x08A0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0890, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0898, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0894, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0830, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0800, .reg_data = 0x8E, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0838, .reg_data = 0xFE, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x082C, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0834, .reg_data = 0x0F, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x081C, .reg_data = 0x0A, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0814, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x083C, .reg_data = 0xB8, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0804, .reg_data = 0x0C, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0820, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0808, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {.reg_addr = 0x0810, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0894, .reg_data = 0xD7, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x085C, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0860, .reg_data = 0xBD, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0864, .reg_data = 0x7F, .param_type = CSIPHY_SKEW_CAL}, + + {.reg_addr = 0x0C94, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0CA0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C90, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C98, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C94, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C30, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C00, .reg_data = 0x8E, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C38, .reg_data = 0xFE, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C2C, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C34, .reg_data = 0x0F, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C1C, .reg_data = 0x0A, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C14, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C3C, .reg_data = 0xB8, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C04, .reg_data = 0x0C, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C20, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C08, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {.reg_addr = 0x0C10, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, + {.reg_addr = 0x0C94, .reg_data = 0xD7, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0C5C, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0C60, .reg_data = 0xBD, .param_type = CSIPHY_SKEW_CAL}, + {.reg_addr = 0x0C64, .reg_data = 0x7F, .param_type = CSIPHY_SKEW_CAL}, +}; + +static inline const struct mipi_csi2phy_device_regs * +csi2phy_dev_to_regs(struct mipi_csi2phy_device *csi2phy) +{ + return &csi2phy->soc_cfg->reg_info; +} + +static void phy_qcom_mipi_csi2_hw_version_read(struct mipi_csi2phy_device *csi2phy) +{ + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); + u32 tmp; + + writel(CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6)); + + tmp = readl_relaxed(csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 12)); + csi2phy->hw_version = tmp; + + tmp = readl_relaxed(csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 13)); + csi2phy->hw_version |= (tmp << 8) & 0xFF00; + + tmp = readl_relaxed(csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 14)); + csi2phy->hw_version |= (tmp << 16) & 0xFF0000; + + tmp = readl_relaxed(csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 15)); + csi2phy->hw_version |= (tmp << 24) & 0xFF000000; + + dev_dbg_once(csi2phy->dev, "CSIPHY 3PH HW Version = 0x%08x\n", csi2phy->hw_version); +} + +/* + * phy_qcom_mipi_csi2_reset - Perform software reset on CSIPHY module + * @phy_qcom_mipi_csi2: CSIPHY device + */ +static void phy_qcom_mipi_csi2_reset(struct mipi_csi2phy_device *csi2phy) +{ + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); + + writel(CSIPHY_3PH_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET, + csi2phy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 0)); + usleep_range(5000, 8000); + writel(0x0, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 0)); +} + +/* + * phy_qcom_mipi_csi2_settle_cnt_calc - Calculate settle count value + * + * Helper function to calculate settle count value. This is + * based on the CSI2 T_hs_settle parameter which in turn + * is calculated based on the CSI2 transmitter link frequency. + * + * Return settle count value or 0 if the CSI2 link frequency + * is not available + */ +static u8 phy_qcom_mipi_csi2_settle_cnt_calc(s64 link_freq, u32 timer_clk_rate) +{ + u32 t_hs_prepare_max_ps; + u32 timer_period_ps; + u32 t_hs_settle_ps; + u8 settle_cnt; + u32 ui_ps; + + if (link_freq <= 0) + return 0; + + ui_ps = div_u64(PSEC_PER_SEC, link_freq); + ui_ps /= 2; + t_hs_prepare_max_ps = 85000 + 6 * ui_ps; + t_hs_settle_ps = t_hs_prepare_max_ps; + + timer_period_ps = div_u64(PSEC_PER_SEC, timer_clk_rate); + settle_cnt = t_hs_settle_ps / timer_period_ps - 6; + + return settle_cnt; +} + +static void +phy_qcom_mipi_csi2_gen2_config_lanes(struct mipi_csi2phy_device *csi2phy, + u8 settle_cnt) +{ + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); + const struct mipi_csi2phy_lane_regs *r = regs->init_seq; + int i, array_size = regs->lane_array_size; + u32 val; + + for (i = 0; i < array_size; i++, r++) { + switch (r->param_type) { + case CSIPHY_SETTLE_CNT_LOWER_BYTE: + val = settle_cnt & 0xff; + break; + case CSIPHY_SKEW_CAL: + /* TODO: support application of skew from dt flag */ + continue; + default: + val = r->reg_data; + break; + } + writel(val, csi2phy->base + r->reg_addr); + if (r->delay_us) + udelay(r->delay_us); + } +} + +static int phy_qcom_mipi_csi2_lanes_enable(struct mipi_csi2phy_device *csi2phy, + struct mipi_csi2phy_stream_cfg *cfg) +{ + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); + struct mipi_csi2phy_lanes_cfg *lane_cfg = &cfg->lane_cfg; + u8 settle_cnt; + u8 val; + int i; + + settle_cnt = phy_qcom_mipi_csi2_settle_cnt_calc(cfg->link_freq, csi2phy->timer_clk_rate); + + val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; + for (i = 0; i < cfg->num_data_lanes; i++) + val |= BIT(lane_cfg->data[i].pos * 2); + + writel(val, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 5)); + + val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B; + writel(val, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6)); + + val = 0x02; + writel(val, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 7)); + + val = 0x00; + writel(val, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 0)); + + phy_qcom_mipi_csi2_gen2_config_lanes(csi2phy, settle_cnt); + + /* IRQ_MASK registers - disable all interrupts */ + for (i = CSI_COMMON_STATUS_NUM; i < CSI_CTRL_STATUS_INDEX; i++) { + writel(0, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, i)); + } + + return 0; +} + +static void +phy_qcom_mipi_csi2_lanes_disable(struct mipi_csi2phy_device *csi2phy, + struct mipi_csi2phy_stream_cfg *cfg) +{ + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); + + writel(0, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 5)); + + writel(0, csi2phy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6)); +} + +static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = { + .hw_version_read = phy_qcom_mipi_csi2_hw_version_read, + .reset = phy_qcom_mipi_csi2_reset, + .lanes_enable = phy_qcom_mipi_csi2_lanes_enable, + .lanes_disable = phy_qcom_mipi_csi2_lanes_disable, +}; + +static const struct mipi_csi2phy_clk_freq zero = { 0 }; + +static const struct mipi_csi2phy_clk_freq dphy_4nm_x1e_csiphy = { + .freq = { + 300000000, 400000000, 480000000 + }, + .num_freq = 3, +}; + +static const struct mipi_csi2phy_clk_freq dphy_4nm_x1e_csiphy_timer = { + .freq = { + 266666667, 400000000 + }, + .num_freq = 2, +}; + +static const char * const x1e_clks[] = { + "camnoc_axi", + "cpas_ahb", + "csiphy", + "csiphy_timer" +}; + +const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = { + .ops = &phy_qcom_mipi_csi2_ops_3ph_1_0, + .reg_info = { + .init_seq = lane_regs_x1e80100, + .lane_array_size = ARRAY_SIZE(lane_regs_x1e80100), + .common_regs_offset = 0x1000, + .generation = GEN2, + }, + .supply_names = (const char *[]){ + "vdda-0p8", + "vdda-1p2" + }, + .num_supplies = 2, + .clk_names = (const char **)x1e_clks, + .num_clk = ARRAY_SIZE(x1e_clks), + .opp_clk = x1e_clks[2], + .timer_clk = x1e_clks[3], + .clk_freq = { + zero, + zero, + dphy_4nm_x1e_csiphy, + dphy_4nm_x1e_csiphy_timer, + }, +}; diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c new file mode 100644 index 0000000000000..454144f81b719 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025, Linaro Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-qcom-mipi-csi2.h" + +#define CAMSS_CLOCK_MARGIN_NUMERATOR 105 +#define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 + +static inline void phy_qcom_mipi_csi2_add_clock_margin(u64 *rate) +{ + *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR; + *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR); +} + +static int +phy_qcom_mipi_csi2_set_clock_rates(struct mipi_csi2phy_device *csi2phy, + s64 link_freq) +{ + const struct mipi_csi2phy_soc_cfg *soc_cfg = csi2phy->soc_cfg; + unsigned long rates[MAX_CSI2PHY_CLKS] = {0}; + struct device *dev = csi2phy->dev; + unsigned long vote_freq = 0; + int i, j; + int ret; + + for (i = 0; i < soc_cfg->num_clk; i++) { + const struct mipi_csi2phy_clk_freq *clk_freq = &soc_cfg->clk_freq[i]; + const char *clk_name = soc_cfg->clk_names[i]; + struct clk *clk = csi2phy->clks[i].clk; + u64 min_rate = link_freq / 4; + long round_rate; + + phy_qcom_mipi_csi2_add_clock_margin(&min_rate); + + /* This clock should be enabled only not set */ + if (!clk_freq->num_freq) + continue; + + for (j = 0; j < clk_freq->num_freq; j++) + if (min_rate < clk_freq->freq[j]) + break; + + if (j == clk_freq->num_freq) { + dev_err(dev, + "Pixel clock %llu is too high for %s\n", + min_rate, clk_name); + return -EINVAL; + } + + /* if sensor pixel clock is not available + * set highest possible CSIPHY clock rate + */ + if (min_rate == 0) + j = clk_freq->num_freq - 1; + + round_rate = clk_round_rate(clk, clk_freq->freq[j]); + if (round_rate < 0) { + dev_err(dev, "clk round rate failed: %ld\n", + round_rate); + return -EINVAL; + } + + rates[i] = round_rate; + + if (!strcmp(clk_name, soc_cfg->timer_clk)) + csi2phy->timer_clk_rate = round_rate; + + if (!strcmp(clk_name, soc_cfg->opp_clk)) + vote_freq = round_rate; + } + + if (!vote_freq) { + dev_err(dev, "Unable to find operating point frequency\n"); + return -ENODEV; + }; + + dev_dbg(dev, "OPP freq: %lu Hz\n", vote_freq); + + ret = dev_pm_opp_set_rate(dev, vote_freq); + if (ret < 0) { + dev_err(dev, "Failed to set OPP rate: %d\n", ret); + return ret; + } + + for (i = 0; i < soc_cfg->num_clk; i++) { + if (rates[i] == 0) + continue; + + dev_dbg(dev, "Setting clk %s to %lu Hz\n", + soc_cfg->clk_names[i], rates[i]); + + ret = clk_set_rate(csi2phy->clks[i].clk, rates[i]); + if (ret < 0) { + dev_err(dev, "clk_set_rate failed for %s: %d\n", + soc_cfg->clk_names[i], ret); + return ret; + } + } + + return 0; +} + +static int phy_qcom_mipi_csi2_configure(struct phy *phy, + union phy_configure_opts *opts) +{ + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); + struct phy_configure_opts_mipi_dphy *dphy_cfg_opts = &opts->mipi_dphy; + struct mipi_csi2phy_stream_cfg *stream_cfg = &csi2phy->stream_cfg; + int ret; + int i; + + ret = phy_mipi_dphy_config_validate(dphy_cfg_opts); + if (ret) + return ret; + + if (dphy_cfg_opts->lanes < 1 || dphy_cfg_opts->lanes > CSI2_MAX_DATA_LANES) + return -EINVAL; + + stream_cfg->combo_mode = 0; + stream_cfg->link_freq = dphy_cfg_opts->hs_clk_rate; + stream_cfg->num_data_lanes = dphy_cfg_opts->lanes; + + /* + * phy_configure_opts_mipi_dphy.lanes starts from zero to + * the maximum number of enabled lanes. + * + * TODO: add support for bitmask of enabled lanes and polarities + * of those lanes to the phy_configure_opts_mipi_dphy struct. + * For now take the polarities as zero and the position as fixed + * this is fine as no current upstream implementation maps otherwise. + */ + for (i = 0; i < stream_cfg->num_data_lanes; i++) { + stream_cfg->lane_cfg.data[i].pol = 0; + stream_cfg->lane_cfg.data[i].pos = i; + } + + stream_cfg->lane_cfg.clk.pol = 0; + stream_cfg->lane_cfg.clk.pos = 7; + + return 0; +} + +static int phy_qcom_mipi_csi2_power_on(struct phy *phy) +{ + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); + const struct mipi_csi2phy_hw_ops *ops = csi2phy->soc_cfg->ops; + struct device *dev = &phy->dev; + int ret; + + ret = regulator_bulk_enable(csi2phy->soc_cfg->num_supplies, + csi2phy->supplies); + if (ret) + return ret; + + ret = phy_qcom_mipi_csi2_set_clock_rates(csi2phy, csi2phy->stream_cfg.link_freq); + if (ret) + goto poweroff_phy; + + ret = clk_bulk_prepare_enable(csi2phy->soc_cfg->num_clk, + csi2phy->clks); + if (ret) { + dev_err(dev, "failed to enable clocks, %d\n", ret); + goto poweroff_phy; + } + + ops->reset(csi2phy); + + ops->hw_version_read(csi2phy); + + return ops->lanes_enable(csi2phy, &csi2phy->stream_cfg); + +poweroff_phy: + regulator_bulk_disable(csi2phy->soc_cfg->num_supplies, + csi2phy->supplies); + + return ret; +} + +static int phy_qcom_mipi_csi2_power_off(struct phy *phy) +{ + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); + + clk_bulk_disable_unprepare(csi2phy->soc_cfg->num_clk, + csi2phy->clks); + regulator_bulk_disable(csi2phy->soc_cfg->num_supplies, + csi2phy->supplies); + + return 0; +} + +static const struct phy_ops phy_qcom_mipi_csi2_ops = { + .configure = phy_qcom_mipi_csi2_configure, + .power_on = phy_qcom_mipi_csi2_power_on, + .power_off = phy_qcom_mipi_csi2_power_off, + .owner = THIS_MODULE, +}; + +static int phy_qcom_mipi_csi2_probe(struct platform_device *pdev) +{ + unsigned int i, num_clk, num_supplies; + struct mipi_csi2phy_device *csi2phy; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct phy *generic_phy; + int ret; + + csi2phy = devm_kzalloc(dev, sizeof(*csi2phy), GFP_KERNEL); + if (!csi2phy) + return -ENOMEM; + + csi2phy->dev = dev; + csi2phy->soc_cfg = device_get_match_data(&pdev->dev); + + if (!csi2phy->soc_cfg) + return -EINVAL; + + num_clk = csi2phy->soc_cfg->num_clk; + csi2phy->clks = devm_kzalloc(dev, sizeof(*csi2phy->clks) * num_clk, GFP_KERNEL); + if (!csi2phy->clks) + return -ENOMEM; + + for (i = 0; i < num_clk; i++) + csi2phy->clks[i].id = csi2phy->soc_cfg->clk_names[i]; + + ret = devm_clk_bulk_get(dev, num_clk, csi2phy->clks); + if (ret) + return dev_err_probe(dev, ret, "Failed to get clocks\n"); + + ret = devm_pm_opp_set_clkname(dev, csi2phy->soc_cfg->opp_clk); + if (ret) + return dev_err_probe(dev, ret, "Failed to set opp clkname\n"); + + ret = devm_pm_opp_of_add_table(dev); + if (ret && ret != -ENODEV) + return dev_err_probe(dev, ret, "invalid OPP table in device tree\n"); + + num_supplies = csi2phy->soc_cfg->num_supplies; + csi2phy->supplies = devm_kzalloc(dev, sizeof(*csi2phy->supplies) * num_supplies, + GFP_KERNEL); + if (!csi2phy->supplies) + return -ENOMEM; + + for (i = 0; i < num_supplies; i++) + csi2phy->supplies[i].supply = csi2phy->soc_cfg->supply_names[i]; + + ret = devm_regulator_bulk_get(dev, num_supplies, csi2phy->supplies); + if (ret) + return dev_err_probe(dev, ret, + "failed to get regulator supplies\n"); + + csi2phy->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(csi2phy->base)) + return PTR_ERR(csi2phy->base); + + generic_phy = devm_phy_create(dev, NULL, &phy_qcom_mipi_csi2_ops); + if (IS_ERR(generic_phy)) { + ret = PTR_ERR(generic_phy); + return dev_err_probe(dev, ret, "failed to create phy\n"); + } + csi2phy->phy = generic_phy; + + phy_set_drvdata(generic_phy, csi2phy); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (!IS_ERR(phy_provider)) + dev_dbg(dev, "Registered MIPI CSI2 PHY device\n"); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id phy_qcom_mipi_csi2_of_match_table[] = { + { .compatible = "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e }, + { } +}; +MODULE_DEVICE_TABLE(of, phy_qcom_mipi_csi2_of_match_table); + +static struct platform_driver phy_qcom_mipi_csi2_driver = { + .probe = phy_qcom_mipi_csi2_probe, + .driver = { + .name = "qcom-mipi-csi2-phy", + .of_match_table = phy_qcom_mipi_csi2_of_match_table, + }, +}; + +module_platform_driver(phy_qcom_mipi_csi2_driver); + +MODULE_DESCRIPTION("Qualcomm MIPI CSI2 PHY driver"); +MODULE_AUTHOR("Bryan O'Donoghue "); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h new file mode 100644 index 0000000000000..4f3a245ba6a53 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * + * Qualcomm MIPI CSI2 CPHY/DPHY driver + * + * Copyright (C) 2025 Linaro Ltd. + */ +#ifndef __PHY_QCOM_MIPI_CSI2_H__ +#define __PHY_QCOM_MIPI_CSI2_H__ + +#include + +#define CSI2_MAX_DATA_LANES 4 + +struct mipi_csi2phy_lane { + u8 pos; + u8 pol; +}; + +struct mipi_csi2phy_lanes_cfg { + struct mipi_csi2phy_lane data[CSI2_MAX_DATA_LANES]; + struct mipi_csi2phy_lane clk; +}; + +struct mipi_csi2phy_stream_cfg { + u8 combo_mode; + s64 link_freq; + u8 num_data_lanes; + struct mipi_csi2phy_lanes_cfg lane_cfg; +}; + +struct mipi_csi2phy_device; + +struct mipi_csi2phy_hw_ops { + void (*hw_version_read)(struct mipi_csi2phy_device *csi2phy_dev); + void (*reset)(struct mipi_csi2phy_device *csi2phy_dev); + int (*lanes_enable)(struct mipi_csi2phy_device *csi2phy_dev, + struct mipi_csi2phy_stream_cfg *cfg); + void (*lanes_disable)(struct mipi_csi2phy_device *csi2phy_dev, + struct mipi_csi2phy_stream_cfg *cfg); +}; + +struct mipi_csi2phy_lane_regs { + const s32 reg_addr; + const s32 reg_data; + const u32 delay_us; + const u32 param_type; +}; + +struct mipi_csi2phy_device_regs { + const struct mipi_csi2phy_lane_regs *init_seq; + const int lane_array_size; + const u32 common_regs_offset; + enum { + GEN1 = 0, + GEN1_660, + GEN1_670, + GEN2, + } generation; +}; + +#define MAX_CSI2PHY_CLKS 8 +struct mipi_csi2phy_clk_freq { + u32 num_freq; + u32 freq[MAX_CSI2PHY_CLKS]; +}; + +struct mipi_csi2phy_soc_cfg { + const struct mipi_csi2phy_hw_ops *ops; + const struct mipi_csi2phy_device_regs reg_info; + + const char ** const supply_names; + const unsigned int num_supplies; + + const char ** const clk_names; + const unsigned int num_clk; + + const char * const opp_clk; + const char * const timer_clk; + + const struct mipi_csi2phy_clk_freq clk_freq[]; +}; + +struct mipi_csi2phy_device { + struct device *dev; + + struct phy *phy; + void __iomem *base; + + struct clk_bulk_data *clks; + struct regulator_bulk_data *supplies; + u32 timer_clk_rate; + + const struct mipi_csi2phy_soc_cfg *soc_cfg; + struct mipi_csi2phy_stream_cfg stream_cfg; + + u32 hw_version; +}; + +extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e; + +#endif /* __PHY_QCOM_MIPI_CSI2_H__ */ From de13059426e56f39d15e1e23326368d69a091efa Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:42 +0000 Subject: [PATCH 379/438] FROMLIST: dt-bindings: media: qcom,x1e80100-camss: Add optional PHY handle definitions Add optional PHY handle definitions. This will allow for supporting both legacy PHY definitions as well as supporting the optional new handle based approach. Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-1-a59c3f037d0b@linaro.org/ --- .../bindings/media/qcom,x1e80100-camss.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml index 2d1662ef522b7..bb18236b4f344 100644 --- a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml @@ -126,6 +126,16 @@ properties: description: 1.2V supply to a PHY. + phys: + maxItems: 4 + + phy-names: + items: + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy4 + ports: $ref: /schemas/graph.yaml#/properties/ports @@ -351,6 +361,11 @@ examples: vdd-csiphy-0p8-supply = <&csiphy_0p8_supply>; vdd-csiphy-1p2-supply = <&csiphy_1p2_supply>; + phys = <&csiphy0>, <&csiphy1>, + <&csiphy2>, <&csiphy4>; + phy-names = "csiphy0", "csiphy1", + "csiphy2", "csiphy4"; + ports { #address-cells = <1>; #size-cells = <0>; From b7aaa0d87f20fd217c8d0cdb859f35d36cc8f5b3 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:43 +0000 Subject: [PATCH 380/438] FROMLIST: dt-bindings: media: qcom,x1e80100-camss: Add support for combo-mode endpoints Qualcomm CSI2 PHYs support a mode where two sensors may be attached to the one CSIPHY. When we have one endpoint we may have - DPHY 1, 2 or 4 data lanes + 1 clock lane - CPHY 3 wire data lane When we have two endpoints this indicates the special fixed combo-mode. - DPHY endpoint0 => 2+1 and endpoint1 => 1+1 data-lane/clock-lane combination. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-2-a59c3f037d0b@linaro.org/ --- .../bindings/media/qcom,x1e80100-camss.yaml | 69 +++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml index bb18236b4f344..8dbaab16b11d4 100644 --- a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml @@ -140,7 +140,8 @@ properties: $ref: /schemas/graph.yaml#/properties/ports description: - CSI input ports. + CSI input ports. Supports either standard single sensor mode or + Qualcomm's combo mode with one sensor in 2x1 + 1x1 data-lane, clock-lane mode. patternProperties: "^port@[0-3]$": @@ -148,26 +149,86 @@ properties: unevaluatedProperties: false description: - Input port for receiving CSI data from a CSIPHY. + Input port for receiving CSI data. properties: - endpoint: + endpoint@0: $ref: video-interfaces.yaml# unevaluatedProperties: false + description: + Endpoint for receiving a single sensor input (or first leg of combo). + properties: data-lanes: minItems: 1 - maxItems: 4 + maxItems: 4 # Base max allows 4 (for D-PHY) + + clock-lanes: + maxItems: 1 bus-type: enum: - 1 # MEDIA_BUS_TYPE_CSI2_CPHY - 4 # MEDIA_BUS_TYPE_CSI2_DPHY + endpoint@1: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + description: + Endpoint for receiving the second leg of a combo sensor input. + + properties: + data-lanes: + maxItems: 1 + + clock-lanes: + maxItems: 1 + + bus-type: + const: 4 # Combo is D-PHY specific + required: - data-lanes + allOf: + # Case 1: Combo Mode (endpoint@1 is present) + # If endpoint@1 exists, we restrict endpoint@0 to 2 lanes (D-PHY split) + - if: + required: + - endpoint@1 + then: + properties: + endpoint@0: + properties: + data-lanes: + minItems: 2 + maxItems: 2 + bus-type: + const: 4 + endpoint@1: + properties: + data-lanes: + minItems: 1 + maxItems: 1 + bus-type: + const: 4 + + # Case 2: Single Mode (endpoint@1 is missing) + # We explicitly allow up to 4 lanes here to cover the D-PHY use case. + - if: + not: + required: + - endpoint@1 + then: + properties: + endpoint@0: + properties: + data-lanes: + minItems: 1 + maxItems: 4 + required: - compatible - reg From ac281e634987bded1cc3e7b8db4ce3f58e815d74 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:44 +0000 Subject: [PATCH 381/438] FROMLIST: dt-bindings: media: qcom,x1e80100-camss: Add iommus minItems: 5 Specify a minimum number of iommus entries. Currently the schema requires exactly eight. Add minItems to allow fewer entries while retaining the existing maximum. Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-3-a59c3f037d0b@linaro.org/ --- .../devicetree/bindings/media/qcom,x1e80100-camss.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml index 8dbaab16b11d4..f406cf6f8f9c1 100644 --- a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml @@ -104,6 +104,7 @@ properties: - const: sf_icp_mnoc iommus: + minItems: 5 maxItems: 8 power-domains: @@ -404,11 +405,8 @@ examples: iommus = <&apps_smmu 0x800 0x60>, <&apps_smmu 0x860 0x60>, - <&apps_smmu 0x1800 0x60>, <&apps_smmu 0x1860 0x60>, <&apps_smmu 0x18e0 0x00>, - <&apps_smmu 0x1980 0x20>, - <&apps_smmu 0x1900 0x00>, <&apps_smmu 0x19a0 0x20>; power-domains = <&camcc CAM_CC_IFE_0_GDSC>, From 349168fa92adccef0be1c09b56ea1909799bcdf7 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:45 +0000 Subject: [PATCH 382/438] FROMLIST: dt-bindings: media: qcom,x1e80100-camss: Allow CSIPHY supplies to be optional When CSIPHY devices are modelled as standalone PHY nodes the voltage rails are defined per-PHY. Allow the CAMSS-level supply properties to be omitted in this case. Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-4-a59c3f037d0b@linaro.org/ --- .../devicetree/bindings/media/qcom,x1e80100-camss.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml index f406cf6f8f9c1..3a5f179c15910 100644 --- a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml @@ -243,8 +243,6 @@ required: - iommus - power-domains - power-domain-names - - vdd-csiphy-0p8-supply - - vdd-csiphy-1p2-supply - ports additionalProperties: false From 6c62f59188dd106198de2944e55b4513b3fb1e82 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:46 +0000 Subject: [PATCH 383/438] FROMLIST: media: qcom: camss: Add legacy_phy flag to SoC definition structures Flag which SoCs have legacy - builtin PHY code. This will be useful in subsequent patches to inform PHY bringup logic if legacy bindings are available. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-5-a59c3f037d0b@linaro.org/ --- drivers/media/platform/qcom/camss/camss.c | 17 +++++++++++++++++ drivers/media/platform/qcom/camss/camss.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 00b87fd9afbd8..5fb5ad87e1671 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -5104,6 +5104,7 @@ static void camss_remove(struct platform_device *pdev) static const struct camss_resources msm8916_resources = { .version = CAMSS_8x16, + .legacy_phy = true, .csiphy_res = csiphy_res_8x16, .csid_res = csid_res_8x16, .ispif_res = &ispif_res_8x16, @@ -5115,6 +5116,7 @@ static const struct camss_resources msm8916_resources = { static const struct camss_resources msm8939_resources = { .version = CAMSS_8x39, + .legacy_phy = true, .csiphy_res = csiphy_res_8x39, .csid_res = csid_res_8x39, .ispif_res = &ispif_res_8x39, @@ -5126,6 +5128,7 @@ static const struct camss_resources msm8939_resources = { static const struct camss_resources msm8953_resources = { .version = CAMSS_8x53, + .legacy_phy = true, .icc_res = icc_res_8x53, .icc_path_num = ARRAY_SIZE(icc_res_8x53), .csiphy_res = csiphy_res_8x96, @@ -5139,6 +5142,7 @@ static const struct camss_resources msm8953_resources = { static const struct camss_resources msm8996_resources = { .version = CAMSS_8x96, + .legacy_phy = true, .csiphy_res = csiphy_res_8x96, .csid_res = csid_res_8x96, .ispif_res = &ispif_res_8x96, @@ -5150,6 +5154,7 @@ static const struct camss_resources msm8996_resources = { static const struct camss_resources qcm2290_resources = { .version = CAMSS_2290, + .legacy_phy = true, .csiphy_res = csiphy_res_2290, .csid_res = csid_res_2290, .vfe_res = vfe_res_2290, @@ -5163,6 +5168,7 @@ static const struct camss_resources qcm2290_resources = { static const struct camss_resources qcs8300_resources = { .version = CAMSS_8300, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_8300, .csid_res = csid_res_8775p, .csid_wrapper_res = &csid_wrapper_res_sm8550, @@ -5177,6 +5183,7 @@ static const struct camss_resources qcs8300_resources = { static const struct camss_resources sa8775p_resources = { .version = CAMSS_8775P, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_8775p, .csid_res = csid_res_8775p, .csid_wrapper_res = &csid_wrapper_res_sm8550, @@ -5190,6 +5197,7 @@ static const struct camss_resources sa8775p_resources = { static const struct camss_resources sdm660_resources = { .version = CAMSS_660, + .legacy_phy = true, .csiphy_res = csiphy_res_660, .csid_res = csid_res_660, .ispif_res = &ispif_res_660, @@ -5201,6 +5209,7 @@ static const struct camss_resources sdm660_resources = { static const struct camss_resources sdm670_resources = { .version = CAMSS_845, + .legacy_phy = true, .csiphy_res = csiphy_res_670, .csid_res = csid_res_670, .vfe_res = vfe_res_670, @@ -5212,6 +5221,7 @@ static const struct camss_resources sdm670_resources = { static const struct camss_resources sdm845_resources = { .version = CAMSS_845, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_845, .csid_res = csid_res_845, .vfe_res = vfe_res_845, @@ -5223,6 +5233,7 @@ static const struct camss_resources sdm845_resources = { static const struct camss_resources sm6150_resources = { .version = CAMSS_6150, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_sm6150, .csid_res = csid_res_sm6150, .vfe_res = vfe_res_sm6150, @@ -5236,6 +5247,7 @@ static const struct camss_resources sm6150_resources = { static const struct camss_resources sm8250_resources = { .version = CAMSS_8250, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_8250, .csid_res = csid_res_8250, .vfe_res = vfe_res_8250, @@ -5249,6 +5261,7 @@ static const struct camss_resources sm8250_resources = { static const struct camss_resources sc8280xp_resources = { .version = CAMSS_8280XP, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_sc8280xp, .csid_res = csid_res_sc8280xp, .ispif_res = NULL, @@ -5263,6 +5276,7 @@ static const struct camss_resources sc8280xp_resources = { static const struct camss_resources sc7280_resources = { .version = CAMSS_7280, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_7280, .csid_res = csid_res_7280, .vfe_res = vfe_res_7280, @@ -5276,6 +5290,7 @@ static const struct camss_resources sc7280_resources = { static const struct camss_resources sm8550_resources = { .version = CAMSS_8550, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_8550, .csid_res = csid_res_8550, .vfe_res = vfe_res_8550, @@ -5290,6 +5305,7 @@ static const struct camss_resources sm8550_resources = { static const struct camss_resources sm8650_resources = { .version = CAMSS_8650, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_sm8650, .csid_res = csid_res_sm8650, .csid_wrapper_res = &csid_wrapper_res_sm8550, @@ -5304,6 +5320,7 @@ static const struct camss_resources sm8650_resources = { static const struct camss_resources x1e80100_resources = { .version = CAMSS_X1E80100, .pd_name = "top", + .legacy_phy = true, .csiphy_res = csiphy_res_x1e80100, .csid_res = csid_res_x1e80100, .vfe_res = vfe_res_x1e80100, diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 6d048414c919e..24ec3ad7990e7 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -104,6 +104,7 @@ enum icc_count { struct camss_resources { enum camss_version version; const char *pd_name; + const bool legacy_phy; const struct camss_subdev_resources *csiphy_res; const struct camss_subdev_resources *csid_res; const struct camss_subdev_resources *ispif_res; From 58ebfc8e653cf9f55a2c341c0c04c7ce1480c34d Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:47 +0000 Subject: [PATCH 384/438] FROMLIST: media: qcom: camss: Add support for PHY API devices Add the ability to use a PHY pointer which interacts with the standard PHY API. In the first instance the code will try to use the new PHY interface. If no PHYs are present in the DT then the legacy method will be attempted. Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-6-a59c3f037d0b@linaro.org/ --- drivers/media/platform/qcom/camss/Kconfig | 1 + .../media/platform/qcom/camss/camss-csiphy.c | 185 ++++++++++++++++-- .../media/platform/qcom/camss/camss-csiphy.h | 7 + drivers/media/platform/qcom/camss/camss.c | 72 +++++-- 4 files changed, 235 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/platform/qcom/camss/Kconfig index 4eda48cb1adf0..1edc5e5a1829e 100644 --- a/drivers/media/platform/qcom/camss/Kconfig +++ b/drivers/media/platform/qcom/camss/Kconfig @@ -7,3 +7,4 @@ config VIDEO_QCOM_CAMSS select VIDEO_V4L2_SUBDEV_API select VIDEOBUF2_DMA_SG select V4L2_FWNODE + select PHY_QCOM_MIPI_CSI2 diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 62623393f4144..b8bfbf2fef8fa 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -7,12 +7,14 @@ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2016-2018 Linaro Ltd. */ +#include #include #include #include #include #include #include +#include #include #include #include @@ -131,10 +133,10 @@ static u8 csiphy_get_bpp(const struct csiphy_format_info *formats, } /* - * csiphy_set_clock_rates - Calculate and set clock rates on CSIPHY module + * csiphy_set_clock_rates_legacy - Calculate and set clock rates on CSIPHY module * @csiphy: CSIPHY device */ -static int csiphy_set_clock_rates(struct csiphy_device *csiphy) +static int csiphy_set_clock_rates_legacy(struct csiphy_device *csiphy) { struct device *dev = csiphy->camss->dev; s64 link_freq; @@ -200,7 +202,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy) * * Return 0 on success or a negative error code otherwise */ -static int csiphy_set_power(struct v4l2_subdev *sd, int on) +static int csiphy_set_power_legacy(struct v4l2_subdev *sd, int on) { struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); struct device *dev = csiphy->camss->dev; @@ -219,7 +221,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) return ret; } - ret = csiphy_set_clock_rates(csiphy); + ret = csiphy_set_clock_rates_legacy(csiphy); if (ret < 0) { regulator_bulk_disable(csiphy->num_supplies, csiphy->supplies); @@ -254,7 +256,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) } /* - * csiphy_stream_on - Enable streaming on CSIPHY module + * csiphy_stream_on_legacy - Enable streaming on CSIPHY module * @csiphy: CSIPHY device * * Helper function to enable streaming on CSIPHY module. @@ -262,7 +264,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) * * Return 0 on success or a negative error code otherwise */ -static int csiphy_stream_on(struct csiphy_device *csiphy) +static int csiphy_stream_on_legacy(struct csiphy_device *csiphy) { struct csiphy_config *cfg = &csiphy->cfg; s64 link_freq; @@ -306,11 +308,86 @@ static int csiphy_stream_on(struct csiphy_device *csiphy) * * Helper function to disable streaming on CSIPHY module */ -static void csiphy_stream_off(struct csiphy_device *csiphy) +static void csiphy_stream_off_legacy(struct csiphy_device *csiphy) { csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg); } +/* + * csiphy_stream_on - Enable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to enable streaming on CSIPHY module. + * Main configuration of CSIPHY module is also done here. + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_stream_on(struct csiphy_device *csiphy) +{ + u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats, + csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); + u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; + struct phy_configure_opts_mipi_dphy *dphy_cfg; + union phy_configure_opts dphy_opts = { 0 }; + struct device *dev = csiphy->camss->dev; + s64 link_freq; + int ret; + + dphy_cfg = &dphy_opts.mipi_dphy; + + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); + + if (link_freq < 0) { + dev_err(dev, + "Cannot get CSI2 transmitter's link frequency\n"); + return -EINVAL; + } + + phy_mipi_dphy_get_default_config_for_hsclk(link_freq, num_lanes, dphy_cfg); + + phy_set_mode(csiphy->phy, PHY_MODE_MIPI_DPHY); + ret = phy_configure(csiphy->phy, &dphy_opts); + if (ret) { + dev_err(dev, "failed to configure MIPI D-PHY\n"); + goto error; + } + + return phy_power_on(csiphy->phy); + +error: + return ret; +} + +/* + * csiphy_stream_off - Disable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to disable streaming on CSIPHY module + */ +static void csiphy_stream_off(struct csiphy_device *csiphy) +{ + phy_power_off(csiphy->phy); +} + +/* + * csiphy_set_stream - Enable/disable streaming on CSIPHY module + * @sd: CSIPHY V4L2 subdevice + * @enable: Requested streaming state + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_set_stream_legacy(struct v4l2_subdev *sd, int enable) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + int ret = 0; + + if (enable) + ret = csiphy_stream_on_legacy(csiphy); + else + csiphy_stream_off_legacy(csiphy); + + return ret; +} /* * csiphy_set_stream - Enable/disable streaming on CSIPHY module @@ -568,16 +645,16 @@ static bool csiphy_match_clock_name(const char *clock_name, const char *format, } /* - * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources + * msm_csiphy_subdev_init_legacy - Initialize CSIPHY device structure and resources * @csiphy: CSIPHY device * @res: CSIPHY module resources table * @id: CSIPHY module id * * Return 0 on success or a negative error code otherwise */ -int msm_csiphy_subdev_init(struct camss *camss, - struct csiphy_device *csiphy, - const struct camss_subdev_resources *res, u8 id) +int msm_csiphy_subdev_init_legacy(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id) { struct device *dev = camss->dev; struct platform_device *pdev = to_platform_device(dev); @@ -705,6 +782,69 @@ int msm_csiphy_subdev_init(struct camss *camss, return ret; } +/* + * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources + * @csiphy: CSIPHY device + * @res: CSIPHY module resources table + * @id: CSIPHY module id + * + * Return 0 on success or a negative error code otherwise + */ +int msm_csiphy_subdev_init(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id) +{ + struct device *dev = camss->dev; + struct of_phandle_args args; + u8 combo_mode; + int idx; + int ret; + + snprintf(csiphy->name, ARRAY_SIZE(csiphy->name), "csiphy%d", id); + + idx = of_property_match_string(dev->of_node, "phy-names", csiphy->name); + if (idx < 0) { + dev_err(dev, "%s not found\n", csiphy->name); + return idx; + } + + ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells", idx, &args); + if (ret < 0) { + dev_err(dev, "unable to parse phys args %s\n", csiphy->name); + return ret; + } + + if (!of_device_is_available(args.np)) + goto put_np; + + combo_mode = args.args[0]; + if (combo_mode != PHY_TYPE_DPHY) { + dev_err(dev, "%s mode %d not supported\n", csiphy->name, combo_mode); + ret = -EOPNOTSUPP; + goto put_np; + } + + csiphy->phy = devm_phy_get(dev, csiphy->name); + if (IS_ERR(csiphy->phy)) { + ret = PTR_ERR(csiphy->phy); + goto put_np; + } + + csiphy->camss = camss; + csiphy->id = id; + csiphy->cfg.combo_mode = combo_mode; + csiphy->res = &res->csiphy; + + ret = phy_init(csiphy->phy); + if (ret) + dev_err(dev, "phy %s init fail %d\n", csiphy->name, ret); + +put_np: + of_node_put(args.np); + + return ret; +} + /* * csiphy_link_setup - Setup CSIPHY connections * @entity: Pointer to media entity structure @@ -739,8 +879,12 @@ static int csiphy_link_setup(struct media_entity *entity, return 0; } -static const struct v4l2_subdev_core_ops csiphy_core_ops = { - .s_power = csiphy_set_power, +static const struct v4l2_subdev_core_ops csiphy_core_ops_legacy = { + .s_power = csiphy_set_power_legacy, +}; + +static const struct v4l2_subdev_video_ops csiphy_video_ops_legacy = { + .s_stream = csiphy_set_stream_legacy, }; static const struct v4l2_subdev_video_ops csiphy_video_ops = { @@ -754,8 +898,13 @@ static const struct v4l2_subdev_pad_ops csiphy_pad_ops = { .set_fmt = csiphy_set_format, }; +static const struct v4l2_subdev_ops csiphy_v4l2_ops_legacy = { + .core = &csiphy_core_ops_legacy, + .video = &csiphy_video_ops_legacy, + .pad = &csiphy_pad_ops, +}; + static const struct v4l2_subdev_ops csiphy_v4l2_ops = { - .core = &csiphy_core_ops, .video = &csiphy_video_ops, .pad = &csiphy_pad_ops, }; @@ -784,7 +933,11 @@ int msm_csiphy_register_entity(struct csiphy_device *csiphy, struct device *dev = csiphy->camss->dev; int ret; - v4l2_subdev_init(sd, &csiphy_v4l2_ops); + if (IS_ERR(csiphy->phy)) + v4l2_subdev_init(sd, &csiphy_v4l2_ops_legacy); + else + v4l2_subdev_init(sd, &csiphy_v4l2_ops); + sd->internal_ops = &csiphy_v4l2_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", @@ -823,6 +976,8 @@ int msm_csiphy_register_entity(struct csiphy_device *csiphy, */ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy) { + if (!IS_ERR(csiphy->phy)) + phy_exit(csiphy->phy); v4l2_device_unregister_subdev(&csiphy->subdev); media_entity_cleanup(&csiphy->subdev.entity); } diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 2d5054819df7f..25b803c06e8bf 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -95,6 +96,7 @@ struct csiphy_device_regs { struct csiphy_device { struct camss *camss; + struct phy *phy; u8 id; struct v4l2_subdev subdev; struct media_pad pads[MSM_CSIPHY_PADS_NUM]; @@ -102,6 +104,7 @@ struct csiphy_device { void __iomem *base_clk_mux; u32 irq; char irq_name[30]; + char name[16]; struct camss_clock *clock; bool *rate_set; int nclocks; @@ -116,6 +119,10 @@ struct csiphy_device { struct camss_subdev_resources; +int msm_csiphy_subdev_init_legacy(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id); + int msm_csiphy_subdev_init(struct camss *camss, struct csiphy_device *csiphy, const struct camss_subdev_resources *res, u8 id); diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 5fb5ad87e1671..b1737b5d52160 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4450,14 +4450,35 @@ static int camss_parse_endpoint_node(struct device *dev, static int camss_parse_ports(struct camss *camss) { struct device *dev = camss->dev; + const struct camss_resources *res = camss->res; struct fwnode_handle *fwnode = dev_fwnode(dev), *ep; int ret; fwnode_graph_for_each_endpoint(fwnode, ep) { struct camss_async_subdev *csd; + struct fwnode_handle *remote; + + if (!fwnode_device_is_available(ep)) + continue; + + if (res->legacy_phy) { + csd = v4l2_async_nf_add_fwnode_remote(&camss->notifier, ep, + typeof(*csd)); + } else { + /* + * For non-legacy PHY, the CSIPHY is a separate device. + * Register the remote endpoint (CSIPHY's endpoint) as + * the async subdev, not the remote port parent. + */ + remote = fwnode_graph_get_remote_endpoint(ep); + if (!remote) + continue; + + csd = v4l2_async_nf_add_fwnode(&camss->notifier, remote, + struct camss_async_subdev); + fwnode_handle_put(remote); + } - csd = v4l2_async_nf_add_fwnode_remote(&camss->notifier, ep, - typeof(*csd)); if (IS_ERR(csd)) { ret = PTR_ERR(csd); goto err_cleanup; @@ -4489,15 +4510,26 @@ static int camss_init_subdevices(struct camss *camss) unsigned int i; int ret; - for (i = 0; i < camss->res->csiphy_num; i++) { - ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], - &res->csiphy_res[i], - res->csiphy_res[i].csiphy.id); - if (ret < 0) { - dev_err(camss->dev, - "Failed to init csiphy%d sub-device: %d\n", - i, ret); - return ret; + if (!res->legacy_phy) { + for (i = 0; i < camss->res->csiphy_num; i++) { + ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], + &res->csiphy_res[i], + res->csiphy_res[i].csiphy.id); + if (ret < 0) + return ret; + } + } else { + for (i = 0; i < camss->res->csiphy_num; i++) { + ret = msm_csiphy_subdev_init_legacy(camss, &camss->csiphy[i], + &res->csiphy_res[i], + res->csiphy_res[i].csiphy.id); + if (ret < 0) { + dev_err(camss->dev, + "Failed to init csiphy%d sub-device: %d\n", + i, ret); + return ret; + } + camss->csiphy[i].phy = ERR_PTR(-ENODEV); } } @@ -4574,6 +4606,9 @@ static int camss_link_entities(struct camss *camss) for (i = 0; i < camss->res->csiphy_num; i++) { for (j = 0; j < camss->res->csid_num; j++) { + if (!camss->csiphy[i].phy) + continue; + ret = media_create_pad_link(&camss->csiphy[i].subdev.entity, MSM_CSIPHY_PAD_SRC, &camss->csid[j].subdev.entity, @@ -4683,6 +4718,9 @@ static int camss_register_entities(struct camss *camss) int ret; for (i = 0; i < camss->res->csiphy_num; i++) { + if (!camss->csiphy[i].phy) + continue; + ret = msm_csiphy_register_entity(&camss->csiphy[i], &camss->v4l2_dev); if (ret < 0) { @@ -4738,8 +4776,10 @@ static int camss_register_entities(struct camss *camss) i = camss->res->csiphy_num; err_reg_csiphy: - for (i--; i >= 0; i--) - msm_csiphy_unregister_entity(&camss->csiphy[i]); + for (i--; i >= 0; i--) { + if (camss->csiphy[i].phy) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + } return ret; } @@ -4754,8 +4794,10 @@ static void camss_unregister_entities(struct camss *camss) { unsigned int i; - for (i = 0; i < camss->res->csiphy_num; i++) - msm_csiphy_unregister_entity(&camss->csiphy[i]); + for (i = 0; i < camss->res->csiphy_num; i++) { + if (camss->csiphy[i].phy) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + } for (i = 0; i < camss->res->csid_num; i++) msm_csid_unregister_entity(&camss->csid[i]); From f57340e0da5a216055cdd0a0d1e11ef68d98f717 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:28:48 +0000 Subject: [PATCH 385/438] FROMLIST: media: qcom: camss: Drop legacy PHY descriptions from x1e x1e is the first CAMSS SoC to use the new PHY interface. Drop the redundant legacy CSIPHY descriptions. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v9-7-a59c3f037d0b@linaro.org/ --- drivers/media/platform/qcom/camss/camss.c | 37 ----------------------- 1 file changed, 37 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index b1737b5d52160..0ebe634f5d96b 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -3895,15 +3895,6 @@ static const struct resources_icc icc_res_sa8775p[] = { static const struct camss_subdev_resources csiphy_res_x1e80100[] = { /* CSIPHY0 */ { - .regulators = { - { .supply = "vdd-csiphy-0p8", .init_load_uA = 105000 }, - { .supply = "vdd-csiphy-1p2", .init_load_uA = 58900 } - }, - .clock = { "csiphy0", "csiphy0_timer" }, - .clock_rate = { { 300000000, 400000000, 480000000 }, - { 266666667, 400000000 } }, - .reg = { "csiphy0" }, - .interrupt = { "csiphy0" }, .csiphy = { .id = 0, .hw_ops = &csiphy_ops_3ph_1_0, @@ -3912,15 +3903,6 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { }, /* CSIPHY1 */ { - .regulators = { - { .supply = "vdd-csiphy-0p8", .init_load_uA = 105000 }, - { .supply = "vdd-csiphy-1p2", .init_load_uA = 58900 } - }, - .clock = { "csiphy1", "csiphy1_timer" }, - .clock_rate = { { 300000000, 400000000, 480000000 }, - { 266666667, 400000000 } }, - .reg = { "csiphy1" }, - .interrupt = { "csiphy1" }, .csiphy = { .id = 1, .hw_ops = &csiphy_ops_3ph_1_0, @@ -3929,15 +3911,6 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { }, /* CSIPHY2 */ { - .regulators = { - { .supply = "vdd-csiphy-0p8", .init_load_uA = 105000 }, - { .supply = "vdd-csiphy-1p2", .init_load_uA = 58900 } - }, - .clock = { "csiphy2", "csiphy2_timer" }, - .clock_rate = { { 300000000, 400000000, 480000000 }, - { 266666667, 400000000 } }, - .reg = { "csiphy2" }, - .interrupt = { "csiphy2" }, .csiphy = { .id = 2, .hw_ops = &csiphy_ops_3ph_1_0, @@ -3946,15 +3919,6 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { }, /* CSIPHY4 */ { - .regulators = { - { .supply = "vdd-csiphy-0p8", .init_load_uA = 105000 }, - { .supply = "vdd-csiphy-1p2", .init_load_uA = 58900 } - }, - .clock = { "csiphy4", "csiphy4_timer" }, - .clock_rate = { { 300000000, 400000000, 480000000 }, - { 266666667, 400000000 } }, - .reg = { "csiphy4" }, - .interrupt = { "csiphy4" }, .csiphy = { .id = 4, .hw_ops = &csiphy_ops_3ph_1_0, @@ -5362,7 +5326,6 @@ static const struct camss_resources sm8650_resources = { static const struct camss_resources x1e80100_resources = { .version = CAMSS_X1E80100, .pd_name = "top", - .legacy_phy = true, .csiphy_res = csiphy_res_x1e80100, .csid_res = csid_res_x1e80100, .vfe_res = vfe_res_x1e80100, From 3ac185b6fda6e11ccf618770b83f3cd988f473e4 Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Fri, 2 Jan 2026 18:10:18 +0530 Subject: [PATCH 386/438] mmc: host: sdhci-msm: Add support for wrapped keys Add the wrapped key support for sdhci-msm by implementing the needed methods in struct blk_crypto_ll_ops and setting the appropriate flag in blk_crypto_profile::key_types_supported. Tested on SC7280 eMMC variant. How to test: Use the "v1.3.0" tag from https://github.com/google/fscryptctl and build fscryptctl that supports generating wrapped keys. Enable the following config options: CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_QCOM_INLINE_CRYPTO_ENGINE=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_MMC_CRYPTO=y Enable "qcom_ice.use_wrapped_keys" via kernel command line. $ mkfs.ext4 -F -O encrypt,stable_inodes /dev/disk/by-partlabel/vm-data $ mount /dev/disk/by-partlabel/vm-data -o inlinecrypt /mnt $ fscryptctl generate_hw_wrapped_key /dev/disk/by-partlabel/vm-data > /mnt/key.longterm $ fscryptctl prepare_hw_wrapped_key /dev/disk/by-partlabel/vm-data < /mnt/key.longterm > /tmp/key.ephemeral $ KEYID=$(fscryptctl add_key --hw-wrapped-key < /tmp/key.ephemeral /mnt) $ rm -rf /mnt/dir $ mkdir /mnt/dir $ fscryptctl set_policy --iv-ino-lblk-32 "$KEYID" /mnt/dir $ dmesg > /mnt/dir/test.txt $ sync Reboot the board $ mount /dev/disk/by-partlabel/vm-data -o inlinecrypt /mnt $ ls /mnt/dir # File should be encrypted $ fscryptctl prepare_hw_wrapped_key /dev/disk/by-partlabel/vm-data < /mnt/key.longterm > /tmp/key.ephemeral $ KEYID=$(fscryptctl add_key --hw-wrapped-key < /tmp/key.ephemeral /mnt) $ fscryptctl set_policy --iv-ino-lblk-32 "$KEYID" /mnt/dir $ cat /mnt/dir/test.txt # File should now be decrypted Tested-by: Wenjia Zhang Signed-off-by: Neeraj Soni Acked-by: Adrian Hunter Reviewed-by: Eric Biggers --- drivers/mmc/host/sdhci-msm.c | 47 +++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 3b85233131b38..98356c17e5386 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1914,11 +1914,6 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, if (IS_ERR_OR_NULL(ice)) return PTR_ERR_OR_ZERO(ice); - if (qcom_ice_get_supported_key_type(ice) != BLK_CRYPTO_KEY_TYPE_RAW) { - dev_warn(dev, "Wrapped keys not supported. Disabling inline encryption support.\n"); - return 0; - } - msm_host->ice = ice; /* Initialize the blk_crypto_profile */ @@ -1932,7 +1927,7 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, profile->ll_ops = sdhci_msm_crypto_ops; profile->max_dun_bytes_supported = 4; - profile->key_types_supported = BLK_CRYPTO_KEY_TYPE_RAW; + profile->key_types_supported = qcom_ice_get_supported_key_type(ice); profile->dev = dev; /* @@ -2012,9 +2007,49 @@ static int sdhci_msm_ice_keyslot_evict(struct blk_crypto_profile *profile, return qcom_ice_evict_key(msm_host->ice, slot); } +static int sdhci_msm_ice_derive_sw_secret(struct blk_crypto_profile *profile, + const u8 *eph_key, size_t eph_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + struct sdhci_msm_host *msm_host = sdhci_msm_host_from_crypto_profile(profile); + + return qcom_ice_derive_sw_secret(msm_host->ice, eph_key, eph_key_size, + sw_secret); +} + +static int sdhci_msm_ice_import_key(struct blk_crypto_profile *profile, + const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct sdhci_msm_host *msm_host = sdhci_msm_host_from_crypto_profile(profile); + + return qcom_ice_import_key(msm_host->ice, raw_key, raw_key_size, lt_key); +} + +static int sdhci_msm_ice_generate_key(struct blk_crypto_profile *profile, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct sdhci_msm_host *msm_host = sdhci_msm_host_from_crypto_profile(profile); + + return qcom_ice_generate_key(msm_host->ice, lt_key); +} + +static int sdhci_msm_ice_prepare_key(struct blk_crypto_profile *profile, + const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct sdhci_msm_host *msm_host = sdhci_msm_host_from_crypto_profile(profile); + + return qcom_ice_prepare_key(msm_host->ice, lt_key, lt_key_size, eph_key); +} + static const struct blk_crypto_ll_ops sdhci_msm_crypto_ops = { .keyslot_program = sdhci_msm_ice_keyslot_program, .keyslot_evict = sdhci_msm_ice_keyslot_evict, + .derive_sw_secret = sdhci_msm_ice_derive_sw_secret, + .import_key = sdhci_msm_ice_import_key, + .generate_key = sdhci_msm_ice_generate_key, + .prepare_key = sdhci_msm_ice_prepare_key, }; #else /* CONFIG_MMC_CRYPTO */ From ee496ca417bc706043f5ab1aeec7ab8681d16385 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 13:51:12 +0530 Subject: [PATCH 387/438] FROMLIST: dt-bindings: crypto: qcom,ice: Require power-domain and iface clk Update the inline-crypto engine DT binding to reflect that power-domain and clock-names are now mandatory. Also update the maximum number of clocks that can be specified to two. These new fields are mandatory because ICE needs to vote on the power domain before it attempts to vote on the core and iface clocks to avoid clock 'stuck' issues. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-1-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- .../bindings/crypto/qcom,inline-crypto-engine.yaml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml index 061ff718b23d6..1078de779c16e 100644 --- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml @@ -29,12 +29,20 @@ properties: maxItems: 1 clocks: + maxItems: 2 + + clock-names: + maxItems: 2 + + power-domains: maxItems: 1 required: - compatible - reg - clocks + - clock-names + - power-domains additionalProperties: false @@ -46,6 +54,10 @@ examples: compatible = "qcom,sm8550-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0x01d88000 0x8000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc UFS_PHY_GDSC>; }; ... From 6675f5595d7b963f5c41503f77518bb8501c4992 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:25:10 +0530 Subject: [PATCH 388/438] FROMLIST: arm64: dts: qcom: lemans: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the UFS_PHY_GDSC power domain is enabled. Specify both the UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for lemans. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-3-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/lemans.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 808827b83553d..4473aa8bd5f43 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -2758,7 +2758,11 @@ compatible = "qcom,sa8775p-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0x0 0x01d88000 0x0 0x18000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc UFS_PHY_GDSC>; }; cryptobam: dma-controller@1dc4000 { From 4622e9a502a5df34252112e3a8b687fb46f7bd27 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Fri, 23 Jan 2026 18:46:25 +0530 Subject: [PATCH 389/438] FROMLIST: arm64: dts: qcom: monaco: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the GCC_UFS_PHY_GDSC power domain is enabled. Specify both the GCC_UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for monaco. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-4-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/monaco.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 5d2df4305d1c1..083c99bf4a4a9 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -2725,7 +2725,11 @@ compatible = "qcom,qcs8300-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0x0 0x01d88000 0x0 0x18000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc GCC_UFS_PHY_GDSC>; }; crypto: crypto@1dfa000 { From 1434fd89cc2ed123641f449e9dbaa028ba79c3e4 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:27:25 +0530 Subject: [PATCH 390/438] FROMLIST: arm64: dts: qcom: sc7180: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the UFS_PHY_GDSC power domain is enabled. Specify both the UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for sc7180. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-5-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 45b9864e3304b..74eb895cf4da7 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -1605,7 +1605,11 @@ compatible = "qcom,sc7180-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0 0x01d90000 0 0x8000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc UFS_PHY_GDSC>; }; ipa: ipa@1e40000 { From a1310e6297b5e40e9e8e3fc99512fa607ad9a764 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 16:15:04 +0530 Subject: [PATCH 391/438] FROMLIST: arm64: dts: qcom: kodiak: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the GCC_UFS_PHY_GDSC power domain is enabled. Specify both the GCC_UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for kodiak. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-6-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 6079e67ea829b..cc59bbcb07cbc 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -2579,7 +2579,11 @@ compatible = "qcom,sc7280-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0 0x01d88000 0 0x8000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc GCC_UFS_PHY_GDSC>; }; cryptobam: dma-controller@1dc4000 { From e86738a3345b16d7383edf2ea980f5bfc9779a57 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:30:05 +0530 Subject: [PATCH 392/438] FROMLIST: arm64: dts: qcom: sm8450: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the UFS_PHY_GDSC power domain is enabled. Specify both the UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for sm8450. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-7-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 920a2d1c04d0c..3d243e757fa1a 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -5374,7 +5374,11 @@ compatible = "qcom,sm8450-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0 0x01d88000 0 0x8000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc UFS_PHY_GDSC>; }; cryptobam: dma-controller@1dc4000 { From e670e835c548d3a1d5e1ebf2b30bd16314a1e548 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:31:52 +0530 Subject: [PATCH 393/438] FROMLIST: arm64: dts: qcom: sm8550: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the UFS_PHY_GDSC power domain is enabled. Specify both the UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for sm8550. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-8-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index e3f93f4f412de..b6c8c76429ba9 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -2449,7 +2449,11 @@ "qcom,inline-crypto-engine"; reg = <0 0x01d88000 0 0x18000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc UFS_PHY_GDSC>; }; tcsr_mutex: hwlock@1f40000 { From 4e48c910cc9100f1de2860c11ac9a1db4ea30376 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:32:31 +0530 Subject: [PATCH 394/438] FROMLIST: arm64: dts: qcom: sm8650: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the UFS_PHY_GDSC power domain is enabled. Specify both the UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for sm8650. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-9-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/sm8650.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi index 357e43b907405..c32a817efdb47 100644 --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi @@ -4081,7 +4081,11 @@ "qcom,inline-crypto-engine"; reg = <0 0x01d88000 0 0x18000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc UFS_PHY_GDSC>; }; cryptobam: dma-controller@1dc4000 { From a207c39dbba7250e613cc8b8886292d59332a478 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:33:19 +0530 Subject: [PATCH 395/438] FROMLIST: arm64: dts: qcom: sm8750: Add power-domain and iface clk for ice node Qualcomm in-line crypto engine (ICE) platform driver specifies and votes for it's own resources. Before accessing ICE hardware, the 'core' and 'iface' clocks must be turned on by the driver. This can only be done if the GCC_UFS_PHY_GDSC power domain is enabled. Specify both the GCC_UFS_PHY_GDSC power domain and 'core' and 'iface' clocks in the ICE node for sm8750. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-10-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index f56b1f889b857..e870bdf2528c2 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -2083,7 +2083,11 @@ "qcom,inline-crypto-engine"; reg = <0x0 0x01d88000 0x0 0x18000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "ice_core_clk", + "iface_clk"; + power-domains = <&gcc GCC_UFS_PHY_GDSC>; }; cryptobam: dma-controller@1dc4000 { From 725a9c8705f2171bd0f08d3f12276acb9321e83e Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 15:28:59 +0530 Subject: [PATCH 396/438] FROMLIST: soc: qcom: ice: Add explicit power-domain and clock voting calls for ICE Since Qualcomm inline-crypto engine (ICE) is now a dedicated driver de-coupled from the QCOM UFS driver, it should explicitly vote for it's needed resources during probe, specifically the UFS_PHY_GDSC power-domain and the 'core' and 'iface' clocks. Also updated the suspend and resume callbacks to handle votes on these resources. Link: https://lore.kernel.org/all/20260123-qcom_ice_power_and_clk_vote-v1-11-e9059776f85c@qti.qualcomm.com/ Signed-off-by: Harshal Dev --- drivers/soc/qcom/ice.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index b203bc685cadd..4b50d05ca02a3 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include @@ -108,6 +110,7 @@ struct qcom_ice { void __iomem *base; struct clk *core_clk; + struct clk *iface_clk; bool use_hwkm; bool hwkm_init_complete; u8 hwkm_version; @@ -310,12 +313,20 @@ int qcom_ice_resume(struct qcom_ice *ice) struct device *dev = ice->dev; int err; + pm_runtime_get_sync(dev); err = clk_prepare_enable(ice->core_clk); if (err) { dev_err(dev, "failed to enable core clock (%d)\n", err); return err; } + + err = clk_prepare_enable(ice->iface_clk); + if (err) { + dev_err(dev, "failed to enable iface clock (%d)\n", + err); + return err; + } qcom_ice_hwkm_init(ice); return qcom_ice_wait_bist_status(ice); } @@ -323,7 +334,9 @@ EXPORT_SYMBOL_GPL(qcom_ice_resume); int qcom_ice_suspend(struct qcom_ice *ice) { + clk_disable_unprepare(ice->iface_clk); clk_disable_unprepare(ice->core_clk); + pm_runtime_put_sync(ice->dev); ice->hwkm_init_complete = false; return 0; @@ -584,6 +597,10 @@ static struct qcom_ice *qcom_ice_create(struct device *dev, if (IS_ERR(engine->core_clk)) return ERR_CAST(engine->core_clk); + engine->iface_clk = devm_clk_get_enabled(dev, "iface_clk"); + if (IS_ERR(engine->iface_clk)) + return ERR_CAST(engine->iface_clk); + if (!qcom_ice_check_supported(engine)) return ERR_PTR(-EOPNOTSUPP); @@ -725,6 +742,9 @@ static int qcom_ice_probe(struct platform_device *pdev) return PTR_ERR(base); } + devm_pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + engine = qcom_ice_create(&pdev->dev, base); if (IS_ERR(engine)) return PTR_ERR(engine); From f6d0da7a04a6930481e39ca97cd39f4c64bb8132 Mon Sep 17 00:00:00 2001 From: Debraj Mukhopadhyay Date: Fri, 16 Jan 2026 17:40:04 +0530 Subject: [PATCH 397/438] mmc: Avoid reprogram all keys to Inline Crypto Engine for MMC runtime suspend resume Crypto reprogram all keys is called for each MMC runtime suspend/resume in current upstream design. If this is implemented as a non-interruptible call to TEE for security, the cpu core is blocked for execution while this call executes although the crypto engine already has the keys. For example, glitches in audio/video streaming applications have been observed due to this. Add the flag MMC_CAP2_CRYPTO_NO_REPROG as part of host->caps2 to control reprogramming keys to crypto engine for socs which dont require this feature. Link: https://lore.kernel.org/all/20260116121004.1829223-1-neeraj.soni@oss.qualcomm.com/ Signed-off-by: Seshu Madhavi Puppala Co-developed-by: Ram Prakash Gupta Signed-off-by: Ram Prakash Gupta Co-developed-by: Sarthak Garg Signed-off-by: Sarthak Garg Signed-off-by: Debraj Mukhopadhyay Signed-off-by: Neeraj Soni Acked-by: Adrian Hunter --- drivers/mmc/core/crypto.c | 2 +- drivers/mmc/host/sdhci-msm.c | 6 ++++++ include/linux/mmc/host.h | 5 +---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/crypto.c b/drivers/mmc/core/crypto.c index fec4fbf16a5b6..a5a90bfc634ee 100644 --- a/drivers/mmc/core/crypto.c +++ b/drivers/mmc/core/crypto.c @@ -15,7 +15,7 @@ void mmc_crypto_set_initial_state(struct mmc_host *host) { /* Reset might clear all keys, so reprogram all the keys. */ - if (host->caps2 & MMC_CAP2_CRYPTO) + if ((host->caps2 & MMC_CAP2_CRYPTO) && !(host->caps2 & MMC_CAP2_CRYPTO_NO_REPROG)) blk_crypto_reprogram_all_keys(&host->crypto_profile); } diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 98356c17e5386..d9338387edd58 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1947,6 +1947,7 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, } mmc->caps2 |= MMC_CAP2_CRYPTO; + mmc->caps2 |= MMC_CAP2_CRYPTO_NO_REPROG; return 0; } @@ -2564,6 +2565,11 @@ static int sdhci_msm_gcc_reset(struct device *dev, struct sdhci_host *host) usleep_range(200, 210); reset_control_put(reset); +#ifdef CONFIG_MMC_CRYPTO + if (host->mmc->caps2 & MMC_CAP2_CRYPTO) + blk_crypto_reprogram_all_keys(&host->mmc->crypto_profile); +#endif + return ret; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index e0e2c265e5d10..2fd76f966e244 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -457,12 +457,9 @@ struct mmc_host { #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ #define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */ #define MMC_CAP2_MERGE_CAPABLE (1 << 26) /* Host can merge a segment over the segment size */ -#ifdef CONFIG_MMC_CRYPTO #define MMC_CAP2_CRYPTO (1 << 27) /* Host supports inline encryption */ -#else -#define MMC_CAP2_CRYPTO 0 -#endif #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */ +#define MMC_CAP2_CRYPTO_NO_REPROG (1 << 29) /* Host handles inline crypto key reprogramming */ bool uhs2_sd_tran; /* UHS-II flag for SD_TRAN state */ bool uhs2_app_cmd; /* UHS-II flag for APP command */ From 749b1a111ca3146d75c31007cae0d104e530441a Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:07 +0000 Subject: [PATCH 398/438] FROMLIST: arm64: dts: qcom: x1e80100: Add CCI definitions Add in two CCI buses. One bus has two CCI bus master pinouts: cci_i2c_sda0 = gpio101 cci_i2c_scl0 = gpio102 cci_i2c_sda1 = gpio103 cci_i2c_scl1 = gpio104 The second bus has two CCI bus master pinouts: cci_i2c_sda2 = gpio105 cci_i2c_scl2 = gpio106 aon_cci_i2c_sda3 = gpio235 aon_cci_i2c_scl3 = gpio236 Reviewed-by: Konrad Dybcio Reviewed-by: Vladimir Zapolskiy Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-2-f3f7ddfbf849@linaro.org/ --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 150 ++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 97d238f6b7ec9..065baf75b4f6c 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -5802,6 +5802,84 @@ #power-domain-cells = <1>; }; + cci0: cci@ac15000 { + compatible = "qcom,x1e80100-cci", "qcom,msm8996-cci"; + reg = <0 0x0ac15000 0 0x1000>; + + interrupts = ; + + clocks = <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CCI_0_CLK>; + clock-names = "camnoc_axi", + "cpas_ahb", + "cci"; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + pinctrl-0 = <&cci0_default>; + pinctrl-1 = <&cci0_sleep>; + pinctrl-names = "default", "sleep"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci0_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci0_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + cci1: cci@ac16000 { + compatible = "qcom,x1e80100-cci", "qcom,msm8996-cci"; + reg = <0 0x0ac16000 0 0x1000>; + + interrupts = ; + + clocks = <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CCI_1_CLK>; + clock-names = "camnoc_axi", + "cpas_ahb", + "cci"; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + pinctrl-0 = <&cci1_default>; + pinctrl-1 = <&cci1_sleep>; + pinctrl-names = "default", "sleep"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci1_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci1_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + camcc: clock-controller@ade0000 { compatible = "qcom,x1e80100-camcc"; reg = <0 0x0ade0000 0 0x20000>; @@ -6452,6 +6530,78 @@ gpio-ranges = <&tlmm 0 0 239>; wakeup-parent = <&pdc>; + cci0_default: cci0-default-state { + cci0_i2c0_default: cci0-i2c0-default-pins { + /* cci_i2c_sda0, cci_i2c_scl0 */ + pins = "gpio101", "gpio102"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-up; + }; + + cci0_i2c1_default: cci0-i2c1-default-pins { + /* cci_i2c_sda1, cci_i2c_scl1 */ + pins = "gpio103", "gpio104"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + cci0_sleep: cci0-sleep-state { + cci0_i2c0_sleep: cci0-i2c0-sleep-pins { + /* cci_i2c_sda0, cci_i2c_scl0 */ + pins = "gpio101", "gpio102"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-down; + }; + + cci0_i2c1_sleep: cci0-i2c1-sleep-pins { + /* cci_i2c_sda1, cci_i2c_scl1 */ + pins = "gpio103", "gpio104"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cci1_default: cci1-default-state { + cci1_i2c0_default: cci1-i2c0-default-pins { + /* cci_i2c_sda2, cci_i2c_scl2 */ + pins = "gpio105", "gpio106"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-up; + }; + + cci1_i2c1_default: cci1-i2c1-default-pins { + /* aon_cci_i2c_sda3, aon_cci_i2c_scl3 */ + pins = "gpio235", "gpio236"; + function = "aon_cci"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + cci1_sleep: cci1-sleep-state { + cci1_i2c0_sleep: cci1-i2c0-sleep-pins { + /* cci_i2c_sda2, cci_i2c_scl2 */ + pins = "gpio105", "gpio106"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-down; + }; + + cci1_i2c1_sleep: cci1-i2c1-sleep-pins { + /* aon_cci_i2c_sda3, aon_cci_i2c_scl3 */ + pins = "gpio235", "gpio236"; + function = "aon_cci"; + drive-strength = <2>; + bias-pull-down; + }; + }; + edp0_hpd_default: edp0-hpd-default-state { pins = "gpio119"; function = "edp0_hot"; From 49814a0669a33dea3f133dde76179ac2b8163fbc Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:08 +0000 Subject: [PATCH 399/438] FROMLIST: arm64: dts: qcom: x1e80100: Add MIPI CSI PHY nodes Add csiphy nodes for - csiphy0 - csiphy1 - csiphy2 - csiphy4 The irregular naming of the PHYs comes directly from the hardware which for whatever reason skipped csiphy3. Separating the nodes from CAMSS as we have done with the sensor I2C bus aka the CCI interface is justified since the CSIPHYs have their own pinouts and voltage rails. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-3-f3f7ddfbf849@linaro.org/ --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 115 ++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 065baf75b4f6c..3560375657309 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -928,6 +928,25 @@ }; }; + csiphy_opp_table: opp-table-csiphy { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + qup_opp_table_100mhz: opp-table-qup100mhz { compatible = "operating-points-v2"; @@ -5880,6 +5899,102 @@ }; }; + csiphy0: csiphy@ace4000 { + compatible = "qcom,x1e80100-csi2-phy"; + reg = <0 0x0ace4000 0 0x2000>; + + clocks = <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "csiphy", + "csiphy_timer", + "camnoc_axi", + "cpas_ahb"; + + operating-points-v2 = <&csiphy_opp_table>; + + interrupts = ; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + #phy-cells = <1>; + + status = "disabled"; + }; + + csiphy1: csiphy@ace6000 { + compatible = "qcom,x1e80100-csi2-phy"; + reg = <0 0x0ace6000 0 0x2000>; + + clocks = <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "csiphy", + "csiphy_timer", + "camnoc_axi", + "cpas_ahb"; + + operating-points-v2 = <&csiphy_opp_table>; + + interrupts = ; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + #phy-cells = <1>; + + status = "disabled"; + }; + + csiphy2: csiphy@ace8000 { + compatible = "qcom,x1e80100-csi2-phy"; + reg = <0 0x0ace8000 0 0x2000>; + + clocks = <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "csiphy", + "csiphy_timer", + "camnoc_axi", + "cpas_ahb"; + + operating-points-v2 = <&csiphy_opp_table>; + + interrupts = ; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + #phy-cells = <1>; + + status = "disabled"; + }; + + csiphy4: csiphy@acec000 { + compatible = "qcom,x1e80100-csi2-phy"; + reg = <0 0x0acec000 0 0x2000>; + + clocks = <&camcc CAM_CC_CSIPHY4_CLK>, + <&camcc CAM_CC_CSI4PHYTIMER_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>; + clock-names = "csiphy", + "csiphy_timer", + "camnoc_axi", + "cpas_ahb"; + + operating-points-v2 = <&csiphy_opp_table>; + + interrupts = ; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + + #phy-cells = <1>; + + status = "disabled"; + }; + camcc: clock-controller@ade0000 { compatible = "qcom,x1e80100-camcc"; reg = <0 0x0ade0000 0 0x20000>; From 0079f029c9eb8984f62f3edddc0849739da035d0 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:09 +0000 Subject: [PATCH 400/438] FROMLIST: arm64: dts: qcom: x1e80100: Add CAMSS block definition Add dtsi to describe the xe180100 CAMSS block 4 x CSIPHY 3 x TPG 2 x CSID 2 x CSID Lite 2 x IFE 2 x IFE Lite Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-4-f3f7ddfbf849@linaro.org/ --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 203 ++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 3560375657309..d2de79a297851 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -5899,6 +5900,208 @@ }; }; + camss: isp@acb7000 { + compatible = "qcom,x1e80100-camss"; + + reg = <0 0x0acb7000 0 0x2000>, + <0 0x0acb9000 0 0x2000>, + <0 0x0acbb000 0 0x2000>, + <0 0x0acc6000 0 0x1000>, + <0 0x0acca000 0 0x1000>, + <0 0x0acb6000 0 0x1000>, + <0 0x0ace4000 0 0x1000>, + <0 0x0ace6000 0 0x1000>, + <0 0x0ace8000 0 0x1000>, + <0 0x0acec000 0 0x4000>, + <0 0x0acf6000 0 0x1000>, + <0 0x0acf7000 0 0x1000>, + <0 0x0acf8000 0 0x1000>, + <0 0x0ac62000 0 0x4000>, + <0 0x0ac71000 0 0x4000>, + <0 0x0acc7000 0 0x2000>, + <0 0x0accb000 0 0x2000>; + + reg-names = "csid0", + "csid1", + "csid2", + "csid_lite0", + "csid_lite1", + "csid_wrapper", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy4", + "csitpg0", + "csitpg1", + "csitpg2", + "vfe0", + "vfe1", + "vfe_lite0", + "vfe_lite1"; + + clocks = <&camcc CAM_CC_CAMNOC_AXI_NRT_CLK>, + <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CORE_AHB_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CPAS_FAST_AHB_CLK>, + <&camcc CAM_CC_CPAS_IFE_0_CLK>, + <&camcc CAM_CC_CPAS_IFE_1_CLK>, + <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&camcc CAM_CC_CSID_CLK>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY4_CLK>, + <&camcc CAM_CC_CSI4PHYTIMER_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&gcc GCC_CAMERA_SF_AXI_CLK>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_FAST_AHB_CLK>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_FAST_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>; + + clock-names = "camnoc_nrt_axi", + "camnoc_rt_axi", + "core_ahb", + "cpas_ahb", + "cpas_fast_ahb", + "cpas_vfe0", + "cpas_vfe1", + "cpas_vfe_lite", + "cphy_rx_clk_src", + "csid", + "csid_csiphy_rx", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "csiphy2", + "csiphy2_timer", + "csiphy4", + "csiphy4_timer", + "gcc_axi_hf", + "gcc_axi_sf", + "vfe0", + "vfe0_fast_ahb", + "vfe1", + "vfe1_fast_ahb", + "vfe_lite", + "vfe_lite_ahb", + "vfe_lite_cphy_rx", + "vfe_lite_csid"; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + ; + + interrupt-names = "csid0", + "csid1", + "csid2", + "csid_lite0", + "csid_lite1", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy4", + "vfe0", + "vfe1", + "vfe_lite0", + "vfe_lite1"; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_ICP QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "ahb", + "hf_mnoc", + "sf_mnoc", + "sf_icp_mnoc"; + + iommus = <&apps_smmu 0x800 0x60>, + <&apps_smmu 0x860 0x60>, + <&apps_smmu 0x1860 0x60>, + <&apps_smmu 0x18e0 0x00>, + <&apps_smmu 0x19a0 0x20>; + + phys = <&csiphy0 PHY_TYPE_DPHY>, <&csiphy1 PHY_TYPE_DPHY>, + <&csiphy2 PHY_TYPE_DPHY>, <&csiphy4 PHY_TYPE_DPHY>; + phy-names = "csiphy0", "csiphy1", + "csiphy2", "csiphy4"; + + power-domains = <&camcc CAM_CC_IFE_0_GDSC>, + <&camcc CAM_CC_IFE_1_GDSC>, + <&camcc CAM_CC_TITAN_TOP_GDSC>; + power-domain-names = "ife0", + "ife1", + "top"; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + camss_csiphy0_inep0: endpoint@0 { + reg = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + camss_csiphy1_inep0: endpoint@0 { + reg = <0>; + }; + }; + + port@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + camss_csiphy2_inep0: endpoint@0 { + reg = <0>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + camss_csiphy4_inep0: endpoint@0 { + reg = <0>; + }; + }; + }; + }; + csiphy0: csiphy@ace4000 { compatible = "qcom,x1e80100-csi2-phy"; reg = <0 0x0ace4000 0 0x2000>; From dbd6bdd761a278d6121a39f803eb3b93bf75105a Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:10 +0000 Subject: [PATCH 401/438] FROMLIST: arm64: dts: qcom: x1e80100-crd: Add pm8010 CRD pmic,id=m regulators Add pmic,id = m rpmh to regulator definitions. This regulator set provides vreg_l3m_1p8 the regulator for the ov08x40 RGB sensor on the CRD. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-5-f3f7ddfbf849@linaro.org/ --- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi index ded96fb43489b..c89f5ad0aed56 100644 --- a/arch/arm64/boot/dts/qcom/x1-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi @@ -865,6 +865,36 @@ regulator-initial-mode = ; }; }; + + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "m"; + + vdd-l1-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-l4-supply = <&vreg_s4c_1p8>; + vdd-l7-supply = <&vreg_bob1>; + + vreg_l3m_1p8: ldo3 { + regulator-name = "vreg_l3m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1808000>; + regulator-initial-mode = ; + }; + + vreg_l4m_1p8: ldo4 { + regulator-name = "vreg_l4m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1808000>; + regulator-initial-mode = ; + }; + + vreg_l7m_2p9: ldo7 { + regulator-name = "vreg_l7m_2p9"; + regulator-min-microvolt = <2912000>; + regulator-max-microvolt = <2912000>; + regulator-initial-mode = ; + }; + }; }; &gpu { From 4b1f65ae88b62faf520ee8b3bcaa5be28fe24d79 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:11 +0000 Subject: [PATCH 402/438] FROMLIST: arm64: dts: qcom: x1e80100-crd: Add ov08x40 RGB sensor on CSIPHY4 Define ov08x40 on cci1_i2c1. The RGB sensor appears on the AON CCI pins connected to CSIPHY4 in four lane mode. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-6-f3f7ddfbf849@linaro.org/ --- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 76 ++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi index c89f5ad0aed56..d47404c71b80b 100644 --- a/arch/arm64/boot/dts/qcom/x1-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -901,6 +902,65 @@ status = "okay"; }; +&camss { + status = "okay"; + + ports { + /* + * port0 => csiphy0 + * port1 => csiphy1 + * port2 => csiphy2 + * port3 => csiphy4 + */ + port@3 { + camss_csiphy4_inep0: endpoint@0 { + clock-lanes = <7>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&ov08x40_ep>; + }; + }; + }; +}; + +&cci1 { + status = "okay"; +}; + +&cci1_i2c1 { + camera@36 { + compatible = "ovti,ov08x40"; + reg = <0x36>; + + reset-gpios = <&tlmm 237 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam_rgb_default>; + pinctrl-names = "default"; + + clocks = <&camcc CAM_CC_MCLK4_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK4_CLK>; + assigned-clock-rates = <19200000>; + + orientation = <0>; /* front facing */ + + avdd-supply = <&vreg_l7b_2p8>; + dovdd-supply = <&vreg_l3m_1p8>; + + port { + ov08x40_ep: endpoint { + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <400000000>; + remote-endpoint = <&camss_csiphy4_inep0>; + }; + }; + }; +}; + +&csiphy4 { + vdda-0p8-supply = <&vreg_l2c_0p8>; + vdda-1p2-supply = <&vreg_l1c_1p2>; + + status = "okay"; +}; + &i2c0 { clock-frequency = <400000>; @@ -1515,6 +1575,22 @@ <44 4>, /* SPI (TPM) */ <238 1>; /* UFS Reset */ + cam_rgb_default: cam-rgb-default-state { + mclk-pins { + pins = "gpio100"; + function = "cam_aon"; + drive-strength = <16>; + bias-disable; + }; + + reset-n-pins { + pins = "gpio237"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; + edp_reg_en: edp-reg-en-state { pins = "gpio70"; function = "gpio"; From 4bc427e26433d9810c4abc3476258dd3bd032fb6 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:12 +0000 Subject: [PATCH 403/438] FROMLIST: arm64: dts: qcom: x1e80100-t14s: Add pm8010 camera PMIC with voltage levels for IR and RGB camera Add the PM8010 PMIC providing the following voltage rails: vreg_l1m_r @ 1v2 IR sensor vreg_l2m_r @ 1v2 RGB sensor vreg_l3m_r @ 1v8 IR sensor vreg_l4m_r @ 1v8 RGB sensor vreg_l5m_r @ 2v8 IR sensor vreg_l7m_r @ 2v8 RGB sensor Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-7-f3f7ddfbf849@linaro.org/ --- .../qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi index 4d7fd51f370b7..ee49785c9d005 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi @@ -562,6 +562,13 @@ regulator-initial-mode = ; }; + vreg_l7b_2p8: ldo7 { + regulator-name = "vreg_l7b_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + vreg_l8b_3p0: ldo8 { regulator-name = "vreg_l8b_3p0"; regulator-min-microvolt = <3072000>; @@ -805,6 +812,58 @@ regulator-initial-mode = ; }; }; + + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "m"; + + vdd-l1-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-l4-supply = <&vreg_s4c_1p8>; + vdd-l7-supply = <&vreg_bob1>; + + vreg_l1m_1p2: ldo1 { + regulator-name = "vreg_l1m_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + }; + + vreg_l2m_1p2: ldo2 { + regulator-name = "vreg_l2m_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + }; + + vreg_l3m_1p8: ldo3 { + regulator-name = "vreg_l3m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + regulator-initial-mode = ; + }; + + vreg_l4m_1p8: ldo4 { + regulator-name = "vreg_l4m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + regulator-initial-mode = ; + }; + + vreg_l5m_2p8: ldo5 { + regulator-name = "vreg_l5m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + + vreg_l7m_2p8: ldo7 { + regulator-name = "vreg_l7m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + }; + }; &gpu { From 140fe206c696d21cd587de4fd8b144c86927a447 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:13 +0000 Subject: [PATCH 404/438] FROMLIST: arm64: dts: qcom: x1e80100-t14s: Add on ov02c10 RGB sensor on CSIPHY4 Switch on the ov02c10 RGB sensor on CSIPHY4. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-8-f3f7ddfbf849@linaro.org/ --- .../qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi index ee49785c9d005..54bf21f1c6f37 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -866,6 +867,66 @@ }; +&camss { + status = "okay"; + + ports { + /* + * port0 => csiphy0 + * port1 => csiphy1 + * port2 => csiphy2 + * port3 => csiphy4 + */ + port@3 { + camss_csiphy4_inep0: endpoint@0 { + clock-lanes = <7>; + data-lanes = <0 1>; + remote-endpoint = <&ov02c10_ep>; + }; + }; + }; +}; + +&cci1 { + status = "okay"; +}; + +&cci1_i2c1 { + camera@36 { + compatible = "ovti,ov02c10"; + reg = <0x36>; + + reset-gpios = <&tlmm 237 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_rgb_default>; + + clocks = <&camcc CAM_CC_MCLK4_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK4_CLK>; + assigned-clock-rates = <19200000>; + + orientation = <0>; /* front facing */ + + avdd-supply = <&vreg_l7m_2p8>; + dvdd-supply = <&vreg_l2m_1p2>; + dovdd-supply = <&vreg_l4m_1p8>; + + port { + ov02c10_ep: endpoint { + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <400000000>; + remote-endpoint = <&camss_csiphy4_inep0>; + }; + }; + }; +}; + +&csiphy4 { + vdda-0p8-supply = <&vreg_l2c_0p8>; + vdda-1p2-supply = <&vreg_l1c_1p2>; + + status = "okay"; +}; + &gpu { status = "okay"; }; @@ -1447,6 +1508,22 @@ <72 2>, /* Secure EC I2C connection (?) */ <238 1>; /* UFS Reset */ + cam_rgb_default: cam-rgb-default-state { + mclk-pins { + pins = "gpio100"; + function = "cam_aon"; + drive-strength = <16>; + bias-disable; + }; + + reset-n-pins { + pins = "gpio237"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; + ec_int_n_default: ec-int-n-state { pins = "gpio66"; function = "gpio"; From 1d01f39568eaebb676531940940b00ade96e1b7f Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Feb 2026 14:51:14 +0000 Subject: [PATCH 405/438] FROMLIST: arm64: dts: qcom: x1e80100-lenovo-yoga-slim7x: Add pm8010 camera PMIC with voltage levels for IR and RGB camera Add voltage regulators-8 for Camera on slim7x including: - vreg_l7m_2p8 - vreg_l2m_1p2 - vreg_l4m_1p8 Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Link: https://lore.kernel.org/all/20260226-x1e-camss-csi2-phy-dtsi-v1-9-f3f7ddfbf849@linaro.org/ --- .../dts/qcom/x1e80100-lenovo-yoga-slim7x.dts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts index d6472e5a3f9fa..f10dff1da7f8e 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts @@ -795,6 +795,57 @@ regulator-initial-mode = ; }; }; + + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "m"; + + vdd-l1-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-l4-supply = <&vreg_s4c_1p8>; + vdd-l7-supply = <&vreg_bob1>; + + vreg_l1m_1p2: ldo1 { + regulator-name = "vreg_l1m_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + }; + + vreg_l2m_1p2: ldo2 { + regulator-name = "vreg_l2m_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + }; + + vreg_l3m_1p8: ldo3 { + regulator-name = "vreg_l3m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + regulator-initial-mode = ; + }; + + vreg_l4m_1p8: ldo4 { + regulator-name = "vreg_l4m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + regulator-initial-mode = ; + }; + + vreg_l5m_2p8: ldo5 { + regulator-name = "vreg_l5m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + + vreg_l7m_2p8: ldo7 { + regulator-name = "vreg_l7m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + }; }; &gpu { From 5f9f4d84db995ee799fde8b758b3de51dc8c1036 Mon Sep 17 00:00:00 2001 From: Tingguo Cheng Date: Fri, 27 Feb 2026 13:29:39 +0800 Subject: [PATCH 406/438] FROMLIST: arm64: dts: qcom: hamoa-iot-som: Add pm8010 L4M regulator Add pm8010 L4M regulator which is used by Camera I2C pull-up. Signed-off-by: Tingguo Cheng Signed-off-by: Wenmeng Liu Link: https://lore.kernel.org/all/20260227-hamoa_evk-v1-1-36f895a24d8f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi index b8e3e04a6fbd4..5d9af325c931e 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi @@ -376,6 +376,21 @@ regulator-initial-mode = ; }; }; + + /* PM8010_M */ + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "m"; + + vdd-l3-l4-supply = <&vreg_s4c_1p8>; + + vreg_l4m_1p8: ldo4 { + regulator-name = "vrer_l4m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1808000>; + regulator-initial-mode = ; + }; + }; }; &iris { From ca55fffe472bf48471465ef11ad52cb048ac1702 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Fri, 27 Feb 2026 13:29:40 +0800 Subject: [PATCH 407/438] FROMLIST: arm64: dts: qcom: hamoa-iot-evk-camera-imx577: Add DT overlay Enable IMX577 via CCI on Hamoa EVK Core Kit. The Hamoa EVK board does not include a camera sensor by default, this DTSO has enabled the Arducam 12.3MP IMX577 Mini Camera Module on the CSI-1 interface. Signed-off-by: Wenmeng Liu Link: https://lore.kernel.org/all/20260227-hamoa_evk-v1-2-36f895a24d8f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/Makefile | 3 + .../dts/qcom/hamoa-iot-evk-camera-imx577.dtso | 81 +++++++++++++++++++ arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 16 ++++ 3 files changed, 100 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/hamoa-iot-evk-camera-imx577.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 7aa407322466e..b3291af71da8c 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -14,9 +14,12 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8094-sony-xperia-kitakami-karin_windy.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk.dtb +dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk-camera-imx577.dtbo +hamoa-iot-evk-camera-imx577-dtbs := hamoa-iot-evk.dtb hamoa-iot-evk-camera-imx577.dtbo hamoa-iot-evk-el2-dtbs := hamoa-iot-evk.dtb x1-el2.dtbo +dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk-camera-imx577.dtb dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-rdp432-c2.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-tplink-archer-ax55-v1.dtb diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk-camera-imx577.dtso b/arch/arm64/boot/dts/qcom/hamoa-iot-evk-camera-imx577.dtso new file mode 100644 index 0000000000000..f45a7fbd14b1f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk-camera-imx577.dtso @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include + +&{/} { + vreg_cam1_1p8: regulator-cam1 { + compatible = "regulator-fixed"; + regulator-name = "vreg_cam1"; + startup-delay-us = <1000>; + enable-active-high; + gpio = <&tlmm 19 GPIO_ACTIVE_HIGH>; + }; +}; + +&camss { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + csiphy1_ep: endpoint@0 { + clock-lanes = <7>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&imx577_ep>; + }; + }; + }; +}; + +&cci0 { + status = "okay"; +}; + +&cci0_i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx577"; + reg = <0x1a>; + + reset-gpios = <&tlmm 110 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam1_default>; + pinctrl-names = "default"; + + clocks = <&camcc CAM_CC_MCLK1_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK1_CLK>; + assigned-clock-rates = <24000000>; + + dvdd-supply = <&vreg_cam1_1p8>; + dovdd-supply = <&vreg_l4m_1p8>; + + port { + imx577_ep: endpoint { + link-frequencies = /bits/ 64 <600000000>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&csiphy1_ep>; + }; + }; + }; +}; + +&csiphy1 { + vdda-0p8-supply = <&vreg_l2c_0p8>; + vdda-1p2-supply = <&vreg_l1c_1p2>; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index e6c7b0ed385de..801bff722e3c5 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -1324,6 +1324,22 @@ }; &tlmm { + cam1_default: cam1-default-state { + mclk-pins { + pins = "gpio97"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + rst-pins { + pins = "gpio110"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; + edp_reg_en: edp-reg-en-state { pins = "gpio70"; function = "gpio"; From eb85927badaa90ce7685b575ad805b7af1449ab0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 18 Feb 2026 18:05:42 +0100 Subject: [PATCH 408/438] FROMLIST: arm64: dts: qcom: sm8750: Add display (MDSS) with Display CC Add device nodes for entire display: MDSS, DPU, DSI, DSI PHYs, DisplayPort and Display Clock Controller. Link: https://lore.kernel.org/r/20260218-sm8750-display-dts-v4-1-1743e9848864@oss.qualcomm.com Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Krzysztof Kozlowski Reviewed-by: Taniya Das --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 437 +++++++++++++++++++++++++++ 1 file changed, 437 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index f56b1f889b857..82963f4a6a550 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -3,7 +3,9 @@ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ +#include #include +#include #include #include #include @@ -3001,6 +3003,441 @@ #power-domain-cells = <1>; }; + mdss: display-subsystem@ae00000 { + compatible = "qcom,sm8750-mdss"; + reg = <0x0 0x0ae00000 0x0 0x1000>; + reg-names = "mdss"; + + interrupts = ; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>; + + resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; + + interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", + "cpu-cfg"; + + power-domains = <&dispcc MDSS_GDSC>; + + iommus = <&apps_smmu 0x800 0x2>; + + interrupt-controller; + #interrupt-cells = <1>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdss_mdp: display-controller@ae01000 { + compatible = "qcom,sm8750-dpu"; + reg = <0 0x0ae01000 0 0x93000>, + <0 0x0aeb0000 0 0x2008>; + reg-names = "mdp", + "vbif"; + + interrupts-extended = <&mdss 0>; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <19200000>; + + operating-points-v2 = <&mdp_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dpu_intf1_out: endpoint { + remote-endpoint = <&mdss_dsi0_in>; + }; + }; + + port@1 { + reg = <1>; + + dpu_intf2_out: endpoint { + remote-endpoint = <&mdss_dsi1_in>; + }; + }; + + port@2 { + reg = <2>; + + dpu_intf0_out: endpoint { + remote-endpoint = <&mdss_dp0_in>; + }; + }; + }; + + mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-156000000 { + opp-hz = /bits/ 64 <156000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + }; + + opp-207000000 { + opp-hz = /bits/ 64 <207000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-337000000 { + opp-hz = /bits/ 64 <337000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-417000000 { + opp-hz = /bits/ 64 <417000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-532000000 { + opp-hz = /bits/ 64 <532000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-575000000 { + opp-hz = /bits/ 64 <575000000>; + required-opps = <&rpmhpd_opp_nom_l1>; + }; + }; + }; + + mdss_dsi0: dsi@ae94000 { + compatible = "qcom,sm8750-dsi-ctrl", "qcom,mdss-dsi-ctrl"; + reg = <0x0 0x0ae94000 0x0 0x400>; + reg-names = "dsi_ctrl"; + + interrupts-extended = <&mdss 4>; + + clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>, + <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>, + <&dispcc DISP_CC_MDSS_PCLK0_CLK>, + <&dispcc DISP_CC_MDSS_ESC0_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, + <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&dispcc DISP_CC_ESYNC0_CLK>, + <&dispcc DISP_CC_OSC_CLK>, + <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>, + <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>; + clock-names = "byte", + "byte_intf", + "pixel", + "core", + "iface", + "bus", + "dsi_pll_pixel", + "dsi_pll_byte", + "esync", + "osc", + "byte_src", + "pixel_src"; + + operating-points-v2 = <&mdss_dsi_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&mdss_dsi0_phy>; + phy-names = "dsi"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dsi0_in: endpoint { + remote-endpoint = <&dpu_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dsi0_out: endpoint { + }; + }; + }; + + mdss_dsi_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-140630000 { + opp-hz = /bits/ 64 <140630000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + }; + + opp-187500000 { + opp-hz = /bits/ 64 <187500000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-358000000 { + opp-hz = /bits/ 64 <358000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + mdss_dsi0_phy: phy@ae95000 { + compatible = "qcom,sm8750-dsi-phy-3nm"; + reg = <0x0 0x0ae95000 0x0 0x200>, + <0x0 0x0ae95200 0x0 0x280>, + <0x0 0x0ae95500 0x0 0x400>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&bi_tcxo_div2>; + clock-names = "iface", + "ref"; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + mdss_dsi1: dsi@ae96000 { + compatible = "qcom,sm8750-dsi-ctrl", "qcom,mdss-dsi-ctrl"; + reg = <0x0 0x0ae96000 0x0 0x400>; + reg-names = "dsi_ctrl"; + + interrupts-extended = <&mdss 5>; + + clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>, + <&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>, + <&dispcc DISP_CC_MDSS_PCLK1_CLK>, + <&dispcc DISP_CC_MDSS_ESC1_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>, + <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>, + <&dispcc DISP_CC_ESYNC1_CLK>, + <&dispcc DISP_CC_OSC_CLK>, + <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>, + <&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>; + clock-names = "byte", + "byte_intf", + "pixel", + "core", + "iface", + "bus", + "dsi_pll_pixel", + "dsi_pll_byte", + "esync", + "osc", + "byte_src", + "pixel_src"; + + operating-points-v2 = <&mdss_dsi_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&mdss_dsi1_phy>; + phy-names = "dsi"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dsi1_in: endpoint { + remote-endpoint = <&dpu_intf2_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dsi1_out: endpoint { + }; + }; + }; + }; + + mdss_dsi1_phy: phy@ae97000 { + compatible = "qcom,sm8750-dsi-phy-3nm"; + reg = <0x0 0x0ae97000 0x0 0x200>, + <0x0 0x0ae97200 0x0 0x280>, + <0x0 0x0ae97500 0x0 0x400>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", + "ref"; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + mdss_dp0: displayport-controller@af54000 { + compatible = "qcom,sm8750-dp", "qcom,sm8650-dp"; + reg = <0x0 0xaf54000 0x0 0x104>, + <0x0 0xaf54200 0x0 0xc0>, + <0x0 0xaf55000 0x0 0x770>, + <0x0 0xaf56000 0x0 0x9c>, + <0x0 0xaf57000 0x0 0x9c>; + + interrupts-extended = <&mdss 12>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_LINK_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL0_CLK>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL1_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel", + "stream_1_pixel"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>; + assigned-clock-parents = <&usb_dp_qmpphy QMP_USB43DP_DP_LINK_CLK>, + <&usb_dp_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_dp_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; + + operating-points-v2 = <&dp_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&usb_dp_qmpphy QMP_USB43DP_DP_PHY>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + status = "disabled"; + + dp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-192000000 { + opp-hz = /bits/ 64 <192000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + }; + + opp-270000000 { + opp-hz = /bits/ 64 <270000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-810000000 { + opp-hz = /bits/ 64 <810000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dp0_in: endpoint { + remote-endpoint = <&dpu_intf0_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp0_out: endpoint { + data-lanes = <0 1 2 3>; + }; + }; + }; + }; + }; + + dispcc: clock-controller@af00000 { + compatible = "qcom,sm8750-dispcc"; + reg = <0 0x0af00000 0 0x20000>; + + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&gcc GCC_DISP_AHB_CLK>, + <&sleep_clk>, + <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, + <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>, + <&usb_dp_qmpphy QMP_USB43DP_DP_LINK_CLK>, + <&usb_dp_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <0>, /* dp1 */ + <0>, + <0>, /* dp2 */ + <0>, + <0>, /* dp3 */ + <0>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sm8750-pdc", "qcom,pdc"; reg = <0x0 0x0b220000 0x0 0x10000>, <0x0 0x164400f0 0x0 0x64>; From 058fce59482b2f44407365d4425134ed837b8324 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 18 Feb 2026 18:05:43 +0100 Subject: [PATCH 409/438] FROMLIST: arm64: dts: qcom: sm8750-mtp: Enable display Enable display on MTP8750 board with Novatek NT37801 panel. Link: https://lore.kernel.org/r/20260218-sm8750-display-dts-v4-2-1743e9848864@oss.qualcomm.com Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Signed-off-by: Krzysztof Kozlowski --- arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 63 +++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts index cb718331496ee..050a85df7358d 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts @@ -937,6 +937,48 @@ qcom,dmic-sample-rate = <4800000>; }; +&mdss { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&vreg_l3g_1p2>; + + status = "okay"; + + panel@0 { + compatible = "novatek,nt37801"; + reg = <0>; + + reset-gpios = <&tlmm 98 GPIO_ACTIVE_LOW>; + + vddio-supply = <&vreg_l12b_1p8>; + vci-supply = <&vreg_l13b_3p0>; + vdd-supply = <&vreg_l11b_1p0>; + + pinctrl-0 = <&disp0_reset_n_active>, <&mdp_vsync>; + pinctrl-1 = <&disp0_reset_n_suspend>, <&mdp_vsync>; + pinctrl-names = "default", "sleep"; + + port { + panel0_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; +}; + +&mdss_dsi0_out { + remote-endpoint = <&panel0_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vdds-supply = <&vreg_l3i_0p88>; + + status = "okay"; +}; + &pm8550_flash { status = "okay"; @@ -1225,6 +1267,27 @@ bias-pull-up; }; + mdp_vsync: mdp-vsync-state { + pins = "gpio86"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + disp0_reset_n_active: disp0-reset-n-active-state { + pins = "gpio98"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + disp0_reset_n_suspend: disp0-reset-n-suspend-state { + pins = "gpio98"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + wcd_default: wcd-reset-n-active-state { pins = "gpio101"; function = "gpio"; From 107ff7003a5aaa7b413340800bbe0a63f12fe2ac Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Tue, 3 Feb 2026 15:46:32 +0800 Subject: [PATCH 410/438] FROMLIST: arm64: dts: qcom: sm8750: enable ETR and CTCU devices Embedded Trace Router(ETR) is working as a DDR memory sink to collect tracing data from source device and the CTCU device serves as the control unit for the ETR device. Link: https://lore.kernel.org/all/20260204-enable-ctcu-and-etr-v3-3-0bb95c590ae1@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 177 +++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index 82963f4a6a550..1b68d3ddaacde 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -4011,6 +4011,35 @@ #reset-cells = <1>; }; + ctcu@10001000 { + compatible = "qcom,sm8750-ctcu", "qcom,sa8775p-ctcu"; + reg = <0x0 0x10001000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ctcu_in0: endpoint { + remote-endpoint = <&etr0_out>; + }; + }; + + port@1 { + reg = <1>; + + ctcu_in1: endpoint { + remote-endpoint = <&etr1_out>; + }; + }; + }; + }; + stm@10002000 { compatible = "arm,coresight-stm", "arm,primecell"; reg = <0x0 0x10002000 0x0 0x1000>, @@ -4124,6 +4153,122 @@ }; }; + replicator@10046000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x10046000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + qdss_rep_in: endpoint { + remote-endpoint = <&swao_rep_out0>; + }; + }; + }; + + out-ports { + port { + qdss_rep_out0: endpoint { + remote-endpoint = <&etr_rep_in>; + }; + }; + }; + }; + + tmc@10048000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x10048000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + iommus = <&apps_smmu 0x04e0 0x0>; + arm,scatter-gather; + + in-ports { + port { + etr0_in: endpoint { + remote-endpoint = <&etr_rep_out0>; + }; + }; + }; + + out-ports { + port { + etr0_out: endpoint { + remote-endpoint = <&ctcu_in0>; + }; + }; + }; + }; + + replicator@1004e000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x1004e000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + etr_rep_in: endpoint { + remote-endpoint = <&qdss_rep_out0>; + }; + }; + }; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + etr_rep_out0: endpoint { + remote-endpoint = <&etr0_in>; + }; + }; + + port@1 { + reg = <1>; + + etr_rep_out1: endpoint { + remote-endpoint = <&etr1_in>; + }; + }; + }; + }; + + tmc_etr1: tmc@1004f000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x1004f000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + iommus = <&apps_smmu 0x0500 0x0>; + arm,scatter-gather; + arm,buffer-size = <0x400000>; + + in-ports { + port { + etr1_in: endpoint { + remote-endpoint = <&etr_rep_out1>; + }; + }; + }; + + out-ports { + port { + etr1_out: endpoint { + remote-endpoint = <&ctcu_in1>; + }; + }; + }; + }; + tpdm@10800000 { compatible = "qcom,coresight-tpdm", "arm,primecell"; reg = <0x0 0x10800000 0x0 0x1000>; @@ -4794,6 +4939,38 @@ }; }; }; + + out-ports { + port { + tmc_etf_out: endpoint { + remote-endpoint = <&swao_rep_in>; + }; + }; + }; + }; + + replicator@10b06000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x10b06000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + swao_rep_in: endpoint { + remote-endpoint = <&tmc_etf_out>; + }; + }; + }; + + out-ports { + port { + swao_rep_out0: endpoint { + remote-endpoint = <&qdss_rep_in>; + }; + }; + }; }; tpda@10b08000 { From 7bfc082859703275f737027cb772055d109f9045 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sun, 22 Feb 2026 22:07:57 +0530 Subject: [PATCH 411/438] FROMLIST: arm64: dts: qcom: sm8750: Add camera clock controller The camera clock controller is split into cambistmclk and camcc. The cambist clock controller handles the mclks and the rest of the clocks of camera are part of the camcc clock controller. Add the camcc clock controller device node for SM8750 SoC. Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20260220-sm8750_camcc_dt-v2-1-e4b7faf35854@oss.qualcomm.com Signed-off-by: Taniya Das --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index 1b68d3ddaacde..c0c0c08675f1f 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include #include @@ -2073,6 +2075,23 @@ clocks = <&rpmhcc RPMH_IPA_CLK>; }; + cambistmclkcc: clock-controller@1760000 { + compatible = "qcom,sm8750-cambistmclkcc"; + reg = <0x0 0x1760000 0x0 0x6000>; + clocks = <&gcc GCC_CAM_BIST_MCLK_AHB_CLK> , + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + mmss_noc: interconnect@1780000 { compatible = "qcom,sm8750-mmss-noc"; reg = <0x0 0x01780000 0x0 0x5b800>; @@ -3438,6 +3457,23 @@ #power-domain-cells = <1>; }; + camcc: clock-controller@ade0000 { + compatible = "qcom,sm8750-camcc"; + reg = <0x0 0xade0000 0x0 0x20000>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sm8750-pdc", "qcom,pdc"; reg = <0x0 0x0b220000 0x0 0x10000>, <0x0 0x164400f0 0x0 0x64>; From 171e9030867b9a8c7460f17fcf7ecaefeb0b5938 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Fri, 20 Feb 2026 12:06:40 +0530 Subject: [PATCH 412/438] FROMLIST: arm64: dts: qcom: qcm6490-idp: Fix WCD9370 reset GPIO polarity The WCD9370 audio codec reset line on QCM6490 IDP should be active-low, but the device tree described it as active-high. As a result, the codec is kept in reset and fails to reset the SoundWire, leading to timeouts and ASoC card probe failure (-ETIMEDOUT). Fix the reset GPIO polarity to GPIO_ACTIVE_LOW so the codec can properly initialize. Link: https://lore.kernel.org/all/20260220090220.2992193-1-ravi.hothi@oss.qualcomm.com/ Fixes: aa04c298619f ("arm64: dts: qcom: qcm6490-idp: Add WSA8830 speakers and WCD9370 headset codec") Signed-off-by: Ravi Hothi --- arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index e3f79b8dde729..50ff128b99eb0 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -178,7 +178,7 @@ pinctrl-0 = <&wcd_default>; pinctrl-names = "default"; - reset-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 83 GPIO_ACTIVE_LOW>; vdd-buck-supply = <&vreg_l17b_1p7>; vdd-rxtx-supply = <&vreg_l18b_1p8>; From a8f0ac95669719d85dfd4a062d71154b5ca1a72f Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sat, 28 Feb 2026 12:29:05 +0530 Subject: [PATCH 413/438] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: use DP controller native HPD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The base device tree configures the edp_hot_plug_det pin using the "edp_hot" function on GPIO 60. However, on qcs6490-rb3gen2 this external HPD GPIO does not generate a connect event when a display is already connected at boot, causing the DP/eDP display to remain disabled. The DP controller’s native HPD correctly detects the connected sink in this scenario, so continue using the DP controller native HPD on the qcs6490-rb3gen2 platform instead of the external HPD GPIO. Link: https://lore.kernel.org/all/20260228-edp_hpd_rb3_gen2_for_next-v1-1-aebc047eddc1@oss.qualcomm.com/ Signed-off-by: Vishnu Saini --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index af4925ffa40c9..b714394f9a469 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -49,8 +49,6 @@ label = "DP"; type = "mini"; - hpd-gpios = <&tlmm 60 GPIO_ACTIVE_HIGH>; - port { dp_connector_in: endpoint { remote-endpoint = <&mdss_edp_out>; @@ -1714,7 +1712,6 @@ /* PINCTRL - ADDITIONS TO NODES IN PARENT DEVICE TREE FILES */ &edp_hot_plug_det { - function = "gpio"; bias-disable; }; From be3e7a4e9a0e14d733662fa8f78e4ebc4af5070a Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 8 Jan 2026 10:00:04 +0800 Subject: [PATCH 414/438] QCLINUX: qcom-dcc: Add driver support for Data Capture and Compare unit(DCC) The DCC is a DMA Engine designed to capture and store data during system crash or software triggers. The DCC operates based on user inputs via the debugfs interface. The user gives addresses as inputs and these addresses are stored in the dcc sram. In case of a system crash or a manual software trigger by the user through the debugfs interface, the dcc captures and stores the values at these addresses. This patch contains the driver which has all the methods pertaining to the debugfs interface, auxiliary functions to support all the four fundamental operations of dcc namely read, write, read/modify/write and loop. The probe method here instantiates all the resources necessary for dcc to operate mainly the dedicated dcc sram where it stores the values. The DCC driver can be used for debugging purposes without going for a reboot since it can perform software triggers as well based on user inputs. Also add the documentation for debugfs entries which explains the functionalities of each debugfs file that has been created for dcc. The following is the justification of using debugfs interface over the other alternatives like sysfs/ioctls i) As can be seen from the debugfs attribute descriptions, some of the debugfs attribute files here contains multiple arguments which needs to be accepted from the user. This goes against the design style of sysfs. ii) The user input patterns have been made simple and convenient in this case with the use of debugfs interface as user doesn't need to shuffle between different files to execute one instruction as was the case on using other alternatives. Signed-off-by: Jie Gan --- drivers/misc/Kconfig | 8 + drivers/misc/Makefile | 1 + drivers/misc/qcom-dcc.c | 1610 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1619 insertions(+) create mode 100644 drivers/misc/qcom-dcc.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 5cc79d1517af5..62b73f320df6d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -309,6 +309,14 @@ config QCOM_FASTRPC applications DSP processor. Say M if you want to enable this module. +config QCOM_DCC + tristate "Qualcomm Technologies, Inc. Data Capture and Compare (DCC) engine driver" + depends on ARCH_QCOM || COMPILE_TEST + help + This option enables the driver for the Data Capture and Compare engine. DCC + driver provides interfaces to configure DCC block and read back the captured + data from the DCC's internal SRAM. The module name for this is qcom-dcc. + config SGI_GRU tristate "SGI GRU driver" depends on X86_UV && SMP diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b32a2597d2467..338ed270b7cfc 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -75,3 +75,4 @@ obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o obj-y += keba/ obj-y += amd-sbi/ obj-$(CONFIG_MISC_RP1) += rp1/ +obj-$(CONFIG_QCOM_DCC) += qcom-dcc.o diff --git a/drivers/misc/qcom-dcc.c b/drivers/misc/qcom-dcc.c new file mode 100644 index 0000000000000..a511faac5d4b0 --- /dev/null +++ b/drivers/misc/qcom-dcc.c @@ -0,0 +1,1610 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/* + * DCC(Data Capture and Compare) is a DMA engine designed for debugging + * purposes. + * In case of a system crash or manual software triggers by the user the + * DCC hardware stores the value at the register addresses which can be + * used for debugging purposes. + * The DCC driver provides the user with debugfs interface to configure the + * register addresses. The options that the DCC hardware provides include + * reading from registers, writing to registers, first reading and then + * writing to registers and looping through the values of the same + * register. + * + * In certain cases a register write needs to be executed for accessing the + * rest of the registers, also the user might want to record the changing + * values of a register with time for which he has the option to use the + * loop feature. + * + * The options mentioned above are exposed to the user by debugfs files + * once the driver is probed. The details and usage of this debugfs files + * are documented in Documentation/ABI/testing/debugfs-driver-dcc. + * + * As an example let us consider a couple of debug scenarios where DCC has + * been proved to be effective for debugging purposes:- + * + * i)TimeStamp Related Issue + * + * On SC7180, there was a coresight timestamp issue where it would + * occasionally be all 0 instead of proper timestamp values. + * + * Proper timestamp: + * Idx:3373; ID:10; I_TIMESTAMP : Timestamp.; Updated val = + * 0x13004d8f5b7aa; CC=0x9e + * + * Zero timestamp: + * Idx:3387; ID:10; I_TIMESTAMP : Timestamp.; Updated val = 0x0; CC=0xa2 + * + * Now this is a non-fatal issue and doesn't need a system reset, but still + * needs to be rootcaused and fixed for those who do care about coresight + * etm traces. + * Since this is a timestamp issue, we would be looking for any timestamp + * related clocks and such. + * + * We get all the clk register details from IP documentation and configure + * it via DCC config debugfs node. Before that we set the current + * linked list. + * + * Program the linked list with the addresses + * echo R 0x10c004 > /sys/kernel/debug/qcom-dcc/../3/config + * echo R 0x10c008 > /sys/kernel/debug/qcom-dcc/../3/config + * echo R 0x10c00c > /sys/kernel/debug/qcom-dcc/../3/config + * echo R 0x10c010 > /sys/kernel/debug/qcom-dcc/../3/config + * ..... and so on for other timestamp related clk registers + * + * Other way of specifying is in "addr len" pair, in below case it + * specifies to capture 4 words starting 0x10C004 + * + * echo R 0x10C004 4 > /sys/kernel/debug/qcom-dcc/../3/config + * + * Configuration can be saved to a file and reuse it later. + * cat /sys/kernel/debug/qcom-dcc/../3/config > config_3 + * Post reboot, write the file to config. + * echo config_3 > /sys/kernel/debug/qcom-dcc/../3/config + * + * Enable DCC + * echo 1 > /sys/kernel/debug/qcom-dcc/../3/enable + * + * Run the timestamp test for working case + * + * Send SW trigger + * echo 1 > /sys/kernel/debug/qcom-dcc/../trigger + * + * Read SRAM + * cat /dev/dcc_sram > dcc_sram1.bin + * + * Run the timestamp test for non-working case + * + * Send SW trigger + * echo 1 > /sys/kernel/debug/qcom-dcc/../trigger + * + * Read SRAM + * cat /dev/dcc_sram > dcc_sram2.bin + * + * Get the parser from + * https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/tools/-/tree/opensource-tools.lnx.1.0.r176-rel/dcc_parser + * + * Parse the SRAM bin + * python dcc_parser.py -s dcc_sram1.bin --v2 -o output/ python + * dcc_parser.py -s dcc_sram2.bin --v2 -o output/ + * + * Sample parsed output of dcc_sram1.bin: + * + * + * 03/14/21 + * Linux DCC Parser + * + * + * + * + * + * + * next_ll_offset : 0x1c + * + * ii)NOC register errors + * + * A particular class of registers called NOC which are functional + * registers was reporting errors while logging the values.To trace these + * errors the DCC has been used effectively. + * The steps followed were similar to the ones mentioned above. + * In addition to NOC registers a few other dependent registers were + * configured in DCC to monitor it's values during a crash. A look at the + * dependent register values revealed that the crash was happening due to a + * secured access to one of these dependent registers. + * All these debugging activity and finding the root cause was achieved + * using DCC. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STATUS_READY_TIMEOUT 5000 /* microseconds */ + +/* DCC registers */ +#define DCC_HW_INFO 0x04 +#define DCC_LL_NUM_INFO 0x10 +#define DCC_LL_LOCK 0x00 +#define DCC_LL_CFG 0x04 +#define DCC_LL_BASE 0x08 +#define DCC_FD_BASE 0x0c +#define DCC_LL_OFFSET 0x80 +#define DCC_LL_TIMEOUT 0x10 +#define DCC_LL_INT_ENABLE 0x18 +#define DCC_LL_INT_STATUS 0x1c +#define DCC_LL_SW_TRIGGER 0x2c +#define DCC_LL_BUS_ACCESS_STATUS 0x30 + +/* Default value used if a bit 6 in the HW_INFO register is set. */ +#define DCC_FIX_LOOP_OFFSET 16 + +/* Mask to find version info from HW_Info register */ +#define DCC_VER_INFO_MASK BIT(9) + +#define MAX_DCC_OFFSET GENMASK(9, 2) +#define MAX_DCC_LEN GENMASK(6, 0) +#define MAX_LOOP_CNT GENMASK(7, 0) +#define MAX_LOOP_ADDR 10 + +#define DCC_ADDR_DESCRIPTOR 0x00 +#define DCC_ADDR_LIMIT 27 +#define DCC_WORD_SIZE sizeof(u32) +#define DCC_ADDR_RANGE_MASK GENMASK(31, 4) +#define DCC_LOOP_DESCRIPTOR BIT(30) +#define DCC_RD_MOD_WR_DESCRIPTOR BIT(31) +#define DCC_LINK_DESCRIPTOR GENMASK(31, 30) +#define DCC_STATUS_MASK GENMASK(1, 0) +#define DCC_LOCK_MASK BIT(0) +#define DCC_LOOP_OFFSET_MASK BIT(6) +#define DCC_TRIGGER_MASK BIT(9) + +#define DCC_WRITE_MASK BIT(15) +#define DCC_WRITE_OFF_MASK GENMASK(7, 0) +#define DCC_WRITE_LEN_MASK GENMASK(14, 8) + +#define DCC_READ_IND 0x00 +#define DCC_WRITE_IND (BIT(28)) + +#define DCC_AHB_IND 0x00 +#define DCC_APB_IND BIT(29) + +#define DCC_MAX_LINK_LIST 8 + +#define DCC_VER_MASK2 GENMASK(5, 0) + +#define DCC_SRAM_WORD_LENGTH 4 + +#define DCC_RD_MOD_WR_ADDR 0xC105E + +#define MEM_MAP_VER1 0x1 +#define MEM_MAP_VER2 0x2 +#define MEM_MAP_VER3 0x3 + +#define LINE_BUFFER_MAX_SZ 50 +enum dcc_descriptor_type { + DCC_READ_TYPE, + DCC_LOOP_TYPE, + DCC_READ_WRITE_TYPE, + DCC_WRITE_TYPE +}; + +/** + * struct dcc_config_entry - configuration information related to each dcc instruction + * @base: Base address of the register to be configured in dcc + * @offset: Offset to the base address to be configured in dcc + * @len: Length of the address in words of 4 bytes to be configured in dcc + * @loop_cnt: The number of times to loop on the register address in case + of loop instructions + * @write_val: The value to be written on the register address in case of + write instructions + * @mask: Mask corresponding to the value to be written in case of + write instructions + * @apb_bus: Type of bus to be used for the instruction, can be either + 'apb' if 1 or 'ahb' if 0 + * @desc_type: Stores the type of dcc instruction + * @list: This is used to append this instruction to the list of + instructions + */ +struct dcc_config_entry { + u32 base; + u32 offset; + u32 len; + u32 loop_cnt; + u32 write_val; + u32 mask; + bool apb_bus; + enum dcc_descriptor_type desc_type; + struct list_head list; +}; + +/** + * struct dcc_drvdata - configuration information related to a dcc device + * @base: Base Address of the dcc device + * @dev: The device attached to the driver data + * @mutex: Lock to protect access and manipulation of dcc_drvdata + * @ram_base: Base address for the SRAM dedicated for the dcc device + * @ram_size: Total size of the SRAM dedicated for the dcc device + * @ram_offset: Offset to the SRAM dedicated for dcc device + * @ram_cfg: Used for address limit calculation for dcc + * @ram_start: Starting address of DCC SRAM + * @mem_map_ver: Memory map version of DCC hardware + * @sram_dev: Miscellaneous device equivalent of dcc SRAM + * @cfg_head: Points to the head of the linked list of addresses + * @dbg_dir: The dcc debugfs directory under which all the debugfs files are placed + * @max_link_list: Total number of linkedlists supported by the DCC configuration + * @loop_shift: Loop offset bits range for the addresses + * @enable_bitmap: Bitmap to capture the enabled status of each linked list of addresses + */ +struct dcc_drvdata { + void __iomem *base; + void __iomem *ram_base; + struct device *dev; + /* Lock to protect access and manipulation of dcc_drvdata */ + struct mutex mutex; + size_t ram_size; + u32 ram_offset; + unsigned int ram_cfg; + unsigned int ram_start; + u64 mem_map_ver; + struct miscdevice sram_dev; + struct list_head *cfg_head; + struct dentry *dbg_dir; + size_t max_link_list; + u8 loop_shift; + unsigned long *enable_bitmap; + char **temp_buff_ptr; +}; + +struct dcc_cfg_attr { + u32 addr; + u32 prev_addr; + u32 prev_off; + u32 link; + u32 sram_offset; +}; + +struct dcc_cfg_loop_attr { + u32 loop_cnt; + u32 loop_len; + u32 loop_off; + bool loop_start; +}; + +static inline u32 dcc_status(int version) +{ + return version == 1 ? 0x0c : 0x1c; +} + +static inline u32 dcc_list_offset(int version) +{ + if (version == 1) + return 0x1c; + else if (version == 2) + return 0x2c; + else + return 0x34; +} + +static inline void dcc_list_writel(struct dcc_drvdata *drvdata, + u32 val, u32 ll, u32 off) +{ + u32 offset = dcc_list_offset(drvdata->mem_map_ver) + off; + + writel(val, drvdata->base + ll * DCC_LL_OFFSET + offset); +} + +static inline u32 dcc_list_readl(struct dcc_drvdata *drvdata, u32 ll, u32 off) +{ + u32 offset = dcc_list_offset(drvdata->mem_map_ver) + off; + + return readl(drvdata->base + ll * DCC_LL_OFFSET + offset); +} + +static void dcc_sram_write_auto(struct dcc_drvdata *drvdata, + u32 val, u32 *off) +{ + /* If the overflow condition is met increment the offset + * and return to indicate that overflow has occurred + */ + if (*off > drvdata->ram_size - 4) { + *off += 4; + return; + } + + writel(val, drvdata->ram_base + *off); + + *off += 4; +} + +static int dcc_sw_trigger(struct dcc_drvdata *drvdata) +{ + void __iomem *addr; + int i; + u32 status; + u32 ll_cfg; + u32 tmp_ll_cfg; + u32 val; + int ret = 0; + + mutex_lock(&drvdata->mutex); + + for (i = 0; i < drvdata->max_link_list; i++) { + if (!test_bit(i, drvdata->enable_bitmap)) + continue; + ll_cfg = dcc_list_readl(drvdata, i, DCC_LL_CFG); + if (drvdata->mem_map_ver == MEM_MAP_VER3) + tmp_ll_cfg = ll_cfg & ~BIT(8); + else + tmp_ll_cfg = ll_cfg & ~DCC_TRIGGER_MASK; + + dcc_list_writel(drvdata, tmp_ll_cfg, i, DCC_LL_CFG); + dcc_list_writel(drvdata, 1, i, DCC_LL_SW_TRIGGER); + dcc_list_writel(drvdata, ll_cfg, i, DCC_LL_CFG); + } + + addr = drvdata->base + dcc_status(drvdata->mem_map_ver); + if (readl_poll_timeout(addr, val, !FIELD_GET(DCC_STATUS_MASK, val), + 1, STATUS_READY_TIMEOUT)) { + dev_err(drvdata->dev, "DCC is busy after receiving sw trigger\n"); + ret = -EBUSY; + goto out_unlock; + } + + for (i = 0; i < drvdata->max_link_list; i++) { + if (!test_bit(i, drvdata->enable_bitmap)) + continue; + + status = dcc_list_readl(drvdata, i, DCC_LL_BUS_ACCESS_STATUS); + if (!status) + continue; + + dev_err(drvdata->dev, "Read access error for list %d err: 0x%x\n", + i, status); + ll_cfg = dcc_list_readl(drvdata, i, DCC_LL_CFG); + if (drvdata->mem_map_ver == MEM_MAP_VER3) + tmp_ll_cfg = ll_cfg & ~BIT(8); + else + tmp_ll_cfg = ll_cfg & ~DCC_TRIGGER_MASK; + + dcc_list_writel(drvdata, tmp_ll_cfg, i, DCC_LL_CFG); + dcc_list_writel(drvdata, DCC_STATUS_MASK, i, DCC_LL_BUS_ACCESS_STATUS); + dcc_list_writel(drvdata, ll_cfg, i, DCC_LL_CFG); + ret = -ENODATA; + break; + } + +out_unlock: + mutex_unlock(&drvdata->mutex); + return ret; +} + +static void dcc_ll_cfg_reset_link(struct dcc_cfg_attr *cfg) +{ + cfg->addr = 0x00; + cfg->link = 0; + cfg->prev_off = 0; + cfg->prev_addr = cfg->addr; +} + +static void dcc_emit_read_write(struct dcc_drvdata *drvdata, + struct dcc_config_entry *entry, + struct dcc_cfg_attr *cfg) +{ + if (cfg->link) { + /* + * write new offset = 1 to continue + * processing the list + */ + + dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset); + + /* Reset link and prev_off */ + dcc_ll_cfg_reset_link(cfg); + } + + cfg->addr = DCC_RD_MOD_WR_DESCRIPTOR; + dcc_sram_write_auto(drvdata, cfg->addr, &cfg->sram_offset); + + dcc_sram_write_auto(drvdata, entry->mask, &cfg->sram_offset); + + dcc_sram_write_auto(drvdata, entry->write_val, &cfg->sram_offset); + + cfg->addr = 0; +} + +static void dcc_emit_loop(struct dcc_drvdata *drvdata, struct dcc_config_entry *entry, + struct dcc_cfg_attr *cfg, + struct dcc_cfg_loop_attr *cfg_loop, + u32 *total_len) +{ + int loop; + + /* Check if we need to write link of prev entry */ + if (cfg->link) + dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset); + + if (cfg_loop->loop_start) { + loop = (cfg->sram_offset - cfg_loop->loop_off) / 4; + loop |= (cfg_loop->loop_cnt << drvdata->loop_shift) & + GENMASK(DCC_ADDR_LIMIT, drvdata->loop_shift); + loop |= DCC_LOOP_DESCRIPTOR; + *total_len += (*total_len - cfg_loop->loop_len) * cfg_loop->loop_cnt; + + dcc_sram_write_auto(drvdata, loop, &cfg->sram_offset); + + cfg_loop->loop_start = false; + cfg_loop->loop_len = 0; + cfg_loop->loop_off = 0; + } else { + cfg_loop->loop_start = true; + cfg_loop->loop_cnt = entry->loop_cnt - 1; + cfg_loop->loop_len = *total_len; + cfg_loop->loop_off = cfg->sram_offset; + } + + /* Reset link and prev_off */ + dcc_ll_cfg_reset_link(cfg); +} + +static void dcc_emit_write(struct dcc_drvdata *drvdata, + struct dcc_config_entry *entry, + struct dcc_cfg_attr *cfg) +{ + u32 off; + + if (cfg->link) { + /* + * write new offset = 1 to continue + * processing the list + */ + dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset); + + /* Reset link and prev_off */ + cfg->addr = 0x00; + cfg->prev_off = 0; + cfg->prev_addr = cfg->addr; + } + + off = entry->offset / 4; + /* write new offset-length pair to correct position */ + cfg->link |= ((off & DCC_WRITE_OFF_MASK) | DCC_WRITE_MASK | + FIELD_PREP(DCC_WRITE_LEN_MASK, entry->len)); + cfg->link |= DCC_LINK_DESCRIPTOR; + + /* Address type */ + cfg->addr = (entry->base >> 4) & GENMASK(DCC_ADDR_LIMIT, 0); + if (entry->apb_bus) + cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_WRITE_IND | DCC_APB_IND; + else + cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_WRITE_IND | DCC_AHB_IND; + dcc_sram_write_auto(drvdata, cfg->addr, &cfg->sram_offset); + + dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset); + + dcc_sram_write_auto(drvdata, entry->write_val, &cfg->sram_offset); + + cfg->addr = 0x00; + cfg->link = 0; +} + +static int dcc_emit_read(struct dcc_drvdata *drvdata, + struct dcc_config_entry *entry, + struct dcc_cfg_attr *cfg, + u32 *pos, u32 *total_len) +{ + u32 off; + u32 temp_off; + + cfg->addr = (entry->base >> 4) & GENMASK(27, 0); + + if (entry->apb_bus) + cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_READ_IND | DCC_APB_IND; + else + cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_READ_IND | DCC_AHB_IND; + + off = entry->offset / 4; + + *total_len += entry->len * 4; + + if (!cfg->prev_addr || cfg->prev_addr != cfg->addr || cfg->prev_off > off) { + /* Check if we need to write prev link entry */ + if (cfg->link) + dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset); + dev_dbg(drvdata->dev, "DCC: sram address 0x%x\n", cfg->sram_offset); + + /* Write address */ + dcc_sram_write_auto(drvdata, cfg->addr, &cfg->sram_offset); + + /* Reset link and prev_off */ + cfg->link = 0; + cfg->prev_off = 0; + } + + if ((off - cfg->prev_off) > 0xff || entry->len > MAX_DCC_LEN) { + dev_err(drvdata->dev, "DCC: Programming error Base: 0x%x, offset 0x%x\n", + entry->base, entry->offset); + return -EINVAL; + } + + if (cfg->link) { + /* + * link already has one offset-length so new + * offset-length needs to be placed at + * bits [29:15] + */ + *pos = 15; + + /* Clear bits [31:16] */ + cfg->link &= GENMASK(14, 0); + } else { + /* + * link is empty, so new offset-length needs + * to be placed at bits [15:0] + */ + *pos = 0; + cfg->link = 1 << 15; + } + + /* write new offset-length pair to correct position */ + temp_off = (off - cfg->prev_off) & GENMASK(7, 0); + cfg->link |= (temp_off | ((entry->len << 8) & GENMASK(14, 8))) << *pos; + + cfg->link |= DCC_LINK_DESCRIPTOR; + + if (*pos) { + dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset); + cfg->link = 0; + } + + cfg->prev_off = off + entry->len - 1; + cfg->prev_addr = cfg->addr; + return 0; +} + +static int dcc_emit_config(struct dcc_drvdata *drvdata, unsigned int curr_list) +{ + int ret; + u32 total_len, pos; + struct dcc_config_entry *entry; + struct dcc_cfg_attr cfg = {0}; + struct dcc_cfg_loop_attr cfg_loop = {0}; + + cfg.sram_offset = drvdata->ram_cfg * 4; + total_len = 0; + + list_for_each_entry(entry, &drvdata->cfg_head[curr_list], list) { + switch (entry->desc_type) { + case DCC_READ_WRITE_TYPE: + dcc_emit_read_write(drvdata, entry, &cfg); + break; + + case DCC_LOOP_TYPE: + dcc_emit_loop(drvdata, entry, &cfg, &cfg_loop, &total_len); + break; + + case DCC_WRITE_TYPE: + dcc_emit_write(drvdata, entry, &cfg); + break; + + case DCC_READ_TYPE: + ret = dcc_emit_read(drvdata, entry, &cfg, &pos, &total_len); + if (ret) + goto err; + break; + } + } + + if (cfg.link) + dcc_sram_write_auto(drvdata, cfg.link, &cfg.sram_offset); + + if (cfg_loop.loop_start) { + dev_err(drvdata->dev, "DCC: Programming error: Loop unterminated\n"); + ret = -EINVAL; + goto err; + } + + /* Handling special case of list ending with a rd_mod_wr */ + if (cfg.addr == DCC_RD_MOD_WR_DESCRIPTOR) { + cfg.addr = (DCC_RD_MOD_WR_ADDR) & GENMASK(27, 0); + cfg.addr |= DCC_ADDR_DESCRIPTOR; + dcc_sram_write_auto(drvdata, cfg.addr, &cfg.sram_offset); + } + + /* Setting zero to indicate end of the list */ + cfg.link = DCC_LINK_DESCRIPTOR; + dcc_sram_write_auto(drvdata, cfg.link, &cfg.sram_offset); + + /* Check if sram offset exceeds the ram size */ + if (cfg.sram_offset > drvdata->ram_size) + goto overstep; + + /* Update ram_cfg and check if the data will overstep */ + drvdata->ram_cfg = (cfg.sram_offset + total_len) / 4; + + if (cfg.sram_offset + total_len > drvdata->ram_size) { + cfg.sram_offset += total_len; + goto overstep; + } + + drvdata->ram_start = cfg.sram_offset / 4; + return 0; +overstep: + ret = -EINVAL; + memset_io(drvdata->ram_base, 0, drvdata->ram_size); + +err: + return ret; +} + +static bool dcc_valid_list(struct dcc_drvdata *drvdata, unsigned int curr_list) +{ + u32 lock_reg; + + if (list_empty(&drvdata->cfg_head[curr_list])) + return false; + + if (test_bit(curr_list, drvdata->enable_bitmap)) { + dev_err(drvdata->dev, "List %d is already enabled\n", curr_list); + return false; + } + + lock_reg = dcc_list_readl(drvdata, curr_list, DCC_LL_LOCK); + if (lock_reg & DCC_LOCK_MASK) { + dev_err(drvdata->dev, "List %d is already locked\n", curr_list); + return false; + } + + return true; +} + +static bool is_dcc_enabled(struct dcc_drvdata *drvdata) +{ + int list; + + for (list = 0; list < drvdata->max_link_list; list++) + if (test_bit(list, drvdata->enable_bitmap)) + return true; + + return false; +} + +static int dcc_enable(struct dcc_drvdata *drvdata, unsigned int curr_list) +{ + int ret; + u32 ram_cfg_base; + + mutex_lock(&drvdata->mutex); + + if (!dcc_valid_list(drvdata, curr_list)) { + ret = -EINVAL; + goto out_unlock; + } + + /* Fill dcc sram with the poison value. + * This helps in understanding bus + * hang from registers returning a zero + */ + if (!is_dcc_enabled(drvdata)) + memset_io(drvdata->ram_base, 0xde, drvdata->ram_size); + + /* 1. Take ownership of the list */ + dcc_list_writel(drvdata, DCC_LOCK_MASK, curr_list, DCC_LL_LOCK); + + /* 2. Program linked-list in the SRAM */ + ram_cfg_base = drvdata->ram_cfg; + ret = dcc_emit_config(drvdata, curr_list); + if (ret) { + dcc_list_writel(drvdata, 0, curr_list, DCC_LL_LOCK); + goto out_unlock; + } + + /* 3. Program DCC_RAM_CFG reg */ + dcc_list_writel(drvdata, ram_cfg_base + + drvdata->ram_offset / 4, curr_list, DCC_LL_BASE); + dcc_list_writel(drvdata, drvdata->ram_start + + drvdata->ram_offset / 4, curr_list, DCC_FD_BASE); + dcc_list_writel(drvdata, 0xFFF, curr_list, DCC_LL_TIMEOUT); + + /* 4. Clears interrupt status register */ + dcc_list_writel(drvdata, 0, curr_list, DCC_LL_INT_ENABLE); + dcc_list_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)), + curr_list, DCC_LL_INT_STATUS); + + set_bit(curr_list, drvdata->enable_bitmap); + + /* 5. Configure trigger */ + if (drvdata->mem_map_ver == MEM_MAP_VER3) + dcc_list_writel(drvdata, BIT(8), + curr_list, DCC_LL_CFG); + else + dcc_list_writel(drvdata, DCC_TRIGGER_MASK, + curr_list, DCC_LL_CFG); + +out_unlock: + mutex_unlock(&drvdata->mutex); + return ret; +} + +static void dcc_disable(struct dcc_drvdata *drvdata, int curr_list) +{ + mutex_lock(&drvdata->mutex); + + if (!test_bit(curr_list, drvdata->enable_bitmap)) + goto out_unlock; + dcc_list_writel(drvdata, 0, curr_list, DCC_LL_CFG); + dcc_list_writel(drvdata, 0, curr_list, DCC_LL_BASE); + dcc_list_writel(drvdata, 0, curr_list, DCC_FD_BASE); + dcc_list_writel(drvdata, 0, curr_list, DCC_LL_LOCK); + clear_bit(curr_list, drvdata->enable_bitmap); +out_unlock: + mutex_unlock(&drvdata->mutex); +} + +static u32 dcc_filp_curr_list(const struct file *filp) +{ + struct dentry *dentry = file_dentry(filp); + int curr_list, ret; + + ret = kstrtoint(dentry->d_parent->d_name.name, 0, &curr_list); + if (ret) + return ret; + + return curr_list; +} + +static ssize_t enable_read(struct file *filp, char __user *userbuf, + size_t count, loff_t *ppos) +{ + char *buf; + int curr_list = dcc_filp_curr_list(filp); + struct dcc_drvdata *drvdata = filp->private_data; + + if (curr_list < 0) + return curr_list; + + mutex_lock(&drvdata->mutex); + if (test_bit(curr_list, drvdata->enable_bitmap)) + buf = "Y\n"; + else + buf = "N\n"; + mutex_unlock(&drvdata->mutex); + + return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); +} + +static ssize_t enable_write(struct file *filp, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + int ret = 0, curr_list; + bool val; + struct dcc_drvdata *drvdata = filp->private_data; + + curr_list = dcc_filp_curr_list(filp); + if (curr_list < 0) + return curr_list; + + ret = kstrtobool_from_user(userbuf, count, &val); + if (ret < 0) + return ret; + + if (val) { + ret = dcc_enable(drvdata, curr_list); + if (ret) + return ret; + } else { + dcc_disable(drvdata, curr_list); + } + + return count; +} + +static const struct file_operations enable_fops = { + .read = enable_read, + .write = enable_write, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +static ssize_t trigger_write(struct file *filp, + const char __user *user_buf, size_t count, + loff_t *ppos) +{ + int ret; + unsigned int val; + struct dcc_drvdata *drvdata = filp->private_data; + + ret = kstrtouint_from_user(user_buf, count, 0, &val); + if (ret < 0) + return ret; + + if (val != 1) + return -EINVAL; + + ret = dcc_sw_trigger(drvdata); + if (ret < 0) + return ret; + + return count; +} + +static const struct file_operations trigger_fops = { + .write = trigger_write, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +static int dcc_config_add(struct dcc_drvdata *drvdata, unsigned int addr, + unsigned int len, bool apb_bus, int curr_list) +{ + int ret = 0; + struct dcc_config_entry *entry, *pentry; + unsigned int base, offset; + + mutex_lock(&drvdata->mutex); + + if (!len || len > drvdata->ram_size / DCC_WORD_SIZE) { + dev_err(drvdata->dev, "DCC: Invalid length\n"); + ret = -EINVAL; + goto out_unlock; + } + + base = addr & DCC_ADDR_RANGE_MASK; + + if (!list_empty(&drvdata->cfg_head[curr_list])) { + pentry = list_last_entry(&drvdata->cfg_head[curr_list], + struct dcc_config_entry, list); + + if (pentry->desc_type == DCC_READ_TYPE && + addr >= (pentry->base + pentry->offset) && + addr <= (pentry->base + pentry->offset + MAX_DCC_OFFSET)) { + /* Re-use base address from last entry */ + base = pentry->base; + + if ((pentry->len * 4 + pentry->base + pentry->offset) + == addr) { + len += pentry->len; + + if (len > MAX_DCC_LEN) + pentry->len = MAX_DCC_LEN; + else + pentry->len = len; + + addr = pentry->base + pentry->offset + + pentry->len * 4; + len -= pentry->len; + } + } + } + + offset = addr - base; + + while (len) { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { + ret = -ENOMEM; + goto out_unlock; + } + + entry->base = base; + entry->offset = offset; + entry->len = min_t(u32, len, MAX_DCC_LEN); + entry->desc_type = DCC_READ_TYPE; + entry->apb_bus = apb_bus; + INIT_LIST_HEAD(&entry->list); + list_add_tail(&entry->list, + &drvdata->cfg_head[curr_list]); + + len -= entry->len; + offset += MAX_DCC_LEN * 4; + } + +out_unlock: + mutex_unlock(&drvdata->mutex); + return ret; +} + +static ssize_t dcc_config_add_read(struct dcc_drvdata *drvdata, char *buf, int curr_list) +{ + bool bus; + int len, nval; + unsigned int base; + char apb_bus[4]; + + nval = sscanf(buf, "%x %i %3s", &base, &len, apb_bus); + if (nval <= 0 || nval > 3) + return -EINVAL; + + if (nval == 1) { + len = 1; + bus = false; + } else if (nval == 2) { + bus = false; + } else if (!strcmp("apb", apb_bus)) { + bus = true; + } else if (!strcmp("ahb", apb_bus)) { + bus = false; + } else { + return -EINVAL; + } + + return dcc_config_add(drvdata, base, len, bus, curr_list); +} + +static void dcc_config_reset(struct dcc_drvdata *drvdata) +{ + struct dcc_config_entry *entry, *temp; + int curr_list; + + mutex_lock(&drvdata->mutex); + + for (curr_list = 0; curr_list < drvdata->max_link_list; curr_list++) { + list_for_each_entry_safe(entry, temp, + &drvdata->cfg_head[curr_list], list) { + list_del(&entry->list); + } + } + drvdata->ram_start = 0; + drvdata->ram_cfg = 0; + mutex_unlock(&drvdata->mutex); +} + +static ssize_t config_reset_write(struct file *filp, + const char __user *user_buf, size_t count, + loff_t *ppos) +{ + unsigned int val; + int ret; + struct dcc_drvdata *drvdata = filp->private_data; + + ret = kstrtouint_from_user(user_buf, count, 0, &val); + if (ret < 0) + return ret; + + if (val) + dcc_config_reset(drvdata); + + return count; +} + +static const struct file_operations config_reset_fops = { + .write = config_reset_write, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +static ssize_t ready_read(struct file *filp, char __user *userbuf, + size_t count, loff_t *ppos) +{ + char *buf; + struct dcc_drvdata *drvdata = filp->private_data; + + if (!is_dcc_enabled(drvdata)) + return -EINVAL; + + if (!FIELD_GET(BIT(1), readl(drvdata->base + dcc_status(drvdata->mem_map_ver)))) + buf = "Y\n"; + else + buf = "N\n"; + + return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf) + 1); +} + +static const struct file_operations ready_fops = { + .read = ready_read, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +static ssize_t loop_offset_read(struct file *filp, char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[4]; + struct dcc_drvdata *drvdata = filp->private_data; + + snprintf(buf, sizeof(buf), "%d", drvdata->loop_shift); + return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf) + 1); +} + +static const struct file_operations loop_offset_fops = { + .read = loop_offset_read, + .open = simple_open, + .llseek = generic_file_llseek, +}; +static int dcc_add_loop(struct dcc_drvdata *drvdata, unsigned long loop_cnt, int curr_list) +{ + struct dcc_config_entry *entry; + + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + entry->loop_cnt = min_t(u32, loop_cnt, MAX_LOOP_CNT); + entry->desc_type = DCC_LOOP_TYPE; + INIT_LIST_HEAD(&entry->list); + list_add_tail(&entry->list, &drvdata->cfg_head[curr_list]); + + return 0; +} + +static ssize_t dcc_config_add_loop(struct dcc_drvdata *drvdata, char *buf, int curr_list) +{ + int ret, i = 0; + char *token, *input; + char delim[2] = " "; + unsigned int val[MAX_LOOP_ADDR]; + + input = buf; + + while ((token = strsep(&input, delim)) && i < MAX_LOOP_ADDR) { + ret = kstrtouint(token, 0, &val[i++]); + if (ret) + return ret; + } + + if (token) { + dev_err(drvdata->dev, "Max limit %u of loop address exceeded\n", + MAX_LOOP_ADDR); + return -EINVAL; + } + + if (val[1] < 1 || val[1] > 8 || val[1] > (i - 2)) + return -EINVAL; + + ret = dcc_add_loop(drvdata, val[0], curr_list); + if (ret) + return ret; + + for (i = 0; i < val[1]; i++) + dcc_config_add(drvdata, val[i + 2], 1, false, curr_list); + + return dcc_add_loop(drvdata, 1, curr_list); +} + +static int dcc_rd_mod_wr_add(struct dcc_drvdata *drvdata, unsigned int mask, + unsigned int val, int curr_list) +{ + int ret = 0; + struct dcc_config_entry *entry; + + mutex_lock(&drvdata->mutex); + + if (list_empty(&drvdata->cfg_head[curr_list])) { + dev_err(drvdata->dev, "DCC: No read address programmed\n"); + ret = -EPERM; + goto out_unlock; + } + + entry = devm_kzalloc(drvdata->dev, sizeof(*entry), GFP_KERNEL); + if (!entry) { + ret = -ENOMEM; + goto out_unlock; + } + + entry->desc_type = DCC_READ_WRITE_TYPE; + entry->mask = mask; + entry->write_val = val; + list_add_tail(&entry->list, &drvdata->cfg_head[curr_list]); +out_unlock: + mutex_unlock(&drvdata->mutex); + return ret; +} + +static ssize_t dcc_config_add_read_write(struct dcc_drvdata *drvdata, char *buf, int curr_list) +{ + int ret; + int nval; + unsigned int addr, mask, val; + + nval = sscanf(buf, "%x %x %x", &addr, &mask, &val); + + if (nval <= 1 || nval > 3) + return -EINVAL; + + ret = dcc_config_add(drvdata, addr, 1, false, curr_list); + if (ret) + return ret; + + return dcc_rd_mod_wr_add(drvdata, mask, val, curr_list); +} + +static int dcc_add_write(struct dcc_drvdata *drvdata, unsigned int addr, + unsigned int write_val, int apb_bus, int curr_list) +{ + struct dcc_config_entry *entry; + + entry = devm_kzalloc(drvdata->dev, sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + entry->desc_type = DCC_WRITE_TYPE; + entry->base = addr & GENMASK(31, 4); + entry->offset = addr - entry->base; + entry->write_val = write_val; + entry->len = 1; + entry->apb_bus = apb_bus; + list_add_tail(&entry->list, &drvdata->cfg_head[curr_list]); + + return 0; +} + +static ssize_t dcc_config_add_write(struct dcc_drvdata *drvdata, char *buf, int curr_list) +{ + bool bus; + int nval; + unsigned int addr, write_val; + char apb_bus[4]; + + nval = sscanf(buf, "%x %x %3s", &addr, &write_val, apb_bus); + + if (nval <= 1 || nval > 3) + return -EINVAL; + + if (nval == 2) + bus = false; + + if (nval == 3) { + if (!strcmp("apb", apb_bus)) + bus = true; + else if (!strcmp("ahb", apb_bus)) + bus = false; + else + return -EINVAL; + } + + return dcc_add_write(drvdata, addr, write_val, bus, curr_list); +} + +static int config_show(struct seq_file *m, void *data) +{ + struct dcc_drvdata *drvdata = m->private; + struct dcc_config_entry *entry, *next_entry, *prev_entry, *loop_entry; + int index = 0, curr_list, i; + unsigned int loop_val[MAX_LOOP_ADDR]; + + curr_list = dcc_filp_curr_list(m->file); + if (curr_list < 0) + return curr_list; + + mutex_lock(&drvdata->mutex); + + list_for_each_entry(entry, &drvdata->cfg_head[curr_list], list) { + index++; + switch (entry->desc_type) { + case DCC_READ_WRITE_TYPE: + prev_entry = list_prev_entry(entry, list); + seq_printf(m, "RW 0x%x 0x%x 0x%x\n", + prev_entry->base + prev_entry->offset, + entry->mask, + entry->write_val); + break; + case DCC_LOOP_TYPE: + loop_entry = entry; + loop_val[0] = loop_entry->loop_cnt; + loop_entry = list_next_entry(loop_entry, list); + for (i = 0; i < (MAX_LOOP_ADDR-2); + i++, loop_entry = list_next_entry(loop_entry, list)) { + if (loop_entry->desc_type == DCC_READ_TYPE) { + loop_val[i+2] = loop_entry->base + loop_entry->offset; + } else if (loop_entry->desc_type == DCC_LOOP_TYPE) { + loop_val[i+2] = loop_entry->loop_cnt; + loop_val[1] = i; + entry = loop_entry; + break; + } + } + seq_printf(m, "L 0x%x 0x%x", loop_val[0], loop_val[1]); + for (i = 0; i < loop_val[1]; i++) + seq_printf(m, " 0x%x", loop_val[i+2]); + seq_puts(m, "\n"); + break; + case DCC_WRITE_TYPE: + seq_printf(m, "W 0x%x 0x%x %s\n", + entry->base + entry->offset, + entry->write_val, + entry->apb_bus ? "apb":"ahb"); + break; + case DCC_READ_TYPE: + if (entry->len == 1) { + next_entry = list_next_entry(entry, list); + if (next_entry && next_entry->desc_type == DCC_READ_WRITE_TYPE) + continue; + } + seq_printf(m, "R 0x%x 0x%x %s\n", + entry->base + entry->offset, + entry->len, + entry->apb_bus ? "apb":"ahb"); + } + } + mutex_unlock(&drvdata->mutex); + return 0; +} + +static int config_open(struct inode *inode, struct file *file) +{ + struct dcc_drvdata *drvdata = inode->i_private; + + return single_open(file, config_show, drvdata); +} + +static ssize_t config_write(struct file *filp, + const char __user *user_buf, size_t count, + loff_t *ppos) +{ + int ret, curr_list; + char *token, *line; + char *buf, *bufp, *temp_buff; + char *delim = " "; + struct dcc_drvdata *drvdata = filp->f_inode->i_private; + ssize_t processed_len = 0; + + if (count == 0) + return -EINVAL; + buf = kzalloc(count+1, GFP_KERNEL); + if (buf) + bufp = buf; + else + return -ENOMEM; + + ret = copy_from_user(buf, user_buf, count); + if (ret) + goto err; + + curr_list = dcc_filp_curr_list(filp); + if (curr_list < 0) { + ret = curr_list; + goto err; + } + + while (bufp[0] != '\0') { + /* Parse line by line */ + line = strsep(&bufp, "\n"); + /* When one complete line could be parsed */ + if (line && bufp) { + processed_len += strlen(line) + 1; + if (drvdata->temp_buff_ptr && drvdata->temp_buff_ptr[curr_list]) { + temp_buff = drvdata->temp_buff_ptr[curr_list]; + /* Size of combined string must not be greater than + * allowed line size. + */ + if (strlen(line) + strlen(temp_buff) + 1 > LINE_BUFFER_MAX_SZ) { + dev_err(drvdata->dev, "Invalid input\n"); + ret = -EINVAL; + goto err; + } + strlcat(temp_buff, line, PAGE_SIZE); + line = temp_buff; + kfree(temp_buff); + drvdata->temp_buff_ptr[curr_list] = NULL; + } + + token = strsep(&line, delim); + + if (!strcmp("R", token)) { + ret = dcc_config_add_read(drvdata, line, curr_list); + } else if (!strcmp("W", token)) { + ret = dcc_config_add_write(drvdata, line, curr_list); + } else if (!strcmp("RW", token)) { + ret = dcc_config_add_read_write(drvdata, line, curr_list); + } else if (!strcmp("L", token)) { + ret = dcc_config_add_loop(drvdata, line, curr_list); + } else { + dev_err(drvdata->dev, "%s is not a correct input\n", token); + ret = -EINVAL; + } + + if (ret) + goto err; + } else { + /* Save the incomplete line to a temporary buffer and rejoin it later */ + if (!drvdata->temp_buff_ptr) { + drvdata->temp_buff_ptr = devm_kcalloc(drvdata->dev, + drvdata->max_link_list, + sizeof(char *), + GFP_KERNEL); + if (!drvdata->temp_buff_ptr) { + ret = -ENOMEM; + goto err; + } + } + drvdata->temp_buff_ptr[curr_list] = kzalloc(LINE_BUFFER_MAX_SZ, + GFP_KERNEL); + temp_buff = drvdata->temp_buff_ptr[curr_list]; + if (!temp_buff) { + ret = -ENOMEM; + goto err; + } + if ((count - processed_len) >= LINE_BUFFER_MAX_SZ) { + dev_err(drvdata->dev, "Invalid input\n"); + ret = -EINVAL; + goto err; + } + memcpy(temp_buff, line, count - processed_len); + temp_buff[count - processed_len + 1] = '\0'; + processed_len += (strlen(temp_buff) + 1); + break; + } + } + + kfree(buf); + return processed_len; + +err: + kfree(buf); + if (drvdata->temp_buff_ptr && drvdata->temp_buff_ptr[curr_list]) { + kfree(drvdata->temp_buff_ptr[curr_list]); + drvdata->temp_buff_ptr[curr_list] = NULL; + } + return ret; +} + +static const struct file_operations config_fops = { + .open = config_open, + .read = seq_read, + .write = config_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static void dcc_delete_debug_dir(struct dcc_drvdata *drvdata) +{ + debugfs_remove_recursive(drvdata->dbg_dir); +}; + +static void dcc_create_debug_dir(struct dcc_drvdata *drvdata) +{ + int i; + char list_num[10]; + struct dentry *dcc_dev, *list; + struct device *dev = drvdata->dev; + + drvdata->dbg_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); + dcc_dev = debugfs_create_dir(dev_name(dev), drvdata->dbg_dir); + + for (i = 0; i < drvdata->max_link_list; i++) { + snprintf(list_num, sizeof(list_num), "%d", i); + list = debugfs_create_dir(list_num, dcc_dev); + debugfs_create_file("enable", 0600, list, drvdata, &enable_fops); + debugfs_create_file("config", 0600, list, drvdata, &config_fops); + } + + debugfs_create_file("trigger", 0200, drvdata->dbg_dir, drvdata, &trigger_fops); + debugfs_create_file("ready", 0400, drvdata->dbg_dir, drvdata, &ready_fops); + debugfs_create_file("config_reset", 0200, drvdata->dbg_dir, drvdata, &config_reset_fops); + debugfs_create_file("loop_offset", 0400, drvdata->dbg_dir, drvdata, &loop_offset_fops); +} + +static ssize_t dcc_sram_read(struct file *file, char __user *data, + size_t len, loff_t *ppos) +{ + unsigned char *buf; + struct dcc_drvdata *drvdata; + + drvdata = container_of(file->private_data, struct dcc_drvdata, + sram_dev); + + /* EOF check */ + if (*ppos >= drvdata->ram_size) + return 0; + + if ((*ppos + len) > drvdata->ram_size) + len = (drvdata->ram_size - *ppos); + + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memcpy_fromio(buf, drvdata->ram_base + *ppos, len); + + if (copy_to_user(data, buf, len)) { + kfree(buf); + return -EFAULT; + } + + *ppos += len; + + kfree(buf); + + return len; +} + +static void dcc_configure_list(struct dcc_drvdata *drvdata, struct device_node *np) +{ + const char *prop; + int ret, curr_list, index = 0; + char *token, *bufp; + char *delim = " "; + u32 len, processed_len = 0; + + ret = of_property_read_u32(np, "qcom,curr-link-list", + &curr_list); + if (ret) + return; + + if(!of_get_property(np, "qcom,link-list", &len)) + return; + + bufp = kzalloc(len+1, GFP_KERNEL); + if (!bufp) + return; + + while (!of_property_read_string_index(np, "qcom,link-list", index, &prop)) { + strncpy(bufp, prop, strlen(prop)); + bufp[strlen(prop)] = '\0'; + + processed_len += strlen(bufp) + 1; + + token = strsep(&bufp, delim); + + if (!strcmp("R", token)) { + ret = dcc_config_add_read(drvdata, bufp, curr_list); + } else if (!strcmp("W", token)) { + ret = dcc_config_add_write(drvdata, bufp, curr_list); + } else if (!strcmp("RW", token)) { + ret = dcc_config_add_read_write(drvdata, bufp, curr_list); + } else if (!strcmp("L", token)) { + ret = dcc_config_add_loop(drvdata, bufp, curr_list); + } else { + dev_err(drvdata->dev, "%s is not a correct input\n", token); + ret = -EINVAL; + } + + if (ret < 0) + dev_err(drvdata->dev, "Configure line %s failed\n", prop); + + index++; + } + + dcc_enable(drvdata, curr_list); + kfree(bufp); +} + +static const struct file_operations dcc_sram_fops = { + .owner = THIS_MODULE, + .read = dcc_sram_read, +}; + +static int dcc_sram_dev_init(struct dcc_drvdata *drvdata) +{ + drvdata->sram_dev.minor = MISC_DYNAMIC_MINOR; + drvdata->sram_dev.name = "dcc_sram"; + drvdata->sram_dev.fops = &dcc_sram_fops; + + return misc_register(&drvdata->sram_dev); +} + +static void dcc_sram_dev_exit(struct dcc_drvdata *drvdata) +{ + misc_deregister(&drvdata->sram_dev); +} + +static int dcc_probe(struct platform_device *pdev) +{ + u32 val; + int ret = 0, i; + struct device *dev = &pdev->dev; + struct dcc_drvdata *drvdata; + struct resource *res; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &pdev->dev; + platform_set_drvdata(pdev, drvdata); + + drvdata->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(drvdata->base)) + return PTR_ERR(drvdata->base); + + drvdata->ram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); + if (IS_ERR(drvdata->ram_base)) + return PTR_ERR(drvdata->ram_base); + + drvdata->ram_size = resource_size(res); + ret = of_property_read_u32(pdev->dev.of_node, "qcom,dcc-offset", + &drvdata->ram_offset); + if (ret) + return -EINVAL; + + drvdata->mem_map_ver = (u64)of_device_get_match_data(&pdev->dev); + + switch (drvdata->mem_map_ver) { + case MEM_MAP_VER3: + case MEM_MAP_VER2: + drvdata->max_link_list = readl(drvdata->base + DCC_LL_NUM_INFO); + if (!drvdata->max_link_list) + return -EINVAL; + break; + case MEM_MAP_VER1: + drvdata->max_link_list = DCC_MAX_LINK_LIST; + break; + default: + dev_err(drvdata->dev, "Unsupported memory map version.\n"); + return -EINVAL; + } + + val = readl(drvdata->base + DCC_HW_INFO); + /* Either set the fixed loop offset or calculate + * it from the total number of words in dcc_sram. + * Max consecutive addresses dcc can loop is + * equivalent to the words in dcc_sram. + */ + if (val & DCC_LOOP_OFFSET_MASK) + drvdata->loop_shift = DCC_FIX_LOOP_OFFSET; + else + drvdata->loop_shift = get_bitmask_order((drvdata->ram_offset + + drvdata->ram_size) / DCC_SRAM_WORD_LENGTH - 1); + + mutex_init(&drvdata->mutex); + + drvdata->enable_bitmap = devm_kcalloc(dev, BITS_TO_LONGS(drvdata->max_link_list), + sizeof(*drvdata->enable_bitmap), GFP_KERNEL); + if (!drvdata->enable_bitmap) + return -ENOMEM; + + drvdata->cfg_head = devm_kcalloc(dev, drvdata->max_link_list, + sizeof(*drvdata->cfg_head), GFP_KERNEL); + if (!drvdata->cfg_head) + return -ENOMEM; + + for (i = 0; i < drvdata->max_link_list; i++) + INIT_LIST_HEAD(&drvdata->cfg_head[i]); + + ret = dcc_sram_dev_init(drvdata); + if (ret) { + dev_err(drvdata->dev, "DCC: sram node not registered.\n"); + return ret; + } + + dcc_create_debug_dir(drvdata); + dcc_configure_list(drvdata, pdev->dev.of_node); + + return 0; +} + +static void dcc_remove(struct platform_device *pdev) +{ + struct dcc_drvdata *drvdata = platform_get_drvdata(pdev); + + dcc_delete_debug_dir(drvdata); + dcc_sram_dev_exit(drvdata); + dcc_config_reset(drvdata); +} + +static const struct of_device_id dcc_match_table[] = { + { .compatible = "qcom,dcc-v1", .data = (void *)MEM_MAP_VER1 }, + { .compatible = "qcom,dcc-v2", .data = (void *)MEM_MAP_VER2 }, + { .compatible = "qcom,dcc-v3", .data = (void *)MEM_MAP_VER3 }, + { } +}; +MODULE_DEVICE_TABLE(of, dcc_match_table); + +static struct platform_driver dcc_driver = { + .probe = dcc_probe, + .remove = dcc_remove, + .driver = { + .name = "qcom-dcc", + .of_match_table = dcc_match_table, + }, +}; + +module_platform_driver(dcc_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm Technologies Inc. DCC driver"); From 33b2ed518990c1f6c1c1509567a83901c3d42c07 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 8 Jan 2026 11:28:06 +0800 Subject: [PATCH 415/438] QCLINUX: add qcom_debug.config for debug features The config file is created to contain specific debug features such as DCC/memory dump driver. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom_debug.config | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/arm64/configs/qcom_debug.config diff --git a/arch/arm64/configs/qcom_debug.config b/arch/arm64/configs/qcom_debug.config new file mode 100644 index 0000000000000..874f80f29d314 --- /dev/null +++ b/arch/arm64/configs/qcom_debug.config @@ -0,0 +1 @@ +CONFIG_QCOM_DCC=m From 0fcb861bbaa6bbc39de7c1fbe16335e5c37438f9 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 8 Jan 2026 17:47:45 +0800 Subject: [PATCH 416/438] QCLINUX: qcom-dcc: add qcom-dcc dev driver Create qcom-dcc dev driver for matching the qcom-dcc driver without DT. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom_debug.config | 1 + drivers/misc/Kconfig | 8 +- drivers/misc/Makefile | 1 + drivers/misc/qcom-dcc-dev.c | 116 +++++++++++++++++++++++++++ drivers/misc/qcom-dcc.c | 79 ++---------------- drivers/misc/qcom-dcc.h | 20 +++++ 6 files changed, 153 insertions(+), 72 deletions(-) create mode 100644 drivers/misc/qcom-dcc-dev.c create mode 100644 drivers/misc/qcom-dcc.h diff --git a/arch/arm64/configs/qcom_debug.config b/arch/arm64/configs/qcom_debug.config index 874f80f29d314..eb2b32af3b40b 100644 --- a/arch/arm64/configs/qcom_debug.config +++ b/arch/arm64/configs/qcom_debug.config @@ -1 +1,2 @@ CONFIG_QCOM_DCC=m +CONFIG_QCOM_DCC_DEV=m diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 62b73f320df6d..02388dcebba1f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -310,13 +310,19 @@ config QCOM_FASTRPC module. config QCOM_DCC - tristate "Qualcomm Technologies, Inc. Data Capture and Compare (DCC) engine driver" + tristate "Qualcomm Data Capture and Compare (DCC) engine driver" depends on ARCH_QCOM || COMPILE_TEST help This option enables the driver for the Data Capture and Compare engine. DCC driver provides interfaces to configure DCC block and read back the captured data from the DCC's internal SRAM. The module name for this is qcom-dcc. +config QCOM_DCC_DEV + tristate "Qualcomm Data Capture and Compare (DCC) engine device instance" + depends on QCOM_DCC + help + This is the device instance of the QCOM DCC driver. + config SGI_GRU tristate "SGI GRU driver" depends on X86_UV && SMP diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 338ed270b7cfc..812746940d628 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -76,3 +76,4 @@ obj-y += keba/ obj-y += amd-sbi/ obj-$(CONFIG_MISC_RP1) += rp1/ obj-$(CONFIG_QCOM_DCC) += qcom-dcc.o +obj-$(CONFIG_QCOM_DCC_DEV) += qcom-dcc-dev.o diff --git a/drivers/misc/qcom-dcc-dev.c b/drivers/misc/qcom-dcc-dev.c new file mode 100644 index 0000000000000..e0eb2e61d652b --- /dev/null +++ b/drivers/misc/qcom-dcc-dev.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include "qcom-dcc.h" + +#define DEV_NAME "qcom-dcc" + +static struct platform_device *dcc_pdev; + +static const struct dcc_pdata talos_pdata = { + .base = 0x010a2000, + .size = 0x00001000, + .ram_base = 0x010ae000, + .ram_size = 0x00002000, + .dcc_offset = 0x6000, + .map_ver = 0x1, +}; + +static const struct dcc_pdata lemans_pdata = { + .base = 0x040ff000, + .size = 0x00001000, + .ram_base = 0x040b8800, + .ram_size = 0x00006000, + .dcc_offset = 0x38800, + .map_ver = 0x3, +}; + +static const struct dcc_pdata kodiak_pdata = { + .base = 0x0117f000, + .size = 0x00001000, + .ram_base = 0x01112000, + .ram_size = 0x00006000, + .dcc_offset = 0x12000, + .map_ver = 0x2, +}; + +static int __init dcc_dev_init(void) +{ + int ret; + u32 soc_id; + + dcc_pdev = platform_device_alloc(DEV_NAME, -1); + if (!dcc_pdev) + return -ENOMEM; + + ret = qcom_smem_get_soc_id(&soc_id); + if (ret) + goto fail; + + switch (soc_id) { + case 475: + case 497: + case 498: + case 515: + ret = platform_device_add_data(dcc_pdev, &kodiak_pdata, sizeof(kodiak_pdata)); + if (ret) + goto fail; + + break; + case 534: + case 606: + case 667: + case 674: + case 675: + case 676: + ret = platform_device_add_data(dcc_pdev, &lemans_pdata, sizeof(lemans_pdata)); + if (ret) + goto fail; + + break; + case 377: + case 380: + case 384: + case 401: + case 406: + case 680: + ret = platform_device_add_data(dcc_pdev, &talos_pdata, sizeof(talos_pdata)); + if (ret) + goto fail; + + break; + default: + pr_err("DCC: Invalid SoC ID\n"); + ret = -EINVAL; + goto fail; + } + + ret = platform_device_add(dcc_pdev); + if (ret) + goto fail; + + pr_info("DCC platform device has registered\n"); + + return 0; + +fail: + pr_err("Failed to register DCC platform device\n"); + platform_device_put(dcc_pdev); + + return ret; +} + +static void __exit dcc_dev_exit(void) +{ + platform_device_unregister(dcc_pdev); +} + +module_init(dcc_dev_init); +module_exit(dcc_dev_exit); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm Technologies Inc. DCC driver, device stub"); diff --git a/drivers/misc/qcom-dcc.c b/drivers/misc/qcom-dcc.c index a511faac5d4b0..e75f98b90d8f7 100644 --- a/drivers/misc/qcom-dcc.c +++ b/drivers/misc/qcom-dcc.c @@ -135,6 +135,8 @@ #include #include +#include "qcom-dcc.h" + #define STATUS_READY_TIMEOUT 5000 /* microseconds */ /* DCC registers */ @@ -1423,57 +1425,6 @@ static ssize_t dcc_sram_read(struct file *file, char __user *data, return len; } -static void dcc_configure_list(struct dcc_drvdata *drvdata, struct device_node *np) -{ - const char *prop; - int ret, curr_list, index = 0; - char *token, *bufp; - char *delim = " "; - u32 len, processed_len = 0; - - ret = of_property_read_u32(np, "qcom,curr-link-list", - &curr_list); - if (ret) - return; - - if(!of_get_property(np, "qcom,link-list", &len)) - return; - - bufp = kzalloc(len+1, GFP_KERNEL); - if (!bufp) - return; - - while (!of_property_read_string_index(np, "qcom,link-list", index, &prop)) { - strncpy(bufp, prop, strlen(prop)); - bufp[strlen(prop)] = '\0'; - - processed_len += strlen(bufp) + 1; - - token = strsep(&bufp, delim); - - if (!strcmp("R", token)) { - ret = dcc_config_add_read(drvdata, bufp, curr_list); - } else if (!strcmp("W", token)) { - ret = dcc_config_add_write(drvdata, bufp, curr_list); - } else if (!strcmp("RW", token)) { - ret = dcc_config_add_read_write(drvdata, bufp, curr_list); - } else if (!strcmp("L", token)) { - ret = dcc_config_add_loop(drvdata, bufp, curr_list); - } else { - dev_err(drvdata->dev, "%s is not a correct input\n", token); - ret = -EINVAL; - } - - if (ret < 0) - dev_err(drvdata->dev, "Configure line %s failed\n", prop); - - index++; - } - - dcc_enable(drvdata, curr_list); - kfree(bufp); -} - static const struct file_operations dcc_sram_fops = { .owner = THIS_MODULE, .read = dcc_sram_read, @@ -1499,7 +1450,7 @@ static int dcc_probe(struct platform_device *pdev) int ret = 0, i; struct device *dev = &pdev->dev; struct dcc_drvdata *drvdata; - struct resource *res; + const struct dcc_pdata *pdata = dev_get_platdata(dev); drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) @@ -1508,21 +1459,17 @@ static int dcc_probe(struct platform_device *pdev) drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); - drvdata->base = devm_platform_ioremap_resource(pdev, 0); + drvdata->base = devm_ioremap(dev, pdata->base, pdata->size); if (IS_ERR(drvdata->base)) return PTR_ERR(drvdata->base); - drvdata->ram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); + drvdata->ram_base = devm_ioremap(dev, pdata->ram_base, pdata->ram_size); if (IS_ERR(drvdata->ram_base)) return PTR_ERR(drvdata->ram_base); - drvdata->ram_size = resource_size(res); - ret = of_property_read_u32(pdev->dev.of_node, "qcom,dcc-offset", - &drvdata->ram_offset); - if (ret) - return -EINVAL; - - drvdata->mem_map_ver = (u64)of_device_get_match_data(&pdev->dev); + drvdata->ram_size = pdata->ram_size; + drvdata->ram_offset = pdata->dcc_offset; + drvdata->mem_map_ver = pdata->map_ver; switch (drvdata->mem_map_ver) { case MEM_MAP_VER3: @@ -1573,7 +1520,6 @@ static int dcc_probe(struct platform_device *pdev) } dcc_create_debug_dir(drvdata); - dcc_configure_list(drvdata, pdev->dev.of_node); return 0; } @@ -1587,20 +1533,11 @@ static void dcc_remove(struct platform_device *pdev) dcc_config_reset(drvdata); } -static const struct of_device_id dcc_match_table[] = { - { .compatible = "qcom,dcc-v1", .data = (void *)MEM_MAP_VER1 }, - { .compatible = "qcom,dcc-v2", .data = (void *)MEM_MAP_VER2 }, - { .compatible = "qcom,dcc-v3", .data = (void *)MEM_MAP_VER3 }, - { } -}; -MODULE_DEVICE_TABLE(of, dcc_match_table); - static struct platform_driver dcc_driver = { .probe = dcc_probe, .remove = dcc_remove, .driver = { .name = "qcom-dcc", - .of_match_table = dcc_match_table, }, }; diff --git a/drivers/misc/qcom-dcc.h b/drivers/misc/qcom-dcc.h new file mode 100644 index 0000000000000..513c95dc742b5 --- /dev/null +++ b/drivers/misc/qcom-dcc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _QCOM_DCC_H +#define _QCOM_DCC_H + +#include + +struct dcc_pdata { + phys_addr_t base; + resource_size_t size; + phys_addr_t ram_base; + resource_size_t ram_size; + u32 dcc_offset; + u8 map_ver; +}; + +#endif From 01d59d21a9179472325e34a0a1555159f5bd85dd Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 9 Jan 2026 14:42:21 +0800 Subject: [PATCH 417/438] QCLINUX: memory-dump: add QCOM memory dump driver The memory dump driver allows various client subsystems to register respective dump regions. At the time of deadlocks or cpu hangs these dump regions are captured to give a snapshot of the system at the time of the crash. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom_debug.config | 1 + drivers/firmware/qcom/Kconfig | 9 + drivers/firmware/qcom/Makefile | 1 + drivers/firmware/qcom/memory_dump_v2.c | 1143 +++++++++++++++++++++ include/linux/firmware/qcom/memory_dump.h | 136 +++ 5 files changed, 1290 insertions(+) create mode 100644 drivers/firmware/qcom/memory_dump_v2.c create mode 100644 include/linux/firmware/qcom/memory_dump.h diff --git a/arch/arm64/configs/qcom_debug.config b/arch/arm64/configs/qcom_debug.config index eb2b32af3b40b..2e85e8df0469b 100644 --- a/arch/arm64/configs/qcom_debug.config +++ b/arch/arm64/configs/qcom_debug.config @@ -1,2 +1,3 @@ CONFIG_QCOM_DCC=m CONFIG_QCOM_DCC_DEV=m +CONFIG_QCOM_MEMORY_DUMP_V2=m diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig index b477d54b495a6..531c6d2598ce0 100644 --- a/drivers/firmware/qcom/Kconfig +++ b/drivers/firmware/qcom/Kconfig @@ -74,4 +74,13 @@ config QCOM_QSEECOM_UEFISECAPP Select Y here to provide access to EFI variables on the aforementioned platforms. +config QCOM_MEMORY_DUMP_V2 + tristate "QCOM Memory Dump V2 Support" + depends on QCOM_TZMEM + help + This enables memory dump feature. It allows various client + subsystems to register respective dump regions. At the time + of deadlocks or cpu hangs these dump regions are captured to + give a snapshot of the system at the time of the crash. + endmenu diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile index 0be40a1abc13c..c5e17ba255937 100644 --- a/drivers/firmware/qcom/Makefile +++ b/drivers/firmware/qcom/Makefile @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o obj-$(CONFIG_QCOM_TZMEM) += qcom_tzmem.o obj-$(CONFIG_QCOM_QSEECOM) += qcom_qseecom.o obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o +obj-$(CONFIG_QCOM_MEMORY_DUMP_V2) += memory_dump_v2.o diff --git a/drivers/firmware/qcom/memory_dump_v2.c b/drivers/firmware/qcom/memory_dump_v2.c new file mode 100644 index 0000000000000..baf4c980f39fb --- /dev/null +++ b/drivers/firmware/qcom/memory_dump_v2.c @@ -0,0 +1,1143 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014-2017, 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSM_DUMP_TABLE_VERSION MSM_DUMP_MAKE_VERSION(2, 0) + +#define SCM_CMD_DEBUG_LAR_UNLOCK 0x4 + +#define CPUSS_REGDUMP 0xEF +#define SPR_DUMP_CPU0 0x1F0 +#define SPR_DUMP_CPU1 0x1F1 +#define SPR_DUMP_CPU2 0x1F2 +#define SPR_DUMP_CPU3 0x1F3 +#define SPR_DUMP_CPU4 0x1F4 +#define SPR_DUMP_CPU5 0x1F5 +#define SPR_DUMP_CPU6 0x1F6 +#define SPR_DUMP_CPU7 0x1F7 +#define SPR_DATA_HEADER_SIZE 5 +#define SPR_DATA_HEADER_TAIL_SIZE 1 +#define SPR_INPUT_DATA_TAIL_SIZE 1 +#define SPR_INPUT_DATA_SIZE 1 +#define SPR_OUTPUT_DATA_SIZE 2 +#define MAX_CORE_NUM 8 + +#define INPUT_DATA_BY_HLOS 0x00C0FFEE +#define FORMAT_VERSION_1 0x1 +#define FORMAT_VERSION_2 0x2 +#define CORE_REG_NUM_DEFAULT 0x1 + +#define MAGIC_INDEX 0 +#define FORMAT_VERSION_INDEX 1 +#define SYS_REG_INPUT_INDEX 2 +#define OUTPUT_DUMP_INDEX 3 +#define PERCORE_INDEX 4 +#define SYSTEM_REGS_INPUT_INDEX 5 + +#define CMD_REPEAT_READ (0x2 << 24) +#define CMD_DELAY (0x1 << 24) +#define CMD_READ 0x0 +#define CMD_READ_WORD 0x1 +#define CMD_WRITE 0x2 +#define CMD_EXTRA 0x3 + +#define CMD_MASK 0x3 +#define OFFSET_MASK GENMASK(31, 2) +#define EXTRA_CMD_MASK GENMASK(31, 24) +#define EXTRA_VALUE_MASK GENMASK(23, 0) +#define MAX_EXTRA_VALUE 0xffffff + +struct sprs_dump_data { + void *dump_vaddr; + u32 size; + u32 sprs_data_index; + u32 used_memory; +}; + +struct cpuss_regdump_data { + void *dump_vaddr; + u32 size; + u32 core_reg_num; + u32 core_reg_used_num; + u32 core_reg_end_index; + u32 sys_reg_size; + u32 used_memory; +}; + +struct cpuss_dump_data { + struct mutex mutex; + struct cpuss_regdump_data *cpussregdata; + struct sprs_dump_data *sprdata[MAX_CORE_NUM]; +}; + +struct reg_dump_data { + uint32_t magic; + uint32_t version; + uint32_t system_regs_input_index; + uint32_t regdump_output_byte_offset; +}; + +struct msm_dump_table { + uint32_t version; + uint32_t num_entries; + struct msm_dump_entry entries[MAX_NUM_ENTRIES]; +}; + +struct msm_memory_dump { + uint64_t table_phys; + struct msm_dump_table *table; +}; + +/** + * Set bit 0 if percore reg dump initialized. + * Set bit 1 if spr dump initialized. + */ +#define PERCORE_REG_INITIALIZED BIT(0) +#define SPRS_INITIALIZED BIT(1) + +static struct msm_memory_dump memdump; + +/** + * reset_sprs_dump_table - reset the sprs dump table + * + * This function calculates system_regs_input_index and + * regdump_output_byte_offset to store into the dump memory. + * It also updates members of cpudata by the parameter core_reg_num. + * + * Returns 0 on success, or -ENOMEM on error of no enough memory. + */ +static int reset_sprs_dump_table(struct device *dev) +{ + int ret = 0; + struct reg_dump_data *p; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + int i = 0; + + if (!cpudata) + return -EFAULT; + + mutex_lock(&cpudata->mutex); + + for (i = 0; i < MAX_CORE_NUM; i++) { + if (cpudata->sprdata[i]) { + cpudata->sprdata[i]->sprs_data_index = 0; + cpudata->sprdata[i]->used_memory = (SPR_DATA_HEADER_SIZE + + SPR_INPUT_DATA_TAIL_SIZE) * sizeof(uint32_t); + memset(cpudata->sprdata[i]->dump_vaddr, 0xDE, + cpudata->sprdata[i]->size); + p = (struct reg_dump_data *)cpudata->sprdata[i]->dump_vaddr; + p->magic = INPUT_DATA_BY_HLOS; + p->version = FORMAT_VERSION_1; + p->system_regs_input_index = SYSTEM_REGS_INPUT_INDEX; + p->regdump_output_byte_offset = (SPR_DATA_HEADER_SIZE + + SPR_INPUT_DATA_TAIL_SIZE) * sizeof(uint32_t); + memset((uint32_t *)cpudata->sprdata[i]->dump_vaddr + + PERCORE_INDEX, 0x0, (SPR_DATA_HEADER_TAIL_SIZE + + SPR_INPUT_DATA_TAIL_SIZE) * sizeof(uint32_t)); + } + } + + mutex_unlock(&cpudata->mutex); + return ret; +} + + +/** + * update_reg_dump_table - update the register dump table + * @core_reg_num: the number of per-core registers + * + * This function calculates system_regs_input_index and + * regdump_output_byte_offset to store into the dump memory. + * It also updates members of cpudata by the parameter core_reg_num. + * + * Returns 0 on success, or -ENOMEM on error of no enough memory. + */ +static int update_reg_dump_table(struct device *dev, u32 core_reg_num) +{ + int ret = 0; + u32 system_regs_input_index = SYSTEM_REGS_INPUT_INDEX + + core_reg_num * 2; + u32 regdump_output_byte_offset = (system_regs_input_index + 1) + * sizeof(uint32_t); + struct reg_dump_data *p; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + mutex_lock(&cpudata->mutex); + + if (regdump_output_byte_offset >= cpudata->cpussregdata->size || + regdump_output_byte_offset / sizeof(uint32_t) + < system_regs_input_index + 1) { + ret = -ENOMEM; + goto err; + } + + cpudata->cpussregdata->core_reg_num = core_reg_num; + cpudata->cpussregdata->core_reg_used_num = 0; + cpudata->cpussregdata->core_reg_end_index = PERCORE_INDEX; + cpudata->cpussregdata->sys_reg_size = 0; + cpudata->cpussregdata->used_memory = regdump_output_byte_offset; + + memset(cpudata->cpussregdata->dump_vaddr, 0xDE, cpudata->cpussregdata->size); + p = (struct reg_dump_data *)cpudata->cpussregdata->dump_vaddr; + p->magic = INPUT_DATA_BY_HLOS; + p->version = FORMAT_VERSION_2; + p->system_regs_input_index = system_regs_input_index; + p->regdump_output_byte_offset = regdump_output_byte_offset; + memset((uint32_t *)cpudata->cpussregdata->dump_vaddr + PERCORE_INDEX, 0x0, + (system_regs_input_index - PERCORE_INDEX + 1) + * sizeof(uint32_t)); + +err: + mutex_unlock(&cpudata->mutex); + return ret; +} + +static ssize_t core_reg_num_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + if (!cpudata) + return -EFAULT; + + mutex_lock(&cpudata->mutex); + + ret = scnprintf(buf, PAGE_SIZE, "%u\n", cpudata->cpussregdata->core_reg_num); + + mutex_unlock(&cpudata->mutex); + return ret; +} + +static ssize_t core_reg_num_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned int val; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + if (kstrtouint(buf, 16, &val)) + return -EINVAL; + + mutex_lock(&cpudata->mutex); + + if (cpudata->cpussregdata->core_reg_used_num || cpudata->cpussregdata->sys_reg_size) { + dev_err(dev, "Couldn't set core_reg_num, register available in list\n"); + ret = -EPERM; + goto err; + } + if (val == cpudata->cpussregdata->core_reg_num) { + mutex_unlock(&cpudata->mutex); + return size; + } + + mutex_unlock(&cpudata->mutex); + + ret = update_reg_dump_table(dev, val); + if (ret) { + dev_err(dev, "Couldn't set core_reg_num, no enough memory\n"); + return ret; + } + + return size; + +err: + mutex_unlock(&cpudata->mutex); + return ret; +} +static DEVICE_ATTR_RW(core_reg_num); + +/** + * This function shows configs of per-core and system registers. + */ +static ssize_t register_config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char local_buf[64]; + int len = 0, count = 0; + int index, system_index_start, index_end; + uint32_t register_offset, val; + uint32_t *p, cmd; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + buf[0] = '\0'; + + if (!cpudata) + return -EFAULT; + + mutex_lock(&cpudata->mutex); + + p = (uint32_t *)cpudata->cpussregdata->dump_vaddr; + + /* print per-core & system registers */ + len = scnprintf(local_buf, 64, "per-core registers:\n"); + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + + system_index_start = *(p + SYS_REG_INPUT_INDEX); + index_end = system_index_start + + cpudata->cpussregdata->sys_reg_size / sizeof(uint32_t) + 1; + for (index = PERCORE_INDEX; index < index_end;) { + if (index == system_index_start) { + len = scnprintf(local_buf, 64, "system registers:\n"); + if ((count + len) > PAGE_SIZE) { + dev_err(dev, "Couldn't write complete config\n"); + break; + } + + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + } + + register_offset = *(p + index); + if (register_offset == 0) { + index++; + continue; + } + + cmd = register_offset & CMD_MASK; + register_offset &= OFFSET_MASK; + + switch (cmd) { + case CMD_READ: + val = *(p + index + 1); + len = scnprintf(local_buf, 64, + "0x%x, 0x%x, r\n", + register_offset, val); + index += 2; + break; + case CMD_READ_WORD: + len = scnprintf(local_buf, 64, + "0x%x, 0x%x, r\n", + register_offset, 0x4); + index++; + break; + case CMD_WRITE: + val = *(p + index + 1); + len = scnprintf(local_buf, 64, + "0x%x, 0x%x, w\n", + register_offset, val); + index += 2; + break; + case CMD_EXTRA: + val = *(p + index + 1); + cmd = val & EXTRA_CMD_MASK; + val &= EXTRA_VALUE_MASK; + if (cmd == CMD_DELAY) + len = scnprintf(local_buf, 64, + "0x%x, 0x%x, d\n", + register_offset, val); + else + len = scnprintf(local_buf, 64, + "0x%x, 0x%x, R\n", + register_offset, val); + index += 2; + break; + } + + if ((count + len) > PAGE_SIZE) { + dev_err(dev, "Couldn't write complete config\n"); + break; + } + + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + } + + mutex_unlock(&cpudata->mutex); + return count; +} + +static int config_cpuss_register(struct device *dev, + uint32_t *p, uint32_t index, char cmd, + uint32_t register_offset, uint32_t val) +{ + int ret = 0; + + switch (cmd) { + case 'r': + if (val > 4) { + *(p + index) = register_offset; + *(p + index + 1) = val; + } else { + *(p + index) = register_offset | CMD_READ_WORD; + } + break; + case 'R': + if (val > MAX_EXTRA_VALUE) { + dev_err(dev, "repeat read time exceeded the limit\n"); + ret = -EINVAL; + return ret; + } + *(p + index) = register_offset | CMD_EXTRA; + *(p + index + 1) = val | CMD_REPEAT_READ; + break; + case 'd': + if (val > MAX_EXTRA_VALUE) { + dev_err(dev, "sleep time exceeded the limit\n"); + ret = -EINVAL; + return ret; + } + *(p + index) = CMD_EXTRA; + *(p + index + 1) = val | CMD_DELAY; + break; + case 'w': + *(p + index) = register_offset | CMD_WRITE; + *(p + index + 1) = val; + break; + default: + dev_err(dev, "Don't support this command\n"); + ret = -EINVAL; + } + return ret; +} +/** + * This function sets configs of per-core or system registers. + */ +static ssize_t register_config_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + uint32_t register_offset, val, reserve_size = 4, per_core = 0; + int nval; + char cmd; + uint32_t num_cores; + u32 extra_memory; + u32 used_memory; + u32 system_reg_end_index; + uint32_t *p; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + nval = sscanf(buf, "%x %x %c %u", ®ister_offset, + &val, &cmd, &per_core); + if (nval < 2) + return -EINVAL; + if (nval == 2) + cmd = 'r'; + if (per_core > 1) + return -EINVAL; + if (register_offset & 0x3) { + dev_err(dev, "Invalid address, must be 4 byte aligned\n"); + return -EINVAL; + } + + if (cmd == 'r' || cmd == 'R') { + if (val == 0) { + dev_err(dev, "Invalid length of 0\n"); + return -EINVAL; + } + if (cmd == 'r' && val & 0x3) { + dev_err(dev, "Invalid length, must be 4 byte aligned\n"); + return -EINVAL; + } + if (cmd == 'R') + reserve_size = val * 4; + else + reserve_size = val; + } + + mutex_lock(&cpudata->mutex); + + p = (uint32_t *)cpudata->cpussregdata->dump_vaddr; + if (per_core) { /* per-core register */ + if (cpudata->cpussregdata->core_reg_used_num == + cpudata->cpussregdata->core_reg_num) { + dev_err(dev, "Couldn't add per-core config, out of range\n"); + ret = -EINVAL; + goto err; + } + + num_cores = num_possible_cpus(); + extra_memory = reserve_size * num_cores; + used_memory = cpudata->cpussregdata->used_memory + extra_memory; + if (extra_memory / num_cores < reserve_size || + used_memory > cpudata->cpussregdata->size || + used_memory < cpudata->cpussregdata->used_memory) { + dev_err(dev, "Couldn't add per-core reg config, no enough memory\n"); + ret = -ENOMEM; + goto err; + } + + ret = config_cpuss_register(dev, p, cpudata->cpussregdata->core_reg_end_index, + cmd, register_offset, val); + if (ret) + goto err; + + if (cmd == 'r' && val == 4) + cpudata->cpussregdata->core_reg_end_index++; + else + cpudata->cpussregdata->core_reg_end_index += 2; + + cpudata->cpussregdata->core_reg_used_num++; + cpudata->cpussregdata->used_memory = used_memory; + } else { /* system register */ + system_reg_end_index = *(p + SYS_REG_INPUT_INDEX) + + cpudata->cpussregdata->sys_reg_size / sizeof(uint32_t); + + if (cmd == 'r' && reserve_size == 4) + extra_memory = sizeof(uint32_t) + reserve_size; + else + extra_memory = sizeof(uint32_t) * 2 + reserve_size; + + used_memory = cpudata->cpussregdata->used_memory + extra_memory; + if (extra_memory < reserve_size || + used_memory > cpudata->cpussregdata->size || + used_memory < cpudata->cpussregdata->used_memory) { + dev_err(dev, "Couldn't add system reg config, no enough memory\n"); + ret = -ENOMEM; + goto err; + } + + ret = config_cpuss_register(dev, p, system_reg_end_index, + cmd, register_offset, val); + if (ret) + goto err; + + if (cmd == 'r' && val == 4) { + system_reg_end_index++; + cpudata->cpussregdata->sys_reg_size += sizeof(uint32_t); + } else { + system_reg_end_index += 2; + cpudata->cpussregdata->sys_reg_size += sizeof(uint32_t) * 2; + } + + cpudata->cpussregdata->used_memory = used_memory; + *(p + system_reg_end_index) = 0x0; + *(p + OUTPUT_DUMP_INDEX) = (system_reg_end_index + 1) + * sizeof(uint32_t); + } + + ret = size; + +err: + mutex_unlock(&cpudata->mutex); + return ret; +} +static DEVICE_ATTR_RW(register_config); + +static ssize_t format_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct reg_dump_data *p; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + if (!cpudata) + return -EFAULT; + + mutex_lock(&cpudata->mutex); + p = (struct reg_dump_data *)cpudata->cpussregdata->dump_vaddr; + ret = scnprintf(buf, PAGE_SIZE, "%u\n", p->version); + + mutex_unlock(&cpudata->mutex); + return ret; +} +static DEVICE_ATTR_RO(format_version); +/** + * This function resets the register dump table. + */ +static ssize_t register_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned int val; + + if (kstrtouint(buf, 16, &val)) + return -EINVAL; + if (val != 1) + return -EINVAL; + + update_reg_dump_table(dev, CORE_REG_NUM_DEFAULT); + + return size; +} +static DEVICE_ATTR_WO(register_reset); + +/** + * This function shows configs of per-core spr dump. + */ +static ssize_t spr_config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char local_buf[64]; + int len = 0, count = 0; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + int i = 0, index = 0; + uint32_t *p; + + buf[0] = '\0'; + + if (!cpudata) + return -EFAULT; + + mutex_lock(&cpudata->mutex); + + len = scnprintf(local_buf, 64, "spr data list below:\n"); + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + + for (i = 0; i < MAX_CORE_NUM; i++) { + if (count > PAGE_SIZE) { + dev_err(dev, "Couldn't write complete config\n"); + break; + } + if (!cpudata->sprdata[i]) { + dev_err(dev, "SPR data pinter for CPU%d is empty\n", i); + continue; + } + p = (uint32_t *)cpudata->sprdata[i]->dump_vaddr; + len = scnprintf(local_buf, 64, "spr data for CPU[%d] below:\n", i); + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + index = 0; + while (index < cpudata->sprdata[i]->sprs_data_index) { + if (count > PAGE_SIZE) { + dev_err(dev, "Couldn't write complete config\n"); + break; + } + len = scnprintf(local_buf, 64, "%d\n", *(p + SPR_DATA_HEADER_SIZE + index)); + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + index++; + } + } + + mutex_unlock(&cpudata->mutex); + return count; +} + +/** + * This function sets configs for sprs dump. + */ +static ssize_t spr_config_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = 0; + uint32_t spr_data, cpu_num; + uint32_t index; + int nval; + uint32_t *p; + u32 reserved = 0; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + nval = sscanf(buf, "%d %d", &spr_data, &cpu_num); + if (nval != 2) + return -EINVAL; + if (!cpudata) + return -EFAULT; + + if (cpu_num >= MAX_CORE_NUM) { + dev_err(dev, "Input the wrong CPU number\n"); + return -EINVAL; + } + reserved = (SPR_INPUT_DATA_SIZE + SPR_OUTPUT_DATA_SIZE) * sizeof(uint32_t); + + mutex_lock(&cpudata->mutex); + if (cpudata->sprdata[cpu_num]) { + p = (uint32_t *)cpudata->sprdata[cpu_num]->dump_vaddr; + index = cpudata->sprdata[cpu_num]->sprs_data_index; + + if (cpudata->sprdata[cpu_num]->size > + cpudata->sprdata[cpu_num]->used_memory + reserved) { + p = (uint32_t *)cpudata->sprdata[cpu_num]->dump_vaddr; + *(p + OUTPUT_DUMP_INDEX) = (SPR_DATA_HEADER_SIZE + + index + SPR_INPUT_DATA_TAIL_SIZE + 1) * sizeof(uint32_t); + *(p + SPR_DATA_HEADER_SIZE + index) = spr_data; + *(p + SPR_DATA_HEADER_SIZE + index + 1) = 0; + cpudata->sprdata[cpu_num]->sprs_data_index++; + cpudata->sprdata[cpu_num]->used_memory = + cpudata->sprdata[cpu_num]->used_memory + reserved; + } else { + dev_err(dev, "Couldn't add SPR config, no enough memory\n"); + ret = -ENOMEM; + goto err; + } + } + ret = size; + +err: + mutex_unlock(&cpudata->mutex); + return ret; +} +static DEVICE_ATTR_RW(spr_config); + +/** + * This function resets the sprs dump table. + */ +static ssize_t sprs_register_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned int val; + + if (kstrtouint(buf, 16, &val)) + return -EINVAL; + if (val != 1) + return -EINVAL; + + reset_sprs_dump_table(dev); + + return size; +} +static DEVICE_ATTR_WO(sprs_register_reset); + +static ssize_t sprs_format_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char local_buf[64]; + int len = 0, count = 0, i = 0; + struct reg_dump_data *p; + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + buf[0] = '\0'; + + if (!cpudata) + return -EFAULT; + + mutex_lock(&cpudata->mutex); + + for (i = 0; i < MAX_CORE_NUM; i++) { + if (cpudata->sprdata[i]) { + p = (struct reg_dump_data *)cpudata->sprdata[i]->dump_vaddr; + len = scnprintf(local_buf, 64, + "SPR data format version for cpu%d is %d\n", i, p->version); + strlcat(buf, local_buf, PAGE_SIZE); + count += len; + } + } + + mutex_unlock(&cpudata->mutex); + return count; +} +static DEVICE_ATTR_RO(sprs_format_version); + + +static const struct device_attribute *register_dump_attrs[] = { + &dev_attr_core_reg_num, + &dev_attr_register_config, + &dev_attr_register_reset, + &dev_attr_format_version, + NULL, +}; + +static const struct device_attribute *spr_dump_attrs[] = { + &dev_attr_spr_config, + &dev_attr_sprs_register_reset, + &dev_attr_sprs_format_version, + NULL, +}; + +static int memory_dump_create_files(struct device *dev, + const struct device_attribute **attrs) +{ + int ret = 0; + int i, j; + + for (i = 0; attrs[i] != NULL; i++) { + ret = device_create_file(dev, attrs[i]); + if (ret) { + dev_err(dev, "Couldn't create sysfs attribute: %s\n", + attrs[i]->attr.name); + for (j = 0; j < i; j++) + device_remove_file(dev, attrs[j]); + break; + } + } + return ret; +} + +static void cpuss_create_nodes(struct platform_device *pdev, + int initialized) +{ + if (initialized & PERCORE_REG_INITIALIZED) { + if (memory_dump_create_files(&pdev->dev, register_dump_attrs)) + dev_err(&pdev->dev, "Fail to create files for cpuss register dump\n"); + } + if (initialized & SPRS_INITIALIZED) { + if (memory_dump_create_files(&pdev->dev, spr_dump_attrs)) + dev_err(&pdev->dev, "Fail to create files for spr dump\n"); + } +} + +uint32_t msm_dump_table_version(void) +{ + return MSM_DUMP_TABLE_VERSION; +} +EXPORT_SYMBOL_GPL(msm_dump_table_version); + +static int msm_dump_table_register(struct msm_dump_entry *entry) +{ + struct msm_dump_entry *e; + struct msm_dump_table *table = memdump.table; + + if (!table || table->num_entries >= MAX_NUM_ENTRIES) + return -EINVAL; + + e = &table->entries[table->num_entries]; + e->id = entry->id; + e->type = MSM_DUMP_TYPE_TABLE; + e->addr = entry->addr; + table->num_entries++; + + return 0; +} + +static struct msm_dump_table *msm_dump_get_table(enum msm_dump_table_ids id) +{ + struct msm_dump_table *table = memdump.table; + int i; + unsigned long offset; + + if (!table) { + pr_err("mem dump base table does not exist\n"); + return ERR_PTR(-EINVAL); + } + + for (i = 0; i < MAX_NUM_ENTRIES; i++) { + if (table->entries[i].id == id) + break; + } + if (i == MAX_NUM_ENTRIES || !table->entries[i].addr) { + pr_err("mem dump base table entry %d invalid\n", id); + return ERR_PTR(-EINVAL); + } + + offset = table->entries[i].addr - memdump.table_phys; + /* Get the apps table pointer */ + table = (void *)memdump.table + offset; + + return table; +} + +static int register_dump_table_entry(enum msm_dump_table_ids id, + struct msm_dump_entry *entry) +{ + struct msm_dump_entry *e; + struct msm_dump_table *table; + + table = msm_dump_get_table(id); + if (IS_ERR(table)) + return PTR_ERR(table); + + if (!table || table->num_entries >= MAX_NUM_ENTRIES) + return -EINVAL; + + e = &table->entries[table->num_entries]; + e->id = entry->id; + e->type = MSM_DUMP_TYPE_DATA; + e->addr = entry->addr; + table->num_entries++; + + return 0; +} + +/** + * msm_dump_data_register_nominidump - register to dump data framework + * @id: ID of the dump table. + * @entry: dump entry to be registered + * This api will register the entry passed to dump table only + */ +int msm_dump_data_register_nominidump(enum msm_dump_table_ids id, + struct msm_dump_entry *entry) +{ + return register_dump_table_entry(id, entry); +} +EXPORT_SYMBOL_GPL(msm_dump_data_register_nominidump); + +#define MSM_DUMP_TOTAL_SIZE_OFFSET 0x724 +static int init_memdump_imem_area(size_t size) +{ + struct device_node *np; + void __iomem *imem_base; + + np = of_find_compatible_node(NULL, NULL, + "qcom,msm-imem-mem-dump-table"); + if (!np) { + pr_err("mem dump base table DT node does not exist\n"); + return -ENODEV; + } + + imem_base = of_iomap(np, 0); + if (!imem_base) { + pr_err("mem dump base table imem offset mapping failed\n"); + return -ENOMEM; + } + + memcpy_toio(imem_base, &memdump.table_phys, + sizeof(memdump.table_phys)); + memcpy_toio(imem_base + MSM_DUMP_TOTAL_SIZE_OFFSET, + &size, sizeof(size_t)); + + /* Ensure write to imem_base is complete before unmapping */ + mb(); + pr_info("MSM Memory Dump base table set up in IMEM\n"); + + iounmap(imem_base); + return 0; +} + +static int init_memory_dump(void *dump_vaddr, phys_addr_t phys_addr) +{ + struct msm_dump_table *table; + struct msm_dump_entry entry; + int ret; + + memdump.table = dump_vaddr; + memdump.table->version = MSM_DUMP_TABLE_VERSION; + memdump.table_phys = phys_addr; + dump_vaddr += sizeof(*table); + phys_addr += sizeof(*table); + table = dump_vaddr; + table->version = MSM_DUMP_TABLE_VERSION; + entry.id = MSM_DUMP_TABLE_APPS; + entry.addr = phys_addr; + ret = msm_dump_table_register(&entry); + if (ret) { + pr_err("mem dump apps data table register failed\n"); + return ret; + } + pr_info("MSM Memory Dump apps data table set up\n"); + + return 0; +} + +static int mem_dump_reserve_mem(struct device *dev) +{ + struct device_node *mem_node; + int ret; + + mem_node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (mem_node) { + ret = of_reserved_mem_device_init_by_idx(dev, + dev->of_node, 0); + of_node_put(dev->of_node); + if (ret) { + dev_err(dev, + "Failed to initialize reserved mem, ret %d\n", + ret); + return ret; + } + } + return 0; +} + +static int cpuss_regdump_init(struct device *dev, + void *dump_vaddr, u32 size) +{ + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + + cpudata->cpussregdata = devm_kzalloc(dev, + sizeof(struct cpuss_regdump_data), GFP_KERNEL); + + if (cpudata->cpussregdata) { + cpudata->cpussregdata->dump_vaddr = dump_vaddr; + cpudata->cpussregdata->size = size; + return 0; + } + return -ENOMEM; +} + +static int sprs_dump_init(struct device *dev, + void *dump_vaddr, u32 size, u32 id) +{ + struct cpuss_dump_data *cpudata = dev_get_drvdata(dev); + int core_num = 0; + + core_num = id - SPR_DUMP_CPU0; + + cpudata->sprdata[core_num] = devm_kzalloc(dev, + sizeof(struct sprs_dump_data), GFP_KERNEL); + if (cpudata->sprdata[core_num]) { + cpudata->sprdata[core_num]->dump_vaddr = dump_vaddr; + cpudata->sprdata[core_num]->size = size; + return 0; + } + return -ENOMEM; +} + +static int cpuss_dump_init(struct platform_device *pdev, + void *dump_vaddr, u32 size, u32 id) +{ + struct cpuss_dump_data *cpudata = dev_get_drvdata(&pdev->dev); + static int initialized; + + if (!cpudata) { + cpudata = devm_kzalloc(&pdev->dev, + sizeof(struct cpuss_dump_data), GFP_KERNEL); + if (cpudata) { + mutex_init(&cpudata->mutex); + platform_set_drvdata(pdev, cpudata); + } else + return initialized; + } + + if (id == CPUSS_REGDUMP) { + if (!cpuss_regdump_init(&pdev->dev, dump_vaddr, size)) + initialized |= PERCORE_REG_INITIALIZED; + } else { + if (!sprs_dump_init(&pdev->dev, dump_vaddr, size, id)) + initialized |= SPRS_INITIALIZED; + } + + return initialized; +} + +#define MSM_DUMP_DATA_SIZE sizeof(struct msm_dump_data) +static int mem_dump_alloc(struct platform_device *pdev) +{ + struct device_node *child_node; + const struct device_node *node = pdev->dev.of_node; + struct msm_dump_data *dump_data; + struct msm_dump_entry dump_entry; + size_t total_size; + u32 size, id; + int ret, no_of_nodes; + dma_addr_t dma_handle; + phys_addr_t phys_addr; + struct sg_table mem_dump_sgt; + void *dump_vaddr; + u64 shm_bridge_handle; + int initialized = 0; + + if (mem_dump_reserve_mem(&pdev->dev) != 0) + return -ENOMEM; + total_size = size = ret = no_of_nodes = 0; + /* For dump table registration with IMEM */ + total_size = sizeof(struct msm_dump_table) * 2; + for_each_available_child_of_node(node, child_node) { + ret = of_property_read_u32(child_node, "qcom,dump-size", &size); + if (ret) { + dev_err(&pdev->dev, "Unable to find size for %s\n", + child_node->name); + continue; + } + + total_size += size; + no_of_nodes++; + } + + total_size += (MSM_DUMP_DATA_SIZE * no_of_nodes); + total_size = ALIGN(total_size, SZ_4K); + dump_vaddr = dmam_alloc_coherent(&pdev->dev, total_size, + &dma_handle, GFP_KERNEL); + if (!dump_vaddr) + return -ENOMEM; + + dma_get_sgtable(&pdev->dev, &mem_dump_sgt, dump_vaddr, + dma_handle, total_size); + phys_addr = page_to_phys(sg_page(mem_dump_sgt.sgl)); + sg_free_table(&mem_dump_sgt); + + memset(dump_vaddr, 0x0, total_size); + ret = qcom_tzmem_shm_bridge_create(phys_addr, total_size, &shm_bridge_handle); + if (ret) { + dev_err(&pdev->dev, "Failed to create shm bridge.ret=%d\n", ret); + return ret; + } + + ret = init_memory_dump(dump_vaddr, phys_addr); + if (ret) { + dev_err(&pdev->dev, "Memory Dump table set up is failed\n"); + qcom_tzmem_shm_bridge_delete(shm_bridge_handle); + return ret; + } + + ret = init_memdump_imem_area(total_size); + if (ret) { + qcom_tzmem_shm_bridge_delete(shm_bridge_handle); + return ret; + } + + dump_vaddr += (sizeof(struct msm_dump_table) * 2); + phys_addr += (sizeof(struct msm_dump_table) * 2); + for_each_available_child_of_node(node, child_node) { + ret = of_property_read_u32(child_node, "qcom,dump-size", &size); + if (ret) + continue; + + ret = of_property_read_u32(child_node, "qcom,dump-id", &id); + if (ret) { + dev_err(&pdev->dev, "Unable to find id for %s\n", + child_node->name); + continue; + } + + dump_data = dump_vaddr; + dump_data->addr = phys_addr + MSM_DUMP_DATA_SIZE; + dump_data->len = size; + dump_entry.id = id; + strscpy(dump_data->name, child_node->name, + sizeof(dump_data->name)); + dump_entry.addr = phys_addr; + ret = msm_dump_data_register_nominidump(MSM_DUMP_TABLE_APPS, + &dump_entry); + if (ret) + dev_err(&pdev->dev, "Data dump setup failed, id = %d\n", + id); + + if ((id == CPUSS_REGDUMP) || + ((id >= SPR_DUMP_CPU0) && (id <= SPR_DUMP_CPU7))) + initialized = cpuss_dump_init(pdev, + (dump_vaddr + MSM_DUMP_DATA_SIZE), size, id); + + dump_vaddr += (size + MSM_DUMP_DATA_SIZE); + phys_addr += (size + MSM_DUMP_DATA_SIZE); + } + + cpuss_create_nodes(pdev, initialized); + + if (initialized & SPRS_INITIALIZED) + reset_sprs_dump_table(&pdev->dev); + + return ret; +} + +static int mem_dump_probe(struct platform_device *pdev) +{ + int ret; + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (ret < 0) + return ret; + + ret = mem_dump_alloc(pdev); + return ret; +} + +static const struct of_device_id mem_dump_match_table[] = { + {.compatible = "qcom,mem-dump",}, + {} +}; + +static struct platform_driver mem_dump_driver = { + .probe = mem_dump_probe, + .driver = { + .name = "msm_mem_dump", + .of_match_table = mem_dump_match_table, + }, +}; + +module_platform_driver(mem_dump_driver); + +MODULE_DESCRIPTION("Memory Dump V2 Driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/firmware/qcom/memory_dump.h b/include/linux/firmware/qcom/memory_dump.h new file mode 100644 index 0000000000000..ebb7c89d2f243 --- /dev/null +++ b/include/linux/firmware/qcom/memory_dump.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012, 2014-2017, 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __MSM_MEMORY_DUMP_H +#define __MSM_MEMORY_DUMP_H + +#include +#include + +enum dump_client_type { + MSM_CPU_CTXT = 0, + MSM_L1_CACHE, + MSM_L2_CACHE, + MSM_OCMEM, + MSM_TMC_ETFETB, + MSM_ETM0_REG, + MSM_ETM1_REG, + MSM_ETM2_REG, + MSM_ETM3_REG, + MSM_TMC0_REG, /* TMC_ETR */ + MSM_TMC1_REG, /* TMC_ETF */ + MSM_LOG_BUF, + MSM_LOG_BUF_FIRST_IDX, + MAX_NUM_CLIENTS, +}; + +struct msm_client_dump { + enum dump_client_type id; + unsigned long start_addr; + unsigned long end_addr; +}; + +#ifdef CONFIG_QCOM_MEMORY_DUMP +extern int msm_dump_tbl_register(struct msm_client_dump *client_entry); +#else +static inline int msm_dump_tbl_register(struct msm_client_dump *entry) +{ + return -EIO; +} +#endif + + +#if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) +extern uint32_t msm_dump_table_version(void); +#else +static inline uint32_t msm_dump_table_version(void) +{ + return 0; +} +#endif + +#define MSM_DUMP_MAKE_VERSION(ma, mi) ((ma << 20) | mi) +#define MSM_DUMP_MAJOR(val) (val >> 20) +#define MSM_DUMP_MINOR(val) (val & 0xFFFFF) + + +#define MAX_NUM_ENTRIES 0x150 + +enum msm_dump_data_ids { + MSM_DUMP_DATA_CPU_CTX = 0x00, + MSM_DUMP_DATA_L1_INST_CACHE = 0x60, + MSM_DUMP_DATA_L1_DATA_CACHE = 0x80, + MSM_DUMP_DATA_ETM_REG = 0xA0, + MSM_DUMP_DATA_L2_CACHE = 0xC0, + MSM_DUMP_DATA_L3_CACHE = 0xD0, + MSM_DUMP_DATA_OCMEM = 0xE0, + MSM_DUMP_DATA_CNSS_WLAN = 0xE1, + MSM_DUMP_DATA_WIGIG = 0xE2, + MSM_DUMP_DATA_PMIC = 0xE4, + MSM_DUMP_DATA_DBGUI_REG = 0xE5, + MSM_DUMP_DATA_DCC_REG = 0xE6, + MSM_DUMP_DATA_DCC_SRAM = 0xE7, + MSM_DUMP_DATA_MISC = 0xE8, + MSM_DUMP_DATA_VSENSE = 0xE9, + MSM_DUMP_DATA_RPM = 0xEA, + MSM_DUMP_DATA_SCANDUMP = 0xEB, + MSM_DUMP_DATA_RPMH = 0xEC, + MSM_DUMP_DATA_TMC_ETF = 0xF0, + MSM_DUMP_DATA_TMC_ETF_SWAO = 0xF1, + MSM_DUMP_DATA_TMC_REG = 0x100, + MSM_DUMP_DATA_TMC_ETF_SWAO_REG = 0x102, + MSM_DUMP_DATA_LOG_BUF = 0x110, + MSM_DUMP_DATA_LOG_BUF_FIRST_IDX = 0x111, + MSM_DUMP_DATA_SCANDUMP_PER_CPU = 0x130, + MSM_DUMP_DATA_LLCC_PER_INSTANCE = 0x140, + MSM_DUMP_DATA_MAX = MAX_NUM_ENTRIES, +}; + +enum msm_dump_table_ids { + MSM_DUMP_TABLE_APPS, + MSM_DUMP_TABLE_MAX = MAX_NUM_ENTRIES, +}; + +enum msm_dump_type { + MSM_DUMP_TYPE_DATA, + MSM_DUMP_TYPE_TABLE, +}; + +struct msm_dump_data { + uint32_t version; + uint32_t magic; + char name[32]; + uint64_t addr; + uint64_t len; + uint32_t reserved; +}; + +struct msm_dump_entry { + uint32_t id; + char name[32]; + uint32_t type; + uint64_t addr; +}; + +#if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) +extern int msm_dump_data_register(enum msm_dump_table_ids id, + struct msm_dump_entry *entry); +extern int msm_dump_data_register_nominidump(enum msm_dump_table_ids id, + struct msm_dump_entry *entry); +#else +static inline int msm_dump_data_register(enum msm_dump_table_ids id, + struct msm_dump_entry *entry) +{ + return -EINVAL; +} +static inline int msm_dump_data_register_nominidump(enum msm_dump_table_ids id, + struct msm_dump_entry *entry) +{ + return -EINVAL; +} +#endif + +#endif From 04927aa32c487110a30ff2d98de7509725584884 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 12 Jan 2026 11:30:00 +0800 Subject: [PATCH 418/438] QCLINUX: mem-dump: add memory dump device driver Create memory dump device driver for matching the memory dump v2 driver without DT configuration. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom_debug.config | 1 + drivers/firmware/qcom/Kconfig | 6 + drivers/firmware/qcom/Makefile | 1 + drivers/firmware/qcom/memory_dump_dev.c | 379 ++++++++++++++++++++++ drivers/firmware/qcom/memory_dump_v2.c | 67 ++-- include/linux/firmware/qcom/memory_dump.h | 13 + 6 files changed, 420 insertions(+), 47 deletions(-) create mode 100644 drivers/firmware/qcom/memory_dump_dev.c diff --git a/arch/arm64/configs/qcom_debug.config b/arch/arm64/configs/qcom_debug.config index 2e85e8df0469b..d50f78f3a3ea2 100644 --- a/arch/arm64/configs/qcom_debug.config +++ b/arch/arm64/configs/qcom_debug.config @@ -1,3 +1,4 @@ CONFIG_QCOM_DCC=m CONFIG_QCOM_DCC_DEV=m CONFIG_QCOM_MEMORY_DUMP_V2=m +CONFIG_QCOM_MEMORY_DUMP_DEV=m diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig index 531c6d2598ce0..39f63ef92e01a 100644 --- a/drivers/firmware/qcom/Kconfig +++ b/drivers/firmware/qcom/Kconfig @@ -83,4 +83,10 @@ config QCOM_MEMORY_DUMP_V2 of deadlocks or cpu hangs these dump regions are captured to give a snapshot of the system at the time of the crash. +config QCOM_MEMORY_DUMP_DEV + tristate "QCOM Memory Dump V2 device stub" + depends on QCOM_MEMORY_DUMP_V2 + help + Device stub for memory dump V2 driver. + endmenu diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile index c5e17ba255937..01b293cae79ed 100644 --- a/drivers/firmware/qcom/Makefile +++ b/drivers/firmware/qcom/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_QCOM_TZMEM) += qcom_tzmem.o obj-$(CONFIG_QCOM_QSEECOM) += qcom_qseecom.o obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o obj-$(CONFIG_QCOM_MEMORY_DUMP_V2) += memory_dump_v2.o +obj-$(CONFIG_QCOM_MEMORY_DUMP_DEV) += memory_dump_dev.o diff --git a/drivers/firmware/qcom/memory_dump_dev.c b/drivers/firmware/qcom/memory_dump_dev.c new file mode 100644 index 0000000000000..556ebafae5280 --- /dev/null +++ b/drivers/firmware/qcom/memory_dump_dev.c @@ -0,0 +1,379 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#define DEV_NAME "msm_mem_dump" + +static struct platform_device *mem_dump_pdev; + +enum dump_ids { + C0_CONTEXT = 0x0, + C100_CONTEXT = 0x1, + C200_CONTEXT = 0x2, + C300_CONTEXT = 0x3, + C400_CONTEXT = 0x4, + C500_CONTEXT = 0x5, + C600_CONTEXT = 0x6, + C700_CONTEXT = 0x7, + L1_ITLB10000 = 0x24, + L1_ITLB10100 = 0x25, + L1_ITLB10200 = 0x26, + L1_ITLB10300 = 0x27, + L1_DTLB10000 = 0x44, + L1_DTLB10100 = 0x45, + L1_DTLB10200 = 0x46, + L1_DTLB10300 = 0x47, + L1_ICACHE0 = 0x60, + L1_ICACHE100 = 0x61, + L1_ICACHE200 = 0x62, + L1_ICACHE300 = 0x63, + L1_ICACHE10000 = 0x64, + L1_ICACHE10100 = 0x65, + L1_ICACHE10200 = 0x66, + L1_ICACHE10300 = 0x67, + L1_DCACHE0 = 0x80, + L1_DCACHE100 = 0x81, + L1_DCACHE200 = 0x82, + L1_DCACHE300 = 0x83, + L1_DCACHE10000 = 0x84, + L1_DCACHE10100 = 0x85, + L1_DCACHE10200 = 0x86, + L1_DCACHE10300 = 0x87, + L2_CACHE10000 = 0xc4, + L2_CACHE10100 = 0xc5, + L2_CACHE10200 = 0xc6, + L2_CACHE10300 = 0xc7, + PMIC = 0xe4, + MISC_DATA = 0xe8, + RPM_SW = 0xea, + RPMH = 0xec, + CPUSS_REG = 0xef, + TMC_ETF = 0xf0, + ETF_SWAO = 0xf1, + ETF_LPASS = 0xf4, + FCM = 0xee, + ETR_REG = 0x100, + ETF_REG = 0x101, + ETFSWAO_REG = 0x102, + ETFLPASS_REG = 0x104, + L2_TLB0 = 0x120, + L2_TLB100 = 0x121, + L2_TLB200 = 0x122, + L2_TLB300 = 0x123, + L2_TLB10000 = 0x124, + L2_TLB10100 = 0x125, + L2_TLB10200 = 0x126, + L2_TLB10300 = 0x127, + C0_SCANDUMP = 0x130, + C100_SCANDUMP = 0x131, + C200_SCANDUMP = 0x132, + C300_SCANDUMP = 0x133, + C10000_SCANDUMP = 0x134, + C10100_SCANDUMP = 0x135, + C10200_SCANDUMP = 0x136, + C10300_SCANDUMP = 0x137, + LLCC1_D_CACHE = 0x140, + LLCC2_D_CACHE = 0x141, + MHM_SCAN = 0x161, + GEMNOC = 0x162, + OSM_REG = 0x163, + PCU_REG = 0x164, + FSM_DATA = 0x165, +}; + +static const struct dump_item lemans_items[] = { + { C0_CONTEXT, 0x800, "c0-context" }, + { C0_SCANDUMP, 0x40000, "c0-scandump" }, + { C100_CONTEXT, 0x800, "c100-context" }, + { C100_SCANDUMP, 0x40000, "c100-scandump" }, + { C200_CONTEXT, 0x800, "c200-context" }, + { C200_SCANDUMP, 0x40000, "c200-scandump" }, + { C300_CONTEXT, 0x800, "c300-context" }, + { C300_SCANDUMP, 0x40000, "c300-scandump" }, + { C400_CONTEXT, 0x800, "c400-context" }, + { C500_CONTEXT, 0x800, "c500-context" }, + { C600_CONTEXT, 0x800, "c600-context" }, + { C700_CONTEXT, 0x800, "c700-context" }, + { C10000_SCANDUMP, 0x40000, "c10000-scandump" }, + { C10100_SCANDUMP, 0x40000, "c10100-scandump" }, + { C10200_SCANDUMP, 0x40000, "c10200-scandump" }, + { C10300_SCANDUMP, 0x40000, "c10300-scandump" }, + { CPUSS_REG, 0x20000, "cpuss-reg" }, + { ETF_SWAO, 0x10000, "etf-swao" }, + { ETFSWAO_REG, 0x1000, "etfswao-reg" }, + { ETR_REG, 0x1000, "etr-reg" }, + { FCM, 0x8400, "fcm" }, + { L1_DCACHE0, 0x12100, "l1-dcache0" }, + { L1_DCACHE100, 0x12100, "l1-dcache100" }, + { L1_DCACHE200, 0x12100, "l1-dcache200" }, + { L1_DCACHE300, 0x12100, "l1-dcache300" }, + { L1_DCACHE10000, 0x12100, "l1-dcache10000" }, + { L1_DCACHE10100, 0x12100, "l1-dcache10100" }, + { L1_DCACHE10200, 0x12100, "l1-dcache10200" }, + { L1_DCACHE10300, 0x12100, "l1-dcache10300" }, + { L1_DTLB10000, 0x300, "l1-dtlb10000" }, + { L1_DTLB10100, 0x300, "l1-dtlb10100" }, + { L1_DTLB10200, 0x300, "l1-dtlb10200" }, + { L1_DTLB10300, 0x300, "l1-dtlb10300" }, + { L1_ICACHE0, 0x26100, "l1-icache0" }, + { L1_ICACHE100, 0x26100, "l1-icache100" }, + { L1_ICACHE200, 0x26100, "l1-icache200" }, + { L1_ICACHE300, 0x26100, "l1-icache300" }, + { L1_ICACHE10000, 0x26100, "l1-icache10000" }, + { L1_ICACHE10100, 0x26100, "l1-icache10100" }, + { L1_ICACHE10200, 0x26100, "l1-icache10200" }, + { L1_ICACHE10300, 0x26100, "l1-icache10300" }, + { L1_ITLB10000, 0x300, "l1-itlb10000" }, + { L1_ITLB10100, 0x300, "l1-itlb10100" }, + { L1_ITLB10200, 0x300, "l1-itlb10200" }, + { L1_ITLB10300, 0x300, "l1-itlb10300" }, + { L2_CACHE10000, 0x90100, "l2-cache10000" }, + { L2_CACHE10100, 0x90100, "l2-cache10100" }, + { L2_CACHE10200, 0x90100, "l2-cache10200" }, + { L2_CACHE10300, 0x90100, "l2-cache10300" }, + { L2_TLB0, 0x6100, "l2-tlb0" }, + { L2_TLB100, 0x6100, "l2-tlb100" }, + { L2_TLB200, 0x6100, "l2-tlb200" }, + { L2_TLB300, 0x6100, "l2-tlb300" }, + { L2_TLB10000, 0x6100, "l2-tlb10000" }, + { L2_TLB10100, 0x6100, "l2-tlb10100" }, + { L2_TLB10200, 0x6100, "l2-tlb10200" }, + { L2_TLB10300, 0x6100, "l2-tlb10300" }, + { MISC_DATA, 0x1000, "misc-data" }, + { PMIC, 0x80000, "pmic" }, + { RPM_SW, 0x28000, "rpm-sw" }, + { RPMH, 0x2000000, "rpmh" }, +}; + +static const struct dump_item talos_items[] = { + { C0_CONTEXT, 0x800, "c0-context" }, + { C100_CONTEXT, 0x800, "c100-context" }, + { C200_CONTEXT, 0x800, "c200-context" }, + { C300_CONTEXT, 0x800, "c300-context" }, + { C400_CONTEXT, 0x800, "c400-context" }, + { C500_CONTEXT, 0x800, "c500-context" }, + { C600_CONTEXT, 0x800, "c600-context" }, + { C700_CONTEXT, 0x800, "c700-context" }, + { RPMH, 0x2000000, "rpmh" }, + { RPM_SW, 0x28000, "rpm-sw" }, + { PMIC, 0x10000, "pmic" }, + { FCM, 0x8400, "fcm" }, + { TMC_ETF, 0x8000, "tmc-etf" }, + { ETF_SWAO, 0x8000, "etf-swao" }, + { ETR_REG, 0x1000, "etr-reg" }, + { ETF_REG, 0x1000, "etf-reg" }, + { ETFSWAO_REG, 0x1000, "etfswao-reg" }, + { MISC_DATA, 0x1000, "misc-data" }, + { L1_ICACHE0, 0x8800, "l1-icache0" }, + { L1_ICACHE100, 0x8800, "l1-icache100" }, + { L1_ICACHE200, 0x8800, "l1-icache200" }, + { L1_ICACHE300, 0x8800, "l1-icache300" }, + { L1_ICACHE10000, 0x8800, "l1-icache400" }, + { L1_ICACHE10100, 0x8800, "l1-icache500" }, + { L1_ICACHE10200, 0x11000, "l1-icache600" }, + { L1_ICACHE10300, 0x11000, "l1-icache700" }, + { L1_DCACHE0, 0x9000, "l1-dcache0" }, + { L1_DCACHE100, 0x9000, "l1-dcache100" }, + { L1_DCACHE200, 0x9000, "l1-dcache200" }, + { L1_DCACHE300, 0x9000, "l1-dcache300" }, + { L1_DCACHE10000, 0x9000, "l1-dcache400" }, + { L1_DCACHE10100, 0x9000, "l1-dcache500" }, + { L1_DCACHE10200, 0x12000, "l1-dcache600" }, + { L1_DCACHE10300, 0x12000, "l1-dcache700" }, + { L1_ITLB10200, 0x300, "l1-itlb600" }, + { L1_ITLB10300, 0x300, "l1-itlb700" }, + { L1_DTLB10200, 0x480, "l1-dtlb600" }, + { L1_DTLB10300, 0x480, "l1-dtlb700" }, + { L2_CACHE10200, 0x48000, "l2-cache600" }, + { L2_CACHE10300, 0x48000, "l2-cache700" }, + { L2_TLB0, 0x5000, "l2-tlb0" }, + { L2_TLB100, 0x5000, "l2-tlb100" }, + { L2_TLB200, 0x5000, "l2-tlb200" }, + { L2_TLB300, 0x5000, "l2-tlb300" }, + { L2_TLB10000, 0x5000, "l2-tlb400" }, + { L2_TLB10100, 0x5000, "l2-tlb500" }, + { L2_TLB10200, 0x7800, "l2-tlb600" }, + { L2_TLB10300, 0x7800, "l2-tlb700" }, + { LLCC1_D_CACHE, 0x6c000, "llcc1-d-cache" }, +}; + +static const struct dump_item kodiak_items[] = { + { C0_CONTEXT, 0x800, "c0-context" }, + { C0_SCANDUMP, 0x10100, "c0-scandump" }, + { C100_CONTEXT, 0x800, "c100-context" }, + { C100_SCANDUMP, 0x10100, "c100-scandump" }, + { C200_CONTEXT, 0x800, "c200-context" }, + { C200_SCANDUMP, 0x10100, "c200-scandump" }, + { C300_CONTEXT, 0x800, "c300-context" }, + { C300_SCANDUMP, 0x10100, "c300-scandump" }, + { C400_CONTEXT, 0x800, "c400-context" }, + { C10000_SCANDUMP, 0x40000, "c400-scandump" }, + { C500_CONTEXT, 0x800, "c500-context" }, + { C10100_SCANDUMP, 0x40000, "c500-scandump" }, + { C600_CONTEXT, 0x800, "c600-context" }, + { C10200_SCANDUMP, 0x40000, "c600-scandump" }, + { C700_CONTEXT, 0x800, "c700-context" }, + { C10300_SCANDUMP, 0x40000, "c700-scandump" }, + { CPUSS_REG, 0x30000, "cpuss-reg" }, + { ETF_LPASS, 0x4000, "etf-lpass" }, + { ETFLPASS_REG, 0x1000, "etflpass-reg" }, + { ETF_SWAO, 0x10000, "etf-swao" }, + { ETFSWAO_REG, 0x1000, "etfswao-reg" }, + { ETR_REG, 0x1000, "etr-reg" }, + { FCM, 0x8400, "fcm" }, + { FSM_DATA, 0x400, "fsm-data" }, + { GEMNOC, 0x100000, "gemnoc" }, + { L1_DCACHE0, 0x9100, "l1-dcache0" }, + { L1_DCACHE100, 0x9100, "l1-dcache100" }, + { L1_DCACHE200, 0x9100, "l1-dcache200" }, + { L1_DCACHE300, 0x9100, "l1-dcache300" }, + { L1_DCACHE10000, 0x9100, "l1-dcache400" }, + { L1_DCACHE10100, 0x9100, "l1-dcache500" }, + { L1_DCACHE10200, 0x9100, "l1-dcache600" }, + { L1_DCACHE10300, 0x12100, "l1-dcache700" }, + { L1_DTLB10000, 0x300, "l1-dtlb400" }, + { L1_DTLB10100, 0x300, "l1-dtlb500" }, + { L1_DTLB10200, 0x300, "l1-dtlb600" }, + { L1_DTLB10300, 0x3a0, "l1-dtlb700" }, + { L1_ICACHE0, 0x10900, "l1-icache0" }, + { L1_ICACHE100, 0x10900, "l1-icache100" }, + { L1_ICACHE200, 0x10900, "l1-icache200" }, + { L1_ICACHE300, 0x10900, "l1-icache300" }, + { L1_ICACHE10000, 0x15100, "l1-icache400" }, + { L1_ICACHE10100, 0x15100, "l1-icache500" }, + { L1_ICACHE10200, 0x15100, "l1-icache600" }, + { L1_ICACHE10300, 0x32100, "l1-icache700" }, + { L1_ITLB10000, 0x300, "l1-itlb400" }, + { L1_ITLB10100, 0x300, "l1-itlb500" }, + { L1_ITLB10200, 0x300, "l1-itlb600" }, + { L1_ITLB10300, 0x400, "l1-itlb700" }, + { L2_CACHE10000, 0x90100, "l2-cache400" }, + { L2_CACHE10100, 0x90100, "l2-cache500" }, + { L2_CACHE10200, 0x90100, "l2-cache600" }, + { L2_CACHE10300, 0x120100, "l2-cache700" }, + { L2_TLB0, 0x5b00, "l2-tlb0" }, + { L2_TLB100, 0x5b00, "l2-tlb100" }, + { L2_TLB200, 0x5b00, "l2-tlb200" }, + { L2_TLB300, 0x5b00, "l2-tlb300" }, + { L2_TLB10000, 0x6100, "l2-tlb400" }, + { L2_TLB10100, 0x6100, "l2-tlb500" }, + { L2_TLB10200, 0x6100, "l2-tlb600" }, + { L2_TLB10300, 0xc100, "l2-tlb700" }, + { LLCC1_D_CACHE, 0x1141c0, "llcc1-d-cache" }, + { LLCC2_D_CACHE, 0x1141c0, "llcc2-d-cache" }, + { MHM_SCAN, 0x20000, "mhm-scan" }, + { MISC_DATA, 0x1000, "misc-data" }, + { OSM_REG, 0x400, "osm-reg" }, + { PCU_REG, 0x400, "pcu-reg" }, + { PMIC, 0x200000, "pmic" }, + { RPM_SW, 0x28000, "rpm-sw" }, + { RPMH, 0x2000000, "rpmh" }, +}; + +static const struct dump_table lemans_dump_table = { + .items = lemans_items, + .num_of_items = ARRAY_SIZE(lemans_items), + .imem_base = 0x146d8010, + .imem_size = 0x8, +}; + +static const struct dump_table talos_dump_table = { + .items = talos_items, + .num_of_items = ARRAY_SIZE(lemans_items), + .imem_base = 0x146aa010, + .imem_size = 0x8, +}; + +static const struct dump_table kodiak_dump_table = { + .items = kodiak_items, + .num_of_items = ARRAY_SIZE(kodiak_items), + .imem_base = 0x146aa010, + .imem_size = 0x8, +}; + +static int __init mem_dump_dev_init(void) +{ + int ret; + u32 soc_id; + + mem_dump_pdev = platform_device_alloc(DEV_NAME, -1); + if (!mem_dump_pdev) + return -ENOMEM; + + ret = qcom_smem_get_soc_id(&soc_id); + if (ret) + goto fail; + + switch (soc_id) { + case 377: + case 380: + case 384: + case 401: + case 406: + case 680: + ret = platform_device_add_data(mem_dump_pdev, + &talos_dump_table, sizeof(talos_dump_table)); + if (ret) + goto fail; + + break; + case 534: + case 606: + case 667: + case 674: + case 675: + case 676: + ret = platform_device_add_data(mem_dump_pdev, + &lemans_dump_table, sizeof(lemans_dump_table)); + if (ret) + goto fail; + + break; + case 475: + case 497: + case 498: + case 515: + ret = platform_device_add_data(mem_dump_pdev, + &kodiak_dump_table, sizeof(kodiak_dump_table)); + if (ret) + goto fail; + + break; + default: + dev_err(&mem_dump_pdev->dev, "Invalid SoC ID\n"); + ret = -EINVAL; + goto fail; + } + + ret = platform_device_add(mem_dump_pdev); + if (ret) + goto fail; + + dev_info(&mem_dump_pdev->dev, "Register platform device successfully\n"); + + return 0; + +fail: + dev_err(&mem_dump_pdev->dev, + "Failed to register memory dump platform device\n"); + platform_device_put(mem_dump_pdev); + + return ret; +} + +static void __exit mem_dump_dev_exit(void) +{ + platform_device_unregister(mem_dump_pdev); +} + +module_init(mem_dump_dev_init); +module_exit(mem_dump_dev_exit); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm Technologies Inc. Memory Dump driver V2, device stub"); diff --git a/drivers/firmware/qcom/memory_dump_v2.c b/drivers/firmware/qcom/memory_dump_v2.c index baf4c980f39fb..470d6047ee656 100644 --- a/drivers/firmware/qcom/memory_dump_v2.c +++ b/drivers/firmware/qcom/memory_dump_v2.c @@ -865,19 +865,11 @@ int msm_dump_data_register_nominidump(enum msm_dump_table_ids id, EXPORT_SYMBOL_GPL(msm_dump_data_register_nominidump); #define MSM_DUMP_TOTAL_SIZE_OFFSET 0x724 -static int init_memdump_imem_area(size_t size) +static int init_memdump_imem_area(const struct dump_table *table, size_t size) { - struct device_node *np; void __iomem *imem_base; - np = of_find_compatible_node(NULL, NULL, - "qcom,msm-imem-mem-dump-table"); - if (!np) { - pr_err("mem dump base table DT node does not exist\n"); - return -ENODEV; - } - - imem_base = of_iomap(np, 0); + imem_base = ioremap(table->imem_base, table->imem_size); if (!imem_base) { pr_err("mem dump base table imem offset mapping failed\n"); return -ENOMEM; @@ -924,13 +916,17 @@ static int init_memory_dump(void *dump_vaddr, phys_addr_t phys_addr) static int mem_dump_reserve_mem(struct device *dev) { struct device_node *mem_node; + struct reserved_mem *rmem; int ret; - mem_node = of_parse_phandle(dev->of_node, "memory-region", 0); + mem_node = of_find_node_by_path("/reserved-memory/mem-dump-region"); if (mem_node) { - ret = of_reserved_mem_device_init_by_idx(dev, - dev->of_node, 0); - of_node_put(dev->of_node); + rmem = of_reserved_mem_lookup(mem_node); + of_node_put(mem_node); + if (!rmem || !rmem->ops || !rmem->ops->device_init) + return -EINVAL; + + ret = rmem->ops->device_init(rmem, dev); if (ret) { dev_err(dev, "Failed to initialize reserved mem, ret %d\n", @@ -1005,34 +1001,26 @@ static int cpuss_dump_init(struct platform_device *pdev, #define MSM_DUMP_DATA_SIZE sizeof(struct msm_dump_data) static int mem_dump_alloc(struct platform_device *pdev) { - struct device_node *child_node; - const struct device_node *node = pdev->dev.of_node; struct msm_dump_data *dump_data; struct msm_dump_entry dump_entry; size_t total_size; u32 size, id; - int ret, no_of_nodes; + int i, ret, no_of_nodes; dma_addr_t dma_handle; phys_addr_t phys_addr; struct sg_table mem_dump_sgt; void *dump_vaddr; u64 shm_bridge_handle; int initialized = 0; + const struct dump_table *table = dev_get_platdata(&pdev->dev); if (mem_dump_reserve_mem(&pdev->dev) != 0) return -ENOMEM; total_size = size = ret = no_of_nodes = 0; /* For dump table registration with IMEM */ total_size = sizeof(struct msm_dump_table) * 2; - for_each_available_child_of_node(node, child_node) { - ret = of_property_read_u32(child_node, "qcom,dump-size", &size); - if (ret) { - dev_err(&pdev->dev, "Unable to find size for %s\n", - child_node->name); - continue; - } - - total_size += size; + for (i = 0; i < table->num_of_items; i++) { + total_size += table->items[i].size; no_of_nodes++; } @@ -1062,7 +1050,7 @@ static int mem_dump_alloc(struct platform_device *pdev) return ret; } - ret = init_memdump_imem_area(total_size); + ret = init_memdump_imem_area(table, total_size); if (ret) { qcom_tzmem_shm_bridge_delete(shm_bridge_handle); return ret; @@ -1070,24 +1058,15 @@ static int mem_dump_alloc(struct platform_device *pdev) dump_vaddr += (sizeof(struct msm_dump_table) * 2); phys_addr += (sizeof(struct msm_dump_table) * 2); - for_each_available_child_of_node(node, child_node) { - ret = of_property_read_u32(child_node, "qcom,dump-size", &size); - if (ret) - continue; - - ret = of_property_read_u32(child_node, "qcom,dump-id", &id); - if (ret) { - dev_err(&pdev->dev, "Unable to find id for %s\n", - child_node->name); - continue; - } - + for (i = 0; i < table->num_of_items; i++) { + size = table->items[i].size; + id = table->items[i].dump_id; dump_data = dump_vaddr; dump_data->addr = phys_addr + MSM_DUMP_DATA_SIZE; dump_data->len = size; dump_entry.id = id; - strscpy(dump_data->name, child_node->name, - sizeof(dump_data->name)); + strscpy(dump_data->name, table->items[i].name, + sizeof(table->items[i].name)); dump_entry.addr = phys_addr; ret = msm_dump_data_register_nominidump(MSM_DUMP_TABLE_APPS, &dump_entry); @@ -1124,16 +1103,10 @@ static int mem_dump_probe(struct platform_device *pdev) return ret; } -static const struct of_device_id mem_dump_match_table[] = { - {.compatible = "qcom,mem-dump",}, - {} -}; - static struct platform_driver mem_dump_driver = { .probe = mem_dump_probe, .driver = { .name = "msm_mem_dump", - .of_match_table = mem_dump_match_table, }, }; diff --git a/include/linux/firmware/qcom/memory_dump.h b/include/linux/firmware/qcom/memory_dump.h index ebb7c89d2f243..e72436feb0544 100644 --- a/include/linux/firmware/qcom/memory_dump.h +++ b/include/linux/firmware/qcom/memory_dump.h @@ -115,6 +115,19 @@ struct msm_dump_entry { uint64_t addr; }; +struct dump_item { + u32 dump_id; + size_t size; + const char *name; +}; + +struct dump_table { + const struct dump_item *items; + u32 num_of_items; + phys_addr_t imem_base; + resource_size_t imem_size; +}; + #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) extern int msm_dump_data_register(enum msm_dump_table_ids id, struct msm_dump_entry *entry); From 75ec75270f66ec30923cdf604105a1a00b092cc6 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 2 Feb 2026 18:16:25 +0800 Subject: [PATCH 419/438] QCLINUX: memory-dump: add logic for reserving CMA memory Memory dump driver needs a large CMA memory zone for storing memory dump table. Add codes for reserving CMA memory during the init stage. Signed-off-by: Jie Gan --- arch/arm64/configs/qcom_debug.config | 2 +- arch/arm64/mm/init.c | 4 ++ drivers/firmware/qcom/Kconfig | 1 + drivers/firmware/qcom/memory_dump_v2.c | 58 +++++++++-------------- include/linux/firmware/qcom/memory_dump.h | 4 +- 5 files changed, 31 insertions(+), 38 deletions(-) diff --git a/arch/arm64/configs/qcom_debug.config b/arch/arm64/configs/qcom_debug.config index d50f78f3a3ea2..48ae2fb9737ac 100644 --- a/arch/arm64/configs/qcom_debug.config +++ b/arch/arm64/configs/qcom_debug.config @@ -1,4 +1,4 @@ CONFIG_QCOM_DCC=m CONFIG_QCOM_DCC_DEV=m -CONFIG_QCOM_MEMORY_DUMP_V2=m +CONFIG_QCOM_MEMORY_DUMP_V2=y CONFIG_QCOM_MEMORY_DUMP_DEV=m diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 96711b8578fd0..dae135db3845e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -48,6 +48,7 @@ #include #include #include +#include /* * We need to be able to catch inadvertent references to memstart_addr @@ -324,6 +325,9 @@ void __init bootmem_init(void) * reserved, so do it here. */ arch_reserve_crashkernel(); +#if defined(CONFIG_QCOM_MEMORY_DUMP_V2) + reserve_memdump_cma(); +#endif memblock_dump_all(); } diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig index 39f63ef92e01a..dd20fed163e3f 100644 --- a/drivers/firmware/qcom/Kconfig +++ b/drivers/firmware/qcom/Kconfig @@ -77,6 +77,7 @@ config QCOM_QSEECOM_UEFISECAPP config QCOM_MEMORY_DUMP_V2 tristate "QCOM Memory Dump V2 Support" depends on QCOM_TZMEM + depends on CMA help This enables memory dump feature. It allows various client subsystems to register respective dump regions. At the time diff --git a/drivers/firmware/qcom/memory_dump_v2.c b/drivers/firmware/qcom/memory_dump_v2.c index 470d6047ee656..831d1aea86e09 100644 --- a/drivers/firmware/qcom/memory_dump_v2.c +++ b/drivers/firmware/qcom/memory_dump_v2.c @@ -18,6 +18,10 @@ #include #include #include +#include +#include +#include +#include #define MSM_DUMP_TABLE_VERSION MSM_DUMP_MAKE_VERSION(2, 0) @@ -913,30 +917,6 @@ static int init_memory_dump(void *dump_vaddr, phys_addr_t phys_addr) return 0; } -static int mem_dump_reserve_mem(struct device *dev) -{ - struct device_node *mem_node; - struct reserved_mem *rmem; - int ret; - - mem_node = of_find_node_by_path("/reserved-memory/mem-dump-region"); - if (mem_node) { - rmem = of_reserved_mem_lookup(mem_node); - of_node_put(mem_node); - if (!rmem || !rmem->ops || !rmem->ops->device_init) - return -EINVAL; - - ret = rmem->ops->device_init(rmem, dev); - if (ret) { - dev_err(dev, - "Failed to initialize reserved mem, ret %d\n", - ret); - return ret; - } - } - return 0; -} - static int cpuss_regdump_init(struct device *dev, void *dump_vaddr, u32 size) { @@ -998,6 +978,18 @@ static int cpuss_dump_init(struct platform_device *pdev, return initialized; } +struct cma *memdump_cma; +void __init reserve_memdump_cma(void) +{ + unsigned long long cma_size = 0x3000000; + unsigned long long request_size = roundup(cma_size, PAGE_SIZE); + + if (cma_declare_contiguous(0, request_size, 0, 0, 0, false, + "memdump", &memdump_cma)) { + pr_warn("memdump CMA reservation failed\n"); + } +} + #define MSM_DUMP_DATA_SIZE sizeof(struct msm_dump_data) static int mem_dump_alloc(struct platform_device *pdev) { @@ -1006,16 +998,13 @@ static int mem_dump_alloc(struct platform_device *pdev) size_t total_size; u32 size, id; int i, ret, no_of_nodes; - dma_addr_t dma_handle; phys_addr_t phys_addr; - struct sg_table mem_dump_sgt; void *dump_vaddr; u64 shm_bridge_handle; int initialized = 0; const struct dump_table *table = dev_get_platdata(&pdev->dev); + struct page *reserved_page; - if (mem_dump_reserve_mem(&pdev->dev) != 0) - return -ENOMEM; total_size = size = ret = no_of_nodes = 0; /* For dump table registration with IMEM */ total_size = sizeof(struct msm_dump_table) * 2; @@ -1026,15 +1015,12 @@ static int mem_dump_alloc(struct platform_device *pdev) total_size += (MSM_DUMP_DATA_SIZE * no_of_nodes); total_size = ALIGN(total_size, SZ_4K); - dump_vaddr = dmam_alloc_coherent(&pdev->dev, total_size, - &dma_handle, GFP_KERNEL); - if (!dump_vaddr) + reserved_page = cma_alloc(memdump_cma, total_size >> PAGE_SHIFT, + 0, false); + if (!reserved_page) return -ENOMEM; - - dma_get_sgtable(&pdev->dev, &mem_dump_sgt, dump_vaddr, - dma_handle, total_size); - phys_addr = page_to_phys(sg_page(mem_dump_sgt.sgl)); - sg_free_table(&mem_dump_sgt); + phys_addr = page_to_phys(reserved_page); + dump_vaddr = page_to_virt(reserved_page); memset(dump_vaddr, 0x0, total_size); ret = qcom_tzmem_shm_bridge_create(phys_addr, total_size, &shm_bridge_handle); diff --git a/include/linux/firmware/qcom/memory_dump.h b/include/linux/firmware/qcom/memory_dump.h index e72436feb0544..ead7add4265c5 100644 --- a/include/linux/firmware/qcom/memory_dump.h +++ b/include/linux/firmware/qcom/memory_dump.h @@ -33,6 +33,9 @@ struct msm_client_dump { unsigned long end_addr; }; +void __init reserve_memdump_cma(void); +extern struct cma *memdump_cma; + #ifdef CONFIG_QCOM_MEMORY_DUMP extern int msm_dump_tbl_register(struct msm_client_dump *client_entry); #else @@ -42,7 +45,6 @@ static inline int msm_dump_tbl_register(struct msm_client_dump *entry) } #endif - #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2) extern uint32_t msm_dump_table_version(void); #else From 59765f2430fbbe05a5efe05ae48c4ca2d928af69 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 13:44:34 +0800 Subject: [PATCH 420/438] QCLINUX: qcom-dcc: add device configuration for Pakala Add device configuration to enable DCC on Pakala platform. Signed-off-by: Jie Gan --- drivers/misc/qcom-dcc-dev.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/misc/qcom-dcc-dev.c b/drivers/misc/qcom-dcc-dev.c index e0eb2e61d652b..0c2369a4843ae 100644 --- a/drivers/misc/qcom-dcc-dev.c +++ b/drivers/misc/qcom-dcc-dev.c @@ -39,6 +39,15 @@ static const struct dcc_pdata kodiak_pdata = { .map_ver = 0x2, }; +static const struct dcc_pdata pakala_pdata = { + .base = 0x100ff000, + .size = 0x00001000, + .ram_base = 0x10084000, + .ram_size = 0x4000, + .dcc_offset = 0x4000, + .map_ver = 0x3, +}; + static int __init dcc_dev_init(void) { int ret; @@ -83,6 +92,15 @@ static int __init dcc_dev_init(void) if (ret) goto fail; + break; + case 618: + case 639: + case 705: + case 706: + ret = platform_device_add_data(dcc_pdev, &pakala_pdata, sizeof(pakala_pdata)); + if (ret) + goto fail; + break; default: pr_err("DCC: Invalid SoC ID\n"); From f97d300738f8b3d62bc44ebe5e11f7af43cdd4c8 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 14:10:29 +0800 Subject: [PATCH 421/438] QCLINUX: memory-dump: add memory dump table for Pakala Add memory dump table configuration to enable memory dump function on Pakala platform. Signed-off-by: Jie Gan --- drivers/firmware/qcom/memory_dump_dev.c | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/firmware/qcom/memory_dump_dev.c b/drivers/firmware/qcom/memory_dump_dev.c index 556ebafae5280..1626a67017990 100644 --- a/drivers/firmware/qcom/memory_dump_dev.c +++ b/drivers/firmware/qcom/memory_dump_dev.c @@ -57,12 +57,15 @@ enum dump_ids { CPUSS_REG = 0xef, TMC_ETF = 0xf0, ETF_SWAO = 0xf1, + ETF_SLPI = 0xf3, ETF_LPASS = 0xf4, FCM = 0xee, ETR_REG = 0x100, ETF_REG = 0x101, ETFSWAO_REG = 0x102, + ETFSLPI_REG = 0x103, ETFLPASS_REG = 0x104, + ETR1_REG = 0x105, L2_TLB0 = 0x120, L2_TLB100 = 0x121, L2_TLB200 = 0x122, @@ -86,6 +89,7 @@ enum dump_ids { OSM_REG = 0x163, PCU_REG = 0x164, FSM_DATA = 0x165, + SCANDUMP_SMMU = 0x220, }; static const struct dump_item lemans_items[] = { @@ -277,6 +281,35 @@ static const struct dump_item kodiak_items[] = { { RPMH, 0x2000000, "rpmh" }, }; +static const struct dump_item pakala_items[] = { + { C0_CONTEXT, 0x800, "c0-context" }, + { C100_CONTEXT, 0x800, "c100-context" }, + { C200_CONTEXT, 0x800, "c200-context" }, + { C300_CONTEXT, 0x800, "c300-context" }, + { C400_CONTEXT, 0x800, "c400-context" }, + { C500_CONTEXT, 0x800, "c500-context" }, + { C600_CONTEXT, 0x800, "c600-context" }, + { C700_CONTEXT, 0x800, "c700-context" }, + { RPMH, 0x400000, "rpmh" }, + { RPM_SW, 0x28000, "rpm-sw" }, + { PMIC, 0x200000, "pmic" }, + { FCM, 0x8400, "fcm" }, + { MISC_DATA, 0x1000, "misc-data" }, + { ETF_SWAO, 0x10000, "etf-swao" }, + { ETR_REG, 0x1000, "etr-reg" }, + { ETFSWAO_REG, 0x1000, "etfswao-reg" }, + { ETR1_REG, 0x1000, "etr1-reg" }, + { ETF_SLPI, 0x4000, "etf-slpi" }, + { ETFSLPI_REG, 0x1000, "etfslpi-reg" }, + { ETF_LPASS, 0x4000, "etf-lpass" }, + { ETFLPASS_REG, 0x1000, "etflpass-reg" }, + { OSM_REG, 0x400, "osm-reg" }, + { PCU_REG, 0x400, "pcu-reg" }, + { FSM_DATA, 0x400, "fsm-data" }, + { SCANDUMP_SMMU, 0x40000, "scandump-smmu" }, + { C0_SCANDUMP, 0x380000, "apps-scandump" }, +}; + static const struct dump_table lemans_dump_table = { .items = lemans_items, .num_of_items = ARRAY_SIZE(lemans_items), @@ -298,6 +331,13 @@ static const struct dump_table kodiak_dump_table = { .imem_size = 0x8, }; +static const struct dump_table pakala_dump_table = { + .items = pakala_items, + .num_of_items = ARRAY_SIZE(pakala_items), + .imem_base = 0x14680010, + .imem_size = 0x8, +}; + static int __init mem_dump_dev_init(void) { int ret; @@ -345,6 +385,16 @@ static int __init mem_dump_dev_init(void) if (ret) goto fail; + break; + case 618: + case 639: + case 705: + case 706: + ret = platform_device_add_data(mem_dump_pdev, + &pakala_dump_table, sizeof(pakala_dump_table)); + if (ret) + goto fail; + break; default: dev_err(&mem_dump_pdev->dev, "Invalid SoC ID\n"); From f1d5623f0115bd29c040a7936159dc0f6ac8d62b Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 14:58:04 +0800 Subject: [PATCH 422/438] QCLINUX: qcom-dcc: add device configuration for Kaanapali Add device configuration to enable DCC on Kaanapali platform. Signed-off-by: Jie Gan --- drivers/misc/qcom-dcc-dev.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/misc/qcom-dcc-dev.c b/drivers/misc/qcom-dcc-dev.c index 0c2369a4843ae..5ed2a117b9e81 100644 --- a/drivers/misc/qcom-dcc-dev.c +++ b/drivers/misc/qcom-dcc-dev.c @@ -48,6 +48,15 @@ static const struct dcc_pdata pakala_pdata = { .map_ver = 0x3, }; +static const struct dcc_pdata kaanapali_pdata = { + .base = 0x100ff000, + .size = 0x1000, + .ram_base = 0x10080000, + .ram_size = 0x8000, + .dcc_offset = 0x0, + .map_ver = 0x3, +}; + static int __init dcc_dev_init(void) { int ret; @@ -101,6 +110,18 @@ static int __init dcc_dev_init(void) if (ret) goto fail; + break; + case 660: + case 661: + case 704: + case 722: + case 723: + case 730: + case 743: + ret = platform_device_add_data(dcc_pdev, &kaanapali_pdata, sizeof(kaanapali_pdata)); + if (ret) + goto fail; + break; default: pr_err("DCC: Invalid SoC ID\n"); From 456b9522d0a1b7af0a215dddab2617d1720f7b3d Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 15:16:19 +0800 Subject: [PATCH 423/438] QCLINUX: memory-dump: add memory dump table for Kaanapali Add memory dump table configuration to enable memory dump function on Kaanapali platform. Signed-off-by: Jie Gan --- drivers/firmware/qcom/memory_dump_dev.c | 49 +++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/drivers/firmware/qcom/memory_dump_dev.c b/drivers/firmware/qcom/memory_dump_dev.c index 1626a67017990..d02e6af6c03a0 100644 --- a/drivers/firmware/qcom/memory_dump_dev.c +++ b/drivers/firmware/qcom/memory_dump_dev.c @@ -310,6 +310,35 @@ static const struct dump_item pakala_items[] = { { C0_SCANDUMP, 0x380000, "apps-scandump" }, }; +static const struct dump_item kaanapali_items[] = { + { C0_CONTEXT, 0x800, "c0-context" }, + { C100_CONTEXT, 0x800, "c100-context" }, + { C200_CONTEXT, 0x800, "c200-context" }, + { C300_CONTEXT, 0x800, "c300-context" }, + { C400_CONTEXT, 0x800, "c400-context" }, + { C500_CONTEXT, 0x800, "c500-context" }, + { C600_CONTEXT, 0x800, "c600-context" }, + { C700_CONTEXT, 0x800, "c700-context" }, + { RPMH, 0x400000, "rpmh" }, + { RPM_SW, 0x28000, "rpm-sw" }, + { PMIC, 0x200000, "pmic" }, + { FCM, 0x8400, "fcm" }, + { MISC_DATA, 0x1000, "misc-data" }, + { ETF_SWAO, 0x10000, "etf-swao" }, + { ETR_REG, 0x1000, "etr-reg" }, + { ETFSWAO_REG, 0x1000, "etfswao-reg" }, + { ETR1_REG, 0x1000, "etr1-reg" }, + { ETF_SLPI, 0x4000, "etf-slpi" }, + { ETFSLPI_REG, 0x1000, "etfslpi-reg" }, + { ETF_LPASS, 0x4000, "etf-lpass" }, + { ETFLPASS_REG, 0x1000, "etflpass-reg" }, + { OSM_REG, 0x400, "osm-reg" }, + { PCU_REG, 0x400, "pcu-reg" }, + { FSM_DATA, 0x400, "fsm-data" }, + { SCANDUMP_SMMU, 0x40000, "scandump-smmu" }, + { C0_SCANDUMP, 0x380000, "apps-scandump" }, +}; + static const struct dump_table lemans_dump_table = { .items = lemans_items, .num_of_items = ARRAY_SIZE(lemans_items), @@ -338,6 +367,13 @@ static const struct dump_table pakala_dump_table = { .imem_size = 0x8, }; +static const struct dump_table kaanapali_dump_table = { + .items = kaanapali_items, + .num_of_items = ARRAY_SIZE(kaanapali_items), + .imem_base = 0x14680010, + .imem_size = 0x8, +}; + static int __init mem_dump_dev_init(void) { int ret; @@ -395,6 +431,19 @@ static int __init mem_dump_dev_init(void) if (ret) goto fail; + break; + case 660: + case 661: + case 704: + case 722: + case 723: + case 730: + case 743: + ret = platform_device_add_data(mem_dump_pdev, + &kaanapali_dump_table, sizeof(kaanapali_dump_table)); + if (ret) + goto fail; + break; default: dev_err(&mem_dump_pdev->dev, "Invalid SoC ID\n"); From 49a40c40824ddef7f7ad4b9884cdf5e65bd01c0f Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 15:32:10 +0800 Subject: [PATCH 424/438] QCLINUX: qcom-dcc: add device configuration for Hamoa Add device configuration to enable DCC on Hamoa platform. Signed-off-by: Jie Gan --- drivers/misc/qcom-dcc-dev.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/misc/qcom-dcc-dev.c b/drivers/misc/qcom-dcc-dev.c index 5ed2a117b9e81..ff19dac70011f 100644 --- a/drivers/misc/qcom-dcc-dev.c +++ b/drivers/misc/qcom-dcc-dev.c @@ -57,6 +57,15 @@ static const struct dcc_pdata kaanapali_pdata = { .map_ver = 0x3, }; +static const struct dcc_pdata hamoa_pdata = { + .base = 0x100ff000, + .size = 0x1000, + .ram_base = 0x10080000, + .ram_size = 0x18000, + .dcc_offset = 0x0, + .map_ver = 0x3, +}; + static int __init dcc_dev_init(void) { int ret; @@ -122,6 +131,16 @@ static int __init dcc_dev_init(void) if (ret) goto fail; + break; + case 555: + case 615: + case 616: + case 709: + case 710: + ret = platform_device_add_data(dcc_pdev, &hamoa_pdata, sizeof(hamoa_pdata)); + if (ret) + goto fail; + break; default: pr_err("DCC: Invalid SoC ID\n"); From 281d564aa046eb9cea6f4ab86bfe8c70e1858b36 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 15:45:31 +0800 Subject: [PATCH 425/438] QCLINUX: memory-dump: add memory dump table for Hamoa Add memory dump table configuration to enable memory dump function on Hamoa platform. Signed-off-by: Jie Gan --- drivers/firmware/qcom/memory_dump_dev.c | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/firmware/qcom/memory_dump_dev.c b/drivers/firmware/qcom/memory_dump_dev.c index d02e6af6c03a0..0f89cb201b783 100644 --- a/drivers/firmware/qcom/memory_dump_dev.c +++ b/drivers/firmware/qcom/memory_dump_dev.c @@ -339,6 +339,22 @@ static const struct dump_item kaanapali_items[] = { { C0_SCANDUMP, 0x380000, "apps-scandump" }, }; +static const struct dump_item hamoa_items[] = { + { C0_CONTEXT, 0x800, "c0-context" }, + { C100_CONTEXT, 0x800, "c100-context" }, + { C200_CONTEXT, 0x800, "c200-context" }, + { C300_CONTEXT, 0x800, "c300-context" }, + { C400_CONTEXT, 0x800, "c400-context" }, + { C500_CONTEXT, 0x800, "c500-context" }, + { C600_CONTEXT, 0x800, "c600-context" }, + { C700_CONTEXT, 0x800, "c700-context" }, + { RPMH, 0xc10000, "rpmh" }, + { PMIC, 0x200000, "pmic" }, + { ETF_SWAO, 0x10000, "etf-swao" }, + { ETR_REG, 0x1000, "etr-reg" }, + { ETFSWAO_REG, 0x1000, "etfswao-reg" }, +}; + static const struct dump_table lemans_dump_table = { .items = lemans_items, .num_of_items = ARRAY_SIZE(lemans_items), @@ -374,6 +390,13 @@ static const struct dump_table kaanapali_dump_table = { .imem_size = 0x8, }; +static const struct dump_table hamoa_dump_table = { + .items = hamoa_items, + .num_of_items = ARRAY_SIZE(hamoa_items), + .imem_base = 0x146aa010, + .imem_size = 0x8, +}; + static int __init mem_dump_dev_init(void) { int ret; @@ -444,6 +467,17 @@ static int __init mem_dump_dev_init(void) if (ret) goto fail; + break; + case 555: + case 615: + case 616: + case 709: + case 710: + ret = platform_device_add_data(mem_dump_pdev, + &hamoa_dump_table, sizeof(hamoa_dump_table)); + if (ret) + goto fail; + break; default: dev_err(&mem_dump_pdev->dev, "Invalid SoC ID\n"); From b3bff1d52bdf75862574b137b433e7541ce1637b Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Wed, 4 Mar 2026 09:15:02 +0800 Subject: [PATCH 426/438] QCLINUX: memory-dump: fix array size issue for Talos Fix the wrong arrary size issue for Talos. Signed-off-by: Jie Gan --- drivers/firmware/qcom/memory_dump_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/qcom/memory_dump_dev.c b/drivers/firmware/qcom/memory_dump_dev.c index 0f89cb201b783..78fb377800bc9 100644 --- a/drivers/firmware/qcom/memory_dump_dev.c +++ b/drivers/firmware/qcom/memory_dump_dev.c @@ -364,7 +364,7 @@ static const struct dump_table lemans_dump_table = { static const struct dump_table talos_dump_table = { .items = talos_items, - .num_of_items = ARRAY_SIZE(lemans_items), + .num_of_items = ARRAY_SIZE(talos_items), .imem_base = 0x146aa010, .imem_size = 0x8, }; From 7cd815578b965e77d75260b32199cd681fb0b8d5 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Wed, 4 Mar 2026 10:17:04 +0530 Subject: [PATCH 427/438] FROMLIST: arm64: dts: qcom: glymur: Add remoteproc for SoCCP Add remoteproc PAS loader for SoCCP Link: https://patchwork.kernel.org/project/linux-arm-msm/patch/20250925-v3_glymur_introduction-v1-24-24b601bbecc0@oss.qualcomm.com/ Signed-off-by: Sibi Sankar Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 7 ++++ arch/arm64/boot/dts/qcom/glymur.dtsi | 53 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 08867176cc3bd..6ceaa44028790 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts @@ -913,6 +913,13 @@ status = "okay"; }; +&remoteproc_soccp { + firmware-name = "qcom/glymur/soccp.mbn", + "qcom/glymur/soccp_dtb.mbn"; + + status = "okay"; +}; + &tlmm { gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ <10 2>, /* OOB UART */ diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 7ad5dd7337e05..b2e114337b246 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -2269,6 +2269,59 @@ }; }; + remoteproc_soccp: remoteproc-soccp@d00000 { + compatible = "qcom,glymur-soccp-pas", "qcom,kaanapali-soccp-pas"; + reg = <0x0 0x00d00000 0x0 0x200000>; + + interrupts-extended = <&intc GIC_SPI 167 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 9 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 10 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "pong", + "wake-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + power-domain-names = "cx", + "mx"; + + memory-region = <&soccp_mem>, + <&soccpdtb_mem>; + + qcom,smem-states = <&soccp_smp2p_out 0>, + <&soccp_smp2p_out 10>, + <&soccp_smp2p_out 9>, + <&soccp_smp2p_out 8>; + qcom,smem-state-names = "stop", + "wakeup", + "sleep", + "ping"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + qcom,remote-pid = <19>; + label = "soccp"; + + }; + }; + usb_hs_phy: phy@fa0000 { compatible = "qcom,glymur-m31-eusb2-phy", "qcom,sm8750-m31-eusb2-phy"; From 3b2c87854353df1ea49212b0d8cfcc10fff63e35 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Mon, 2 Feb 2026 17:03:05 +0800 Subject: [PATCH 428/438] FROMLIST: driver: bluetooth:btusb: Allow firmwarea re-download when version matches Since USB can disconnect at any time, if it disconnects during the BT firmware download, the BT controller firmware version may still be updated even without completing the download. When USB reconnects, the BT host detects the same version as in the firmware file, which prevents the firmware from being downloaded again. Therefore, remove the equality check to ensure that after USB reconnection, the BT host can still download the firmware. Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20260108074353.1027877-1-shuai.zhang@oss.qualcomm.com/ --- drivers/bluetooth/btusb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a1c5eb993e478..cf7379ceaa69f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3508,7 +3508,10 @@ static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev, "firmware rome 0x%x build 0x%x", rver_rom, rver_patch, ver_rom, ver_patch); - if (rver_rom != ver_rom || rver_patch <= ver_patch) { + /* Allow rampatch if version is greater than or equal to firmware version. + * Equal versions are acceptable for re-flashing or recovery scenarios. + */ + if (rver_rom != ver_rom || rver_patch < ver_patch) { bt_dev_err(hdev, "rampatch file version did not match with firmware"); err = -EINVAL; goto done; From 45bd0756ae6c1c7113ca04465565bce389d73cbd Mon Sep 17 00:00:00 2001 From: Jinwang Li Date: Mon, 5 Jan 2026 20:25:05 +0800 Subject: [PATCH 429/438] FROMLIST: driver: bluetooth: hci_qca: Cleanup on all setup failures The setup process previously combined error handling and retry gating under one condition. As a result, the final failed attempt exited without performing cleanup. Update the failure path to always perform power and port cleanup on setup failure, and reopen the port only when retrying. Fixes: 9e80587aba4c ("Bluetooth: hci_qca: Enhance retry logic in qca_setup") Signed-off-by: Jinwang Li Reviewed-by: Bartosz Golaszewski Link: https://lore.kernel.org/all/20260205062600.590342-1-jinwang.li@oss.qualcomm.com/ --- drivers/bluetooth/hci_qca.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 5b02e7c3f56dd..bb9f002aa85e9 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2046,19 +2046,23 @@ static int qca_setup(struct hci_uart *hu) } out: - if (ret && retries < MAX_INIT_RETRIES) { - bt_dev_warn(hdev, "Retry BT power ON:%d", retries); + if (ret) { qca_power_shutdown(hu); - if (hu->serdev) { - serdev_device_close(hu->serdev); - ret = serdev_device_open(hu->serdev); - if (ret) { - bt_dev_err(hdev, "failed to open port"); - return ret; + + if (retries < MAX_INIT_RETRIES) { + bt_dev_warn(hdev, "Retry BT power ON:%d", retries); + if (hu->serdev) { + serdev_device_close(hu->serdev); + ret = serdev_device_open(hu->serdev); + if (ret) { + bt_dev_err(hdev, "failed to open port"); + return ret; + } } + retries++; + goto retry; } - retries++; - goto retry; + return ret; } /* Setup bdaddr */ From 97e364685f4a743083dbadddde72cdc1f7e8ab40 Mon Sep 17 00:00:00 2001 From: Pragnesh Papaniya Date: Wed, 4 Mar 2026 13:35:14 +0530 Subject: [PATCH 430/438] FROMLIST: arm64: dts: qcom: glymur: Add glymur BWMONs Add the CPU BWMON nodes for glymur SoCs. Link: https://lore.kernel.org/linux-arm-msm/20260302-glymur_bwmon_dt-v1-1-f4939d75bd47@oss.qualcomm.com/ Co-developed-by: Sibi Sankar Signed-off-by: Sibi Sankar Signed-off-by: Pragnesh Papaniya Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 87 ++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index b2e114337b246..48adc83c9aff7 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -2593,6 +2593,93 @@ status = "disabled"; }; + /* cluster0 */ + bwmon_cluster0: pmu@100c400 { + compatible = "qcom,glymur-cpu-bwmon", "qcom,sdm845-bwmon"; + reg = <0x0 0x0100c400 0x0 0x600>; + + interrupts = ; + + interconnects = <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>; + + operating-points-v2 = <&cpu_bwmon_opp_table>; + + cpu_bwmon_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-0 { + opp-peak-kBps = <800000>; + }; + + opp-1 { + opp-peak-kBps = <2188800>; + }; + + opp-2 { + opp-peak-kBps = <5414400>; + }; + + opp-3 { + opp-peak-kBps = <6220800>; + }; + + opp-4 { + opp-peak-kBps = <6835200>; + }; + + opp-5 { + opp-peak-kBps = <8371200>; + }; + + opp-6 { + opp-peak-kBps = <10944000>; + }; + + opp-7 { + opp-peak-kBps = <12748800>; + }; + + opp-8 { + opp-peak-kBps = <14745600>; + }; + + opp-9 { + opp-peak-kBps = <16896000>; + }; + + opp-10 { + opp-peak-kBps = <19046400>; + }; + }; + }; + + /* cluster1 */ + bwmon_cluster1: pmu@100d400 { + compatible = "qcom,glymur-cpu-bwmon", "qcom,sdm845-bwmon"; + reg = <0x0 0x0100d400 0x0 0x600>; + + interrupts = ; + + interconnects = <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>; + + operating-points-v2 = <&cpu_bwmon_opp_table>; + }; + + /* cluster2 */ + bwmon_cluster2: pmu@100e400 { + compatible = "qcom,glymur-cpu-bwmon", "qcom,sdm845-bwmon"; + reg = <0x0 0x0100e400 0x0 0x600>; + + interrupts = ; + + interconnects = <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>; + + operating-points-v2 = <&cpu_bwmon_opp_table>; + }; + cnoc_main: interconnect@1500000 { compatible = "qcom,glymur-cnoc-main"; reg = <0x0 0x01500000 0x0 0x17080>; From 67f1c40d4a2392e8124be7b67fa641c0e5c76b00 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Fri, 27 Feb 2026 17:34:47 +0530 Subject: [PATCH 431/438] FROMLIST: ASoC: qcom: qdsp6: Fix q6apm remove ordering during ADSP stop and start During ADSP stop and start, the kernel crashes due to the order in which ASoC components are removed. On ADSP stop, the q6apm-audio .remove callback unloads topology and removes PCM runtimes during ASoC teardown. This deletes the RTDs that contain the q6apm DAI components before their removal pass runs, leaving those components still linked to the card and causing crashes on the next rebind. Fix this by ensuring that all dependent (child) components are removed first, and the q6apm component is removed last. [ 48.105720] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d0 [ 48.114763] Mem abort info: [ 48.117650] ESR = 0x0000000096000004 [ 48.121526] EC = 0x25: DABT (current EL), IL = 32 bits [ 48.127010] SET = 0, FnV = 0 [ 48.130172] EA = 0, S1PTW = 0 [ 48.133415] FSC = 0x04: level 0 translation fault [ 48.138446] Data abort info: [ 48.141422] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 [ 48.147079] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 48.152354] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 48.157859] user pgtable: 4k pages, 48-bit VAs, pgdp=00000001173cf000 [ 48.164517] [00000000000000d0] pgd=0000000000000000, p4d=0000000000000000 [ 48.171530] Internal error: Oops: 0000000096000004 [#1] SMP [ 48.177348] Modules linked in: q6prm_clocks q6apm_lpass_dais q6apm_dai snd_q6dsp_common q6prm snd_q6apm 8021q garp mrp stp llc snd_soc_hdmi_codec apr pdr_interface phy_qcom_edp fastrpc qcom_pd_mapper rpmsg_ctrl qrtr_smd rpmsg_char qcom_pdr_msg qcom_iris v4l2_mem2mem videobuf2_dma_contig ath11k_pci msm ubwc_config at24 ath11k videobuf2_memops mac80211 ocmem videobuf2_v4l2 libarc4 drm_gpuvm mhi qrtr videodev drm_exec snd_soc_sc8280xp gpu_sched videobuf2_common nvmem_qcom_spmi_sdam snd_soc_qcom_sdw drm_dp_aux_bus qcom_q6v5_pas qcom_spmi_temp_alarm snd_soc_qcom_common rtc_pm8xxx qcom_pon drm_display_helper cec qcom_pil_info qcom_stats soundwire_bus drm_client_lib mc dispcc0_sa8775p videocc_sa8775p qcom_q6v5 camcc_sa8775p snd_soc_dmic phy_qcom_sgmii_eth snd_soc_max98357a i2c_qcom_geni snd_soc_core dwmac_qcom_ethqos llcc_qcom icc_bwmon qcom_sysmon snd_compress qcom_refgen_regulator coresight_stm stmmac_platform snd_pcm_dmaengine qcom_common coresight_tmc stmmac coresight_replicator qcom_glink_smem coresight_cti stm_core [ 48.177444] coresight_funnel snd_pcm ufs_qcom phy_qcom_qmp_usb gpi phy_qcom_snps_femto_v2 coresight phy_qcom_qmp_ufs qcom_wdt gpucc_sa8775p pcs_xpcs mdt_loader qcom_ice icc_osm_l3 qmi_helpers snd_timer snd soundcore display_connector qcom_rng nvmem_reboot_mode drm_kms_helper phy_qcom_qmp_pcie sha256 cfg80211 rfkill socinfo fuse drm backlight ipv6 [ 48.301059] CPU: 2 UID: 0 PID: 293 Comm: kworker/u32:2 Not tainted 6.19.0-rc6-dirty #10 PREEMPT [ 48.310081] Hardware name: Qualcomm Technologies, Inc. Lemans EVK (DT) [ 48.316782] Workqueue: pdr_notifier_wq pdr_notifier_work [pdr_interface] [ 48.323672] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 48.330825] pc : mutex_lock+0xc/0x54 [ 48.334514] lr : soc_dapm_shutdown_dapm+0x44/0x174 [snd_soc_core] [ 48.340794] sp : ffff800084ddb7b0 [ 48.344207] x29: ffff800084ddb7b0 x28: ffff00009cd9cf30 x27: ffff00009cd9cc00 [ 48.351544] x26: ffff000099610190 x25: ffffa31d2f19c810 x24: ffffa31d2f185098 [ 48.358869] x23: ffff800084ddb7f8 x22: 0000000000000000 x21: 00000000000000d0 [ 48.366198] x20: ffff00009ba6c338 x19: ffff00009ba6c338 x18: 00000000ffffffff [ 48.373528] x17: 000000040044ffff x16: ffffa31d4ae6dca8 x15: 072007740775076f [ 48.380853] x14: 0765076d07690774 x13: 00313a323a656369 x12: 767265733a637673 [ 48.388182] x11: 00000000000003f9 x10: ffffa31d4c7dea98 x9 : 0000000000000001 [ 48.395519] x8 : ffff00009a2aadc0 x7 : 0000000000000003 x6 : 0000000000000000 [ 48.402854] x5 : 0000000000000000 x4 : 0000000000000028 x3 : ffff000ef397a698 [ 48.410180] x2 : ffff00009a2aadc0 x1 : 0000000000000000 x0 : 00000000000000d0 [ 48.417506] Call trace: [ 48.420025] mutex_lock+0xc/0x54 (P) [ 48.423712] snd_soc_dapm_shutdown+0x44/0xbc [snd_soc_core] [ 48.429447] soc_cleanup_card_resources+0x30/0x2c0 [snd_soc_core] [ 48.435719] snd_soc_bind_card+0x4dc/0xcc0 [snd_soc_core] [ 48.441278] snd_soc_add_component+0x27c/0x2c8 [snd_soc_core] [ 48.447192] snd_soc_register_component+0x9c/0xf4 [snd_soc_core] [ 48.453371] devm_snd_soc_register_component+0x64/0xc4 [snd_soc_core] [ 48.459994] apm_probe+0xb4/0x110 [snd_q6apm] [ 48.464479] apr_device_probe+0x24/0x40 [apr] [ 48.468964] really_probe+0xbc/0x298 [ 48.472651] __driver_probe_device+0x78/0x12c [ 48.477132] driver_probe_device+0x40/0x160 [ 48.481435] __device_attach_driver+0xb8/0x134 [ 48.486011] bus_for_each_drv+0x80/0xdc [ 48.489964] __device_attach+0xa8/0x1b0 [ 48.493916] device_initial_probe+0x50/0x54 [ 48.498219] bus_probe_device+0x38/0xa0 [ 48.502170] device_add+0x590/0x760 [ 48.505761] device_register+0x20/0x30 [ 48.509623] of_register_apr_devices+0x1d8/0x318 [apr] [ 48.514905] apr_pd_status+0x2c/0x54 [apr] [ 48.519114] pdr_notifier_work+0x8c/0xe0 [pdr_interface] [ 48.524570] process_one_work+0x150/0x294 [ 48.528692] worker_thread+0x2d8/0x3d8 [ 48.532551] kthread+0x130/0x204 [ 48.535874] ret_from_fork+0x10/0x20 [ 48.539559] Code: d65f03c0 d5384102 d503201f d2800001 (c8e17c02) [ 48.545823] ---[ end trace 0000000000000000 ]--- Link: https://lore.kernel.org/all/20260227144534.278568-1-ravi.hothi@oss.qualcomm.com/ Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support") Cc: stable@vger.kernel.org Signed-off-by: Ravi Hothi --- sound/soc/qcom/qdsp6/q6apm-dai.c | 1 + sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 1 + sound/soc/qcom/qdsp6/q6apm.c | 1 + 3 files changed, 3 insertions(+) diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index de3bdac3e791c..168c166c960d7 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -838,6 +838,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = { .ack = q6apm_dai_ack, .compress_ops = &q6apm_dai_compress_ops, .use_dai_pcm_id = true, + .remove_order = SND_SOC_COMP_ORDER_EARLY, }; static int q6apm_dai_probe(struct platform_device *pdev) diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c index 528756f1332bc..5be37eeea329f 100644 --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c @@ -278,6 +278,7 @@ static const struct snd_soc_component_driver q6apm_lpass_dai_component = { .of_xlate_dai_name = q6dsp_audio_ports_of_xlate_dai_name, .be_pcm_base = AUDIOREACH_BE_PCM_BASE, .use_dai_pcm_id = true, + .remove_order = SND_SOC_COMP_ORDER_FIRST, }; static int q6apm_lpass_dai_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index 44841fde38567..970b08c89bb35 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -715,6 +715,7 @@ static const struct snd_soc_component_driver q6apm_audio_component = { .name = APM_AUDIO_DRV_NAME, .probe = q6apm_audio_probe, .remove = q6apm_audio_remove, + .remove_order = SND_SOC_COMP_ORDER_LAST, }; static int apm_probe(gpr_device_t *gdev) From 77dea0829320ff01c3e948dcd3958aecf9cdba35 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 23 Feb 2026 18:07:27 +0000 Subject: [PATCH 432/438] FROMLIST: ASoC: qcom: q6apm: move component registration to unmanaged version q6apm component registers dais dynamically from ASoC toplology, which are allocated using device managed version apis. Allocating both component and dynamic dais using managed version could lead to incorrect free ordering, dai will be freed while component still holding references to it. Fix this issue by moving component to unmanged version so that the dai pointers are only freeded after the component is removed. ================================================================== BUG: KASAN: slab-use-after-free in snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core] Read of size 8 at addr ffff00084493a6e8 by task kworker/u48:0/3426 Tainted: [W]=WARN Hardware name: LENOVO 21N2ZC5PUS/21N2ZC5PUS, BIOS N42ET57W (1.31 ) 08/08/2024 Workqueue: pdr_notifier_wq pdr_notifier_work [pdr_interface] Call trace: show_stack+0x28/0x7c (C) dump_stack_lvl+0x60/0x80 print_report+0x160/0x4b4 kasan_report+0xac/0xfc __asan_report_load8_noabort+0x20/0x34 snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core] snd_soc_unregister_component_by_driver+0x50/0x88 [snd_soc_core] devm_component_release+0x30/0x5c [snd_soc_core] devres_release_all+0x13c/0x210 device_unbind_cleanup+0x20/0x190 device_release_driver_internal+0x350/0x468 device_release_driver+0x18/0x30 bus_remove_device+0x1a0/0x35c device_del+0x314/0x7f0 device_unregister+0x20/0xbc apr_remove_device+0x5c/0x7c [apr] device_for_each_child+0xd8/0x160 apr_pd_status+0x7c/0xa8 [apr] pdr_notifier_work+0x114/0x240 [pdr_interface] process_one_work+0x500/0xb70 worker_thread+0x630/0xfb0 kthread+0x370/0x6c0 ret_from_fork+0x10/0x20 Allocated by task 77: kasan_save_stack+0x40/0x68 kasan_save_track+0x20/0x40 kasan_save_alloc_info+0x44/0x58 __kasan_kmalloc+0xbc/0xdc __kmalloc_node_track_caller_noprof+0x1f4/0x620 devm_kmalloc+0x7c/0x1c8 snd_soc_register_dai+0x50/0x4f0 [snd_soc_core] soc_tplg_pcm_elems_load+0x55c/0x1eb8 [snd_soc_core] snd_soc_tplg_component_load+0x4f8/0xb60 [snd_soc_core] audioreach_tplg_init+0x124/0x1fc [snd_q6apm] q6apm_audio_probe+0x10/0x1c [snd_q6apm] snd_soc_component_probe+0x5c/0x118 [snd_soc_core] soc_probe_component+0x44c/0xaf0 [snd_soc_core] snd_soc_bind_card+0xad0/0x2370 [snd_soc_core] snd_soc_register_card+0x3b0/0x4c0 [snd_soc_core] devm_snd_soc_register_card+0x50/0xc8 [snd_soc_core] x1e80100_platform_probe+0x208/0x368 [snd_soc_x1e80100] platform_probe+0xc0/0x188 really_probe+0x188/0x804 __driver_probe_device+0x158/0x358 driver_probe_device+0x60/0x190 __device_attach_driver+0x16c/0x2a8 bus_for_each_drv+0x100/0x194 __device_attach+0x174/0x380 device_initial_probe+0x14/0x20 bus_probe_device+0x124/0x154 deferred_probe_work_func+0x140/0x220 process_one_work+0x500/0xb70 worker_thread+0x630/0xfb0 kthread+0x370/0x6c0 ret_from_fork+0x10/0x20 Freed by task 3426: kasan_save_stack+0x40/0x68 kasan_save_track+0x20/0x40 __kasan_save_free_info+0x4c/0x80 __kasan_slab_free+0x78/0xa0 kfree+0x100/0x4a4 devres_release_all+0x144/0x210 device_unbind_cleanup+0x20/0x190 device_release_driver_internal+0x350/0x468 device_release_driver+0x18/0x30 bus_remove_device+0x1a0/0x35c device_del+0x314/0x7f0 device_unregister+0x20/0xbc apr_remove_device+0x5c/0x7c [apr] device_for_each_child+0xd8/0x160 apr_pd_status+0x7c/0xa8 [apr] pdr_notifier_work+0x114/0x240 [pdr_interface] process_one_work+0x500/0xb70 worker_thread+0x630/0xfb0 kthread+0x370/0x6c0 ret_from_fork+0x10/0x20 Link: https://lore.kernel.org/all/20260223180740.444311-2-srinivas.kandagatla@oss.qualcomm.com/ Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support") Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6apm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index 970b08c89bb35..fece0e3def232 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -747,7 +747,7 @@ static int apm_probe(gpr_device_t *gdev) q6apm_get_apm_state(apm); - ret = devm_snd_soc_register_component(dev, &q6apm_audio_component, NULL, 0); + ret = snd_soc_register_component(dev, &q6apm_audio_component, NULL, 0); if (ret < 0) { dev_err(dev, "failed to register q6apm: %d\n", ret); return ret; @@ -756,6 +756,11 @@ static int apm_probe(gpr_device_t *gdev) return of_platform_populate(dev->of_node, NULL, NULL, dev); } +static void apm_remove(gpr_device_t *gdev) +{ + snd_soc_unregister_component(&gdev->dev); +} + struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph, uint32_t mid) { struct audioreach_graph_info *info = graph->info; @@ -820,6 +825,7 @@ MODULE_DEVICE_TABLE(of, apm_device_id); static gpr_driver_t apm_driver = { .probe = apm_probe, + .remove = apm_remove, .gpr_callback = apm_callback, .driver = { .name = "qcom-apm", From b19b46979415fbd7fb333667c2537c6739e6a847 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 23 Feb 2026 18:07:28 +0000 Subject: [PATCH 433/438] FROMLIST: ASoC: qcom: q6apm: remove child devices when apm is removed looks like q6apm driver does not remove the child driver q6apm-dai and q6apm-bedais when the this driver is removed. Fix this by using a manage version of of_platfom_populate. With this change when the dsp is shutdown all the devices assocated with q6apm will now be removed. Link: https://lore.kernel.org/all/20260223180740.444311-3-srinivas.kandagatla@oss.qualcomm.com/ Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support") Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6apm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index fece0e3def232..1fbcbbf3123d4 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -753,7 +753,7 @@ static int apm_probe(gpr_device_t *gdev) return ret; } - return of_platform_populate(dev->of_node, NULL, NULL, dev); + return devm_of_platform_populate(dev); } static void apm_remove(gpr_device_t *gdev) From 4fbd58c55605e8d0a2e550e22d5e1cba24ef3806 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 23 Feb 2026 18:07:29 +0000 Subject: [PATCH 434/438] FROMLIST: ASoC: qcom: qdsp6: topology: check widget type before accessing data Check widget type before accessing the private data, as this could a virtual widget which is no associated with a dsp graph, container and module. Accessing witout check could lead to incorrect memory access. Link: https://lore.kernel.org/all/20260223180740.444311-4-srinivas.kandagatla@oss.qualcomm.com/ Fixes: 36ad9bf1d93d ("ASoC: qdsp6: audioreach: add topology support") Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/topology.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c index e732fac9b8ca0..1f69fba6de26d 100644 --- a/sound/soc/qcom/qdsp6/topology.c +++ b/sound/soc/qcom/qdsp6/topology.c @@ -952,9 +952,6 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp, struct audioreach_container *cont; struct audioreach_module *mod; - mod = dobj->private; - cont = mod->container; - if (w->id == snd_soc_dapm_mixer) { /* virtual widget */ struct snd_ar_control *scontrol = dobj->private; @@ -963,6 +960,11 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp, kfree(scontrol); return 0; } + mod = dobj->private; + if (!mod) + return 0; + + cont = mod->container; mutex_lock(&apm->lock); idr_remove(&apm->modules_idr, mod->instance_id); From 21bf7ca6e9dcdb825f6529bb673cb46865ab4665 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 4 Mar 2026 12:15:34 +0530 Subject: [PATCH 435/438] WORKAROUND: Revert "PCI: dwc: Remove MSI/MSIX capability for Root Port if iMSI-RX is used as MSI controller" commit f5cd8a929c825("PCI: dwc: Remove MSI/MSIX capability for Root Port if iMSI-RX is used as MSI controller") removed MSI & MSIX capability for Root port as dwc controller doesn't support to generate interrupt. Due to this pci framework is falling back to legacy IRQ's. Now controller can generate to interrupts with legacy IRQ's, and actually causing console flood with PCIe continous AER errorsi, these errors will not cause any functional issues. To avoid these errors revert this temporarly untill actual issue got root caused and fixed. Signed-off-by: Krishna Chaitanya Chundru --- drivers/pci/controller/dwc/pcie-designware-host.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 6ae6189e9b8a9..ff9d06c273cc4 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -1165,17 +1165,6 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp) dw_pcie_dbi_ro_wr_dis(pci); - /* - * The iMSI-RX module does not support receiving MSI or MSI-X generated - * by the Root Port. If iMSI-RX is used as the MSI controller, remove - * the MSI and MSI-X capabilities of the Root Port to allow the drivers - * to fall back to INTx instead. - */ - if (pp->use_imsi_rx) { - dw_pcie_remove_capability(pci, PCI_CAP_ID_MSI); - dw_pcie_remove_capability(pci, PCI_CAP_ID_MSIX); - } - return 0; } EXPORT_SYMBOL_GPL(dw_pcie_setup_rc); From af83f63d7ed7028d2158fabde2649939a9fcce43 Mon Sep 17 00:00:00 2001 From: Sushrut Shree Trivedi Date: Thu, 12 Feb 2026 16:14:01 +0530 Subject: [PATCH 436/438] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2-industrial-mezzanine: Add TC9563 PCIe switch node for PCIe0 Add a node for the TC9563 PCIe switch connected to PCIe0. The switch has three downstream ports.Two embedded Ethernet devices are present on one of the downstream ports. All the ports present in the node represent the downstream ports and embedded endpoints. Power to the TC9563 is supplied through two LDO regulators, which are on by default and are added as fixed regulators. TC9563 can be configured through I2C. Signed-off-by: Sushrut Shree Trivedi Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/lkml/20260212-industrial-mezzanine-pcie-v3-1-1e152937a76a@oss.qualcomm.com/ --- .../qcs6490-rb3gen2-industrial-mezzanine.dtso | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso index cc8ee16431679..41006fb4dcc03 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso @@ -5,6 +5,7 @@ /dts-v1/; /plugin/; +#include #include #include @@ -60,6 +61,37 @@ }; }; + vreg_0p9: regulator-vreg-0p9 { + compatible = "regulator-fixed"; + regulator-name = "VREG_0P9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-always-on; + regulator-boot-on; + vin-supply = <&vreg_dc_12v>; + }; + + vreg_1p8: regulator-vreg-1p8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + vin-supply = <&vreg_dc_12v>; + }; + + vreg_dc_12v: regulator-vreg-dc-12v { + compatible = "regulator-fixed"; + regulator-name = "VREG_DC_12V"; + regulator-min-microvolt = <24000000>; + regulator-max-microvolt = <24000000>; + + regulator-always-on; + regulator-boot-on; + }; }; &i2c1 { @@ -125,3 +157,112 @@ spi-max-frequency = <20000000>; }; }; + +&pcie0 { + iommu-map = <0x0 &apps_smmu 0x1c00 0x1>, + <0x100 &apps_smmu 0x1c01 0x1>, + <0x208 &apps_smmu 0x1c04 0x1>, + <0x210 &apps_smmu 0x1c05 0x1>, + <0x218 &apps_smmu 0x1c06 0x1>, + <0x300 &apps_smmu 0x1c07 0x1>, + <0x400 &apps_smmu 0x1c08 0x1>, + <0x500 &apps_smmu 0x1c09 0x1>, + <0x501 &apps_smmu 0x1c10 0x1>; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + status = "okay"; +}; + +&pcie0_port { + #address-cells = <3>; + #size-cells = <2>; + + pcie@0,0 { + compatible = "pci1179,0623"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x2 0xff>; + + vddc-supply = <&vreg_0p9>; + vdd18-supply = <&vreg_1p8>; + vdd09-supply = <&vreg_0p9>; + vddio1-supply = <&vreg_1p8>; + vddio2-supply = <&vreg_1p8>; + vddio18-supply = <&vreg_1p8>; + + i2c-parent = <&i2c1 0x77>; + + resx-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie0_tc9563_resx_n>; + pinctrl-names = "default"; + + pcie@1,0 { + reg = <0x20800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x3 0xff>; + }; + + pcie@2,0 { + reg = <0x21000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x4 0xff>; + }; + + pcie@3,0 { + reg = <0x21800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x5 0xff>; + + pci@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + + pci@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + }; + + }; +}; + +&tlmm { + pcie0_tc9563_resx_n: pcie0-tc9563-resx-state { + pins = "gpio78"; + function = "gpio"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; +}; From 00976f77482aaf1910a6b4257695e0ac4ef6165f Mon Sep 17 00:00:00 2001 From: Sushrut Shree Trivedi Date: Thu, 12 Feb 2026 16:14:02 +0530 Subject: [PATCH 437/438] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2-industrial-mezzanine: Add second TC9563 PCIe switch node for PCIe1 Add a node for the second TC9563 PCIe switch on PCIe1, which is connected in cascade to the first TC9563 switch via the former's downstream port. Two embedded Ethernet devices are present on one of the downstream ports of this second switch as well. All the ports present in the node represent the downstream ports and embedded endpoints. The second TC9563 is powered up via the same LDO regulators as the first one, and these can be controlled via two GPIOs, which are already present as fixed regulators. This TC9563 can also be configured through I2C. Signed-off-by: Sushrut Shree Trivedi Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/lkml/20260212-industrial-mezzanine-pcie-v3-2-1e152937a76a@oss.qualcomm.com/ --- .../qcs6490-rb3gen2-industrial-mezzanine.dtso | 105 ++++++++++++++++++ arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 2 +- 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso index 41006fb4dcc03..b37fb86108f67 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso @@ -255,6 +255,100 @@ }; }; +&pcie1 { + iommu-map = <0x0 &apps_smmu 0x1c80 0x1>, + <0x100 &apps_smmu 0x1c81 0x1>, + <0x208 &apps_smmu 0x1c84 0x1>, + <0x210 &apps_smmu 0x1c85 0x1>, + <0x218 &apps_smmu 0x1c86 0x1>, + <0x300 &apps_smmu 0x1c87 0x1>, + <0x408 &apps_smmu 0x1c90 0x1>, + <0x410 &apps_smmu 0x1c91 0x1>, + <0x418 &apps_smmu 0x1c92 0x1>, + <0x500 &apps_smmu 0x1c93 0x1>, + <0x600 &apps_smmu 0x1c94 0x1>, + <0x700 &apps_smmu 0x1c95 0x1>, + <0x701 &apps_smmu 0x1c96 0x1>, + <0x800 &apps_smmu 0x1c97 0x1>, + <0x900 &apps_smmu 0x1c98 0x1>, + <0x901 &apps_smmu 0x1c99 0x1>; +}; + +&pcie1_switch0_dsp1 { + #address-cells = <3>; + #size-cells = <2>; + + pcie@0,0 { + compatible = "pci1179,0623"; + reg = <0x30000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x2 0xff>; + + vddc-supply = <&vdd_ntn_0p9>; + vdd18-supply = <&vdd_ntn_1p8>; + vdd09-supply = <&vdd_ntn_0p9>; + vddio1-supply = <&vdd_ntn_1p8>; + vddio2-supply = <&vdd_ntn_1p8>; + vddio18-supply = <&vdd_ntn_1p8>; + + i2c-parent = <&i2c1 0x33>; + + resx-gpios = <&tlmm 124 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie1_tc9563_resx_n>; + pinctrl-names = "default"; + + pcie@1,0 { + reg = <0x40800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x3 0xff>; + }; + + pcie@2,0 { + reg = <0x41000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x4 0xff>; + }; + + pcie@3,0 { + reg = <0x41800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x5 0xff>; + + pci@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + + pci@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + }; + }; +}; + &tlmm { pcie0_tc9563_resx_n: pcie0-tc9563-resx-state { pins = "gpio78"; @@ -265,4 +359,15 @@ output-enable; power-source = <0>; }; + + pcie1_tc9563_resx_n: pcie1-tc9563-resx-state { + pins = "gpio124"; + function = "gpio"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; + }; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index b714394f9a469..d8b9b343cfa52 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -850,7 +850,7 @@ pinctrl-0 = <&tc9563_resx_n>; pinctrl-names = "default"; - pcie@1,0 { + pcie1_switch0_dsp1: pcie@1,0 { reg = <0x20800 0x0 0x0 0x0 0x0>; #address-cells = <3>; #size-cells = <2>; From c12d36209e6f8d749edf7d1085f219db7de5628b Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Wed, 4 Mar 2026 16:32:04 +0530 Subject: [PATCH 438/438] Add qcom-next log files for 20260304 Adding merge log file and topic_SHA1 file Signed-off-by: Salendarsingh Gaud --- qcom-next/merge.log | 444 +++++++++++++++++++++++++++++++++++++++++++ qcom-next/topic_SHA1 | 48 +++++ 2 files changed, 492 insertions(+) create mode 100644 qcom-next/merge.log create mode 100644 qcom-next/topic_SHA1 diff --git a/qcom-next/merge.log b/qcom-next/merge.log new file mode 100644 index 0000000000000..7446ef6f0679f --- /dev/null +++ b/qcom-next/merge.log @@ -0,0 +1,444 @@ +Verified existence of local and remote repos: Success +/local/mnt/workspace/automerge/actions-runner/_work/kernel-automation/kernel-automation/kernel-topics /local/mnt/workspace/automerge/actions-runner/_work/kernel-automation/kernel-automation/kernel-topics +Reuse-Recorded-Resolution: Enabled +Downloaded shared rerere cache +Local tree is clean +Removing old remotes ... +The remote kernel https://github.com/qualcomm-linux/kernel.git is no longer tracked. +Delete it [Y/n]? The remote origin https://github.com/qualcomm-linux/kernel-topics.git is no longer tracked. +Delete it [Y/n]? The remote trovalds https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git is no longer tracked. +Delete it [Y/n]? Done, removed 3 old remote(s). +Adding new remotes... +Adding remote baseline https://github.com/qualcomm-linux/kernel.git qcom-next-staging +Updating baseline +Adding remote tech/bsp/clk https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/clk +Updating tech/bsp/clk +Adding remote tech/bsp/interconnect https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/interconnect +Updating tech/bsp/interconnect +Adding remote tech/mem/secure-buffer https://github.com/qualcomm-linux/kernel-topics.git tech/mem/secure-buffer +Updating tech/mem/secure-buffer +Adding remote tech/security/firmware-smc https://github.com/qualcomm-linux/kernel-topics.git tech/security/firmware-smc +Updating tech/security/firmware-smc +Adding remote tech/bsp/soc-infra https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/soc-infra +Updating tech/bsp/soc-infra +Adding remote tech/debug/soc https://github.com/qualcomm-linux/kernel-topics.git tech/debug/soc +Updating tech/debug/soc +Adding remote tech/bsp/pinctrl https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/pinctrl +Updating tech/bsp/pinctrl +Adding remote tech/bsp/remoteproc https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/remoteproc +Updating tech/bsp/remoteproc +Adding remote tech/bus/peripherals https://github.com/qualcomm-linux/kernel-topics.git tech/bus/peripherals +Updating tech/bus/peripherals +Adding remote tech/bus/pci/all https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/all +Updating tech/bus/pci/all +Adding remote tech/bus/pci/mhi https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/mhi +Updating tech/bus/pci/mhi +Adding remote tech/bus/pci/phy https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/phy +Updating tech/bus/pci/phy +Adding remote tech/bus/pci/pwrctl https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/pwrctl +Updating tech/bus/pci/pwrctl +Adding remote tech/bus/usb/dwc https://github.com/qualcomm-linux/kernel-topics.git tech/bus/usb/dwc +Updating tech/bus/usb/dwc +Adding remote tech/bus/usb/gadget https://github.com/qualcomm-linux/kernel-topics.git tech/bus/usb/gadget +Updating tech/bus/usb/gadget +Adding remote tech/bus/usb/phy https://github.com/qualcomm-linux/kernel-topics.git tech/bus/usb/phy +Updating tech/bus/usb/phy +Adding remote tech/debug/eud https://github.com/qualcomm-linux/kernel-topics.git tech/debug/eud +Updating tech/debug/eud +Adding remote tech/debug/hwtracing https://github.com/qualcomm-linux/kernel-topics.git tech/debug/hwtracing +Updating tech/debug/hwtracing +Adding remote tech/debug/rdbg https://github.com/qualcomm-linux/kernel-topics.git tech/debug/rdbg +Updating tech/debug/rdbg +Adding remote tech/pmic/backlight https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/backlight +Updating tech/pmic/backlight +Adding remote tech/pmic/mfd https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/mfd +Updating tech/pmic/mfd +Adding remote tech/pmic/misc https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/misc +Updating tech/pmic/misc +Adding remote tech/pmic/regulator https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/regulator +Updating tech/pmic/regulator +Adding remote tech/pmic/supply https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/supply +Updating tech/pmic/supply +Adding remote tech/mem/dma-buf https://github.com/qualcomm-linux/kernel-topics.git tech/mem/dma-buf +Updating tech/mem/dma-buf +Adding remote tech/mem/iommu https://github.com/qualcomm-linux/kernel-topics.git tech/mem/iommu +Updating tech/mem/iommu +Adding remote tech/mm/audio/all https://github.com/qualcomm-linux/kernel-topics.git tech/mm/audio/all +Updating tech/mm/audio/all +Adding remote tech/mm/audio/soundwire https://github.com/qualcomm-linux/kernel-topics.git tech/mm/audio/soundwire +Updating tech/mm/audio/soundwire +Adding remote tech/mm/camss https://github.com/qualcomm-linux/kernel-topics.git tech/mm/camss +Updating tech/mm/camss +Adding remote tech/mm/drm https://github.com/qualcomm-linux/kernel-topics.git tech/mm/drm +Updating tech/mm/drm +Adding remote tech/mm/fastrpc https://github.com/qualcomm-linux/kernel-topics.git tech/mm/fastrpc +Updating tech/mm/fastrpc +Adding remote tech/mm/phy https://github.com/qualcomm-linux/kernel-topics.git tech/mm/phy +Updating tech/mm/phy +Adding remote tech/mm/video https://github.com/qualcomm-linux/kernel-topics.git tech/mm/video +Updating tech/mm/video +Adding remote tech/mm/gpu https://github.com/qualcomm-linux/kernel-topics.git tech/mm/gpu +Updating tech/mm/gpu +Adding remote tech/mproc/rpmsg https://github.com/qualcomm-linux/kernel-topics.git tech/mproc/rpmsg +Updating tech/mproc/rpmsg +Adding remote tech/mproc/qmi https://github.com/qualcomm-linux/kernel-topics.git tech/mproc/qmi +Updating tech/mproc/qmi +Adding remote tech/net/ath https://github.com/qualcomm-linux/kernel-topics.git tech/net/ath +Updating tech/net/ath +Adding remote tech/net/eth https://github.com/qualcomm-linux/kernel-topics.git tech/net/eth +Updating tech/net/eth +Adding remote tech/net/rmnet https://github.com/qualcomm-linux/kernel-topics.git tech/net/rmnet +Updating tech/net/rmnet +Adding remote tech/net/qrtr https://github.com/qualcomm-linux/kernel-topics.git tech/net/qrtr +Updating tech/net/qrtr +Adding remote tech/net/phy https://github.com/qualcomm-linux/kernel-topics.git tech/net/phy +Updating tech/net/phy +Adding remote tech/net/bluetooth https://github.com/qualcomm-linux/kernel-topics.git tech/net/bluetooth +Updating tech/net/bluetooth +Adding remote tech/pm/opp https://github.com/qualcomm-linux/kernel-topics.git tech/pm/opp +Updating tech/pm/opp +Adding remote tech/pm/pmdomain https://github.com/qualcomm-linux/kernel-topics.git tech/pm/pmdomain +Updating tech/pm/pmdomain +Adding remote tech/pm/power https://github.com/qualcomm-linux/kernel-topics.git tech/pm/power +Updating tech/pm/power +Adding remote tech/pm/thermal https://github.com/qualcomm-linux/kernel-topics.git tech/pm/thermal +Updating tech/pm/thermal +Adding remote tech/security/crypto https://github.com/qualcomm-linux/kernel-topics.git tech/security/crypto +Updating tech/security/crypto +Adding remote tech/security/fscrypt https://github.com/qualcomm-linux/kernel-topics.git tech/security/fscrypt +Updating tech/security/fscrypt +Adding remote tech/security/ice https://github.com/qualcomm-linux/kernel-topics.git tech/security/ice +Updating tech/security/ice +Adding remote tech/storage/nvmem https://github.com/qualcomm-linux/kernel-topics.git tech/storage/nvmem +Updating tech/storage/nvmem +Adding remote tech/storage/phy https://github.com/qualcomm-linux/kernel-topics.git tech/storage/phy +Updating tech/storage/phy +Adding remote tech/storage/all https://github.com/qualcomm-linux/kernel-topics.git tech/storage/all +Updating tech/storage/all +Adding remote tech/virt/gunyah https://github.com/qualcomm-linux/kernel-topics.git tech/virt/gunyah +Updating tech/virt/gunyah +Adding remote tech/all/dt/qcs6490 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs6490 +Updating tech/all/dt/qcs6490 +Adding remote tech/all/dt/qcs9100 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs9100 +Updating tech/all/dt/qcs9100 +Adding remote tech/all/dt/qcs8300 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs8300 +Updating tech/all/dt/qcs8300 +Adding remote tech/all/dt/qcs615 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs615 +Updating tech/all/dt/qcs615 +Adding remote tech/all/dt/agatti https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/agatti +Updating tech/all/dt/agatti +Adding remote tech/all/dt/hamoa https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/hamoa +Updating tech/all/dt/hamoa +Adding remote tech/all/dt/glymur https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/glymur +Updating tech/all/dt/glymur +Adding remote tech/all/dt/kaanapali https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/kaanapali +Updating tech/all/dt/kaanapali +Adding remote tech/all/dt/pakala https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/pakala +Updating tech/all/dt/pakala +Adding remote tech/all/config https://github.com/qualcomm-linux/kernel-topics.git tech/all/config +Updating tech/all/config +Adding remote tech/overlay/dt https://github.com/qualcomm-linux/kernel-topics.git tech/overlay/dt +Updating tech/overlay/dt +Adding remote tech/all/workaround https://github.com/qualcomm-linux/kernel-topics.git tech/all/workaround +Updating tech/all/workaround +Adding remote tech/mproc/all https://github.com/qualcomm-linux/kernel-topics.git tech/mproc/all +Updating tech/mproc/all +Adding remote tech/noup/debug/all https://github.com/qualcomm-linux/kernel-topics.git tech/noup/debug/all +Updating tech/noup/debug/all +Adding remote tech/hwe/unoq https://github.com/qualcomm-linux/kernel-topics.git tech/hwe/unoq +Updating tech/hwe/unoq +Done, added 69 new remote(s). +Updating the remotes ... +Updating tech/bsp/clk +Updating tech/bsp/interconnect +Updating tech/mem/secure-buffer +Updating tech/security/firmware-smc +Updating tech/bsp/soc-infra +Updating tech/debug/soc +Updating tech/bsp/pinctrl +Updating tech/bsp/remoteproc +Updating tech/bus/peripherals +Updating tech/bus/pci/all +Updating tech/bus/pci/mhi +Updating tech/bus/pci/phy +Updating tech/bus/pci/pwrctl +Updating tech/bus/usb/dwc +Updating tech/bus/usb/gadget +Updating tech/bus/usb/phy +Updating tech/debug/eud +Updating tech/debug/hwtracing +Updating tech/debug/rdbg +Updating tech/pmic/backlight +Updating tech/pmic/mfd +Updating tech/pmic/misc +Updating tech/pmic/regulator +Updating tech/pmic/supply +Updating tech/mem/dma-buf +Updating tech/mem/iommu +Updating tech/mm/audio/all +Updating tech/mm/audio/soundwire +Updating tech/mm/camss +Updating tech/mm/drm +Updating tech/mm/fastrpc +Updating tech/mm/phy +Updating tech/mm/video +Updating tech/mm/gpu +Updating tech/mproc/rpmsg +Updating tech/mproc/qmi +Updating tech/net/ath +Updating tech/net/eth +Updating tech/net/rmnet +Updating tech/net/qrtr +Updating tech/net/phy +Updating tech/net/bluetooth +Updating tech/pm/opp +Updating tech/pm/pmdomain +Updating tech/pm/power +Updating tech/pm/thermal +Updating tech/security/crypto +Updating tech/security/fscrypt +Updating tech/security/ice +Updating tech/storage/nvmem +Updating tech/storage/phy +Updating tech/storage/all +Updating tech/virt/gunyah +Updating tech/all/dt/qcs6490 +Updating tech/all/dt/qcs9100 +Updating tech/all/dt/qcs8300 +Updating tech/all/dt/qcs615 +Updating tech/all/dt/agatti +Updating tech/all/dt/hamoa +Updating tech/all/dt/glymur +Updating tech/all/dt/kaanapali +Updating tech/all/dt/pakala +Updating tech/all/config +Updating tech/overlay/dt +Updating tech/all/workaround +Updating tech/mproc/all +Updating tech/noup/debug/all +Updating tech/hwe/unoq +Done, updated 0 remote(s). +Updating baseline ... +Fetching baseline +latest tag/id is 11439c4635edd669ae435eec308f4ab8a0804808 +Done, updated baseline. +Latest tag is 11439c4635edd669ae435eec308f4ab8a0804808 +Create a new integration branch based on 11439c4635edd669ae435eec308f4ab8a0804808 +Merging topic branches... +------------------------------------------ + ** Merging topic branch: tech/bsp/clk/tech/bsp/clk +Merge successful : tech/bsp/clk : 5da9c61ec2c8bd995da2da70ba85d08a606f7bb6 : 12 +------------------------------------------ + ** Merging topic branch: tech/bsp/interconnect/tech/bsp/interconnect +Merge successful : tech/bsp/interconnect : e9171e9aefb18c3343ba123d70c676de820b7ac5 : 3 +------------------------------------------ + ** Merging topic branch: tech/mem/secure-buffer/tech/mem/secure-buffer +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/firmware-smc/tech/security/firmware-smc +Merge successful : tech/security/firmware-smc : a50984a91bb9d551ee48136ee2db90eca0929979 : 2 +------------------------------------------ + ** Merging topic branch: tech/bsp/soc-infra/tech/bsp/soc-infra +Merge successful : tech/bsp/soc-infra : c793ce5e280bffeca61ab6cdf9ef058c3ad92a99 : 5 +------------------------------------------ + ** Merging topic branch: tech/debug/soc/tech/debug/soc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/pinctrl/tech/bsp/pinctrl +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/remoteproc/tech/bsp/remoteproc +Merge successful : tech/bsp/remoteproc : 53b8ced13b8fbbf3e2e4547648cbc647e408b7e0 : 19 +------------------------------------------ + ** Merging topic branch: tech/bus/peripherals/tech/bus/peripherals +Merge successful : tech/bus/peripherals : 486bcf7a4a94e54abf5fd9e6cc6bf68eea22a5d6 : 1 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/all/tech/bus/pci/all +Merge successful : tech/bus/pci/all : ece953449797a67a6bca59f211113f3576ecd857 : 5 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/mhi/tech/bus/pci/mhi +Merge successful : tech/bus/pci/mhi : fb9c1632f424ecdcd7fef1205499a1b64d477cdc : 1 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/phy/tech/bus/pci/phy +Merge successful : tech/bus/pci/phy : e14cf42553bf18fce387080d7a54aa6f5be4bde8 : 2 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/pwrctl/tech/bus/pci/pwrctl +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/dwc/tech/bus/usb/dwc +Merge successful : tech/bus/usb/dwc : 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 : 2 +------------------------------------------ + ** Merging topic branch: tech/bus/usb/gadget/tech/bus/usb/gadget +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/phy/tech/bus/usb/phy +Merge successful : tech/bus/usb/phy : 9f9b6184b76f8a3c677ec883872fc61eaa908c6a : 17 +------------------------------------------ + ** Merging topic branch: tech/debug/eud/tech/debug/eud +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/debug/hwtracing/tech/debug/hwtracing +Merge successful : tech/debug/hwtracing : ef3b67a0f6fb192bc3a1145fb1f420f12562a69f : 30 +------------------------------------------ + ** Merging topic branch: tech/debug/rdbg/tech/debug/rdbg +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/backlight/tech/pmic/backlight +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/mfd/tech/pmic/mfd +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/misc/tech/pmic/misc +Merge successful : tech/pmic/misc : e6525e383cf7a4fe2a6f0b5713045620ef6a9b91 : 9 +------------------------------------------ + ** Merging topic branch: tech/pmic/regulator/tech/pmic/regulator +Merge successful : tech/pmic/regulator : 81fc8fbf0f0a02a7b2d855aee574b88bd7d59107 : 6 +------------------------------------------ + ** Merging topic branch: tech/pmic/supply/tech/pmic/supply +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/dma-buf/tech/mem/dma-buf +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/iommu/tech/mem/iommu +Merge successful : tech/mem/iommu : 4cff31be02c7cce3434b096cb6cba4c11fc7f3c7 : 3 +------------------------------------------ + ** Merging topic branch: tech/mm/audio/all/tech/mm/audio/all +Merge successful : tech/mm/audio/all : 4fbd58c55605e8d0a2e550e22d5e1cba24ef3806 : 9 +------------------------------------------ + ** Merging topic branch: tech/mm/audio/soundwire/tech/mm/audio/soundwire +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/camss/tech/mm/camss +Merge successful : tech/mm/camss : f57340e0da5a216055cdd0a0d1e11ef68d98f717 : 12 +------------------------------------------ + ** Merging topic branch: tech/mm/drm/tech/mm/drm +Merge successful : tech/mm/drm : 54bffffd0e3d05c00fcb65f915f0926b5b5f1167 : 11 +------------------------------------------ + ** Merging topic branch: tech/mm/fastrpc/tech/mm/fastrpc +Merge successful : tech/mm/fastrpc : c29b2a8795e0f64836ca9314837d167013d0699e : 5 +------------------------------------------ + ** Merging topic branch: tech/mm/phy/tech/mm/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/video/tech/mm/video +Merge successful : tech/mm/video : 947c848d2fa9533ce08f51d8825a1972a4110bd4 : 3 +------------------------------------------ + ** Merging topic branch: tech/mm/gpu/tech/mm/gpu +Merge successful : tech/mm/gpu : be65cc66fef5fa8f6494f6809c5a29bc45d9bd39 : 1 +------------------------------------------ + ** Merging topic branch: tech/mproc/rpmsg/tech/mproc/rpmsg +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mproc/qmi/tech/mproc/qmi +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/ath/tech/net/ath +Merge successful : tech/net/ath : 41856302b25c0b1bb43db7d16ee43cb7011558cf : 2 +------------------------------------------ + ** Merging topic branch: tech/net/eth/tech/net/eth +Merge successful : tech/net/eth : 49b156fb09e0950aab5d3b4d6f1a92a3a78766d1 : 1 +------------------------------------------ + ** Merging topic branch: tech/net/rmnet/tech/net/rmnet +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/qrtr/tech/net/qrtr +Merge successful : tech/net/qrtr : 64d75f7e2a793b65d86fd9b35f8d4c40595ba799 : 1 +------------------------------------------ + ** Merging topic branch: tech/net/phy/tech/net/phy +Merge successful : tech/net/phy : a3602e9cbd3dd4519ddc446ddba1261fe4e156bd : 1 +------------------------------------------ + ** Merging topic branch: tech/net/bluetooth/tech/net/bluetooth +Merge successful : tech/net/bluetooth : 45bd0756ae6c1c7113ca04465565bce389d73cbd : 2 +------------------------------------------ + ** Merging topic branch: tech/pm/opp/tech/pm/opp +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/pmdomain/tech/pm/pmdomain +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/power/tech/pm/power +Merge successful : tech/pm/power : 258cb82c0171c9e27437cb4d31db85e5360840b1 : 6 +------------------------------------------ + ** Merging topic branch: tech/pm/thermal/tech/pm/thermal +Merge successful : tech/pm/thermal : 74537a2f6688dda96a14b453163498d5f9062aec : 3 +------------------------------------------ + ** Merging topic branch: tech/security/crypto/tech/security/crypto +Merge successful : tech/security/crypto : a6ce790e0668cc6f98549c390017c5d1be5d983d : 12 +------------------------------------------ + ** Merging topic branch: tech/security/fscrypt/tech/security/fscrypt +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/ice/tech/security/ice +Merge successful : tech/security/ice : f6d0da7a04a6930481e39ca97cd39f4c64bb8132 : 12 +------------------------------------------ + ** Merging topic branch: tech/storage/nvmem/tech/storage/nvmem +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/storage/phy/tech/storage/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/storage/all/tech/storage/all +Merge successful : tech/storage/all : e254daed78f7b24bf852df097b78455ca142666a : 1 +------------------------------------------ + ** Merging topic branch: tech/virt/gunyah/tech/virt/gunyah +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs6490/tech/all/dt/qcs6490 +Merge successful : tech/all/dt/qcs6490 : 00976f77482aaf1910a6b4257695e0ac4ef6165f : 13 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs9100/tech/all/dt/qcs9100 +Merge successful : tech/all/dt/qcs9100 : 2d4fec0cface9aeed412416ff19903a69b65069c : 20 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs8300/tech/all/dt/qcs8300 +Merge successful : tech/all/dt/qcs8300 : 68163aba1a9edb45517946562eb933484fbc9e22 : 20 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs615/tech/all/dt/qcs615 +Merge successful : tech/all/dt/qcs615 : 18f326bc094c615894755a14ddbc2ca2198e6561 : 19 +------------------------------------------ + ** Merging topic branch: tech/all/dt/agatti/tech/all/dt/agatti +Merge successful : tech/all/dt/agatti : c828f10cd2c53b7ff2cc061e73b239973ee17bc6 : 1 +------------------------------------------ + ** Merging topic branch: tech/all/dt/hamoa/tech/all/dt/hamoa +Merge successful : tech/all/dt/hamoa : ca55fffe472bf48471465ef11ad52cb048ac1702 : 26 +------------------------------------------ + ** Merging topic branch: tech/all/dt/glymur/tech/all/dt/glymur +Merge successful : tech/all/dt/glymur : 97e364685f4a743083dbadddde72cdc1f7e8ab40 : 18 +------------------------------------------ + ** Merging topic branch: tech/all/dt/kaanapali/tech/all/dt/kaanapali +Merge failed, manual merge +No files need merging +[qcom-next 737ab83beb36] Merge remote-tracking branch tech/all/dt/kaanapali into qcom-next +Merge successful : tech/all/dt/kaanapali : bd309241c1a5817e1418b78c266df48886e4e6dd : 13 +------------------------------------------ + ** Merging topic branch: tech/all/dt/pakala/tech/all/dt/pakala +Merge successful : tech/all/dt/pakala : 7bfc082859703275f737027cb772055d109f9045 : 4 +------------------------------------------ + ** Merging topic branch: tech/all/config/tech/all/config +Merge successful : tech/all/config : 4a5ea14f1765b6f97b3dfdde6444d4c24c227537 : 46 +------------------------------------------ + ** Merging topic branch: tech/overlay/dt/tech/overlay/dt +Merge failed, manual merge +No files need merging +[qcom-next bd2862e0d022] Merge remote-tracking branch tech/overlay/dt into qcom-next +Merge successful : tech/overlay/dt : 5618ef740c6cdd3743304f6a727b1558937024de : 21 +------------------------------------------ + ** Merging topic branch: tech/all/workaround/tech/all/workaround +Merge successful : tech/all/workaround : 21bf7ca6e9dcdb825f6529bb673cb46865ab4665 : 6 +------------------------------------------ + ** Merging topic branch: tech/mproc/all/tech/mproc/all +Merge successful : tech/mproc/all : 0b822e26e8504392b11cf044b773f4ab494bb9fa : 3 +------------------------------------------ + ** Merging topic branch: tech/noup/debug/all/tech/noup/debug/all +Merge successful : tech/noup/debug/all : b3bff1d52bdf75862574b137b433e7541ce1637b : 13 +------------------------------------------ + ** Merging topic branch: tech/hwe/unoq/tech/hwe/unoq +Merge failed, manual merge +No files need merging +[qcom-next 4d36a7c45a48] Merge remote-tracking branch tech/hwe/unoq into qcom-next +Merge successful : tech/hwe/unoq : b392691156f531e39b61c7d00d9b4c0ca7067ef1 : 15 +Done, merged 46 topic(s). +[main 8736a51] New rr-cache entries from ci-merge + 1 file changed, 1984 insertions(+) + create mode 100644 rr-cache/14bb10df962cdccce8aabc681522e77f8fd40e1e/thisimage.1 diff --git a/qcom-next/topic_SHA1 b/qcom-next/topic_SHA1 new file mode 100644 index 0000000000000..ac2bbae58dca0 --- /dev/null +++ b/qcom-next/topic_SHA1 @@ -0,0 +1,48 @@ +Name SHA Commits +------------------------------------------------------------------------------------ +tech/bsp/clk 5da9c61ec2c8bd995da2da70ba85d08a606f7bb6 12 +tech/bsp/interconnect e9171e9aefb18c3343ba123d70c676de820b7ac5 3 +tech/security/firmware-smc a50984a91bb9d551ee48136ee2db90eca0929979 2 +tech/bsp/soc-infra c793ce5e280bffeca61ab6cdf9ef058c3ad92a99 5 +tech/bsp/remoteproc 53b8ced13b8fbbf3e2e4547648cbc647e408b7e0 19 +tech/bus/peripherals 486bcf7a4a94e54abf5fd9e6cc6bf68eea22a5d6 1 +tech/bus/pci/all ece953449797a67a6bca59f211113f3576ecd857 5 +tech/bus/pci/mhi fb9c1632f424ecdcd7fef1205499a1b64d477cdc 1 +tech/bus/pci/phy e14cf42553bf18fce387080d7a54aa6f5be4bde8 2 +tech/bus/usb/dwc 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 2 +tech/bus/usb/phy 9f9b6184b76f8a3c677ec883872fc61eaa908c6a 17 +tech/debug/hwtracing ef3b67a0f6fb192bc3a1145fb1f420f12562a69f 30 +tech/pmic/misc e6525e383cf7a4fe2a6f0b5713045620ef6a9b91 9 +tech/pmic/regulator 81fc8fbf0f0a02a7b2d855aee574b88bd7d59107 6 +tech/mem/iommu 4cff31be02c7cce3434b096cb6cba4c11fc7f3c7 3 +tech/mm/audio/all 4fbd58c55605e8d0a2e550e22d5e1cba24ef3806 9 +tech/mm/camss f57340e0da5a216055cdd0a0d1e11ef68d98f717 12 +tech/mm/drm 54bffffd0e3d05c00fcb65f915f0926b5b5f1167 11 +tech/mm/fastrpc c29b2a8795e0f64836ca9314837d167013d0699e 5 +tech/mm/video 947c848d2fa9533ce08f51d8825a1972a4110bd4 3 +tech/mm/gpu be65cc66fef5fa8f6494f6809c5a29bc45d9bd39 1 +tech/net/ath 41856302b25c0b1bb43db7d16ee43cb7011558cf 2 +tech/net/eth 49b156fb09e0950aab5d3b4d6f1a92a3a78766d1 1 +tech/net/qrtr 64d75f7e2a793b65d86fd9b35f8d4c40595ba799 1 +tech/net/phy a3602e9cbd3dd4519ddc446ddba1261fe4e156bd 1 +tech/net/bluetooth 45bd0756ae6c1c7113ca04465565bce389d73cbd 2 +tech/pm/power 258cb82c0171c9e27437cb4d31db85e5360840b1 6 +tech/pm/thermal 74537a2f6688dda96a14b453163498d5f9062aec 3 +tech/security/crypto a6ce790e0668cc6f98549c390017c5d1be5d983d 12 +tech/security/ice f6d0da7a04a6930481e39ca97cd39f4c64bb8132 12 +tech/storage/all e254daed78f7b24bf852df097b78455ca142666a 1 +tech/all/dt/qcs6490 00976f77482aaf1910a6b4257695e0ac4ef6165f 13 +tech/all/dt/qcs9100 2d4fec0cface9aeed412416ff19903a69b65069c 20 +tech/all/dt/qcs8300 68163aba1a9edb45517946562eb933484fbc9e22 20 +tech/all/dt/qcs615 18f326bc094c615894755a14ddbc2ca2198e6561 19 +tech/all/dt/agatti c828f10cd2c53b7ff2cc061e73b239973ee17bc6 1 +tech/all/dt/hamoa ca55fffe472bf48471465ef11ad52cb048ac1702 26 +tech/all/dt/glymur 97e364685f4a743083dbadddde72cdc1f7e8ab40 18 +tech/all/dt/kaanapali bd309241c1a5817e1418b78c266df48886e4e6dd 13 +tech/all/dt/pakala 7bfc082859703275f737027cb772055d109f9045 4 +tech/all/config 4a5ea14f1765b6f97b3dfdde6444d4c24c227537 46 +tech/overlay/dt 5618ef740c6cdd3743304f6a727b1558937024de 21 +tech/all/workaround 21bf7ca6e9dcdb825f6529bb673cb46865ab4665 6 +tech/mproc/all 0b822e26e8504392b11cf044b773f4ab494bb9fa 3 +tech/noup/debug/all b3bff1d52bdf75862574b137b433e7541ce1637b 13 +tech/hwe/unoq b392691156f531e39b61c7d00d9b4c0ca7067ef1 15