From 219530647416b7349b498e32caadea3bfc0dcf78 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Tue, 8 Jul 2025 14:55:00 +0800 Subject: [PATCH 001/659] FROMLIST: driver: bluetooth: hci_qca: fix ssr fail when BT_EN is consistently pulled up by hardware If BT_EN is consistently pulled up by hardware, the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits cannot be cleared by qca_setup during SSR. This leads to a failure to send commands due to the error state. To address this, clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits after the coredump collection is complete. Also, add a delay to wait for controller to complete SSR. Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20250825113858.4017780-1-quic_shuaz@quicinc.com/ --- drivers/bluetooth/hci_qca.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 33c43503714b8..907d4ca794dfb 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1653,6 +1653,23 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code) } clear_bit(QCA_HW_ERROR_EVENT, &qca->flags); + + /* + * If the SoC always enables the bt_en pin via hardware and the driver + * cannot control the bt_en pin of the SoC chip, then during SSR, + * the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits cannot be cleared. + * This leads to a reset command timeout failure. + * + * To address this, clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits + * after the coredump collection is complete. + * Also, add msleep delay to wait for controller to complete SSR. + */ + if (!hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) { + clear_bit(QCA_SSR_TRIGGERED, &qca->flags); + clear_bit(QCA_IBS_DISABLED, &qca->flags); + qca->tx_ibs_state = HCI_IBS_TX_AWAKE; + msleep(50); + } } static void qca_reset(struct hci_dev *hdev) From b5902f2daf61ad3eed61a9fbf3d75ba3748cf53e Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Tue, 8 Jul 2025 14:59:40 +0800 Subject: [PATCH 002/659] FROMLIST: driver: bluetooth: hci_qca: Multiple triggers of SSR only generate one coredump file Multiple triggers of SSR only first generate coredump file, duo to memcoredump_flag no clear. add clear coredump flag when ssr completed. Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20250825113858.4017780-1-quic_shuaz@quicinc.com/ --- drivers/bluetooth/hci_qca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 907d4ca794dfb..29e391058fee5 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1668,6 +1668,7 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code) clear_bit(QCA_SSR_TRIGGERED, &qca->flags); clear_bit(QCA_IBS_DISABLED, &qca->flags); qca->tx_ibs_state = HCI_IBS_TX_AWAKE; + qca->memdump_state = QCA_MEMDUMP_IDLE; msleep(50); } } From c29f570c16249b9ae1472b08a3570f2985fa5532 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 21 Oct 2025 10:39:54 +0530 Subject: [PATCH 003/659] 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 004/659] 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 005/659] 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 77748f75daa66e09c008ca52570d923c78ad9f6f Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 22 Oct 2025 00:28:42 -0700 Subject: [PATCH 006/659] FROMLIST: dt-bindings: soc: qcom,aoss-qmp: Document the Kaanapali AOSS channel Document the Always-On Subsystem side channel on the Qualcomm Kaanapali platform for communication with client found on the SoC such as remoteprocs. 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-2-3cd3f390f3e2@oss.qualcomm.com/ --- Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml index 851a1260f8dc8..57aa819939f00 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml @@ -25,6 +25,7 @@ properties: compatible: items: - enum: + - qcom,kaanapali-aoss-qmp - qcom,milos-aoss-qmp - qcom,qcs615-aoss-qmp - qcom,qcs8300-aoss-qmp From 6f257ae4c4d991dd1d9fbd42f79f305db9f0ef19 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Wed, 22 Oct 2025 00:28:44 -0700 Subject: [PATCH 007/659] FROMLIST: dt-bindings: soc: qcom,aoss-qmp: Document the Glymur AOSS side channel Document the Always-on Subsystem side channel on the Glymur SoC. Signed-off-by: Sibi Sankar 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-4-3cd3f390f3e2@oss.qualcomm.com/ --- Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml index 57aa819939f00..c5c1bac2db013 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml @@ -25,6 +25,7 @@ properties: compatible: items: - enum: + - qcom,glymur-aoss-qmp - qcom,kaanapali-aoss-qmp - qcom,milos-aoss-qmp - qcom,qcs615-aoss-qmp From a6f7092e9a363fd462a5825ff15a82af744793cb Mon Sep 17 00:00:00 2001 From: Kamal Wadhwa Date: Thu, 18 Sep 2025 14:57:01 +0530 Subject: [PATCH 008/659] 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 009/659] 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 010/659] 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 011/659] 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 012/659] 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 013/659] 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 c280d7e86faa86b16d3c1e313e95207503cf3770 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:22 +0530 Subject: [PATCH 014/659] 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 dc971666d63a5ebf84df3c98f552a50a8c586ed7 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Mon, 3 Nov 2025 20:59:28 +0530 Subject: [PATCH 015/659] FROMLIST: 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. Add support for the .irq_get_irqchip_state callback so remoteproc can read the current state of the fatal, ready and handover bits. Link: https://lore.kernel.org/r/20251103152929.2434911-2-deepak.singh@oss.qualcomm.com Signed-off-by: Chris Lew Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/smp2p.c | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index cb515c2340c10..39628df367458 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -48,6 +48,9 @@ #define SMP2P_MAGIC 0x504d5324 #define SMP2P_ALL_FEATURES SMP2P_FEATURE_SSR_ACK +#define ONE 1 +#define TWO 2 + /** * struct smp2p_smem_item - in memory communication structure * @magic: magic number @@ -222,6 +225,42 @@ 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 and set to v2. + * Early enumeration of inbound entries is required only + * for early boot processors which have smp2p version 2. + */ + if (in->version != TWO) + 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 +407,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 +676,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 2cf103048fa6404ba91ace93c35997fee43b7f7d Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Mon, 3 Nov 2025 20:59:29 +0530 Subject: [PATCH 016/659] FROMLIST: soc: qcom: smp2p: Add support for smp2p v2 Some remoteproc need smp2p v2 support, mirror the version written by the remote if the remote supports v2. This is needed if the remote does not have backwards compatibility with v1. And reset entry last value on SSR for smp2p v2. Link: https://lore.kernel.org/r/20251103152929.2434911-3-deepak.singh@oss.qualcomm.com Signed-off-by: Chris Lew Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/smp2p.c | 41 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 39628df367458..c35ca7535c144 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. + * + * Driver supports two versions: + * V1 - For processor that start after local host + * V2 - For processor that start in early boot sequence */ #define SMP2P_MAX_ENTRY 16 @@ -50,11 +54,12 @@ #define ONE 1 #define TWO 2 +#define MAX_VERSION TWO /** * 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 @@ -183,14 +188,23 @@ 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; if (!smp2p->ssr_ack_enabled) return false; restart = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT); + restart = restart != smp2p->ssr_ack; + if (restart && in->version > ONE) { + 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) @@ -225,6 +239,20 @@ static void qcom_smp2p_negotiate(struct qcom_smp2p *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]; @@ -522,6 +550,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)); @@ -543,12 +572,18 @@ 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\n"); + 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; + out->version = (in_version) ? in_version : 1; qcom_smp2p_kick(smp2p); From 231704f7d6c09ce72f65029c62e684d4883465c9 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Fri, 24 Oct 2025 15:03:21 +0530 Subject: [PATCH 017/659] FROMLIST: dt-bindings: spmi: split out common QCOM SPMI PMIC arbiter properties Split out the common SPMI PMIC arbiter properties for QCOM 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 PMIC v8 arbiter support patch, as the v8 arbiter also uses these common properties. Signed-off-by: Jishnu Prakash Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251024-pmic_arb_v8-v3-1-cad8d6a2cbc0@oss.qualcomm.com Signed-off-by: Rakesh Kota --- .../spmi/qcom,spmi-pmic-arb-common.yaml | 35 +++++++++++++++++++ .../bindings/spmi/qcom,spmi-pmic-arb.yaml | 17 +-------- .../spmi/qcom,x1e80100-spmi-pmic-arb.yaml | 21 +++-------- 3 files changed, 40 insertions(+), 33 deletions(-) create mode 100644 Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml new file mode 100644 index 0000000000000..8c38ed145e745 --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SPMI Controller (common) + +maintainers: + - David Collins + +description: | + This defines some common properties used to define Qualcomm SPMI controllers + for PMIC arbiter. + +properties: + qcom,ee: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: + indicates the active Execution Environment identifier + + qcom,channel: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: + which of the PMIC Arb provided channels to use for accesses + +required: + - qcom,ee + - qcom,channel + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml index 51daf1b847a9b..d0c683dd52841 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml @@ -19,6 +19,7 @@ description: | allOf: - $ref: spmi.yaml + - $ref: qcom,spmi-pmic-arb-common.yaml properties: compatible: @@ -71,20 +72,6 @@ properties: '#size-cells': true - qcom,ee: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - indicates the active Execution Environment identifier - - qcom,channel: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - which of the PMIC Arb provided channels to use for accesses - qcom,bus-id: $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 @@ -97,8 +84,6 @@ properties: required: - compatible - reg-names - - qcom,ee - - qcom,channel unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml index 7c3cc20a80d6c..08369fdd21612 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml @@ -17,6 +17,9 @@ description: | The PMIC Arbiter can also act as an interrupt controller, providing interrupts to slave devices. +allOf: + - $ref: qcom,spmi-pmic-arb-common.yaml + properties: compatible: oneOf: @@ -45,20 +48,6 @@ properties: '#size-cells': const: 2 - qcom,ee: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - indicates the active Execution Environment identifier - - qcom,channel: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - which of the PMIC Arb provided channels to use for accesses - patternProperties: "^spmi@[a-f0-9]+$": type: object @@ -96,10 +85,8 @@ patternProperties: required: - compatible - reg-names - - qcom,ee - - qcom,channel -additionalProperties: false +unevaluatedProperties: false examples: - | From 095d317c07b7e4bbe4052a97fce5029fbd19b1f6 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Fri, 24 Oct 2025 15:03:22 +0530 Subject: [PATCH 018/659] FROMLIST: dt-bindings: spmi: add support for glymur-spmi-pmic-arb (arbiter v8) SPMI PMIC Arbiter version 8 builds upon version 7 with support for up to four SPMI buses. To achieve this, the register map was slightly rearranged. Add a new binding file and compatible string for version 8 using the name 'glymur' as the Qualcomm Technologies, Inc. Glymur SoC is the first one to use PMIC arbiter version 8. This specifies the new register ranges needed only for version 8. Also document SPMI PMIC Arbiter for Qualcomm Kaanapali SoC, by adding fallback to Glymur compatible string, as it too has version 8 functionality. Signed-off-by: David Collins Signed-off-by: Pankaj Patil Signed-off-by: Kamal Wadhwa Signed-off-by: Jingyi Wang Signed-off-by: Jishnu Prakash Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251024-pmic_arb_v8-v3-2-cad8d6a2cbc0@oss.qualcomm.com Signed-off-by: Rakesh Kota --- .../spmi/qcom,glymur-spmi-pmic-arb.yaml | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml diff --git a/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml new file mode 100644 index 0000000000000..3b5005b96c6d5 --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml @@ -0,0 +1,150 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/qcom,glymur-spmi-pmic-arb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Glymur SPMI Controller (PMIC Arbiter v8) + +maintainers: + - David Collins + +description: | + The Glymur SPMI PMIC Arbiter implements HW version 8 and it's an SPMI + controller with wrapping arbitration logic to allow for multiple on-chip + devices to control up to 4 SPMI separate buses. + + The PMIC Arbiter can also act as an interrupt controller, providing interrupts + to slave devices. + +allOf: + - $ref: /schemas/spmi/qcom,spmi-pmic-arb-common.yaml + +properties: + compatible: + oneOf: + - items: + - enum: + - qcom,kaanapali-spmi-pmic-arb + - const: qcom,glymur-spmi-pmic-arb + - enum: + - qcom,glymur-spmi-pmic-arb + + reg: + items: + - description: core registers + - description: tx-channel per virtual slave registers + - description: rx-channel (called observer) per virtual slave registers + - description: channel to PMIC peripheral mapping registers + + reg-names: + items: + - const: core + - const: chnls + - const: obsrvr + - const: chnl_map + + ranges: true + + '#address-cells': + const: 2 + + '#size-cells': + const: 2 + +patternProperties: + "^spmi@[a-f0-9]+$": + type: object + $ref: /schemas/spmi/spmi.yaml + unevaluatedProperties: false + + properties: + reg: + items: + - description: configuration registers + - description: interrupt controller registers + - description: channel owner EE mapping registers + + reg-names: + items: + - const: cnfg + - const: intr + - const: chnl_owner + + interrupts: + maxItems: 1 + + interrupt-names: + const: periph_irq + + interrupt-controller: true + + '#interrupt-cells': + const: 4 + description: | + cell 1: slave ID for the requested interrupt (0-15) + cell 2: peripheral ID for requested interrupt (0-255) + cell 3: the requested peripheral interrupt (0-7) + cell 4: interrupt flags indicating level-sense information, + as defined in dt-bindings/interrupt-controller/irq.h + +required: + - compatible + - reg-names + +unevaluatedProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + arbiter@c400000 { + compatible = "qcom,glymur-spmi-pmic-arb"; + reg = <0x0 0xc400000 0x0 0x3000>, + <0x0 0xc900000 0x0 0x400000>, + <0x0 0xc4c0000 0x0 0x400000>, + <0x0 0xc403000 0x0 0x8000>; + reg-names = "core", "chnls", "obsrvr", "chnl_map"; + + qcom,ee = <0>; + qcom,channel = <0>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + spmi@c426000 { + reg = <0x0 0xc426000 0x0 0x4000>, + <0x0 0xc8c0000 0x0 0x10000>, + <0x0 0xc42a000 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@c437000 { + reg = <0x0 0xc437000 0x0 0x4000>, + <0x0 0xc8d0000 0x0 0x10000>, + <0x0 0xc43b000 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>; + }; + }; + }; From 45eaf11a441951a7b05dc4178fe45752e6177fbc Mon Sep 17 00:00:00 2001 From: David Collins Date: Fri, 24 Oct 2025 15:03:23 +0530 Subject: [PATCH 019/659] FROMLIST: spmi: spmi-pmic-arb: add support for PMIC arbiter v8 PMIC arbiter v8 supports up to 4 SPMI buses and up to 8192 PMIC peripherals. Its register map differs from v7 as several fields increased in size. Add support for PMIC arbiter version 8. Signed-off-by: David Collins Signed-off-by: Kamal Wadhwa Signed-off-by: Jishnu Prakash Link: https://lore.kernel.org/r/20251024-pmic_arb_v8-v3-3-cad8d6a2cbc0@oss.qualcomm.com Signed-off-by: Rakesh Kota --- drivers/spmi/spmi-pmic-arb.c | 324 +++++++++++++++++++++++++++++++---- 1 file changed, 294 insertions(+), 30 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 91581974ef84e..612736973e4b0 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -3,6 +3,7 @@ * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved. */ #include +#include #include #include #include @@ -25,10 +26,12 @@ #define PMIC_ARB_VERSION_V3_MIN 0x30000000 #define PMIC_ARB_VERSION_V5_MIN 0x50000000 #define PMIC_ARB_VERSION_V7_MIN 0x70000000 +#define PMIC_ARB_VERSION_V8_MIN 0x80000000 #define PMIC_ARB_INT_EN 0x0004 #define PMIC_ARB_FEATURES 0x0004 #define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0) +#define PMIC_ARB_FEATURES_V8_PERIPH_MASK GENMASK(12, 0) #define PMIC_ARB_FEATURES1 0x0008 @@ -50,9 +53,10 @@ #define SPMI_MAPPING_BIT_IS_1_RESULT(X) (((X) >> 0) & 0xFF) #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */ -#define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */ +#define PMIC_ARB_MAX_PPID BIT(13) #define PMIC_ARB_APID_VALID BIT(15) #define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24)) +#define PMIC_ARB_V8_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(31)) #define INVALID_EE 0xFF /* Ownership Table */ @@ -96,30 +100,33 @@ enum pmic_arb_channel { PMIC_ARB_CHANNEL_OBS, }; -#define PMIC_ARB_MAX_BUSES 2 +#define PMIC_ARB_MAX_BUSES 4 +#define PMIC_ARB_MAX_BUSES_V8 4 /* Maximum number of support PMIC peripherals */ #define PMIC_ARB_MAX_PERIPHS 512 #define PMIC_ARB_MAX_PERIPHS_V7 1024 +#define PMIC_ARB_MAX_PERIPHS_V8 8192 #define PMIC_ARB_TIMEOUT_US 1000 #define PMIC_ARB_MAX_TRANS_BYTES (8) #define PMIC_ARB_APID_MASK 0xFF #define PMIC_ARB_PPID_MASK 0xFFF +#define PMIC_ARB_V8_PPID_MASK 0x1FFF /* interrupt enable bit */ #define SPMI_PIC_ACC_ENABLE_BIT BIT(0) #define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \ - ((((slave_id) & 0xF) << 28) | \ - (((periph_id) & 0xFF) << 20) | \ - (((irq_id) & 0x7) << 16) | \ - (((apid) & 0x3FF) << 0)) + (FIELD_PREP(GENMASK(28, 24), (slave_id)) | \ + FIELD_PREP(GENMASK(23, 16), (periph_id)) | \ + FIELD_PREP(GENMASK(15, 13), (irq_id)) | \ + FIELD_PREP(GENMASK(12, 0), (apid))) -#define hwirq_to_sid(hwirq) (((hwirq) >> 28) & 0xF) -#define hwirq_to_per(hwirq) (((hwirq) >> 20) & 0xFF) -#define hwirq_to_irq(hwirq) (((hwirq) >> 16) & 0x7) -#define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x3FF) +#define hwirq_to_sid(hwirq) FIELD_GET(GENMASK(28, 24), (hwirq)) +#define hwirq_to_per(hwirq) FIELD_GET(GENMASK(23, 16), (hwirq)) +#define hwirq_to_irq(hwirq) FIELD_GET(GENMASK(15, 13), (hwirq)) +#define hwirq_to_apid(hwirq) FIELD_GET(GENMASK(12, 0), (hwirq)) struct pmic_arb_ver_ops; @@ -138,11 +145,12 @@ struct spmi_pmic_arb; * @domain: irq domain object for PMIC IRQ domain * @intr: address of the SPMI interrupt control registers. * @cnfg: address of the PMIC Arbiter configuration registers. + * @apid_owner: on v8: address of APID owner mapping table registers * @spmic: spmi controller registered for this bus * @lock: lock to synchronize accesses. - * @base_apid: on v7: minimum APID associated with the particular SPMI - * bus instance - * @apid_count: on v5 and v7: number of APIDs associated with the + * @base_apid: on v7 and v8: minimum APID associated with the + * particular SPMI bus instance + * @apid_count: on v5, v7 and v8: number of APIDs associated with the * particular SPMI bus instance * @mapping_table: in-memory copy of PPID -> APID mapping table. * @mapping_table_valid:bitmap containing valid-only periphs @@ -159,6 +167,7 @@ struct spmi_pmic_arb_bus { struct irq_domain *domain; void __iomem *intr; void __iomem *cnfg; + void __iomem *apid_owner; struct spmi_controller *spmic; raw_spinlock_t lock; u16 base_apid; @@ -181,6 +190,7 @@ struct spmi_pmic_arb_bus { * @wr_base: on v1 "core", on v2 "chnls" register base off DT. * @core: core register base for v2 and above only (see above) * @core_size: core register base size + * @apid_map: on v8, APID mapping table register base * @channel: execution environment channel to use for accesses. * @ee: the current Execution Environment * @ver_ops: version dependent operations. @@ -193,6 +203,7 @@ struct spmi_pmic_arb { void __iomem *wr_base; void __iomem *core; resource_size_t core_size; + void __iomem *apid_map; u8 channel; u8 ee; const struct pmic_arb_ver_ops *ver_ops; @@ -206,6 +217,7 @@ struct spmi_pmic_arb { * * @ver_str: version string. * @get_core_resources: initializes the core, observer and channels + * @get_bus_resources: requests per-SPMI bus register resources * @init_apid: finds the apid base and count * @ppid_to_apid: finds the apid for a given ppid. * @non_data_cmd: on v1 issues an spmi non-data command. @@ -227,6 +239,9 @@ struct spmi_pmic_arb { struct pmic_arb_ver_ops { const char *ver_str; int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); + int (*get_bus_resources)(struct platform_device *pdev, + struct device_node *node, + struct spmi_pmic_arb_bus *bus); int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index); int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ @@ -656,7 +671,7 @@ static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid) unsigned int irq; u32 status, id; int handled = 0; - u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF; + u8 sid = (bus->apid_data[apid].ppid >> 8) & 0x1F; u8 per = bus->apid_data[apid].ppid & 0xFF; status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid)); @@ -686,7 +701,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) int last = bus->max_apid; /* * acc_offset will be non-zero for the secondary SPMI bus instance on - * v7 controllers. + * v7 and v8 controllers. */ int acc_offset = bus->base_apid >> 5; u8 ee = pmic_arb->ee; @@ -913,7 +928,7 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d, return -EINVAL; if (fwspec->param_count != 4) return -EINVAL; - if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7) + if (intspec[0] > 0x1F || intspec[1] > 0xFF || intspec[2] > 0x7) return -EINVAL; ppid = intspec[0] << 8 | intspec[1]; @@ -1160,6 +1175,24 @@ static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid) return apid_valid & ~PMIC_ARB_APID_VALID; } +static void pmic_arb_dump_apid_map(struct spmi_pmic_arb_bus *bus) +{ + struct apid_data *apidd; + u16 apid, ppid; + + /* Dump the mapping table for debug purposes. */ + dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); + for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) { + apid = bus->ppid_to_apid[ppid]; + if (apid & PMIC_ARB_APID_VALID) { + apid &= ~PMIC_ARB_APID_VALID; + apidd = &bus->apid_data[apid]; + dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n", + ppid, apid, apidd->write_ee, apidd->irq_ee); + } + } +} + static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; @@ -1222,17 +1255,7 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) bus->last_apid = i; } - /* Dump the mapping table for debug purposes. */ - dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); - for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) { - apid = bus->ppid_to_apid[ppid]; - if (apid & PMIC_ARB_APID_VALID) { - apid &= ~PMIC_ARB_APID_VALID; - apidd = &bus->apid_data[apid]; - dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n", - ppid, apid, apidd->write_ee, apidd->irq_ee); - } - } + pmic_arb_dump_apid_map(bus); return 0; } @@ -1346,7 +1369,7 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev, } /* - * Only v7 supports 2 buses. Each bus will get a different apid count, read + * Arbiter v7 supports 2 buses. Each bus will get a different apid count, read * from different registers. */ static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) @@ -1424,6 +1447,185 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, return offset; } +static int pmic_arb_get_core_resources_v8(struct platform_device *pdev, + void __iomem *core) +{ + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + + pmic_arb->apid_map = devm_platform_ioremap_resource_byname(pdev, + "chnl_map"); + if (IS_ERR(pmic_arb->apid_map)) + return PTR_ERR(pmic_arb->apid_map); + + pmic_arb->core = core; + + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V8; + + return pmic_arb_get_obsrvr_chnls_v2(pdev); +} + +static int pmic_arb_get_bus_resources_v8(struct platform_device *pdev, + struct device_node *node, + struct spmi_pmic_arb_bus *bus) +{ + int index; + + index = of_property_match_string(node, "reg-names", "chnl_owner"); + if (index < 0) { + dev_err(&pdev->dev, "chnl_owner reg region missing\n"); + return -EINVAL; + } + + bus->apid_owner = devm_of_iomap(&pdev->dev, node, index, NULL); + + return PTR_ERR_OR_ZERO(bus->apid_owner); +} + +static int pmic_arb_read_apid_map_v8(struct spmi_pmic_arb_bus *bus) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + struct apid_data *apidd; + struct apid_data *prev_apidd; + u16 i, apid, ppid, apid_max; + bool valid, is_irq_ee; + u32 regval, offset; + + /* + * In order to allow multiple EEs to write to a single PPID in arbiter + * version 8, there can be more than one APID mapped to each PPID. The + * owner field for each of these mappings specifies the EE which is + * allowed to write to the APID. The owner of the last (highest) APID + * which has the IRQ owner bit set for a given PPID will receive + * interrupts from the PPID. + * + * In arbiter version 8, the APID numbering space is divided between + * the SPMI buses according to this mapping: + * APID = 0 to N-1 --> bus 0 + * APID = N to N+M-1 --> bus 1 + * APID = N+M to N+M+P-1 --> bus 2 + * APID = N+M+P to N+M+P+Q-1 --> bus 3 + * where N = number of APIDs supported by bus 0 + * M = number of APIDs supported by bus 1 + * P = number of APIDs supported by bus 2 + * Q = number of APIDs supported by bus 3 + */ + apidd = &bus->apid_data[bus->base_apid]; + apid_max = bus->base_apid + bus->apid_count; + for (i = bus->base_apid; i < apid_max; i++, apidd++) { + offset = pmic_arb->ver_ops->apid_map_offset(i); + regval = readl_relaxed(pmic_arb->apid_map + offset); + if (!regval) + continue; + ppid = regval & PMIC_ARB_V8_PPID_MASK; + is_irq_ee = PMIC_ARB_V8_CHAN_IS_IRQ_OWNER(regval); + + regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i)); + apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); + + apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE; + + valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID; + apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; + prev_apidd = &bus->apid_data[apid]; + + if (!valid || apidd->write_ee == pmic_arb->ee) { + /* First PPID mapping or one for this EE */ + bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; + } else if (valid && is_irq_ee && + prev_apidd->write_ee == pmic_arb->ee) { + /* + * Duplicate PPID mapping after the one for this EE; + * override the irq owner + */ + prev_apidd->irq_ee = apidd->irq_ee; + } + + apidd->ppid = ppid; + bus->last_apid = i; + } + + pmic_arb_dump_apid_map(bus); + + return 0; +} + +static int pmic_arb_init_apid_v8(struct spmi_pmic_arb_bus *bus, int index) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + int ret, i; + + if (index < 0 || index >= PMIC_ARB_MAX_BUSES_V8) { + dev_err(&bus->spmic->dev, "Unsupported bus index %d detected\n", + index); + return -EINVAL; + } + + bus->base_apid = 0; + bus->apid_count = 0; + for (i = 0; i <= index; i++) { + bus->base_apid += bus->apid_count; + bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES + i * 4) & + PMIC_ARB_FEATURES_V8_PERIPH_MASK; + } + + if (bus->apid_count == 0) { + dev_err(&bus->spmic->dev, "Bus %d not implemented\n", index); + return -EINVAL; + } else if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { + dev_err(&bus->spmic->dev, "Unsupported max APID %d detected\n", + bus->base_apid + bus->apid_count); + return -EINVAL; + } + + ret = pmic_arb_init_apid_min_max(bus); + if (ret) + return ret; + + ret = pmic_arb_read_apid_map_v8(bus); + if (ret) { + dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + ret); + return ret; + } + + return 0; +} + +/* + * v8 offset per ee and per apid for observer channels and per apid for + * read/write channels. + */ +static int pmic_arb_offset_v8(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + u16 apid; + int rc; + u32 offset = 0; + u16 ppid = (sid << 8) | (addr >> 8); + + rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); + if (rc < 0) + return rc; + + apid = rc; + switch (ch_type) { + case PMIC_ARB_CHANNEL_OBS: + offset = 0x40000 * pmic_arb->ee + 0x20 * apid; + break; + case PMIC_ARB_CHANNEL_RW: + if (bus->apid_data[apid].write_ee != pmic_arb->ee) { + dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", + sid, addr); + return -EPERM; + } + offset = 0x200 * apid; + break; + } + + return offset; +} + static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc) { return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); @@ -1490,6 +1692,14 @@ pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n) return pmic_arb->wr_base + 0x100 + 0x1000 * n; } +static void __iomem * +pmic_arb_acc_enable_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + + return pmic_arb->wr_base + 0x100 + 0x200 * n; +} + static void __iomem * pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n) { @@ -1516,6 +1726,14 @@ pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n) return pmic_arb->wr_base + 0x104 + 0x1000 * n; } +static void __iomem * +pmic_arb_irq_status_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + + return pmic_arb->wr_base + 0x104 + 0x200 * n; +} + static void __iomem * pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n) { @@ -1542,6 +1760,14 @@ pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n) return pmic_arb->wr_base + 0x108 + 0x1000 * n; } +static void __iomem * +pmic_arb_irq_clear_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + + return pmic_arb->wr_base + 0x108 + 0x200 * n; +} + static u32 pmic_arb_apid_map_offset_v2(u16 n) { return 0x800 + 0x4 * n; @@ -1557,6 +1783,12 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n) return 0x2000 + 0x4 * n; } +static u32 pmic_arb_apid_map_offset_v8(u16 n) +{ + /* For v8, offset is from "chnl_map" base register, not "core". */ + return 0x4 * n; +} + static void __iomem * pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n) { @@ -1564,7 +1796,7 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n) } /* - * For arbiter version 7, APID ownership table registers have independent + * For arbiter version 7 and 8, APID ownership table registers have independent * numbering space for each SPMI bus instance, so each is indexed starting from * 0. */ @@ -1574,6 +1806,12 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n) return bus->cnfg + 0x4 * (n - bus->base_apid); } +static void __iomem * +pmic_arb_apid_owner_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + return bus->apid_owner + 0x4 * (n - bus->base_apid); +} + static const struct pmic_arb_ver_ops pmic_arb_v1 = { .ver_str = "v1", .get_core_resources = pmic_arb_get_core_resources_v1, @@ -1654,6 +1892,23 @@ static const struct pmic_arb_ver_ops pmic_arb_v7 = { .apid_owner = pmic_arb_apid_owner_v7, }; +static const struct pmic_arb_ver_ops pmic_arb_v8 = { + .ver_str = "v8", + .get_core_resources = pmic_arb_get_core_resources_v8, + .get_bus_resources = pmic_arb_get_bus_resources_v8, + .init_apid = pmic_arb_init_apid_v8, + .ppid_to_apid = pmic_arb_ppid_to_apid_v5, + .non_data_cmd = pmic_arb_non_data_cmd_v2, + .offset = pmic_arb_offset_v8, + .fmt_cmd = pmic_arb_fmt_cmd_v2, + .owner_acc_status = pmic_arb_owner_acc_status_v7, + .acc_enable = pmic_arb_acc_enable_v8, + .irq_status = pmic_arb_irq_status_v8, + .irq_clear = pmic_arb_irq_clear_v8, + .apid_map_offset = pmic_arb_apid_map_offset_v8, + .apid_owner = pmic_arb_apid_owner_v8, +}; + static const struct irq_domain_ops pmic_arb_irq_domain_ops = { .activate = qpnpint_irq_domain_activate, .alloc = qpnpint_irq_domain_alloc, @@ -1731,6 +1986,12 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, bus->spmic = ctrl; bus->id = bus_index; + if (pmic_arb->ver_ops->get_bus_resources) { + ret = pmic_arb->ver_ops->get_bus_resources(pdev, node, bus); + if (ret) + return ret; + } + ret = pmic_arb->ver_ops->init_apid(bus, bus_index); if (ret) return ret; @@ -1825,8 +2086,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->ver_ops = &pmic_arb_v3; else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) pmic_arb->ver_ops = &pmic_arb_v5; - else + else if (hw_ver < PMIC_ARB_VERSION_V8_MIN) pmic_arb->ver_ops = &pmic_arb_v7; + else + pmic_arb->ver_ops = &pmic_arb_v8; err = pmic_arb->ver_ops->get_core_resources(pdev, core); if (err) @@ -1875,6 +2138,7 @@ static void spmi_pmic_arb_remove(struct platform_device *pdev) static const struct of_device_id spmi_pmic_arb_match_table[] = { { .compatible = "qcom,spmi-pmic-arb", }, { .compatible = "qcom,x1e80100-spmi-pmic-arb", }, + { .compatible = "qcom,glymur-spmi-pmic-arb", }, {}, }; MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table); From a322705938efa75ae9b95883d630deb756c0ed91 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 27 Oct 2025 14:22:49 -0700 Subject: [PATCH 020/659] FROMLIST: dt-bindings: soc: qcom: qcom,pmic-glink: Add Kaanapali and Glymur compatibles Document the Kaanapali and Glymur compatibles used to describe the PMIC glink on each platform. Kaanapali will have the same battery supply properties as sm8550 platforms so define qcom,sm8550-pmic-glink as fallback for Kaanapali. Glymur will have the same battery supply properties as x1e80100 platforms so define qcom,x1e80100-pmic-glink as fallback for Glymur. Signed-off-by: Anjelique Melendez Link: https://lore.kernel.org/r/20251027212250.3847537-2-anjelique.melendez@oss.qualcomm.com Signed-off-by: Rakesh Kota --- .../devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml | 7 +++++++ 1 file changed, 7 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..c570221094197 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml @@ -37,12 +37,19 @@ properties: - const: qcom,pmic-glink - items: - enum: + - qcom,kaanapali-pmic-glink - qcom,milos-pmic-glink - qcom,sm8650-pmic-glink - qcom,sm8750-pmic-glink - qcom,x1e80100-pmic-glink - const: qcom,sm8550-pmic-glink - const: qcom,pmic-glink + - items: + - enum: + - qcom,glymur-pmic-glink + - const: qcom,x1e80100-pmic-glink + - const: qcom,sm8550-pmic-glink + - const: qcom,pmic-glink '#address-cells': const: 1 From 30e0cc068de7db63565a371ba3c220ea4dc92785 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 27 Oct 2025 14:22:50 -0700 Subject: [PATCH 021/659] FROMLIST: soc: qcom: pmic_glink: Add charger PDR service path and service name 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 PMICs. For example, on Kaanapali and Glymur, Charger FW runs on SOCCP(another subsystem) which does not have any specific charger PDs defined. Define charger PDR service path and service name as client data so that each PMIC generation can properly define these paths. While at it, add the qcom,kaanapali-pmic-glink and qcom,glymur-pmic-glink compatible strings. Signed-off-by: Anjelique Melendez Link: https://lore.kernel.org/r/20251027212250.3847537-3-anjelique.melendez@oss.qualcomm.com Signed-off-by: Rakesh Kota --- drivers/soc/qcom/pmic_glink.c | 66 ++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index c0a4be5df9267..aa5ba9a0285e5 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; + char *charger_pdr_service_name; + 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; @@ -285,7 +291,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; @@ -302,12 +307,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), @@ -315,27 +318,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); @@ -345,13 +351,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); @@ -365,23 +371,35 @@ 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_sm8450_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 pmic_glink_data pmic_glink_kaanapali_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,pmic-glink", .data = &pmic_glink_sm8450_client_mask }, + { .compatible = "qcom,glymur-pmic-glink", .data = &pmic_glink_kaanapali_data }, + { .compatible = "qcom,kaanapali-pmic-glink", .data = &pmic_glink_kaanapali_data }, + { .compatible = "qcom,pmic-glink", .data = &pmic_glink_sm8450_data }, {} }; MODULE_DEVICE_TABLE(of, pmic_glink_of_match); From 0903ea9aa92cbb5c5094c713b2d7527094d9451b Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 22:31:02 +0530 Subject: [PATCH 022/659] FROMGIT: dt-bindings: pinctrl: qcom,pmic-gpio: Add GPIO bindings for Glymur PMICs Update the Qualcomm Technologies, Inc. PMIC GPIO binding documentation to include compatible strings for PMK8850, PMH0101, PMH0104, PMH0110 and PMCX0102 PMICs. Signed-off-by: Anjelique Melendez Signed-off-by: Jishnu Prakash Signed-off-by: Pankaj Patil Signed-off-by: Kamal Wadhwa Reviewed-by: Bartosz Golaszewski Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250924-glymur-pinctrl-driver-v2-1-11bef014a778@oss.qualcomm.com Signed-off-by: Kamal Wadhwa --- .../bindings/pinctrl/qcom,pmic-gpio.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index 5e6dfcc3fe9b3..8ae4489637f3d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -59,7 +59,11 @@ properties: - qcom,pmc8180-gpio - qcom,pmc8180c-gpio - qcom,pmc8380-gpio + - qcom,pmcx0102-gpio - qcom,pmd8028-gpio + - qcom,pmh0101-gpio + - qcom,pmh0104-gpio + - qcom,pmh0110-gpio - qcom,pmi632-gpio - qcom,pmi8950-gpio - qcom,pmi8994-gpio @@ -68,6 +72,7 @@ properties: - qcom,pmiv0104-gpio - qcom,pmk8350-gpio - qcom,pmk8550-gpio + - qcom,pmk8850-gpio - qcom,pmm8155au-gpio - qcom,pmm8654au-gpio - qcom,pmp8074-gpio @@ -191,6 +196,8 @@ allOf: - qcom,pm8950-gpio - qcom,pm8953-gpio - qcom,pmi632-gpio + - qcom,pmh0104-gpio + - qcom,pmk8850-gpio then: properties: gpio-line-names: @@ -303,6 +310,8 @@ allOf: compatible: contains: enum: + - qcom,pmcx0102-gpio + - qcom,pmh0110-gpio - qcom,pmi8998-gpio then: properties: @@ -318,6 +327,7 @@ allOf: compatible: contains: enum: + - qcom,pmh0101-gpio - qcom,pmih0108-gpio then: properties: @@ -481,13 +491,18 @@ $defs: - gpio1-gpio22 for pm8994 - gpio1-gpio26 for pm8998 - gpio1-gpio22 for pma8084 + - gpio1-gpio14 for pmcx0102 - gpio1-gpio4 for pmd8028 + - gpio1-gpio18 for pmh0101 + - gpio1-gpio8 for pmh0104 + - gpio1-gpio14 for pmh0110 - gpio1-gpio8 for pmi632 - gpio1-gpio2 for pmi8950 - gpio1-gpio10 for pmi8994 - gpio1-gpio18 for pmih0108 - gpio1-gpio4 for pmk8350 - gpio1-gpio6 for pmk8550 + - gpio1-gpio8 for pmk8850 - gpio1-gpio10 for pmm8155au - gpio1-gpio12 for pmm8654au - gpio1-gpio12 for pmp8074 (holes on gpio1 and gpio12) From 06f8c0d26ca68aa7411d08e8364325a7557a5bed Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Wed, 24 Sep 2025 22:31:03 +0530 Subject: [PATCH 023/659] FROMGIT: pinctrl: qcom: spmi-gpio: Add PMCX0102, PMK8850 & PMH01XX PMICs support Add support for PMCX0102, PMH0101, PMH0104, PMH0110 and PMK8850 PMIC GPIOs with adding appropriate compatible strings. Signed-off-by: Anjelique Melendez Signed-off-by: Jishnu Prakash Signed-off-by: Kamal Wadhwa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250924-glymur-pinctrl-driver-v2-2-11bef014a778@oss.qualcomm.com Signed-off-by: Kamal Wadhwa --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 485b68cc93f8e..c4f7d2d7a0176 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1239,7 +1239,11 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 }, { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, { .compatible = "qcom,pmc8380-gpio", .data = (void *) 10 }, + { .compatible = "qcom,pmcx0102-gpio", .data = (void *)14 }, { .compatible = "qcom,pmd8028-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pmh0101-gpio", .data = (void *)18 }, + { .compatible = "qcom,pmh0104-gpio", .data = (void *)8 }, + { .compatible = "qcom,pmh0110-gpio", .data = (void *)14 }, { .compatible = "qcom,pmi632-gpio", .data = (void *) 8 }, { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 }, { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, @@ -1248,6 +1252,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pmiv0104-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmk8550-gpio", .data = (void *) 6 }, + { .compatible = "qcom,pmk8850-gpio", .data = (void *)8 }, { .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmm8654au-gpio", .data = (void *) 12 }, /* pmp8074 has 12 GPIOs with holes on 1 and 12 */ From 62c1622f81ba726b49b2ba43e68e45ed28b3820c Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 24 Sep 2025 22:31:04 +0530 Subject: [PATCH 024/659] FROMGIT:pinctrl: qcom: spmi-gpio: add support for {LV_VIN2, MV_VIN3}_CLK subtypes Add support for SPMI PMIC GPIO subtypes GPIO_LV_VIN2_CLK and GPIO_MV_VIN3_CLK. Signed-off-by: Subbaraman Narayanamurthy Signed-off-by: Jishnu Prakash Signed-off-by: Kamal Wadhwa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250924-glymur-pinctrl-driver-v2-3-11bef014a778@oss.qualcomm.com Signed-off-by: Kamal Wadhwa --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index c4f7d2d7a0176..83f940fe30b26 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -42,6 +42,8 @@ #define PMIC_GPIO_SUBTYPE_GPIO_MV 0x11 #define PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2 0x12 #define PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3 0x13 +#define PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2_CLK 0x14 +#define PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3_CLK 0x15 #define PMIC_MPP_REG_RT_STS 0x10 #define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 @@ -852,11 +854,13 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state, pad->lv_mv_type = true; break; case PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2: + case PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2_CLK: pad->num_sources = 2; pad->have_buffer = true; pad->lv_mv_type = true; break; case PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3: + case PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3_CLK: pad->num_sources = 3; pad->have_buffer = true; pad->lv_mv_type = true; From 486bcf7a4a94e54abf5fd9e6cc6bf68eea22a5d6 Mon Sep 17 00:00:00 2001 From: Jyothi Kumar Seerapu Date: Wed, 5 Nov 2025 19:00:42 -0800 Subject: [PATCH 025/659] 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 026/659] 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 2c0e8b5326b2281b2c6c63aaf73442ce97d4a168 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 16:43:06 -0700 Subject: [PATCH 027/659] FROMLIST: dt-bindings: mfd: qcom,spmi-pmic: Document PMICs present on Kaanapali Document compatibles for the pmh0101, pmh0104, pmh0110 and pmk8850 SPMI PMICs. Signed-off-by: Jishnu Prakash Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20250924-knp-pmic-binding-v1-1-b9cce48b8460@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 078a6886f8b1e..427023cb11c5e 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -78,6 +78,9 @@ properties: - qcom,pmc8380 - qcom,pmd8028 - qcom,pmd9635 + - qcom,pmh0101 + - qcom,pmh0104 + - qcom,pmh0110 - qcom,pmi632 - qcom,pmi8950 - qcom,pmi8962 @@ -87,6 +90,7 @@ properties: - qcom,pmk8002 - qcom,pmk8350 - qcom,pmk8550 + - qcom,pmk8850 - qcom,pmm8155au - qcom,pmm8654au - qcom,pmp8074 From c7a9ba0683a15b1bf60e2c9d70f2404f9f183181 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 16:43:33 -0700 Subject: [PATCH 028/659] FROMLIST: dt-bindings: leds: leds-qcom-lpg: Add support for PMH0101 PWM Add support for PMH0101 PWM modules which are compatible with the PM8350c PWM modules. Signed-off-by: Jishnu Prakash Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20250924-knp-pmic-peri-v2-1-32316039db2f@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml index 841a0229c472a..1278152e8eed1 100644 --- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml @@ -38,6 +38,7 @@ properties: - items: - enum: - qcom,pm8550-pwm + - qcom,pmh0101-pwm - const: qcom,pm8350c-pwm - items: - enum: From cee8f43df808c9c45c14f796a5c5a21b2d52ca95 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 16:43:34 -0700 Subject: [PATCH 029/659] FROMLIST: dt-bindings: leds: qcom,spmi-flash-led: Add PMH0101 compatible Document compatible for PMH0101 Torch and Flash LED controller. Signed-off-by: Jishnu Prakash Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20250924-knp-pmic-peri-v2-2-32316039db2f@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml index bcf0ad4ea57ea..0df3e460a792b 100644 --- a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml +++ b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml @@ -28,6 +28,7 @@ properties: - qcom,pm8150l-flash-led - qcom,pm8350c-flash-led - qcom,pm8550-flash-led + - qcom,pmh0101-flash-led - qcom,pmi8998-flash-led - const: qcom,spmi-flash-led From 87f0f2039aeb54ad0610c97d6d0e15b022c95936 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Fri, 19 Sep 2025 10:50:25 -0700 Subject: [PATCH 030/659] FROMGIT: soc: qcom: pmic_glink: Add support for SOCCP remoteproc channels System On Chip Control Processor (SOCCP) is a subsystem that can have battery management firmware running on it to support Type-C/PD and battery charging. SOCCP does not have multiple PDs and hence PDR is not supported. So, if the subsystem comes up/down, rpmsg driver would be probed or removed. Use that for notifying clients of pmic_glink for PDR events. Add support for battery management FW running on SOCCP by adding the "PMIC_RTR_SOCCP_APPS" channel name to the rpmsg_match list and updating notify_clients logic. Signed-off-by: Anjelique Melendez Link: https://lore.kernel.org/all/20250919175025.2988948-1-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/soc/qcom/pmic_glink.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index aa5ba9a0285e5..13bbc9a5181d2 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -45,6 +45,7 @@ struct pmic_glink { struct mutex state_lock; unsigned int client_state; unsigned int pdr_state; + bool pdr_available; /* serializing clients list updates */ spinlock_t client_lock; @@ -252,9 +253,12 @@ static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev) return dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n"); dev_set_drvdata(&rpdev->dev, pg); + pg->pdr_available = rpdev->id.driver_data; guard(mutex)(&pg->state_lock); pg->ept = rpdev->ept; + if (!pg->pdr_available) + pg->pdr_state = SERVREG_SERVICE_STATE_UP; pmic_glink_state_notify_clients(pg); return 0; @@ -271,11 +275,14 @@ static void pmic_glink_rpmsg_remove(struct rpmsg_device *rpdev) guard(mutex)(&pg->state_lock); pg->ept = NULL; + if (!pg->pdr_available) + pg->pdr_state = SERVREG_SERVICE_STATE_DOWN; pmic_glink_state_notify_clients(pg); } static const struct rpmsg_device_id pmic_glink_rpmsg_id_match[] = { - { "PMIC_RTR_ADSP_APPS" }, + {.name = "PMIC_RTR_ADSP_APPS", .driver_data = true }, + {.name = "PMIC_RTR_SOCCP_APPS", .driver_data = false }, {} }; From 97372deb23bc2fe5d89b8b45ac7f4f97544655da Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 21 Oct 2025 17:45:53 -0700 Subject: [PATCH 031/659] FROMLIST: usb: typec: ucsi_glink: Update request/response buffers to be packed Update the ucsi request/response buffers to be packed to ensure there are no "holes" in memory while we read/write these structs. Signed-off-by: Anjelique Melendez Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/all/20251022004554.1956729-2-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/usb/typec/ucsi/ucsi_glink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 8af79101a2fc7..1f9f0d942c1ae 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -30,24 +30,24 @@ struct ucsi_read_buf_req_msg { struct pmic_glink_hdr hdr; }; -struct ucsi_read_buf_resp_msg { +struct __packed ucsi_read_buf_resp_msg { struct pmic_glink_hdr hdr; u8 buf[UCSI_BUF_SIZE]; u32 ret_code; }; -struct ucsi_write_buf_req_msg { +struct __packed ucsi_write_buf_req_msg { struct pmic_glink_hdr hdr; u8 buf[UCSI_BUF_SIZE]; u32 reserved; }; -struct ucsi_write_buf_resp_msg { +struct __packed ucsi_write_buf_resp_msg { struct pmic_glink_hdr hdr; u32 ret_code; }; -struct ucsi_notify_ind_msg { +struct __packed ucsi_notify_ind_msg { struct pmic_glink_hdr hdr; u32 notification; u32 receiver; From 8fba65f6e2ddebad2e93252a85e30a35fa99733b Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 21 Oct 2025 17:45:54 -0700 Subject: [PATCH 032/659] FROMLIST: usb: typec: ucsi_glink: Increase buffer size to support UCSI v2 UCSI v2 specification has increased the MSG_IN and MSG_OUT size from 16 bytes to 256 bytes each for the message exchange between OPM and PPM This makes the total buffer size increase from 48 bytes to 528 bytes. Update the buffer size to support this increase. Signed-off-by: Anjelique Melendez Reviewed-by: Heikki Krogerus Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20251022004554.1956729-3-anjelique.melendez@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/usb/typec/ucsi/ucsi_glink.c | 80 +++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 1f9f0d942c1ae..11b3e24e34e2b 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -16,10 +16,10 @@ #define PMIC_GLINK_MAX_PORTS 3 -#define UCSI_BUF_SIZE 48 +#define UCSI_BUF_V1_SIZE (UCSI_MESSAGE_OUT + (UCSI_MESSAGE_OUT - UCSI_MESSAGE_IN)) +#define UCSI_BUF_V2_SIZE (UCSIv2_MESSAGE_OUT + (UCSIv2_MESSAGE_OUT - UCSI_MESSAGE_IN)) #define MSG_TYPE_REQ_RESP 1 -#define UCSI_BUF_SIZE 48 #define UC_NOTIFY_RECEIVER_UCSI 0x0 #define UC_UCSI_READ_BUF_REQ 0x11 @@ -32,13 +32,19 @@ struct ucsi_read_buf_req_msg { struct __packed ucsi_read_buf_resp_msg { struct pmic_glink_hdr hdr; - u8 buf[UCSI_BUF_SIZE]; + union { + u8 v2_buf[UCSI_BUF_V2_SIZE]; + u8 v1_buf[UCSI_BUF_V1_SIZE]; + } buf; u32 ret_code; }; struct __packed ucsi_write_buf_req_msg { struct pmic_glink_hdr hdr; - u8 buf[UCSI_BUF_SIZE]; + union { + u8 v2_buf[UCSI_BUF_V2_SIZE]; + u8 v1_buf[UCSI_BUF_V1_SIZE]; + } buf; u32 reserved; }; @@ -72,7 +78,7 @@ struct pmic_glink_ucsi { bool ucsi_registered; bool pd_running; - u8 read_buf[UCSI_BUF_SIZE]; + u8 read_buf[UCSI_BUF_V2_SIZE]; }; static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset, @@ -132,17 +138,35 @@ static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned i const void *val, size_t val_len) { struct ucsi_write_buf_req_msg req = {}; + size_t req_len, buf_len; unsigned long left; int ret; + u8 *buf; req.hdr.owner = PMIC_GLINK_OWNER_USBC; req.hdr.type = MSG_TYPE_REQ_RESP; req.hdr.opcode = UC_UCSI_WRITE_BUF_REQ; - memcpy(&req.buf[offset], val, val_len); + + if (ucsi->ucsi->version >= UCSI_VERSION_2_0) { + buf_len = UCSI_BUF_V2_SIZE; + buf = req.buf.v2_buf; + } else if (ucsi->ucsi->version) { + buf_len = UCSI_BUF_V1_SIZE; + buf = req.buf.v1_buf; + } else { + dev_err(ucsi->dev, "UCSI version unknown\n"); + return -EINVAL; + } + req_len = sizeof(struct pmic_glink_hdr) + buf_len + sizeof(u32); + + if (offset + val_len > buf_len) + return -EINVAL; + + memcpy(&buf[offset], val, val_len); reinit_completion(&ucsi->write_ack); - ret = pmic_glink_send(ucsi->client, &req, sizeof(req)); + ret = pmic_glink_send(ucsi->client, &req, req_len); if (ret < 0) { dev_err(ucsi->dev, "failed to send UCSI write request: %d\n", ret); return ret; @@ -216,12 +240,48 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = { static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len) { - const struct ucsi_read_buf_resp_msg *resp = data; + u32 ret_code, resp_len, buf_len = 0; + u8 *buf; + + if (ucsi->ucsi->version) { + if (ucsi->ucsi->version >= UCSI_VERSION_2_0) { + buf = ((struct ucsi_read_buf_resp_msg *)data)->buf.v2_buf; + buf_len = UCSI_BUF_V2_SIZE; + } else { + buf = ((struct ucsi_read_buf_resp_msg *)data)->buf.v1_buf; + buf_len = UCSI_BUF_V1_SIZE; + } + } else if (!ucsi->ucsi_registered) { + /* + * If UCSI version is not known yet because device is not registered, choose buffer + * size which best fits incoming data + */ + if (len > sizeof(struct pmic_glink_hdr) + UCSI_BUF_V2_SIZE) { + buf = ((struct ucsi_read_buf_resp_msg *)data)->buf.v2_buf; + buf_len = UCSI_BUF_V2_SIZE; + } else { + buf = ((struct ucsi_read_buf_resp_msg *)data)->buf.v1_buf; + buf_len = UCSI_BUF_V1_SIZE; + } + } else { + dev_err(ucsi->dev, "Device has been registered but UCSI version is still unknown\n"); + return; + } - if (resp->ret_code) + resp_len = sizeof(struct pmic_glink_hdr) + buf_len + sizeof(u32); + + if (len > resp_len) + return; + + /* Ensure that buffer_len leaves space for ret_code to be read back from memory */ + if (buf_len > len - sizeof(struct pmic_glink_hdr) - sizeof(u32)) + buf_len = len - sizeof(struct pmic_glink_hdr) - sizeof(u32); + + memcpy(&ret_code, buf + buf_len, sizeof(u32)); + if (ret_code) return; - memcpy(ucsi->read_buf, resp->buf, UCSI_BUF_SIZE); + memcpy(ucsi->read_buf, buf, buf_len); complete(&ucsi->read_ack); } From f3310869238d94afc92886b1a5203be913893c26 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:49 -0800 Subject: [PATCH 033/659] 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/20251203090055.2432719-2-songwei.chai@oss.qualcomm.com/ 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 0e64af07cbb6c891b9a88dd20770505b661dd1c7 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:50 -0800 Subject: [PATCH 034/659] 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/20251203090055.2432719-3-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../testing/sysfs-bus-coresight-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 | 210 ++++++++++++++++++ drivers/hwtracing/qcom/tgu.h | 33 +++ 7 files changed, 276 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-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-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu new file mode 100644 index 0000000000000..ccc2bc92edcdd --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -0,0 +1,9 @@ +What: /sys/bus/coresight/devices//enable_tgu +Date: December 2025 +KernelVersion 6.18 +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 ccc05f1eae3eb..9608a3debb1f0 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..368bb196b9843 --- /dev/null +++ b/drivers/hwtracing/qcom/tgu.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../coresight/coresight-priv.h" +#include "tgu.h" + +DEFINE_CORESIGHT_DEVLIST(tgu_devs, "tgu"); + +static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + /* Enable TGU to program the triggers */ + writel(1, drvdata->base + TGU_CONTROL); + CS_LOCK(drvdata->base); +} + +static int tgu_enable(struct coresight_device *csdev, enum cs_mode mode, + void *data) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + guard(spinlock)(&drvdata->lock); + if (drvdata->enable) + return -EBUSY; + + tgu_write_all_hw_regs(drvdata); + drvdata->enable = true; + + return 0; +} + +static int tgu_disable(struct coresight_device *csdev, void *data) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + spin_lock(&drvdata->lock); + if (drvdata->enable) { + CS_UNLOCK(drvdata->base); + writel(0, drvdata->base + TGU_CONTROL); + CS_LOCK(drvdata->base); + + drvdata->enable = false; + } + spin_unlock(&drvdata->lock); + return 0; +} + +static ssize_t enable_tgu_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + bool enabled; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->lock); + enabled = drvdata->enable; + spin_unlock(&drvdata->lock); + + return sysfs_emit(buf, "%d\n", enabled); +} + +/* 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) +{ + int ret = 0; + unsigned long val; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + if (val) { + ret = pm_runtime_resume_and_get(dev->parent); + if (ret) + return ret; + ret = tgu_enable(drvdata->csdev, CS_MODE_SYSFS, NULL); + if (ret) + pm_runtime_put(dev->parent); + } else { + ret = tgu_disable(drvdata->csdev, NULL); + pm_runtime_put(dev->parent); + } + + if (ret) + return ret; + return size; +} +static DEVICE_ATTR_RW(enable_tgu); + +static const struct coresight_ops_helper tgu_helper_ops = { + .enable = tgu_enable, + .disable = tgu_disable, +}; + +static const struct coresight_ops tgu_ops = { + .helper_ops = &tgu_helper_ops, +}; + +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) +{ + int ret = 0; + struct device *dev = &adev->dev; + struct coresight_desc desc = { 0 }; + struct coresight_platform_data *pdata; + struct tgu_drvdata *drvdata; + + desc.name = coresight_alloc_device_name(&tgu_devs, dev); + if (!desc.name) + return -ENOMEM; + + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + + adev->dev.platform_data = pdata; + + 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 (!drvdata->base) + return -ENOMEM; + + spin_lock_init(&drvdata->lock); + + drvdata->enable = false; + desc.type = CORESIGHT_DEV_TYPE_HELPER; + desc.pdata = adev->dev.platform_data; + desc.dev = &adev->dev; + desc.ops = &tgu_ops; + desc.groups = tgu_attr_groups; + + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) { + ret = PTR_ERR(drvdata->csdev); + goto err; + } + + pm_runtime_put(&adev->dev); + return 0; +err: + pm_runtime_put(&adev->dev); + return ret; +} + +static void tgu_remove(struct amba_device *adev) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(&adev->dev); + + coresight_unregister(drvdata->csdev); +} + +static const struct amba_id tgu_ids[] = { + { + .id = 0x000f0e00, + .mask = 0x000fffff, + .data = "TGU", + }, + { 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_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm TGU driver"); diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h new file mode 100644 index 0000000000000..1a55da90f5216 --- /dev/null +++ b/drivers/hwtracing/qcom/tgu.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _QCOM_TGU_H +#define _QCOM_TGU_H + +/* Register addresses */ +#define TGU_CONTROL 0x0000 + +/** + * 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 + * @csdev: Pointer to the associated coresight device + * @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; + struct coresight_device *csdev; + spinlock_t lock; + bool enable; +}; + +#endif From 0544a9c9e5fec392f5988d09f02a8d48afbf9c10 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:51 -0800 Subject: [PATCH 035/659] 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/20251203090055.2432719-4-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../testing/sysfs-bus-coresight-devices-tgu | 7 + drivers/hwtracing/qcom/tgu.c | 155 ++++++++++++++++++ drivers/hwtracing/qcom/tgu.h | 111 +++++++++++++ 3 files changed, 273 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu index ccc2bc92edcdd..eafb0e0dd030f 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-coresight-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/coresight/devices//step[0:7]_priority[0:3]/reg[0:17] +Date: December 2025 +KernelVersion 6.18 +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 368bb196b9843..a1ad8d97e9d27 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -17,14 +17,120 @@ DEFINE_CORESIGHT_DEVLIST(tgu_devs, "tgu"); +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) +{ + int index; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct tgu_attribute *tgu_attr = + container_of(attr, struct tgu_attribute, attr); + + 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) +{ + int index; + unsigned long val; + + struct tgu_drvdata *tgu_drvdata = dev_get_drvdata(dev->parent); + struct tgu_attribute *tgu_attr = + container_of(attr, struct tgu_attribute, attr); + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + 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->parent); + int ret = SYSFS_GROUP_INVISIBLE; + + 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); + + 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; + CS_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); CS_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 + CORESIGHT_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 + CORESIGHT_DEVID); + + drvdata->max_step = TGU_DEVID_STEPS(devid); +} + static int tgu_enable(struct coresight_device *csdev, enum cs_mode mode, void *data) { @@ -122,6 +228,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, }; @@ -156,6 +294,23 @@ 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); + + drvdata->value_table = + devm_kzalloc(dev, sizeof(*drvdata->value_table), GFP_KERNEL); + if (!drvdata->value_table) + return -ENOMEM; + + drvdata->value_table->priority = devm_kzalloc( + dev, + MAX_PRIORITY * drvdata->max_reg * drvdata->max_step * + sizeof(*(drvdata->value_table->priority)), + GFP_KERNEL); + + if (!drvdata->value_table->priority) + return -ENOMEM; + drvdata->enable = false; desc.type = CORESIGHT_DEV_TYPE_HELPER; desc.pdata = adev->dev.platform_data; diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index 1a55da90f5216..444804e523377 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -9,6 +9,111 @@ /* Register addresses */ #define TGU_CONTROL 0x0000 +#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; +}; + /** * struct tgu_drvdata - Data structure for a TGU (Trigger Generator Unit) * @base: Memory-mapped base address of the TGU device @@ -16,6 +121,9 @@ * @csdev: Pointer to the associated coresight device * @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 @@ -28,6 +136,9 @@ struct tgu_drvdata { struct coresight_device *csdev; spinlock_t lock; bool enable; + struct value_table *value_table; + int max_reg; + int max_step; }; #endif From 042417528d8a75b15e0fe75adabed4fbddcaf1b4 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:52 -0800 Subject: [PATCH 036/659] 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/20251203090055.2432719-5-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../testing/sysfs-bus-coresight-devices-tgu | 7 + drivers/hwtracing/qcom/tgu.c | 153 ++++++++++++++++-- drivers/hwtracing/qcom/tgu.h | 27 ++++ 3 files changed, 173 insertions(+), 14 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu index eafb0e0dd030f..df73a9d5043e9 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -14,3 +14,10 @@ KernelVersion 6.18 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the sensed signal with specific step and priority for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_condition_decode/reg[0:3] +Date: December 2025 +KernelVersion 6.18 +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 a1ad8d97e9d27..b4ff41cf0a111 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -21,8 +21,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->csdev->dev, "%s - Fail\n", __func__); + + return result; } static ssize_t tgu_dataset_show(struct device *dev, @@ -37,8 +65,26 @@ static ssize_t tgu_dataset_show(struct device *dev, 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 -EINVAL; + + 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, @@ -46,6 +92,7 @@ static ssize_t tgu_dataset_store(struct device *dev, const char *buf, size_t size) { int index; + int ret = -EINVAL; unsigned long val; struct tgu_drvdata *tgu_drvdata = dev_get_drvdata(dev->parent); @@ -53,15 +100,32 @@ static ssize_t tgu_dataset_store(struct device *dev, container_of(attr, struct tgu_attribute, attr); if (kstrtoul(buf, 0, &val)) - return -EINVAL; + 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 ret; + + 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: + break; + } + return ret; } static umode_t tgu_node_visible(struct kobject *kobject, @@ -78,13 +142,27 @@ static umode_t tgu_node_visible(struct kobject *kobject, container_of(dev_attr, struct tgu_attribute, attr); 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; @@ -92,8 +170,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 + @@ -101,9 +181,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: CS_LOCK(drvdata->base); + return index >= 0 ? 0 : -EINVAL; } static void tgu_set_reg_number(struct tgu_drvdata *drvdata) @@ -131,19 +225,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 + CORESIGHT_DEVID); + drvdata->max_condition_decode = TGU_DEVID_CONDITIONS(devid); +} + static int tgu_enable(struct coresight_device *csdev, enum cs_mode mode, void *data) { + int ret = 0; struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 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 int tgu_disable(struct coresight_device *csdev, void *data) @@ -260,6 +367,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, }; @@ -296,6 +411,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); drvdata->value_table = devm_kzalloc(dev, sizeof(*drvdata->value_table), GFP_KERNEL); @@ -311,6 +427,15 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata->value_table->priority) return -ENOMEM; + drvdata->value_table->condition_decode = devm_kzalloc( + dev, + drvdata->max_condition_decode * drvdata->max_step * + sizeof(*(drvdata->value_table->condition_decode)), + GFP_KERNEL); + + if (!drvdata->value_table->condition_decode) + return -ENOMEM; + drvdata->enable = false; desc.type = CORESIGHT_DEV_TYPE_HELPER; desc.pdata = adev->dev.platform_data; diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index 444804e523377..cac5efeee1e9c 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -11,6 +11,7 @@ #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 @@ -44,6 +45,7 @@ */ #define STEP_OFFSET 0x1D8 #define PRIORITY_START_OFFSET 0x0074 +#define CONDITION_DECODE_OFFSET 0x0050 #define PRIORITY_OFFSET 0x60 #define REG_OFFSET 0x4 @@ -52,6 +54,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), \ @@ -64,6 +69,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), \ @@ -86,6 +94,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),\ @@ -93,11 +109,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 */ @@ -112,6 +136,7 @@ struct tgu_attribute { struct value_table { unsigned int *priority; + unsigned int *condition_decode; }; /** @@ -124,6 +149,7 @@ struct value_table { * @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 @@ -139,6 +165,7 @@ struct tgu_drvdata { struct value_table *value_table; int max_reg; int max_step; + int max_condition_decode; }; #endif From 1a29066573ecfb2aeecf9663b7826f6dd077bd60 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:53 -0800 Subject: [PATCH 037/659] 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/20251203090055.2432719-6-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../testing/sysfs-bus-coresight-devices-tgu | 7 +++ drivers/hwtracing/qcom/tgu.c | 52 +++++++++++++++++++ drivers/hwtracing/qcom/tgu.h | 27 ++++++++++ 3 files changed, 86 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu index df73a9d5043e9..a0d5e2eb141ba 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -21,3 +21,10 @@ KernelVersion 6.18 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the decode mode with specific step for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_condition_select/reg[0:3] +Date: December 2025 +KernelVersion 6.18 +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 b4ff41cf0a111..98721891251ae 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -36,6 +36,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; } @@ -81,6 +85,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; } @@ -122,6 +129,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: break; } @@ -155,6 +166,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; } @@ -193,6 +213,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: @@ -231,6 +264,8 @@ static void tgu_set_conditions(struct tgu_drvdata *drvdata) devid = readl(drvdata->base + CORESIGHT_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 coresight_device *csdev, enum cs_mode mode, @@ -375,6 +410,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, }; @@ -436,6 +479,15 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata->value_table->condition_decode) return -ENOMEM; + drvdata->value_table->condition_select = devm_kzalloc( + dev, + drvdata->max_condition_select * drvdata->max_step * + sizeof(*(drvdata->value_table->condition_select)), + GFP_KERNEL); + + if (!drvdata->value_table->condition_select) + return -ENOMEM; + drvdata->enable = false; desc.type = CORESIGHT_DEV_TYPE_HELPER; desc.pdata = adev->dev.platform_data; diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index cac5efeee1e9c..5056ec81fdae1 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -46,6 +46,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 @@ -57,6 +58,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), \ @@ -72,6 +76,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), \ @@ -102,6 +109,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),\ @@ -116,12 +132,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 */ @@ -137,6 +161,7 @@ struct tgu_attribute { struct value_table { unsigned int *priority; unsigned int *condition_decode; + unsigned int *condition_select; }; /** @@ -150,6 +175,7 @@ struct value_table { * @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 @@ -166,6 +192,7 @@ struct tgu_drvdata { int max_reg; int max_step; int max_condition_decode; + int max_condition_select; }; #endif From 432bd47598c5c413648253adc7916c34f68016d5 Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:54 -0800 Subject: [PATCH 038/659] 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/20251203090055.2432719-7-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../testing/sysfs-bus-coresight-devices-tgu | 14 ++ drivers/hwtracing/qcom/tgu.c | 120 ++++++++++++++++++ drivers/hwtracing/qcom/tgu.h | 54 ++++++++ 3 files changed, 188 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu index a0d5e2eb141ba..28d1743bd2fc9 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -28,3 +28,17 @@ KernelVersion 6.18 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the next action with specific step for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_timer/reg[0:1] +Date: December 2025 +KernelVersion 6.18 +Contact: Jinlong Mao , Songwei Chai +Description: + (RW) Set/Get the timer value with specific step for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_counter/reg[0:1] +Date: December 2025 +KernelVersion 6.18 +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 98721891251ae..5db876c31a633 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -40,6 +40,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; } @@ -88,6 +94,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; } @@ -133,6 +145,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: break; } @@ -175,6 +195,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; } @@ -226,6 +262,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: @@ -268,6 +328,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 coresight_device *csdev, enum cs_mode mode, void *data) { @@ -418,6 +503,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, }; @@ -455,6 +556,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); drvdata->value_table = devm_kzalloc(dev, sizeof(*drvdata->value_table), GFP_KERNEL); @@ -488,6 +590,24 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata->value_table->condition_select) return -ENOMEM; + drvdata->value_table->timer = devm_kzalloc( + dev, + drvdata->max_step * drvdata->max_timer * + sizeof(*(drvdata->value_table->timer)), + GFP_KERNEL); + + if (!drvdata->value_table->timer) + return -ENOMEM; + + drvdata->value_table->counter = devm_kzalloc( + dev, + drvdata->max_step * drvdata->max_counter * + sizeof(*(drvdata->value_table->counter)), + GFP_KERNEL); + + if (!drvdata->value_table->counter) + return -ENOMEM; + drvdata->enable = false; desc.type = CORESIGHT_DEV_TYPE_HELPER; desc.pdata = adev->dev.platform_data; diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h index 5056ec81fdae1..de438cf868c84 100644 --- a/drivers/hwtracing/qcom/tgu.h +++ b/drivers/hwtracing/qcom/tgu.h @@ -8,10 +8,16 @@ /* Register addresses */ #define TGU_CONTROL 0x0000 +#define CORESIGHT_DEVID2 0xfc0 #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 @@ -47,6 +53,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 @@ -58,6 +66,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) @@ -79,6 +93,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), \ @@ -118,6 +138,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),\ @@ -139,6 +171,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, @@ -146,6 +192,8 @@ enum operation_index { TGU_PRIORITY3, TGU_CONDITION_DECODE, TGU_CONDITION_SELECT, + TGU_TIMER, + TGU_COUNTER }; /* Maximum priority that TGU supports */ @@ -162,6 +210,8 @@ struct value_table { unsigned int *priority; unsigned int *condition_decode; unsigned int *condition_select; + unsigned int *timer; + unsigned int *counter; }; /** @@ -176,6 +226,8 @@ struct value_table { * @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 @@ -193,6 +245,8 @@ struct tgu_drvdata { int max_step; int max_condition_decode; int max_condition_select; + int max_timer; + int max_counter; }; #endif From be9908891a0677b48b7deb7490e30b57c9b6f93d Mon Sep 17 00:00:00 2001 From: Songwei Chai Date: Wed, 3 Dec 2025 01:00:55 -0800 Subject: [PATCH 039/659] 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/20251203090055.2432719-8-songwei.chai@oss.qualcomm.com/ Signed-off-by: Songwei Chai --- .../testing/sysfs-bus-coresight-devices-tgu | 7 ++ drivers/hwtracing/qcom/tgu.c | 75 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu index 28d1743bd2fc9..3029f342fc498 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -42,3 +42,10 @@ KernelVersion 6.18 Contact: Jinlong Mao , Songwei Chai Description: (RW) Set/Get the counter value with specific step for TGU. + +What: /sys/bus/coresight/devices//reset_tgu +Date: December 2025 +KernelVersion 6.18 +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 5db876c31a633..a164867c6b662 100644 --- a/drivers/hwtracing/qcom/tgu.c +++ b/drivers/hwtracing/qcom/tgu.c @@ -434,6 +434,80 @@ 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) +{ + unsigned long value; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + 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; + } + } + + spin_lock(&drvdata->lock); + CS_UNLOCK(drvdata->base); + + writel(0, drvdata->base + TGU_CONTROL); + + 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, "Coresight-TGU reset complete\n"); + + CS_LOCK(drvdata->base); + + drvdata->enable = false; + spin_unlock(&drvdata->lock); + pm_runtime_put(drvdata->dev); + + return size; +} +static DEVICE_ATTR_WO(reset_tgu); + static const struct coresight_ops_helper tgu_helper_ops = { .enable = tgu_enable, .disable = tgu_disable, @@ -445,6 +519,7 @@ static const struct coresight_ops tgu_ops = { static struct attribute *tgu_common_attrs[] = { &dev_attr_enable_tgu.attr, + &dev_attr_reset_tgu.attr, NULL, }; From 6637a3761c7e1487f715dc5608f4efa5664d28fd Mon Sep 17 00:00:00 2001 From: Yingchao Deng Date: Tue, 2 Dec 2025 14:42:20 +0800 Subject: [PATCH 040/659] 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 d0ae10bf61281..4bef860a0484d 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 39ea4ac10727a6785fa1a7922653c31a34880756 Mon Sep 17 00:00:00 2001 From: Yingchao Deng Date: Tue, 2 Dec 2025 14:42:21 +0800 Subject: [PATCH 041/659] 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 5e80002cd448ff43000ce0cb0531808b76412d40 Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Tue, 28 Oct 2025 10:02:15 +0800 Subject: [PATCH 042/659] FROMLIST: coresight: tpda: add sysfs nodes for tpda cross-trigger configuration Introduce sysfs nodes to configure cross-trigger parameters for TPDA. These registers define the characteristics of cross-trigger packets, including generation frequency and flag values. Link: https://lore.kernel.org/all/20251028-configure_tpda_reg-v4-1-23000805d21d@oss.qualcomm.com/ Signed-off-by: Tao Zhang Reviewed-by: James Clark Co-developed-by: Jie Gan Signed-off-by: Jie Gan --- .../testing/sysfs-bus-coresight-devices-tpda | 43 ++++ drivers/hwtracing/coresight/coresight-tpda.c | 230 ++++++++++++++++++ drivers/hwtracing/coresight/coresight-tpda.h | 27 +- 3 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda new file mode 100644 index 0000000000000..80e4b05a1ab42 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda @@ -0,0 +1,43 @@ +What: /sys/bus/coresight/devices//trig_async_enable +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable cross trigger synchronization sequence interface. + +What: /sys/bus/coresight/devices//trig_flag_ts_enable +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable cross trigger FLAG packet request interface. + +What: /sys/bus/coresight/devices//trig_freq_enable +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable cross trigger FREQ packet request interface. + +What: /sys/bus/coresight/devices//freq_ts_enable +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable the timestamp for all FREQ packets. + +What: /sys/bus/coresight/devices//global_flush_req +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Set global (all ports) flush request bit. The bit remains set until a + global flush request sequence completes. + +What: /sys/bus/coresight/devices//cmbchan_mode +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Configure the CMB/MCMB channel mode for all enabled ports. + Value 0 means raw channel mapping mode. Value 1 means channel pair marking mode. diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index 3a3825d27f861..56a48271dbbe6 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -140,9 +140,37 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata) u32 val; val = readl_relaxed(drvdata->base + TPDA_CR); + val &= ~TPDA_CR_MID; val &= ~TPDA_CR_ATID; val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid); + if (drvdata->trig_async) + val |= TPDA_CR_SRIE; + else + val &= ~TPDA_CR_SRIE; + if (drvdata->trig_flag_ts) + val |= TPDA_CR_FLRIE; + else + val &= ~TPDA_CR_FLRIE; + if (drvdata->trig_freq) + val |= TPDA_CR_FRIE; + else + val &= ~TPDA_CR_FRIE; + if (drvdata->freq_ts) + val |= TPDA_CR_FREQTS; + else + val &= ~TPDA_CR_FREQTS; + if (drvdata->cmbchan_mode) + val |= TPDA_CR_CMBCHANMODE; + else + val &= ~TPDA_CR_CMBCHANMODE; writel_relaxed(val, drvdata->base + TPDA_CR); + + /* + * If FLRIE bit is set, set the master and channel + * id as zero + */ + if (drvdata->trig_flag_ts) + writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR); } static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) @@ -258,6 +286,206 @@ static const struct coresight_ops tpda_cs_ops = { .link_ops = &tpda_link_ops, }; +static ssize_t trig_async_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_async); +} + +static ssize_t trig_async_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->trig_async = !!val; + + return size; +} +static DEVICE_ATTR_RW(trig_async_enable); + +static ssize_t trig_flag_ts_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_flag_ts); +} + +static ssize_t trig_flag_ts_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->trig_flag_ts = !!val; + + return size; +} +static DEVICE_ATTR_RW(trig_flag_ts_enable); + +static ssize_t trig_freq_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_freq); +} + +static ssize_t trig_freq_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->trig_freq = !!val; + + return size; +} +static DEVICE_ATTR_RW(trig_freq_enable); + +static ssize_t freq_ts_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->freq_ts); +} + +static ssize_t freq_ts_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->freq_ts = !!val; + + return size; +} +static DEVICE_ATTR_RW(freq_ts_enable); + +static ssize_t global_flush_req_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + CS_UNLOCK(drvdata->base); + val = readl_relaxed(drvdata->base + TPDA_CR); + CS_LOCK(drvdata->base); + /* Only read value for bit 0 */ + val &= BIT(0); + + return sysfs_emit(buf, "%lu\n", val); +} + +static ssize_t global_flush_req_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (!drvdata->csdev->refcnt || !val) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + CS_UNLOCK(drvdata->base); + val = readl_relaxed(drvdata->base + TPDA_CR); + /* Only set bit 0 */ + val |= BIT(0); + writel_relaxed(val, drvdata->base + TPDA_CR); + CS_LOCK(drvdata->base); + + return size; +} +static DEVICE_ATTR_RW(global_flush_req); + +static ssize_t cmbchan_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->cmbchan_mode); +} + +static ssize_t cmbchan_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->cmbchan_mode = !!val; + + return size; +} +static DEVICE_ATTR_RW(cmbchan_mode); + +static struct attribute *tpda_attrs[] = { + &dev_attr_trig_async_enable.attr, + &dev_attr_trig_flag_ts_enable.attr, + &dev_attr_trig_freq_enable.attr, + &dev_attr_freq_ts_enable.attr, + &dev_attr_global_flush_req.attr, + &dev_attr_cmbchan_mode.attr, + NULL, +}; + +static struct attribute_group tpda_attr_grp = { + .attrs = tpda_attrs, +}; + +static const struct attribute_group *tpda_attr_grps[] = { + &tpda_attr_grp, + NULL, +}; + static int tpda_init_default_data(struct tpda_drvdata *drvdata) { int atid; @@ -273,6 +501,7 @@ static int tpda_init_default_data(struct tpda_drvdata *drvdata) return atid; drvdata->atid = atid; + drvdata->freq_ts = true; return 0; } @@ -316,6 +545,7 @@ static int tpda_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &tpda_cs_ops; desc.pdata = adev->dev.platform_data; desc.dev = &adev->dev; + desc.groups = tpda_attr_grps; desc.access = CSDEV_ACCESS_IOMEM(base); drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h index c6af3d2da3efe..0be625fb52fdf 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.h +++ b/drivers/hwtracing/coresight/coresight-tpda.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023,2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CORESIGHT_CORESIGHT_TPDA_H @@ -8,6 +8,19 @@ #define TPDA_CR (0x000) #define TPDA_Pn_CR(n) (0x004 + (n * 4)) +#define TPDA_FPID_CR (0x084) + +/* Cross trigger FREQ packets timestamp bit */ +#define TPDA_CR_FREQTS BIT(2) +/* Cross trigger FREQ packet request bit */ +#define TPDA_CR_FRIE BIT(3) +/* Cross trigger FLAG packet request interface bit */ +#define TPDA_CR_FLRIE BIT(4) +/* Cross trigger synchronization bit */ +#define TPDA_CR_SRIE BIT(5) +/* Packetize CMB/MCMB traffic bit */ +#define TPDA_CR_CMBCHANMODE BIT(20) + /* Aggregator port enable bit */ #define TPDA_Pn_CR_ENA BIT(0) /* Aggregator port CMB data set element size bit */ @@ -19,6 +32,8 @@ /* Bits 6 ~ 12 is for atid value */ #define TPDA_CR_ATID GENMASK(12, 6) +/* Bits 13 ~ 19 is for mid value */ +#define TPDA_CR_MID GENMASK(19, 13) /** * struct tpda_drvdata - specifics associated to an TPDA component @@ -29,6 +44,11 @@ * @enable: enable status of the component. * @dsb_esize Record the DSB element size. * @cmb_esize Record the CMB element size. + * @trig_async: Enable/disable cross trigger synchronization sequence interface. + * @trig_flag_ts: Enable/disable cross trigger FLAG packet request interface. + * @trig_freq: Enable/disable cross trigger FREQ packet request interface. + * @freq_ts: Enable/disable the timestamp for all FREQ packets. + * @cmbchan_mode: Configure the CMB/MCMB channel mode. */ struct tpda_drvdata { void __iomem *base; @@ -38,6 +58,11 @@ struct tpda_drvdata { u8 atid; u32 dsb_esize; u32 cmb_esize; + bool trig_async; + bool trig_flag_ts; + bool trig_freq; + bool freq_ts; + bool cmbchan_mode; }; #endif /* _CORESIGHT_CORESIGHT_TPDA_H */ From c72e4eb47b3983d4223961487325f253c0b3f4ee Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Tue, 28 Oct 2025 10:02:16 +0800 Subject: [PATCH 043/659] FROMLIST: coresight: tpda: add logic to configure TPDA_SYNCR register The TPDA_SYNCR register defines the frequency at which TPDA generates ASYNC packets, enabling userspace tools to accurately parse each valid packet. Link: https://lore.kernel.org/all/20251028-configure_tpda_reg-v4-2-23000805d21d@oss.qualcomm.com/ Signed-off-by: Tao Zhang Reviewed-by: James Clark Co-developed-by: Jie Gan Signed-off-by: Jie Gan --- drivers/hwtracing/coresight/coresight-tpda.c | 7 +++++++ drivers/hwtracing/coresight/coresight-tpda.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index 56a48271dbbe6..c7a656c54d1e2 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -171,6 +171,13 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata) */ if (drvdata->trig_flag_ts) writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR); + + /* Program the counter value for TPDA_SYNCR */ + val = readl_relaxed(drvdata->base + TPDA_SYNCR); + /* Clear the mode */ + val &= ~TPDA_SYNCR_MODE_CTRL; + val |= TPDA_SYNCR_COUNTER_MASK; + writel_relaxed(val, drvdata->base + TPDA_SYNCR); } static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h index 0be625fb52fdf..0c9bf2fade565 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.h +++ b/drivers/hwtracing/coresight/coresight-tpda.h @@ -9,6 +9,7 @@ #define TPDA_CR (0x000) #define TPDA_Pn_CR(n) (0x004 + (n * 4)) #define TPDA_FPID_CR (0x084) +#define TPDA_SYNCR (0x08C) /* Cross trigger FREQ packets timestamp bit */ #define TPDA_CR_FREQTS BIT(2) @@ -27,6 +28,10 @@ #define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6) /* Aggregator port DSB data set element size bit */ #define TPDA_Pn_CR_DSBSIZE BIT(8) +/* TPDA_SYNCR mode control bit */ +#define TPDA_SYNCR_MODE_CTRL BIT(12) +/* TPDA_SYNCR counter mask */ +#define TPDA_SYNCR_COUNTER_MASK GENMASK(11, 0) #define TPDA_MAX_INPORTS 32 From 95d302e539948fd853bf87dd1da1b6eb080bc481 Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Tue, 28 Oct 2025 10:02:17 +0800 Subject: [PATCH 044/659] FROMLIST: coresight: tpda: add sysfs node to flush specific port Setting bit i in the TPDA_FLUSH_CR register initiates a flush request for port i, forcing the data to synchronize and be transmitted to the sink device. Link: https://lore.kernel.org/all/20251028-configure_tpda_reg-v4-3-23000805d21d@oss.qualcomm.com/ Signed-off-by: Tao Zhang Reviewed-by: James Clark Co-developed-by: Jie Gan Signed-off-by: Jie Gan --- .../testing/sysfs-bus-coresight-devices-tpda | 7 ++++ drivers/hwtracing/coresight/coresight-tpda.c | 41 +++++++++++++++++++ drivers/hwtracing/coresight/coresight-tpda.h | 1 + 3 files changed, 49 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda index 80e4b05a1ab42..e047f69fd5ccf 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda @@ -41,3 +41,10 @@ Contact: Jinlong Mao , Tao Zhang /port_flush_req +Date: October 2025 +KernelVersion: 6.19 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Configure the bit i to requests a flush operation of port i on the TPDA. diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index c7a656c54d1e2..9f809dccb760e 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -474,6 +474,46 @@ static ssize_t cmbchan_mode_store(struct device *dev, } static DEVICE_ATTR_RW(cmbchan_mode); +static ssize_t port_flush_req_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + CS_UNLOCK(drvdata->base); + val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR); + CS_LOCK(drvdata->base); + return sysfs_emit(buf, "0x%lx\n", val); +} + +static ssize_t port_flush_req_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + u32 val; + + if (kstrtou32(buf, 0, &val)) + return -EINVAL; + + if (!drvdata->csdev->refcnt || !val) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + CS_UNLOCK(drvdata->base); + writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR); + CS_LOCK(drvdata->base); + + return size; +} +static DEVICE_ATTR_RW(port_flush_req); + static struct attribute *tpda_attrs[] = { &dev_attr_trig_async_enable.attr, &dev_attr_trig_flag_ts_enable.attr, @@ -481,6 +521,7 @@ static struct attribute *tpda_attrs[] = { &dev_attr_freq_ts_enable.attr, &dev_attr_global_flush_req.attr, &dev_attr_cmbchan_mode.attr, + &dev_attr_port_flush_req.attr, NULL, }; diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h index 0c9bf2fade565..284ac63699ad6 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.h +++ b/drivers/hwtracing/coresight/coresight-tpda.h @@ -10,6 +10,7 @@ #define TPDA_Pn_CR(n) (0x004 + (n * 4)) #define TPDA_FPID_CR (0x084) #define TPDA_SYNCR (0x08C) +#define TPDA_FLUSH_CR (0x090) /* Cross trigger FREQ packets timestamp bit */ #define TPDA_CR_FREQTS BIT(2) From 57e4e9a55286fc9eb19aecf949d76e7a3e6f93f6 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 13 Oct 2025 13:49:10 +0800 Subject: [PATCH 045/659] 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/20251211-enable-byte-cntr-for-ctcu-v8-0-3e12ff313191@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 c660cf8adb1c7..0e8448784c62e 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 @csdev where a @remote + * 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 0c68550008e82d445a9a708dfc98ed265844045c Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 13 Oct 2025 13:49:11 +0800 Subject: [PATCH 046/659] FROMLIST: coresight: core: add a new API to retrieve the helper device Retrieving the helper device of the specific coresight device based on its helper_subtype because a single coresight device may has multiple types of the helper devices. Link: https://lore.kernel.org/all/20251211-enable-byte-cntr-for-ctcu-v8-2-3e12ff313191@oss.qualcomm.com/ Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- drivers/hwtracing/coresight/coresight-core.c | 35 ++++++++++++++++++++ drivers/hwtracing/coresight/coresight-priv.h | 2 ++ 2 files changed, 37 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 0e8448784c62e..ef09cf8055c8f 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -585,6 +585,41 @@ struct coresight_device *coresight_get_sink(struct coresight_path *path) } EXPORT_SYMBOL_GPL(coresight_get_sink); +/** + * coresight_get_helper: find the helper device of the assigned csdev. + * + * @csdev: The csdev the helper device is conntected to. + * @subtype: helper_subtype of the expected helper device. + * + * Retrieve the helper device for the specific csdev based on its + * helper_subtype. + * + * Return: the helper's csdev upon success or NULL for fail. + */ +struct coresight_device *coresight_get_helper(struct coresight_device *csdev, + enum coresight_dev_subtype_helper subtype) +{ + int i; + struct coresight_device *helper; + + /* protect the connections */ + mutex_lock(&coresight_mutex); + for (i = 0; i < csdev->pdata->nr_outconns; ++i) { + helper = csdev->pdata->out_conns[i]->dest_dev; + if (!helper || !coresight_is_helper(helper)) + continue; + + if (helper->subtype.helper_subtype == subtype) { + mutex_unlock(&coresight_mutex); + return helper; + } + } + mutex_unlock(&coresight_mutex); + + return NULL; +} +EXPORT_SYMBOL_GPL(coresight_get_helper); + /** * coresight_get_in_port: Find the input port number at @csdev where a @remote * device is connected to. diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index cbf80b83e5ce5..8e39a4dc72564 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -157,6 +157,8 @@ 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); +struct coresight_device *coresight_get_helper(struct coresight_device *csdev, + enum coresight_dev_subtype_helper subtype); #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM3X) int etm_readl_cp14(u32 off, unsigned int *val); From 8d4fff3cddd651202218fabd9a3820f7ec97baed Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 4 Dec 2025 10:26:56 +0800 Subject: [PATCH 047/659] 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/20251211-enable-byte-cntr-for-ctcu-v8-3-3e12ff313191@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 e0d83ee01b77a..2b6ca1f8bed2b 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1919,6 +1919,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(sizeof(struct etr_buf_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(sizeof(struct etr_buf_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(new_node); + 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 95473d1310323..9b3c4e6f0a5e6 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. @@ -243,6 +256,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; @@ -273,6 +288,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 { @@ -445,5 +462,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 831eebdfa6afdfbc6258730f4cadab7b0cd9f23c Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 13 Oct 2025 13:49:14 +0800 Subject: [PATCH 048/659] FROMLIST: coresight: tmc: Introduce sysfs_read_ops to wrap sysfs read operations Introduce sysfs_read_ops as a wrapper, wrap sysfs read operations, for reading trace data from the TMC buffer. Link: https://lore.kernel.org/all/20251211-enable-byte-cntr-for-ctcu-v8-4-3e12ff313191@oss.qualcomm.com/ Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- .../hwtracing/coresight/coresight-tmc-core.c | 50 +++++++++---------- drivers/hwtracing/coresight/coresight-tmc.h | 17 +++++++ 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 1ea255ffa67cf..8b0397a77e57c 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,13 +277,8 @@ 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); - } + if (drvdata->sysfs_ops) + return drvdata->sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); return -EINVAL; } @@ -769,6 +750,18 @@ static void register_crash_dev_interface(struct tmc_drvdata *drvdata, "Valid crash tracedata found\n"); } +static const struct sysfs_read_ops tmc_etb_sysfs_read_ops = { + .read_prepare = tmc_read_prepare_etb, + .read_unprepare = tmc_read_unprepare_etb, + .get_trace_data = tmc_etb_get_sysfs_trace, +}; + +static const struct sysfs_read_ops tmc_etr_sysfs_read_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 +821,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 = &tmc_etb_sysfs_read_ops; break; case TMC_CONFIG_TYPE_ETR: desc.groups = coresight_etr_groups; @@ -841,6 +835,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 = &tmc_etr_sysfs_read_ops; break; case TMC_CONFIG_TYPE_ETF: desc.groups = coresight_etf_groups; @@ -849,6 +844,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 = &tmc_etb_sysfs_read_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 9b3c4e6f0a5e6..c9a82ff6cd007 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -221,6 +221,8 @@ struct etr_buf_node { struct list_head node; }; +struct sysfs_read_ops; + /** * struct tmc_drvdata - specifics associated to an TMC component * @atclk: optional clock for the core parts of the TMC. @@ -258,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; @@ -290,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 sysfs_read_ops *sysfs_ops; +}; + +/** + * struct sysfs_read_ops - read operations for TMC and its helper devices + * @read_prepare: prepare operation. + * @read_unprepare: unprepare operation. + * @get_trace_data: read operation. + */ +struct sysfs_read_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 3d4313919e4debfb729f24399bef387926b27269 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 13 Oct 2025 13:49:15 +0800 Subject: [PATCH 049/659] 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/20251211-enable-byte-cntr-for-ctcu-v8-5-3e12ff313191@oss.qualcomm.com/ Acked-by: Krzysztof Kozlowski Reviewed-by: Mike Leach Signed-off-by: Jie Gan --- .../bindings/arm/qcom,coresight-ctcu.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index c969c16c21ef7..3ce8662e43ff7 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml @@ -39,6 +39,16 @@ properties: items: - const: apb + interrupts: + items: + - description: Byte cntr interrupt for the first etr device + - description: Byte cntr interrupt for the second etr device + + interrupt-names: + items: + - const: etr0 + - const: etr1 + label: description: Description of a coresight device. @@ -60,6 +70,8 @@ additionalProperties: false examples: - | + #include + ctcu@1001000 { compatible = "qcom,sa8775p-ctcu"; reg = <0x1001000 0x1000>; @@ -67,6 +79,11 @@ examples: clocks = <&aoss_qmp>; clock-names = "apb"; + interrupts = , + ; + interrupt-names = "etr0", + "etr1"; + in-ports { #address-cells = <1>; #size-cells = <0>; From 4d75c6b07587f52a171454baa138049735025e1e Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 13 Oct 2025 13:49:16 +0800 Subject: [PATCH 050/659] 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/20251211-enable-byte-cntr-for-ctcu-v8-6-3e12ff313191@oss.qualcomm.com/ Signed-off-by: Jie Gan --- .../testing/sysfs-bus-coresight-devices-ctcu | 6 + drivers/hwtracing/coresight/Makefile | 2 +- .../coresight/coresight-ctcu-byte-cntr.c | 368 ++++++++++++++++++ .../hwtracing/coresight/coresight-ctcu-core.c | 88 ++++- drivers/hwtracing/coresight/coresight-ctcu.h | 62 ++- .../hwtracing/coresight/coresight-tmc-etr.c | 18 + drivers/hwtracing/coresight/coresight-tmc.h | 1 + 7 files changed, 532 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..de1e87b4a72e9 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu @@ -0,0 +1,6 @@ +What: /sys/bus/coresight/devices//irq_threshold +Date: Dec. 2025 +KernelVersion: 6.19 +Contact: Tingwei Zhang ; Jinlong Mao ; Jie Gan +Description: + (RW) Configure the IRQ value for byte-cntr 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..99a871c5585c2 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c @@ -0,0 +1,368 @@ +// 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 = coresight_get_helper(drvdata->csdev, CORESIGHT_DEV_SUBTYPE_HELPER_CTCU); + 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 = coresight_get_helper(drvdata->csdev, CORESIGHT_DEV_SUBTYPE_HELPER_CTCU); + 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 sysfs_read_ops byte_cntr_sysfs_read_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_read_ops = &byte_cntr_sysfs_read_ops; + for (i = 0; i < etr_num; i++) { + byte_cntr_data = &drvdata->byte_cntr_data[i]; + irq_num = of_irq_get_byname(nd, byte_cntr_data->irq_name); + if (irq_num < 0) { + dev_err(dev, "Failed to get IRQ from DT for %s\n", + byte_cntr_data->irq_name); + 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 %s\n", + byte_cntr_data->irq_name); + continue; + } + + byte_cntr_data->irq = irq_num; + init_waitqueue_head(&byte_cntr_data->wq); + } +} diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c index 78be783b3cb25..38bfc6245ed1d 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,23 @@ 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, + .irq_name = "etr0", + .port_num = 0, }, { - .atid_offset = CTCU_ETR1_ATID0, - .port_num = 1, + .atid_offset = CTCU_ETR1_ATID0, + .irq_ctrl_offset = CTCU_ETR1_IRQCTRL, + .irq_name = "etr1", + .port_num = 1, }, }; @@ -64,6 +71,70 @@ 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_drvdata *drvdata = dev_get_drvdata(dev->parent); + int i, len = 0; + + for (i = 0; i < ETR_MAX_NUM; i++) { + if (drvdata->byte_cntr_data[i].irq_ctrl_offset) + len += scnprintf(buf + len, PAGE_SIZE - len, "%u ", + drvdata->byte_cntr_data[i].thresh_val); + } + + len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); + + return len; +} + +static ssize_t irq_threshold_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent); + u32 thresh_vals[ETR_MAX_NUM] = { 0 }; + int num, i; + + num = sscanf(buf, "%i %i", &thresh_vals[0], &thresh_vals[1]); + if (num <= 0 || num > ETR_MAX_NUM) + return -EINVAL; + + /* Threshold 0 disables the interruption. */ + guard(raw_spinlock_irqsave)(&drvdata->spin_lock); + for (i = 0; i < num; i++) { + /* A small threshold will result in a large number of interruptions */ + if (thresh_vals[i] && thresh_vals[i] < SZ_4K) + return -EINVAL; + + if (drvdata->byte_cntr_data[i].irq_ctrl_offset) + drvdata->byte_cntr_data[i].thresh_val = thresh_vals[i]; + } + + return size; +} +static DEVICE_ATTR_RW(irq_threshold); + +static struct attribute *ctcu_attrs[] = { + &dev_attr_irq_threshold.attr, + NULL, +}; + +static struct attribute_group ctcu_attr_grp = { + .attrs = ctcu_attrs, +}; + +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 +213,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 +272,11 @@ 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_name = etr_cfg->irq_name; + 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 +288,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..21938a201dbb1 100644 --- a/drivers/hwtracing/coresight/coresight-ctcu.h +++ b/drivers/hwtracing/coresight/coresight-ctcu.h @@ -5,19 +5,28 @@ #ifndef _CORESIGHT_CTCU_H #define _CORESIGHT_CTCU_H + +#include #include "coresight-trace-id.h" +#include "coresight-tmc.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; + const char *irq_name; }; struct ctcu_config { @@ -25,15 +34,52 @@ 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. + * @irq_name: IRQ name defined in DT. + */ +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; + const char *irq_name; +}; + +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 sysfs_read_ops *byte_cntr_sysfs_read_ops; }; +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 2b6ca1f8bed2b..3aeb0cbc720af 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1163,6 +1163,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) @@ -1226,6 +1230,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 c9a82ff6cd007..36f82e012fc62 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -481,5 +481,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 2488477b3f24d27fd59a5ede342384e77d23d7db Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 13 Oct 2025 13:49:17 +0800 Subject: [PATCH 051/659] FROMLIST: coresight: tmc: integrate byte-cntr's read_ops with sysfs file_ops Add code logic to invoke byte-cntr's sysfs_read_ops if the byte-cntr is enabled. Link: https://lore.kernel.org/all/20251211-enable-byte-cntr-for-ctcu-v8-7-3e12ff313191@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 8b0397a77e57c..41ac99b35a840 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 sysfs_read_ops if in use */ +static const struct sysfs_read_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 *helper; + int port; + + helper = coresight_get_helper(drvdata->csdev, CORESIGHT_DEV_SUBTYPE_HELPER_CTCU); + 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]; + if (byte_cntr_data && byte_cntr_data->thresh_val) + return ctcu_drvdata->byte_cntr_sysfs_read_ops; + + return NULL; +} + static int tmc_read_prepare(struct tmc_drvdata *drvdata) { + const struct sysfs_read_ops *byte_cntr_sysfs_read_ops; int ret = 0; + byte_cntr_sysfs_read_ops = tmc_get_byte_cntr_sysfs_ops(drvdata); + if (byte_cntr_sysfs_read_ops) { + ret = byte_cntr_sysfs_read_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 sysfs_read_ops *byte_cntr_sysfs_read_ops; int ret = 0; + byte_cntr_sysfs_read_ops = tmc_get_byte_cntr_sysfs_ops(drvdata); + if (byte_cntr_sysfs_read_ops) { + ret = byte_cntr_sysfs_read_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 sysfs_read_ops *byte_cntr_sysfs_read_ops; + + byte_cntr_sysfs_read_ops = tmc_get_byte_cntr_sysfs_ops(drvdata); + if (byte_cntr_sysfs_read_ops) + return byte_cntr_sysfs_read_ops->get_trace_data(drvdata, pos, len, bufpp); + if (drvdata->sysfs_ops) return drvdata->sysfs_ops->get_trace_data(drvdata, pos, len, bufpp); @@ -300,7 +347,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 2715520c55f6c0618bccfcc759f3d8e6b3a43cd8 Mon Sep 17 00:00:00 2001 From: Yingchao Deng Date: Fri, 24 Oct 2025 15:05:31 +0800 Subject: [PATCH 052/659] 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/20251024-p_ost-v4-1-3652a06fd055@oss.qualcomm.com/ Signed-off-by: Tingwei Zhang Signed-off-by: Yuanfang Zhang 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..498739b49da06 --- /dev/null +++ b/Documentation/ABI/testing/configfs-stp-policy-p_ost @@ -0,0 +1,6 @@ +What: /config/stp-policy/:p_ost.//entity +Date: Oct 2025 +KernelVersion: 6.18 +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 eda6b11d40a1f..daa4aa09f64dc 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..ac9492ed5c2c0 --- /dev/null +++ b/drivers/hwtracing/stm/p_ost.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + * + * 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 d3ef68b21dc2247cdae45344f5387b181652af60 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:03 -0700 Subject: [PATCH 053/659] FROMLIST: dt-bindings: arm: coresight: Add cpu cluster tmc/funnel/replicator support Add the following compatible strings to the bindings: - arm,coresight-cpu-funnel - arm,coresight-cpu-replicator - arm,coresight-cpu-tmc Each requires 'power-domains' when used. Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-1-31355ac588c2@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../arm/arm,coresight-dynamic-funnel.yaml | 23 +++++++++++++++---- .../arm/arm,coresight-dynamic-replicator.yaml | 22 ++++++++++++++---- .../bindings/arm/arm,coresight-tmc.yaml | 22 ++++++++++++++---- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml index b74db15e5f8af..8f32d4e3bbb75 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml @@ -28,19 +28,32 @@ select: properties: compatible: contains: - const: arm,coresight-dynamic-funnel + enum: + - arm,coresight-dynamic-funnel + - arm,coresight-cpu-funnel required: - compatible allOf: - $ref: /schemas/arm/primecell.yaml# + - if: + properties: + compatible: + contains: + const: arm,coresight-cpu-funnel + then: + required: + - power-domains + properties: compatible: - items: - - const: arm,coresight-dynamic-funnel - - const: arm,primecell - + oneOf: + - items: + - const: arm,coresight-dynamic-funnel + - const: arm,primecell + - items: + - const: arm,coresight-cpu-funnel reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml index 17ea936b796fd..5ce30c4e9c415 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml @@ -28,18 +28,32 @@ select: properties: compatible: contains: - const: arm,coresight-dynamic-replicator + enum: + - arm,coresight-dynamic-replicator + - arm,coresight-cpu-replicator required: - compatible allOf: - $ref: /schemas/arm/primecell.yaml# + - if: + properties: + compatible: + contains: + const: arm,coresight-cpu-replicator + then: + required: + - power-domains + properties: compatible: - items: - - const: arm,coresight-dynamic-replicator - - const: arm,primecell + oneOf: + - items: + - const: arm,coresight-dynamic-replicator + - const: arm,primecell + - items: + - const: arm,coresight-cpu-replicator reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml index 96dd5b5f771a3..d7c0b618fe98a 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml @@ -29,18 +29,32 @@ select: properties: compatible: contains: - const: arm,coresight-tmc + enum: + - arm,coresight-tmc + - arm,coresight-cpu-tmc required: - compatible allOf: - $ref: /schemas/arm/primecell.yaml# + - if: + properties: + compatible: + contains: + const: arm,coresight-cpu-tmc + then: + required: + - power-domains + properties: compatible: - items: - - const: arm,coresight-tmc - - const: arm,primecell + oneOf: + - items: + - const: arm,coresight-tmc + - const: arm,primecell + - items: + - const: arm,coresight-cpu-tmc reg: maxItems: 1 From 905a1f7b99db26a739fb39d4f65bfd69ca023a6c Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:04 -0700 Subject: [PATCH 054/659] FROMLIST: coresight-funnel: Add support for CPU cluster funnel The CPU cluster funnel is a type of CoreSight funnel that resides inside the CPU cluster's power domain. Unlike dynamic funnels, CPU funnels are coupled with CPU clusters and share their power management characteristics. When the CPU cluster enters low-power mode (LPM), the funnel's registers become inaccessible. Moreover, runtime PM operations alone cannot bring the CPU cluster out of LPM, making standard register access unreliable. This patch enhances the existing CoreSight funnel platform driver to support CPU cluster funnels by: - Add cpumask to funnel_drvdata to store CPU cluster's mask for CPU cluster funnel. - Retrieving the associated CPU cluster's cpumask from the power domain. - Using smp_call_function_single() to do clear self claim tag operation. - Refactoring funnel_enable function. For cluster funnels, use smp_call_function_single() to ensure register visibility. - Encapsulating coresight registration in funnel_add_coresight_dev(). - Reusing the existing platform driver infrastructure to minimize duplication and maintain compatibility with static funnel devices. This ensures funnel operations are safe and functional even when the CPU cluster is in low-power mode. Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-2-31355ac588c2@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-funnel.c | 185 +++++++++++++++--- 1 file changed, 154 insertions(+), 31 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 3b248e54471a3..12c29eb98b212 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. + * @cpumask: CPU mask representing 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 *cpumask; +}; + +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->cpumask) + return dynamic_funnel_enable_hw(drvdata, port); + + arg.drvdata = drvdata; + arg.port = port; + + for_each_cpu(cpu, drvdata->cpumask) { + 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->cpumask) { + val = get_funnel_ctrl_hw(drvdata); + } else { + arg.drvdata = drvdata; + for_each_cpu(cpu, drvdata->cpumask) { + 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_cpumask(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,37 @@ 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 (is_of_node(dev_fwnode(dev)) && + of_device_is_compatible(dev->of_node, "arm,coresight-cpu-funnel")) { + drvdata->cpumask = funnel_get_cpumask(dev); + if (!drvdata->cpumask) + return -EINVAL; + + cpus_read_lock(); + for_each_cpu(cpu, drvdata->cpumask) { + 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; } @@ -341,6 +463,7 @@ static void funnel_platform_remove(struct platform_device *pdev) static const struct of_device_id funnel_match[] = { {.compatible = "arm,coresight-static-funnel"}, + {.compatible = "arm,coresight-cpu-funnel"}, {} }; From c02621d3bd92aeb2074b261bb6e2fd92a376b53f Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:05 -0700 Subject: [PATCH 055/659] FROMLIST: coresight-funnel: Handle delay probe for CPU cluster funnel Delay probe the cpu cluster funnel when all CPUs of this cluster are offline, re-probe the funnel when any CPU in the cluster comes online. Key changes: - Introduce a global list to track delayed funnels waiting for CPU online. - Add CPU hotplug callback to retry registration when the CPU comes up. Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-3-31355ac588c2@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 12c29eb98b212..43b9287a865eb 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. * @cpumask: CPU mask representing 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 *cpumask; + struct device *dev; + struct list_head link; }; struct funnel_smp_arg { @@ -372,7 +379,7 @@ static int funnel_probe(struct device *dev, struct resource *res) drvdata->cpumask = funnel_get_cpumask(dev); if (!drvdata->cpumask) return -EINVAL; - + drvdata->dev = dev; cpus_read_lock(); for_each_cpu(cpu, drvdata->cpumask) { ret = smp_call_function_single(cpu, @@ -380,10 +387,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); } @@ -395,9 +407,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; } @@ -535,8 +550,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->cpumask)) { + 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); } @@ -544,6 +592,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 19cb110746b0a1e8468b6b29aab094d6b146fae8 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:06 -0700 Subject: [PATCH 056/659] FROMLIST: coresight-replicator: Add support for CPU cluster replicator The CPU cluster replicator is a type of CoreSight replicator that resides inside the CPU cluster's power domain. Unlike system-wide replicators, CPU replicators are tightly coupled with CPU clusters and inherit their power management characteristics. When the CPU cluster enters low-power mode (LPM), the replicator registers become inaccessible. Moreover, runtime PM alone cannot bring the CPU cluster out of LPM, making standard register access unreliable. This patch enhances the existing CoreSight replicator platform driver to support CPU cluster replicators by: - Adding replicator_claim/disclaim_device_unlocked() to handle device claim/disclaim before CoreSight device registration. - Wrapping replicator_reset and clear_clear_tag in replicator_init_hw. For cluster replicators, use smp_call_function_single() to ensure register visibility. - Encapsulating csdev registration in replicator_add_coresight_dev(). - Refactoring replicator_enable function. For cluster replicators, use smp_call_function_single() to ensure register visibility. - Maintaining compatibility with existing static/dynamic replicators while minimizing duplication. This ensures replicator operations remain safe and functional even when the CPU cluster is in low-power states. Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-4-31355ac588c2@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../coresight/coresight-replicator.c | 202 +++++++++++++++--- 1 file changed, 169 insertions(+), 33 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index e6472658235dc..c5a9c7a2adfa9 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. + * @cpumask: CPU mask representing the CPUs related to this replicator. */ 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 *cpumask; }; -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->cpumask) + return dynamic_replicator_enable(drvdata, 0, outport); + + arg.drvdata = drvdata; + arg.outport = outport; + + for_each_cpu(cpu, drvdata->cpumask) { + 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_cpumask(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,39 @@ 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 (is_of_node(dev_fwnode(dev)) && + of_device_is_compatible(dev->of_node, "arm,coresight-cpu-replicator")) { + drvdata->cpumask = replicator_get_cpumask(dev); + if (!drvdata->cpumask) + return -EINVAL; + + cpus_read_lock(); + for_each_cpu(cpu, drvdata->cpumask) { + 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; } @@ -354,6 +489,7 @@ static const struct dev_pm_ops replicator_dev_pm_ops = { static const struct of_device_id replicator_match[] = { {.compatible = "arm,coresight-replicator"}, {.compatible = "arm,coresight-static-replicator"}, + {.compatible = "arm,coresight-cpu-replicator"}, {} }; From ede86f97dba9552a6314d9fe7f1e4779f83f751d Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:07 -0700 Subject: [PATCH 057/659] FROMLIST: coresight-replicator: Handle delayed probe for CPU cluster replicator Delay probe the CPU cluster replicator when all CPUs of the cluster are offline, and re-probe the replicator when any CPU in the cluster comes online. Key changes: - Maintain a global list to track delayed replicators waiting for CPU online. - Add a CPU hotplug callback to retry registration on CPU online events. Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-5-31355ac588c2@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 c5a9c7a2adfa9..1dfe11940cd60 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. * @cpumask: CPU mask representing the CPUs related to this replicator. + * @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 *cpumask; + struct device *dev; + struct list_head link; }; struct replicator_smp_arg { @@ -395,7 +402,7 @@ static int replicator_probe(struct device *dev, struct resource *res) drvdata->cpumask = replicator_get_cpumask(dev); if (!drvdata->cpumask) return -EINVAL; - + drvdata->dev = dev; cpus_read_lock(); for_each_cpu(cpu, drvdata->cpumask) { ret = smp_call_function_single(cpu, @@ -403,10 +410,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); } @@ -420,8 +432,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; } @@ -554,8 +571,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->cpumask)) { + 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); } @@ -563,6 +616,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 c5df07aeb9f1a2dc9da3f739914af1f009ec1fb2 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:08 -0700 Subject: [PATCH 058/659] FROMLIST: coresight-replicator: Update mgmt_attrs for CPU cluster replicator compatibility This patch refactors the sysfs interfaces to ensure compatibility with CPU cluster replicators. For CPU cluster replicators, register reads are performed via smp_call_function_single(). Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-6-31355ac588c2@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 1dfe11940cd60..22c9bc71817d2 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->cpumask) { + 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->cpumask) { + 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 88c50d84eeb036c368abb87859ad2aee0f45fb0b Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:09 -0700 Subject: [PATCH 059/659] FROMLIST: coresight-tmc: Add support for CPU cluster ETF and refactor probe flow The CPU cluster ETF is a type of Coresight ETF that resides inside the CPU cluster's power domain. Unlike system-level ETFs, these devices share the CPU cluster's power management behavior: when the cluster enters low-power mode, ETF registers become inaccessible. Runtime PM alone cannot bring the cluster out of LPM, making standard register access unreliable. This patch adds support for CPU cluster ETF and restructures the probe sequence to handle such cases safely: - Wrap hardware access in tmc_init_hw_config(). For cluster TMCs, use smp_call_function_single() to ensure register visibility. - Encapsulate CoreSight device registration and misc_register setup in tmc_add_coresight_dev(). This ensures TMC initialization and runtime operations remain safe even when the CPU cluster is in low-power states, while maintaining compatibility with existing system-level TMCs. Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-7-31355ac588c2@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-tmc-core.c | 204 ++++++++++++------ drivers/hwtracing/coresight/coresight-tmc.h | 6 + 2 files changed, 141 insertions(+), 69 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 41ac99b35a840..4909cbf2bcc84 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 @@ -813,56 +814,14 @@ static const struct sysfs_read_ops tmc_etr_sysfs_read_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) { @@ -879,9 +838,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; @@ -899,44 +858,142 @@ 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_cpumask(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 (is_of_node(dev_fwnode(dev)) && + of_device_is_compatible(dev->of_node, "arm,coresight-cpu-tmc")) { + drvdata->cpumask = tmc_get_cpumask(dev); + if (!drvdata->cpumask) + return -EINVAL; + + cpus_read_lock(); + for_each_cpu(cpu, drvdata->cpumask) { + 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; } @@ -982,10 +1039,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->cpumask) + 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) @@ -1040,7 +1099,6 @@ static void tmc_platform_remove(struct platform_device *pdev) if (WARN_ON(!drvdata)) return; - __tmc_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); } @@ -1077,6 +1135,13 @@ static const struct dev_pm_ops tmc_dev_pm_ops = { SET_RUNTIME_PM_OPS(tmc_runtime_suspend, tmc_runtime_resume, NULL) }; +static const struct of_device_id tmc_match[] = { + {.compatible = "arm,coresight-cpu-tmc"}, + {} +}; + +MODULE_DEVICE_TABLE(of, tmc_match); + #ifdef CONFIG_ACPI static const struct acpi_device_id tmc_acpi_ids[] = { {"ARMHC501", 0, 0, 0}, /* ARM CoreSight ETR */ @@ -1091,6 +1156,7 @@ static struct platform_driver tmc_platform_driver = { .remove = tmc_platform_remove, .driver = { .name = "coresight-tmc-platform", + .of_match_table = tmc_match, .acpi_match_table = ACPI_PTR(tmc_acpi_ids), .suppress_bind_attrs = true, .pm = &tmc_dev_pm_ops, diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 36f82e012fc62..030c98cb7867d 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -261,6 +261,9 @@ struct sysfs_read_ops; * @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. + * @cpumask: CPU mask representing 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 sysfs_read_ops *sysfs_ops; + struct cpumask *cpumask; + u32 devid; + const char *desc_name; }; /** From 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 Mon Sep 17 00:00:00 2001 From: Melody Olvera Date: Wed, 15 Oct 2025 16:22:07 +0530 Subject: [PATCH 060/659] 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 7237369ec11c5e78032483f0901b758475af2c42 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Tue, 16 Dec 2025 18:35:16 +0530 Subject: [PATCH 061/659] QCLINUX: Revert "FROMLIST: dt-bindings: mfd: qcom,spmi-pmic: Document PMICs present on Kaanapali" This reverts commit 2c0e8b5326b2 ("FROMLIST: dt-bindings: mfd: qcom,spmi-pmic: Document PMICs present on Kaanapali), in order to apply the latest version of that patch, which adds the same support for both Kaanapali and Glymur. Signed-off-by: Jishnu Prakash --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 427023cb11c5e..078a6886f8b1e 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -78,9 +78,6 @@ properties: - qcom,pmc8380 - qcom,pmd8028 - qcom,pmd9635 - - qcom,pmh0101 - - qcom,pmh0104 - - qcom,pmh0110 - qcom,pmi632 - qcom,pmi8950 - qcom,pmi8962 @@ -90,7 +87,6 @@ properties: - qcom,pmk8002 - qcom,pmk8350 - qcom,pmk8550 - - qcom,pmk8850 - qcom,pmm8155au - qcom,pmm8654au - qcom,pmp8074 From 91e88b9ce499fd46d4b7341e0a9a2e5accccf9ee Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Tue, 16 Dec 2025 15:44:12 +0530 Subject: [PATCH 062/659] FROMLIST: dt-bindings: mfd: qcom,spmi-pmic: Document PMICs present on Glymur and Kaanapali Document compatibles for the pmcx0102, pmh0101, pmh0104, pmh0110, pmk8850 and smb2370 SPMI PMICs. Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20251216-knp-pmic-mfd-v3-1-9d0cd62676d9@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 078a6886f8b1e..50c9b7be3f31b 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -76,8 +76,12 @@ properties: - qcom,pmc8180 - qcom,pmc8180c - qcom,pmc8380 + - qcom,pmcx0102 - qcom,pmd8028 - qcom,pmd9635 + - qcom,pmh0101 + - qcom,pmh0104 + - qcom,pmh0110 - qcom,pmi632 - qcom,pmi8950 - qcom,pmi8962 @@ -87,6 +91,7 @@ properties: - qcom,pmk8002 - qcom,pmk8350 - qcom,pmk8550 + - qcom,pmk8850 - qcom,pmm8155au - qcom,pmm8654au - qcom,pmp8074 @@ -99,6 +104,7 @@ properties: - qcom,pmx75 - qcom,smb2351 - qcom,smb2360 + - qcom,smb2370 - const: qcom,spmi-pmic reg: From 13e23fb3db9c125cd6bd077825ecc99ab8d53e16 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 29 May 2025 17:06:00 +0530 Subject: [PATCH 063/659] 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 9307c2321b29d26ca2f018e0f2b1bdee89b8c158 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 23 Sep 2025 14:20:27 +0530 Subject: [PATCH 064/659] 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 3f57add8c99ebe042ecd2eaa557a5b4a8152e54d Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 26 Sep 2025 10:08:11 +0800 Subject: [PATCH 065/659] 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 123bf9f338d1a43f3080ea9578968ede8a66691a Mon Sep 17 00:00:00 2001 From: Charan Teja Kalla Date: Tue, 30 Sep 2025 18:27:55 +0530 Subject: [PATCH 066/659] 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 f3679c0d06c23fc9836a2021d4288f85017de7ca Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 6 Oct 2025 16:56:58 +0530 Subject: [PATCH 067/659] 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 1aea53156ec51f889de1a3a9ddb1cb06998da508 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 6 Oct 2025 17:11:01 +0530 Subject: [PATCH 068/659] 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 9f6ab7dabf672..2f6c661ec4a0b 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 43bdb68f0c95ee5dd8d8b2f5d1a52def38088964 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 31 Oct 2025 15:58:40 +0800 Subject: [PATCH 069/659] 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 a05e87188b6a8fb51d6c74760ee4fc505a10f29d Mon Sep 17 00:00:00 2001 From: Pushpendra Singh Date: Wed, 13 Aug 2025 16:50:49 +0530 Subject: [PATCH 070/659] FROMLIST: drivers: qcom: icc-bwmon: Change zone1_thres_count to 3 Change zone1_thres_count to 3 from 16 so that driver can reduce bus vote in 3 sample window instead of waiting for 16 windows. Link: https://lore.kernel.org/lkml/d72182bc-f8d4-4314-b2f1-c9242618eb67@quicinc.com/ 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 3bd2b2a2a748a65067a7eea47186963031d73ae3 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Tue, 21 Oct 2025 23:32:30 -0700 Subject: [PATCH 071/659] FROMLIST: dt-bindings: mailbox: qcom: Add CPUCP mailbox controller bindings for Kaanapali Document CPUSS Control Processor (CPUCP) mailbox controller for Qualcomm Kaanapali, which is compatible with X1E80100, use fallback to indicate this. Signed-off-by: Jingyi Wang Acked-by: Rob Herring (Arm) Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251021-knp-cpufreq-v2-1-95391d66c84e@oss.qualcomm.com/ --- Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml index 9122c3d2dc30f..9e91247c521a1 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml @@ -19,6 +19,7 @@ properties: - items: - enum: - qcom,glymur-cpucp-mbox + - qcom,kaanapali-cpucp-mbox - const: qcom,x1e80100-cpucp-mbox - enum: - qcom,x1e80100-cpucp-mbox From e534b6504cbb02e315f959da607605afa122e753 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Sun, 2 Nov 2025 09:10:19 +0530 Subject: [PATCH 072/659] FROMLIST: media: iris: remove v4l2_m2m_ioctl_{de,en}coder_cmd API usage during STOP handling Currently v4l2_m2m_ioctl_{de,enc}coder_cmd is being invoked during STOP command handling. However, this is not required as the iris driver has its own drain and stop handling mechanism in place. Using the m2m command API in this context leads to incorrect behavior, where the LAST flag is prematurely attached to a capture buffer, when there are no buffers in m2m source queue. But, in this scenario even though the source buffers are returned to client, hardware might still need to process the pending capture buffers. Attaching LAST flag prematurely can result in the capture buffer being removed from the destination queue before the hardware has finished processing it, causing issues when the buffer is eventually returned by the hardware. To prevent this, remove the m2m API usage in stop handling. Link: https://lore.kernel.org/linux-media/20251102-iris-drain-fix-v1-1-7f88d187fb48@oss.qualcomm.com/ Fixes: d09100763bed ("media: iris: add support for drain sequence") Fixes: 75db90ae067d ("media: iris: Add support for drain sequence in encoder video device") Reviewed-by: Vikash Garodia Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_vidc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index c9b881923ef18..0c9c23ef2d180 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -572,9 +572,10 @@ static int iris_dec_cmd(struct file *filp, void *fh, mutex_lock(&inst->lock); - ret = v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec); - if (ret) + if (dec->cmd != V4L2_DEC_CMD_STOP && dec->cmd != V4L2_DEC_CMD_START) { + ret = -EINVAL; goto unlock; + } if (inst->state == IRIS_INST_DEINIT) goto unlock; @@ -605,9 +606,10 @@ static int iris_enc_cmd(struct file *filp, void *fh, mutex_lock(&inst->lock); - ret = v4l2_m2m_ioctl_encoder_cmd(filp, fh, enc); - if (ret) + if (enc->cmd != V4L2_ENC_CMD_STOP && enc->cmd != V4L2_ENC_CMD_START) { + ret = -EINVAL; goto unlock; + } if (inst->state == IRIS_INST_DEINIT) goto unlock; From 757b2555092cd76e970e6d383f1b9cb8081a9cb1 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 25 Nov 2025 11:04:19 +0530 Subject: [PATCH 073/659] FROMLIST: media: venus: vdec: restrict EOS addr quirk to IRIS2 only On SM8250 (IRIS2) with firmware older than 1.0.087, the firmware could not handle a dummy device address for EOS buffers, so a NULL device address is sent instead. The existing check used IS_V6() alongside a firmware version gate: if (IS_V6(core) && is_fw_rev_or_older(core, 1, 0, 87)) fdata.device_addr = 0; else fdata.device_addr = 0xdeadb000; However, SC7280 which is also V6, uses a firmware string of the form "1.0.", which the version parser translates to 1.0.0. This unintentionally satisfies the `is_fw_rev_or_older(..., 1, 0, 87)` condition on SC7280. Combined with IS_V6() matching there as well, the quirk is incorrectly applied to SC7280, causing VP9 decode failures. Constrain the check to IRIS2 (SM8250) only, which is the only platform that needed this quirk, by replacing IS_V6() with IS_IRIS2(). This restores correct behavior on SC7280 (no forced NULL EOS buffer address). Link: https://lore.kernel.org/linux-arm-msm/20251125-venus-vp9-fix-v2-1-8bfcea128b95@oss.qualcomm.com/ Fixes: 47f867cb1b63 ("media: venus: fix EOS handling in decoder stop command") Cc: stable@vger.kernel.org Reported-by: Mecid Closes: https://github.com/qualcomm-linux/kernel-topics/issues/222 Co-developed-by: Renjiang Han Signed-off-by: Renjiang Han Signed-off-by: Dikshita Agarwal Tested-by: Renjiang Han --- drivers/media/platform/qcom/venus/vdec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 4a6641fdffcf7..6b3d5e59133e6 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -565,7 +565,13 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) fdata.buffer_type = HFI_BUFFER_INPUT; fdata.flags |= HFI_BUFFERFLAG_EOS; - if (IS_V6(inst->core) && is_fw_rev_or_older(inst->core, 1, 0, 87)) + + /* Send NULL EOS addr for only IRIS2 (SM8250),for firmware <= 1.0.87. + * SC7280 also reports "1.0." parsed as 1.0.0; restricting to IRIS2 + * avoids misapplying this quirk and breaking VP9 decode on SC7280. + */ + + if (IS_IRIS2(inst->core) && is_fw_rev_or_older(inst->core, 1, 0, 87)) fdata.device_addr = 0; else fdata.device_addr = 0xdeadb000; From 7b7df263f0e80caebe5defb2d19fdf7e78b31b2b Mon Sep 17 00:00:00 2001 From: Deepa Guthyappa Madivalara Date: Wed, 10 Dec 2025 10:59:04 -0800 Subject: [PATCH 074/659] FROMLIST: media: uapi: videodev2: Add support for AV1 stateful decoder Introduce a new pixel format, V4L2_PIX_FMT_AV1, to the Video4Linux2(V4L2) API. This format is intended for AV1 bitstreams in stateful decoding/encoding workflows. The fourcc code 'AV10' is used to distinguish this format from the existing V4L2_PIX_FMT_AV1_FRAME, which is used for stateless AV1 decoder implementation. Link: https://lore.kernel.org/all/20251210-av1d_stateful_v3-v10-1-cf4379a3dcff@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Reviewed-by: Nicolas Dufresne Reviewed-by: Hans Verkuil Signed-off-by: Deepa Guthyappa Madivalara --- .../userspace-api/media/v4l/pixfmt-compressed.rst | 8 ++++++++ include/uapi/linux/videodev2.h | 1 + 2 files changed, 9 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst index c7efb0465db64..235f955d3cd5c 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst @@ -275,6 +275,14 @@ Compressed Formats of macroblocks to decode a full corresponding frame to the matching capture buffer. + * .. _V4L2-PIX-FMT-AV1: + + - ``V4L2_PIX_FMT_AV1`` + - 'AV01' + - AV1 compressed video frame. This format is adapted for implementing AV1 + pipeline. The decoder implements stateful video decoder and expects one + temporal unit per buffer in OBU stream format. + The encoder generates one Temporal Unit per buffer. .. raw:: latex \normalsize diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index add08188f0689..848e86617d5c8 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -775,6 +775,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ #define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') /* HEVC parsed slices */ #define V4L2_PIX_FMT_AV1_FRAME v4l2_fourcc('A', 'V', '1', 'F') /* AV1 parsed frame */ +#define V4L2_PIX_FMT_AV1 v4l2_fourcc('A', 'V', '0', '1') /* AV1 */ #define V4L2_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0') /* Sorenson Spark */ #define V4L2_PIX_FMT_RV30 v4l2_fourcc('R', 'V', '3', '0') /* RealVideo 8 */ #define V4L2_PIX_FMT_RV40 v4l2_fourcc('R', 'V', '4', '0') /* RealVideo 9 & 10 */ From 86df7635c1a09dd1bd0ed2d85947bde7cfe4496b Mon Sep 17 00:00:00 2001 From: Deepa Guthyappa Madivalara Date: Wed, 10 Dec 2025 10:59:05 -0800 Subject: [PATCH 075/659] FROMLIST: media: v4l2: Add description for V4L2_PIX_FMT_AV1 in v4l_fill_fmtdesc() Add a descriptive string for the AV1 pixel format to v4l_fill_fmtdesc(), enabling proper reporting of AV1 support via VIDIOC_ENUM_FMT. Link: https://lore.kernel.org/all/20251210-av1d_stateful_v3-v10-2-cf4379a3dcff@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Reviewed-by: Nicolas Dufresne Reviewed-by: Hans Verkuil Signed-off-by: Deepa Guthyappa Madivalara --- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 98512ea4cc5b9..37d33d4a363d7 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1544,6 +1544,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_QC10C: descr = "QCOM Compressed 10-bit Format"; break; case V4L2_PIX_FMT_AJPG: descr = "Aspeed JPEG"; break; case V4L2_PIX_FMT_AV1_FRAME: descr = "AV1 Frame"; break; + case V4L2_PIX_FMT_AV1: descr = "AV1 OBU Stream"; break; case V4L2_PIX_FMT_MT2110T: descr = "Mediatek 10bit Tile Mode"; break; case V4L2_PIX_FMT_MT2110R: descr = "Mediatek 10bit Raster Mode"; break; case V4L2_PIX_FMT_HEXTILE: descr = "Hextile Compressed Format"; break; From 852b4206f9fb6719c18c088068e98ed18d011815 Mon Sep 17 00:00:00 2001 From: Deepa Guthyappa Madivalara Date: Wed, 10 Dec 2025 10:59:06 -0800 Subject: [PATCH 076/659] FROMLIST: media: iris: Add support for AV1 format in iris decoder Extend iris decoder driver to support format V4L2_PIX_FMT_AV1. This change updates the format enumeration (VIDIOC_ENUM_FMT) and allows setting AV1 format via VIDIOC_S_FMT for gen2 and beyond. Gen1 iris hardware decoder does not support AV1 format. Link: https://lore.kernel.org/all/20251210-av1d_stateful_v3-v10-3-cf4379a3dcff@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Reviewed-by: Dikshita Agarwal Signed-off-by: Deepa Guthyappa Madivalara --- .../qcom/iris/iris_hfi_gen2_defines.h | 1 + .../media/platform/qcom/iris/iris_instance.h | 1 + .../platform/qcom/iris/iris_platform_common.h | 2 ++ .../platform/qcom/iris/iris_platform_gen1.c | 22 ++++++++++++++- .../platform/qcom/iris/iris_platform_gen2.c | 28 ++++++++++++++++++- drivers/media/platform/qcom/iris/iris_vdec.c | 23 +++------------ 6 files changed, 56 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h index 1b6a4dbac828f..3d56f257bc562 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h @@ -139,6 +139,7 @@ enum hfi_codec_type { HFI_CODEC_DECODE_HEVC = 3, HFI_CODEC_ENCODE_HEVC = 4, HFI_CODEC_DECODE_VP9 = 5, + HFI_CODEC_DECODE_AV1 = 7, }; enum hfi_picture_type { diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h index 62fbb30691ff9..7e4f5f1dd8921 100644 --- a/drivers/media/platform/qcom/iris/iris_instance.h +++ b/drivers/media/platform/qcom/iris/iris_instance.h @@ -19,6 +19,7 @@ enum iris_fmt_type_out { IRIS_FMT_H264, IRIS_FMT_HEVC, IRIS_FMT_VP9, + IRIS_FMT_AV1, }; enum iris_fmt_type_cap { diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 8d8cdb56a3c77..6e8e762bd5cf7 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -217,6 +217,8 @@ struct iris_platform_data { u64 dma_mask; const char *fwname; u32 pas_id; + struct iris_fmt *inst_iris_fmts; + u32 inst_iris_fmts_size; struct platform_inst_caps *inst_caps; const struct platform_inst_fw_cap *inst_fw_caps_dec; u32 inst_fw_caps_dec_size; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 34cbeb8f52e24..712515b0f3294 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -11,6 +11,7 @@ #include "iris_hfi_gen1_defines.h" #include "iris_vpu_buffer.h" #include "iris_vpu_common.h" +#include "iris_instance.h" #include "iris_platform_sc7280.h" @@ -19,7 +20,22 @@ #define BITRATE_PEAK_DEFAULT (BITRATE_DEFAULT * 2) #define BITRATE_STEP 100 -static const struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = { +static struct iris_fmt platform_fmts_sm8250_dec[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + +static struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = { { .cap_id = PIPE, /* .max, .min and .value are set via platform data */ @@ -337,6 +353,8 @@ const struct iris_platform_data sm8250_data = { .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu-1.0/venus.mbn", .pas_id = IRIS_PAS_ID, + .inst_iris_fmts = platform_fmts_sm8250_dec, + .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), .inst_caps = &platform_inst_cap_sm8250, .inst_fw_caps_dec = inst_fw_cap_sm8250_dec, .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), @@ -386,6 +404,8 @@ const struct iris_platform_data sc7280_data = { .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu20_p1.mbn", .pas_id = IRIS_PAS_ID, + .inst_iris_fmts = platform_fmts_sm8250_dec, + .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), .inst_caps = &platform_inst_cap_sm8250, .inst_fw_caps_dec = inst_fw_cap_sm8250_dec, .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index c1989240c2486..010f6b804e0a5 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -19,6 +19,25 @@ #define VIDEO_ARCH_LX 1 #define BITRATE_MAX 245000000 +static struct iris_fmt platform_fmts_sm8550_dec[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_AV1] = { + .pixfmt = V4L2_PIX_FMT_AV1, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { { .cap_id = PROFILE_H264, @@ -759,6 +778,8 @@ const struct iris_platform_data sm8550_data = { .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu30_p4.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), @@ -809,7 +830,6 @@ const struct iris_platform_data sm8550_data = { .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, @@ -851,6 +871,8 @@ const struct iris_platform_data sm8650_data = { .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu33_p4.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), @@ -933,6 +955,8 @@ const struct iris_platform_data sm8750_data = { .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu35_p4.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), @@ -1019,6 +1043,8 @@ const struct iris_platform_data qcs8300_data = { .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu30_p4_s6.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_qcs8300, .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 69ffe52590d3a..bf7b9c621cb72 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -67,21 +67,6 @@ void iris_vdec_inst_deinit(struct iris_inst *inst) kfree(inst->fmt_src); } -static const struct iris_fmt iris_vdec_formats_out[] = { - [IRIS_FMT_H264] = { - .pixfmt = V4L2_PIX_FMT_H264, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_HEVC] = { - .pixfmt = V4L2_PIX_FMT_HEVC, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_VP9] = { - .pixfmt = V4L2_PIX_FMT_VP9, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, -}; - static const struct iris_fmt iris_vdec_formats_cap[] = { [IRIS_FMT_NV12] = { .pixfmt = V4L2_PIX_FMT_NV12, @@ -101,8 +86,8 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) unsigned int i; switch (type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - fmt = iris_vdec_formats_out; - size = ARRAY_SIZE(iris_vdec_formats_out); + fmt = inst->core->iris_platform_data->inst_iris_fmts; + size = inst->core->iris_platform_data->inst_iris_fmts_size; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = iris_vdec_formats_cap; @@ -131,8 +116,8 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type) switch (type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - fmt = iris_vdec_formats_out; - size = ARRAY_SIZE(iris_vdec_formats_out); + fmt = inst->core->iris_platform_data->inst_iris_fmts; + size = inst->core->iris_platform_data->inst_iris_fmts_size; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = iris_vdec_formats_cap; From 60d5985e0fa6d94dd664d51e95740f408e06fa59 Mon Sep 17 00:00:00 2001 From: Deepa Guthyappa Madivalara Date: Wed, 10 Dec 2025 10:59:07 -0800 Subject: [PATCH 077/659] FROMLIST: media: iris: Define AV1-specific platform capabilities and properties Defining platform specific capabilities specific to AV1 decoder. Set and subscribe to manadatory properties to firmware for AV1. Link: https://lore.kernel.org/all/20251210-av1d_stateful_v3-v10-4-cf4379a3dcff@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Reviewed-by: Dikshita Agarwal Signed-off-by: Deepa Guthyappa Madivalara --- .../media/platform/qcom/iris/iris_buffer.h | 1 + drivers/media/platform/qcom/iris/iris_ctrls.c | 8 ++ .../platform/qcom/iris/iris_hfi_common.h | 3 + .../qcom/iris/iris_hfi_gen2_command.c | 85 ++++++++++- .../qcom/iris/iris_hfi_gen2_defines.h | 8 ++ .../qcom/iris/iris_hfi_gen2_response.c | 22 +++ .../platform/qcom/iris/iris_platform_common.h | 11 ++ .../platform/qcom/iris/iris_platform_gen2.c | 133 ++++++++++++++++++ drivers/media/platform/qcom/iris/iris_vidc.c | 1 + 9 files changed, 270 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h index 325d30fce5c99..5ef365d9236c7 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_buffer.h @@ -42,6 +42,7 @@ enum iris_buffer_type { BUF_SCRATCH_1, BUF_SCRATCH_2, BUF_VPSS, + BUF_PARTIAL, BUF_TYPE_MAX, }; diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c index c0b3a09ad3e3d..87f929442ec65 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.c +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c @@ -98,6 +98,10 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id) return B_FRAME_QP_H264; case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return B_FRAME_QP_HEVC; + case V4L2_CID_MPEG_VIDEO_AV1_PROFILE: + return PROFILE_AV1; + case V4L2_CID_MPEG_VIDEO_AV1_LEVEL: + return LEVEL_AV1; default: return INST_FW_CAP_MAX; } @@ -185,6 +189,10 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; case B_FRAME_QP_HEVC: return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP; + case PROFILE_AV1: + return V4L2_CID_MPEG_VIDEO_AV1_PROFILE; + case LEVEL_AV1: + return V4L2_CID_MPEG_VIDEO_AV1_LEVEL; default: return 0; } diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h index b51471fb32c70..3edb5ae582b49 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h @@ -141,6 +141,9 @@ struct hfi_subscription_params { u32 profile; u32 level; u32 tier; + u32 drap; + u32 film_grain; + u32 super_block; }; u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries); diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index f912955320992..b492d9dfddd3c 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -10,6 +10,7 @@ #define UNSPECIFIED_COLOR_FORMAT 5 #define NUM_SYS_INIT_PACKETS 8 +#define NUM_COMV_AV1 18 #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \ NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32))) @@ -121,6 +122,7 @@ static u32 iris_hfi_gen2_get_port_from_buf_type(struct iris_inst *inst, case BUF_COMV: case BUF_NON_COMV: case BUF_LINE: + case BUF_PARTIAL: return HFI_PORT_BITSTREAM; case BUF_OUTPUT: case BUF_DPB: @@ -380,6 +382,9 @@ static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane) case V4L2_PIX_FMT_H264: profile = inst->fw_caps[PROFILE_H264].value; break; + case V4L2_PIX_FMT_AV1: + profile = inst->fw_caps[PROFILE_AV1].value; + break; } inst_hfi_gen2->src_subcr_params.profile = profile; @@ -409,6 +414,9 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane) case V4L2_PIX_FMT_H264: level = inst->fw_caps[LEVEL_H264].value; break; + case V4L2_PIX_FMT_AV1: + level = inst->fw_caps[LEVEL_AV1].value; + break; } inst_hfi_gen2->src_subcr_params.level = level; @@ -496,10 +504,12 @@ static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane) { - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); u32 tier = inst->fw_caps[TIER].value; + tier = (inst->codec == V4L2_PIX_FMT_AV1) ? inst->fw_caps[TIER_AV1].value : + inst->fw_caps[TIER].value; inst_hfi_gen2->src_subcr_params.tier = tier; return iris_hfi_gen2_session_set_property(inst, @@ -525,6 +535,40 @@ static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane) sizeof(u32)); } +static int iris_hfi_gen2_set_film_grain(struct iris_inst *inst, u32 plane) +{ + u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); + u32 film_grain = inst->fw_caps[FILM_GRAIN].value; + + inst_hfi_gen2->src_subcr_params.film_grain = film_grain; + + return iris_hfi_gen2_session_set_property(inst, + HFI_PROP_AV1_FILM_GRAIN_PRESENT, + HFI_HOST_FLAGS_NONE, + port, + HFI_PAYLOAD_U32_ENUM, + &film_grain, + sizeof(u32)); +} + +static int iris_hfi_gen2_set_super_block(struct iris_inst *inst, u32 plane) +{ + u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); + u32 super_block = inst->fw_caps[SUPER_BLOCK].value; + + inst_hfi_gen2->src_subcr_params.super_block = super_block; + + return iris_hfi_gen2_session_set_property(inst, + HFI_PROP_AV1_SUPER_BLOCK_ENABLED, + HFI_HOST_FLAGS_NONE, + port, + HFI_PAYLOAD_U32_ENUM, + &super_block, + sizeof(u32)); +} + static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) { const struct iris_platform_data *pdata = inst->core->iris_platform_data; @@ -548,6 +592,9 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, {HFI_PROP_TIER, iris_hfi_gen2_set_tier }, {HFI_PROP_FRAME_RATE, iris_hfi_gen2_set_frame_rate }, + {HFI_PROP_AV1_FILM_GRAIN_PRESENT, iris_hfi_gen2_set_film_grain }, + {HFI_PROP_AV1_SUPER_BLOCK_ENABLED, iris_hfi_gen2_set_super_block }, + {HFI_PROP_OPB_ENABLE, iris_hfi_gen2_set_opb_enable }, }; if (inst->domain == DECODER) { @@ -561,6 +608,9 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p } else if (inst->codec == V4L2_PIX_FMT_VP9) { config_params = pdata->dec_input_config_params_vp9; config_params_size = pdata->dec_input_config_params_vp9_size; + } else if (inst->codec == V4L2_PIX_FMT_AV1) { + config_params = pdata->dec_input_config_params_av1; + config_params_size = pdata->dec_input_config_params_av1_size; } else { return -EINVAL; } @@ -615,6 +665,9 @@ static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) break; case V4L2_PIX_FMT_VP9: codec = HFI_CODEC_DECODE_VP9; + break; + case V4L2_PIX_FMT_AV1: + codec = HFI_CODEC_DECODE_AV1; } iris_hfi_gen2_packet_session_property(inst, @@ -780,6 +833,11 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan change_param_size = core->iris_platform_data->dec_input_config_params_vp9_size; break; + case V4L2_PIX_FMT_AV1: + change_param = core->iris_platform_data->dec_input_config_params_av1; + change_param_size = + core->iris_platform_data->dec_input_config_params_av1_size; + break; } payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE; @@ -862,6 +920,16 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan payload_size = sizeof(u32); payload_type = HFI_PAYLOAD_U32; break; + case HFI_PROP_AV1_FILM_GRAIN_PRESENT: + payload[0] = subsc_params.film_grain; + payload_size = sizeof(u32); + payload_type = HFI_PAYLOAD_U32; + break; + case HFI_PROP_AV1_SUPER_BLOCK_ENABLED: + payload[0] = subsc_params.super_block; + payload_size = sizeof(u32); + payload_type = HFI_PAYLOAD_U32; + break; default: prop_type = 0; ret = -EINVAL; @@ -917,6 +985,11 @@ static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) subscribe_prop_size = core->iris_platform_data->dec_output_prop_vp9_size; break; + case V4L2_PIX_FMT_AV1: + subcribe_prop = core->iris_platform_data->dec_output_prop_av1; + subscribe_prop_size = + core->iris_platform_data->dec_output_prop_av1_size; + break; } } @@ -1092,6 +1165,8 @@ static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type return HFI_BUFFER_ARP; case BUF_VPSS: return HFI_BUFFER_VPSS; + case BUF_PARTIAL: + return HFI_BUFFER_PARTIAL_DATA; default: return 0; } @@ -1104,7 +1179,13 @@ static int iris_set_num_comv(struct iris_inst *inst) u32 num_comv; caps = core->iris_platform_data->inst_caps; - num_comv = caps->num_comv; + + /* + * AV1 needs more comv buffers than other codecs. + * Update accordingly. + */ + num_comv = (inst->codec == V4L2_PIX_FMT_AV1) ? + NUM_COMV_AV1 : caps->num_comv; return core->hfi_ops->session_set_property(inst, HFI_PROP_COMV_BUFFER_COUNT, diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h index 3d56f257bc562..5f1f1a7eb91f3 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h @@ -89,10 +89,18 @@ enum hfi_seq_header_mode { #define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169 #define HFI_PROP_NO_OUTPUT 0x0300016a #define HFI_PROP_BUFFER_MARK 0x0300016c +#define HFI_PROP_WORST_COMPRESSION_RATIO 0x03000174 +#define HFI_PROP_WORST_COMPLEXITY_FACTOR 0x03000175 #define HFI_PROP_RAW_RESOLUTION 0x03000178 #define HFI_PROP_TOTAL_PEAK_BITRATE 0x0300017C +#define HFI_PROP_AV1_FILM_GRAIN_PRESENT 0x03000180 +#define HFI_PROP_AV1_SUPER_BLOCK_ENABLED 0x03000181 +#define HFI_PROP_AV1_OP_POINT 0x03000182 #define HFI_PROP_OPB_ENABLE 0x03000184 +#define HFI_PROP_AV1_TILE_ROWS_COLUMNS 0x03000187 +#define HFI_PROP_AV1_DRAP_CONFIG 0x03000189 #define HFI_PROP_COMV_BUFFER_COUNT 0x03000193 +#define HFI_PROP_AV1_UNIFORM_TILE_SPACING 0x03000197 #define HFI_PROP_END 0x03FFFFFF #define HFI_SESSION_ERROR_BEGIN 0x04000000 diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c index 2f1f118eae4f6..eb3373f0ad4a1 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c @@ -54,6 +54,8 @@ static u32 iris_hfi_gen2_buf_type_to_driver(struct iris_inst *inst, return BUF_SCRATCH_2; case HFI_BUFFER_PERSIST: return BUF_PERSIST; + case HFI_BUFFER_PARTIAL_DATA: + return BUF_PARTIAL; default: return 0; } @@ -72,6 +74,7 @@ static bool iris_hfi_gen2_is_valid_hfi_buffer_type(u32 buffer_type) case HFI_BUFFER_DPB: case HFI_BUFFER_PERSIST: case HFI_BUFFER_VPSS: + case HFI_BUFFER_PARTIAL_DATA: return true; default: return false; @@ -596,6 +599,10 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) inst->fw_caps[PROFILE_H264].value = subsc_params.profile; inst->fw_caps[LEVEL_H264].value = subsc_params.level; break; + case V4L2_PIX_FMT_AV1: + inst->fw_caps[PROFILE_AV1].value = subsc_params.profile; + inst->fw_caps[LEVEL_AV1].value = subsc_params.level; + break; } inst->fw_caps[POC].value = subsc_params.pic_order_cnt; @@ -608,6 +615,11 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) iris_inst_change_state(inst, IRIS_INST_ERROR); } + if (inst->codec == V4L2_PIX_FMT_AV1) { + inst->fw_caps[FILM_GRAIN].value = subsc_params.film_grain; + inst->fw_caps[SUPER_BLOCK].value = subsc_params.super_block; + } + inst->fw_min_count = subsc_params.fw_min_count; inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage; @@ -711,6 +723,12 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, case HFI_PROP_NO_OUTPUT: inst_hfi_gen2->hfi_frame_info.no_output = 1; break; + case HFI_PROP_AV1_FILM_GRAIN_PRESENT: + inst_hfi_gen2->src_subcr_params.film_grain = pkt->payload[0]; + break; + case HFI_PROP_AV1_SUPER_BLOCK_ENABLED: + inst_hfi_gen2->src_subcr_params.super_block = pkt->payload[0]; + break; case HFI_PROP_QUALITY_MODE: case HFI_PROP_STAGE: case HFI_PROP_PIPE: @@ -841,6 +859,10 @@ static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) subsc_params->profile = inst->fw_caps[PROFILE_H264].value; subsc_params->level = inst->fw_caps[LEVEL_H264].value; break; + case V4L2_PIX_FMT_AV1: + subsc_params->profile = inst->fw_caps[PROFILE_AV1].value; + subsc_params->level = inst->fw_caps[LEVEL_AV1].value; + break; } subsc_params->pic_order_cnt = inst->fw_caps[POC].value; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 6e8e762bd5cf7..14a2f4dbe38ab 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -103,6 +103,13 @@ enum platform_inst_fw_cap_type { LEVEL_H264, LEVEL_HEVC, LEVEL_VP9, + PROFILE_AV1, + LEVEL_AV1, + TIER_AV1, + DRAP, + FILM_GRAIN, + SUPER_BLOCK, + ENH_LAYER_COUNT, INPUT_BUF_HOST_MAX_COUNT, OUTPUT_BUF_HOST_MAX_COUNT, STAGE, @@ -241,6 +248,8 @@ struct iris_platform_data { unsigned int dec_input_config_params_hevc_size; const u32 *dec_input_config_params_vp9; unsigned int dec_input_config_params_vp9_size; + const u32 *dec_input_config_params_av1; + unsigned int dec_input_config_params_av1_size; const u32 *dec_output_config_params; unsigned int dec_output_config_params_size; const u32 *enc_input_config_params; @@ -255,6 +264,8 @@ struct iris_platform_data { unsigned int dec_output_prop_hevc_size; const u32 *dec_output_prop_vp9; unsigned int dec_output_prop_vp9_size; + const u32 *dec_output_prop_av1; + unsigned int dec_output_prop_av1_size; const u32 *dec_ip_int_buf_tbl; unsigned int dec_ip_int_buf_tbl_size; const u32 *dec_op_int_buf_tbl; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 010f6b804e0a5..b2d8559dd2b85 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -64,6 +64,16 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, .set = iris_set_u32_enum, }, + { + .cap_id = PROFILE_AV1, + .min = V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN), + .value = V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, { .cap_id = PROFILE_VP9, .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, @@ -147,6 +157,33 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, .set = iris_set_u32_enum, }, + { + .cap_id = LEVEL_AV1, + .min = V4L2_MPEG_VIDEO_AV1_LEVEL_2_0, + .max = V4L2_MPEG_VIDEO_AV1_LEVEL_6_1, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_2_2) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_2_3) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_3_2) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_3_3) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_4_2) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_4_3) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_5_0) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_5_1) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_5_2) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_5_3) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_6_0) | + BIT(V4L2_MPEG_VIDEO_AV1_LEVEL_6_1), + .value = V4L2_MPEG_VIDEO_AV1_LEVEL_6_1, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, { .cap_id = TIER, .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, @@ -158,6 +195,53 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, .set = iris_set_u32_enum, }, + { + .cap_id = TIER_AV1, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 0, + .hfi_id = HFI_PROP_TIER, + .flags = CAP_FLAG_INPUT_PORT, + .set = iris_set_u32, + }, + { + .cap_id = DRAP, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 0, + .hfi_id = HFI_PROP_AV1_DRAP_CONFIG, + .flags = CAP_FLAG_INPUT_PORT, + .set = iris_set_u32, + }, + { + .cap_id = FILM_GRAIN, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 0, + .hfi_id = HFI_PROP_AV1_FILM_GRAIN_PRESENT, + .flags = CAP_FLAG_VOLATILE, + }, + { + .cap_id = SUPER_BLOCK, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 0, + .hfi_id = HFI_PROP_AV1_SUPER_BLOCK_ENABLED, + }, + { + .cap_id = ENH_LAYER_COUNT, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 0, + .hfi_id = HFI_PROP_AV1_OP_POINT, + .flags = CAP_FLAG_INPUT_PORT, + .set = iris_set_u32, + }, { .cap_id = INPUT_BUF_HOST_MAX_COUNT, .min = DEFAULT_MAX_HOST_BUF_COUNT, @@ -699,6 +783,19 @@ static const u32 sm8550_vdec_input_config_param_vp9[] = { HFI_PROP_LEVEL, }; +static const u32 sm8550_vdec_input_config_param_av1[] = { + HFI_PROP_BITSTREAM_RESOLUTION, + HFI_PROP_CROP_OFFSETS, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, + HFI_PROP_PROFILE, + HFI_PROP_LEVEL, + HFI_PROP_TIER, + HFI_PROP_AV1_FILM_GRAIN_PRESENT, + HFI_PROP_AV1_SUPER_BLOCK_ENABLED, + HFI_PROP_SIGNAL_COLOR_INFO, +}; + static const u32 sm8550_venc_input_config_params[] = { HFI_PROP_COLOR_FORMAT, HFI_PROP_RAW_RESOLUTION, @@ -736,11 +833,18 @@ static const u32 sm8550_vdec_subscribe_output_properties_vp9[] = { HFI_PROP_PICTURE_TYPE, }; +static const u32 sm8550_vdec_subscribe_output_properties_av1[] = { + HFI_PROP_PICTURE_TYPE, + HFI_PROP_WORST_COMPRESSION_RATIO, + HFI_PROP_WORST_COMPLEXITY_FACTOR, +}; + static const u32 sm8550_dec_ip_int_buf_tbl[] = { BUF_BIN, BUF_COMV, BUF_NON_COMV, BUF_LINE, + BUF_PARTIAL, }; static const u32 sm8550_dec_op_int_buf_tbl[] = { @@ -805,6 +909,10 @@ const struct iris_platform_data sm8550_data = { sm8550_vdec_input_config_param_vp9, .dec_input_config_params_vp9_size = ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_input_config_params_av1 = + sm8550_vdec_input_config_param_av1, + .dec_input_config_params_av1_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_av1), .dec_output_config_params = sm8550_vdec_output_config_params, .dec_output_config_params_size = @@ -830,6 +938,10 @@ const struct iris_platform_data sm8550_data = { .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, .dec_output_prop_vp9_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, + .dec_output_prop_av1_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), + .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, @@ -898,6 +1010,10 @@ const struct iris_platform_data sm8650_data = { sm8550_vdec_input_config_param_vp9, .dec_input_config_params_vp9_size = ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_input_config_params_av1 = + sm8550_vdec_input_config_param_av1, + .dec_input_config_params_av1_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_av1), .dec_output_config_params = sm8550_vdec_output_config_params, .dec_output_config_params_size = @@ -923,6 +1039,9 @@ const struct iris_platform_data sm8650_data = { .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, .dec_output_prop_vp9_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, + .dec_output_prop_av1_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), .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), @@ -981,6 +1100,10 @@ const struct iris_platform_data sm8750_data = { sm8550_vdec_input_config_param_vp9, .dec_input_config_params_vp9_size = ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_input_config_params_av1 = + sm8550_vdec_input_config_param_av1, + .dec_input_config_params_av1_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_av1), .dec_output_config_params = sm8550_vdec_output_config_params, .dec_output_config_params_size = @@ -1006,6 +1129,9 @@ const struct iris_platform_data sm8750_data = { .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, .dec_output_prop_vp9_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, + .dec_output_prop_av1_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), .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), @@ -1070,6 +1196,10 @@ const struct iris_platform_data qcs8300_data = { sm8550_vdec_input_config_param_vp9, .dec_input_config_params_vp9_size = ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_input_config_params_av1 = + sm8550_vdec_input_config_param_av1, + .dec_input_config_params_av1_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_av1), .dec_output_config_params = sm8550_vdec_output_config_params, .dec_output_config_params_size = @@ -1095,6 +1225,9 @@ const struct iris_platform_data qcs8300_data = { .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, .dec_output_prop_vp9_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, + .dec_output_prop_av1_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), .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), diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index 0c9c23ef2d180..bd38d84c9cc79 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -178,6 +178,7 @@ int iris_open(struct file *filp) INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list); INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_2].list); INIT_LIST_HEAD(&inst->buffers[BUF_VPSS].list); + INIT_LIST_HEAD(&inst->buffers[BUF_PARTIAL].list); init_completion(&inst->completion); init_completion(&inst->flush_completion); From c98be2e4b4baa993c0520d0bd31049af06b5966d Mon Sep 17 00:00:00 2001 From: Deepa Guthyappa Madivalara Date: Wed, 10 Dec 2025 10:59:08 -0800 Subject: [PATCH 078/659] FROMLIST: media: iris: Add internal buffer calculation for AV1 decoder Implement internal buffer count and size calculations for AV1 decoder for all the buffer types required by the AV1 decoder, including BIN, COMV, PERSIST, LINE, and PARTIAL. This ensures the hardware decoder has properly allocated memory for AV1 decoding operations, enabling correct AV1 video playback. Link: https://lore.kernel.org/all/20251210-av1d_stateful_v3-v10-5-cf4379a3dcff@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Signed-off-by: Deepa Guthyappa Madivalara --- .../media/platform/qcom/iris/iris_buffer.h | 1 + .../platform/qcom/iris/iris_vpu_buffer.c | 299 +++++++++++++++++- .../platform/qcom/iris/iris_vpu_buffer.h | 116 +++++++ 3 files changed, 412 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h index 5ef365d9236c7..75bb767761824 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_buffer.h @@ -27,6 +27,7 @@ struct iris_inst; * @BUF_SCRATCH_1: buffer to store decoding/encoding context data for HW * @BUF_SCRATCH_2: buffer to store encoding context data for HW * @BUF_VPSS: buffer to store VPSS context data for HW + * @BUF_PARTIAL: buffer for AV1 IBC data * @BUF_TYPE_MAX: max buffer types */ enum iris_buffer_type { diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c index 4463be05ce165..f4985790bae41 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c @@ -9,6 +9,17 @@ #include "iris_hfi_gen2_defines.h" #define HFI_MAX_COL_FRAME 6 +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT (8) +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH (32) +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_HEIGHT (8) +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH (16) +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_HEIGHT (4) +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_WIDTH (48) +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC_UV_TILE_HEIGHT (4) +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC_UV_TILE_WIDTH (24) +#define AV1D_SIZE_BSE_COL_MV_64x64 512 +#define AV1D_SIZE_BSE_COL_MV_128x128 2816 +#define UBWC_TILE_SIZE 256 #ifndef SYSTEM_LAL_TILE10 #define SYSTEM_LAL_TILE10 192 @@ -39,6 +50,31 @@ static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_p return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); } +static u32 size_av1d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 size_yuv, size_bin_hdr, size_bin_res; + + size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ? + ((BIN_BUFFER_THRESHOLD * 3) >> 1) : + ((frame_width * frame_height * 3) >> 1); + size_bin_hdr = size_yuv * AV1_CABAC_HDR_RATIO_HD_TOT; + size_bin_res = size_yuv * AV1_CABAC_RES_RATIO_HD_TOT; + size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, + DMA_ALIGNMENT) * num_vpp_pipes; + size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, + DMA_ALIGNMENT) * num_vpp_pipes; + + return size_bin_hdr + size_bin_res; +} + +static u32 hfi_buffer_bin_av1d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 n_aligned_h = ALIGN(frame_height, 16); + u32 n_aligned_w = ALIGN(frame_width, 16); + + return size_av1d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); +} + static u32 size_h265d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) { u32 product = frame_width * frame_height; @@ -110,6 +146,26 @@ static u32 hfi_buffer_comv_h265d(u32 frame_width, u32 frame_height, u32 _comv_bu return (_size * (_comv_bufcount)) + 512; } +static u32 num_lcu(u32 frame_width, u32 frame_height, u32 lcu_size) +{ + return ((frame_width + lcu_size - 1) / lcu_size) * + ((frame_height + lcu_size - 1) / lcu_size); +} + +static u32 hfi_buffer_comv_av1d(u32 frame_width, u32 frame_height, u32 comv_bufcount) +{ + u32 size; + + size = 2 * ALIGN(max(num_lcu(frame_width, frame_height, 64) * + AV1D_SIZE_BSE_COL_MV_64x64, + num_lcu(frame_width, frame_height, 128) * + AV1D_SIZE_BSE_COL_MV_128x128), + DMA_ALIGNMENT); + size *= comv_bufcount; + + return size; +} + static u32 size_h264d_bse_cmd_buf(u32 frame_height) { u32 height = ALIGN(frame_height, 32); @@ -122,7 +178,7 @@ static u32 size_h265d_bse_cmd_buf(u32 frame_width, u32 frame_height) { u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * - NUM_HW_PIC_BUF, DMA_ALIGNMENT); + NUM_HW_PIC_BUF, DMA_ALIGNMENT); _size = min_t(u32, _size, H265D_MAX_SLICE + 1); _size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF; @@ -174,6 +230,20 @@ static u32 hfi_buffer_persist_h264d(void) DMA_ALIGNMENT); } +static u32 hfi_buffer_persist_av1d(u32 max_width, u32 max_height, u32 total_ref_count) +{ + u32 comv_size, size; + + comv_size = hfi_buffer_comv_av1d(max_width, max_height, total_ref_count); + size = ALIGN((SIZE_AV1D_SEQUENCE_HEADER * 2 + SIZE_AV1D_METADATA + + AV1D_NUM_HW_PIC_BUF * (SIZE_AV1D_TILE_OFFSET + SIZE_AV1D_QM) + + AV1D_NUM_FRAME_HEADERS * (SIZE_AV1D_FRAME_HEADER + + 2 * SIZE_AV1D_PROB_TABLE) + comv_size + HDR10_HIST_EXTRADATA_SIZE + + SIZE_AV1D_METADATA * AV1D_NUM_HW_PIC_BUF), DMA_ALIGNMENT); + + return ALIGN(size, DMA_ALIGNMENT); +} + static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) { u32 size_bse = size_h264d_bse_cmd_buf(frame_height); @@ -459,6 +529,182 @@ static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height, return ALIGN((size + vpss_lb_size), DMA_ALIGNMENT); } +static u32 size_av1d_lb_opb_wr1_nv12_ubwc(u32 frame_width, u32 frame_height) +{ + u32 size, y_width, y_width_a = 128; + + y_width = ALIGN(frame_width, y_width_a); + + size = ((y_width + HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH - 1) / + HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH + + (AV1D_MAX_TILE_COLS - 1)); + return size * UBWC_TILE_SIZE; +} + +static u32 size_av1d_lb_opb_wr1_tp10_ubwc(u32 frame_width, u32 frame_height) +{ + u32 size, y_width, y_width_a = 256; + + y_width = ALIGN(frame_width, y_width_a); + + size = ((y_width + HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_WIDTH - 1) / + HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_WIDTH + + (AV1D_MAX_TILE_COLS - 1)); + + return size * UBWC_TILE_SIZE; +} + +static u32 hfi_buffer_line_av1d(u32 frame_width, u32 frame_height, + bool is_opb, u32 num_vpp_pipes) +{ + u32 size, vpss_lb_size, opbwrbufsize, opbwr8, opbwr10; + + size = ALIGN(size_av1d_lb_fe_top_data(frame_width, frame_height), + DMA_ALIGNMENT) + + ALIGN(size_av1d_lb_fe_top_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) + + ALIGN(size_av1d_lb_fe_left_data(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_av1d_lb_fe_left_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_av1d_lb_se_left_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_av1d_lb_se_top_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) + + ALIGN(size_av1d_lb_pe_top_data(frame_width, frame_height), + DMA_ALIGNMENT) + + ALIGN(size_av1d_lb_vsp_top(frame_width, frame_height), + DMA_ALIGNMENT) + + ALIGN(size_av1d_lb_recon_dma_metadata_wr + (frame_width, frame_height), DMA_ALIGNMENT) * 2 + + ALIGN(size_av1d_qp(frame_width, frame_height), DMA_ALIGNMENT); + opbwr8 = size_av1d_lb_opb_wr1_nv12_ubwc(frame_width, frame_height); + opbwr10 = size_av1d_lb_opb_wr1_tp10_ubwc(frame_width, frame_height); + opbwrbufsize = opbwr8 >= opbwr10 ? opbwr8 : opbwr10; + size = ALIGN((size + opbwrbufsize), DMA_ALIGNMENT); + if (is_opb) { + vpss_lb_size = size_vpss_lb(frame_width, frame_height); + size = ALIGN((size + vpss_lb_size) * 2, DMA_ALIGNMENT); + } + + return size; +} + +static u32 size_av1d_ibc_nv12_ubwc(u32 frame_width, u32 frame_height) +{ + u32 size; + u32 y_width_a = 128, y_height_a = 32; + u32 uv_width_a = 128, uv_height_a = 32; + u32 ybufsize, uvbufsize, y_width, y_height, uv_width, uv_height; + u32 y_meta_width_a = 64, y_meta_height_a = 16; + u32 uv_meta_width_a = 64, uv_meta_height_a = 16; + u32 meta_height, meta_stride, meta_size; + u32 tile_width_y = HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH; + u32 tile_height_y = HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT; + u32 tile_width_uv = HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH; + u32 tile_height_uv = HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_HEIGHT; + + y_width = ALIGN(frame_width, y_width_a); + y_height = ALIGN(frame_height, y_height_a); + uv_width = ALIGN(frame_width, uv_width_a); + uv_height = ALIGN(((frame_height + 1) >> 1), uv_height_a); + ybufsize = ALIGN((y_width * y_height), HFI_ALIGNMENT_4096); + uvbufsize = ALIGN(uv_width * uv_height, HFI_ALIGNMENT_4096); + size = ybufsize + uvbufsize; + meta_stride = ALIGN(((frame_width + (tile_width_y - 1)) / tile_width_y), + y_meta_width_a); + meta_height = ALIGN(((frame_height + (tile_height_y - 1)) / tile_height_y), + y_meta_height_a); + meta_size = ALIGN(meta_stride * meta_height, HFI_ALIGNMENT_4096); + size += meta_size; + meta_stride = ALIGN(((((frame_width + 1) >> 1) + (tile_width_uv - 1)) / + tile_width_uv), uv_meta_width_a); + meta_height = ALIGN(((((frame_height + 1) >> 1) + (tile_height_uv - 1)) / + tile_height_uv), uv_meta_height_a); + meta_size = ALIGN(meta_stride * meta_height, HFI_ALIGNMENT_4096); + size += meta_size; + + return size; +} + +static u32 hfi_yuv420_tp10_calc_y_stride(u32 frame_width, u32 stride_multiple) +{ + u32 stride; + + stride = ALIGN(frame_width, 192); + stride = ALIGN(stride * 4 / 3, stride_multiple); + + return stride; +} + +static u32 hfi_yuv420_tp10_calc_y_bufheight(u32 frame_height, u32 min_buf_height_multiple) +{ + return ALIGN(frame_height, min_buf_height_multiple); +} + +static u32 hfi_yuv420_tp10_calc_uv_stride(u32 frame_width, u32 stride_multiple) +{ + u32 stride; + + stride = ALIGN(frame_width, 192); + stride = ALIGN(stride * 4 / 3, stride_multiple); + + return stride; +} + +static u32 hfi_yuv420_tp10_calc_uv_bufheight(u32 frame_height, u32 min_buf_height_multiple) +{ + return ALIGN(((frame_height + 1) >> 1), min_buf_height_multiple); +} + +static u32 size_av1d_ibc_tp10_ubwc(u32 frame_width, u32 frame_height) +{ + u32 size; + u32 y_width_a = 256, y_height_a = 16, + uv_width_a = 256, uv_height_a = 16; + u32 ybufsize, uvbufsize, y_width, y_height, uv_width, uv_height; + u32 y_meta_width_a = 64, y_meta_height_a = 16, + uv_meta_width_a = 64, uv_meta_height_a = 16; + u32 meta_height, meta_stride, meta_size; + u32 tile_width_y = HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_WIDTH; + u32 tile_height_y = HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_HEIGHT; + u32 tile_width_uv = HFI_COLOR_FORMAT_YUV420_TP10_UBWC_UV_TILE_WIDTH; + u32 tile_height_uv = HFI_COLOR_FORMAT_YUV420_TP10_UBWC_UV_TILE_HEIGHT; + + y_width = hfi_yuv420_tp10_calc_y_stride(frame_width, y_width_a); + y_height = hfi_yuv420_tp10_calc_y_bufheight(frame_height, y_height_a); + uv_width = hfi_yuv420_tp10_calc_uv_stride(frame_width, uv_width_a); + uv_height = hfi_yuv420_tp10_calc_uv_bufheight(frame_height, uv_height_a); + ybufsize = ALIGN(y_width * y_height, HFI_ALIGNMENT_4096); + uvbufsize = ALIGN(uv_width * uv_height, HFI_ALIGNMENT_4096); + size = ybufsize + uvbufsize; + meta_stride = ALIGN(((frame_width + (tile_width_y - 1)) / tile_width_y), + y_meta_width_a); + meta_height = ALIGN(((frame_height + (tile_height_y - 1)) / tile_height_y), + y_meta_height_a); + meta_size = ALIGN(meta_stride * meta_height, HFI_ALIGNMENT_4096); + size += meta_size; + meta_stride = ALIGN(((((frame_width + 1) >> 1) + (tile_width_uv - 1)) / + tile_width_uv), uv_meta_width_a); + meta_height = ALIGN(((((frame_height + 1) >> 1) + (tile_height_uv - 1)) / + tile_height_uv), uv_meta_height_a); + meta_size = ALIGN(meta_stride * meta_height, HFI_ALIGNMENT_4096); + size += meta_size; + + return size; +} + +static u32 hfi_buffer_ibc_av1d(u32 frame_width, u32 frame_height) +{ + u32 size, ibc8, ibc10; + + ibc8 = size_av1d_ibc_nv12_ubwc(frame_width, frame_height); + ibc10 = size_av1d_ibc_tp10_ubwc(frame_width, frame_height); + size = ibc8 >= ibc10 ? ibc8 : ibc10; + + return ALIGN(size, DMA_ALIGNMENT); +} + static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) { u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; @@ -472,6 +718,8 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) return hfi_buffer_bin_h265d(width, height, num_vpp_pipes); else if (inst->codec == V4L2_PIX_FMT_VP9) return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_AV1) + return hfi_buffer_bin_av1d(width, height, num_vpp_pipes); return 0; } @@ -487,18 +735,34 @@ static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) return hfi_buffer_comv_h264d(width, height, num_comv); else if (inst->codec == V4L2_PIX_FMT_HEVC) return hfi_buffer_comv_h265d(width, height, num_comv); + else if (inst->codec == V4L2_PIX_FMT_AV1) { + if (inst->fw_caps[DRAP].value) + return 0; + else + return hfi_buffer_comv_av1d(width, height, num_comv); + } return 0; } static u32 iris_vpu_dec_persist_size(struct iris_inst *inst) { + struct platform_inst_caps *caps; + if (inst->codec == V4L2_PIX_FMT_H264) return hfi_buffer_persist_h264d(); else if (inst->codec == V4L2_PIX_FMT_HEVC) return hfi_buffer_persist_h265d(0); else if (inst->codec == V4L2_PIX_FMT_VP9) return hfi_buffer_persist_vp9d(); + else if (inst->codec == V4L2_PIX_FMT_AV1) { + caps = inst->core->iris_platform_data->inst_caps; + if (inst->fw_caps[DRAP].value) + return hfi_buffer_persist_av1d(caps->max_frame_width, + caps->max_frame_height, 16); + else + return hfi_buffer_persist_av1d(0, 0, 0); + } return 0; } @@ -545,6 +809,8 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst) else if (inst->codec == V4L2_PIX_FMT_VP9) return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_AV1) + return hfi_buffer_line_av1d(width, height, is_opb, num_vpp_pipes); return 0; } @@ -653,6 +919,15 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst) num_vpp_pipes, inst->hfi_rc_type); } +static u32 iris_vpu_dec_partial_size(struct iris_inst *inst) +{ + struct v4l2_format *f = inst->fmt_src; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + + return hfi_buffer_ibc_av1d(width, height); +} + static inline u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size, u32 num_recon, u32 standard) @@ -1414,7 +1689,9 @@ static int output_min_count(struct iris_inst *inst) /* fw_min_count > 0 indicates reconfig event has already arrived */ if (inst->fw_min_count) { - if (iris_split_mode_enabled(inst) && inst->codec == V4L2_PIX_FMT_VP9) + if (iris_split_mode_enabled(inst) && + (inst->codec == V4L2_PIX_FMT_VP9 || + inst->codec == V4L2_PIX_FMT_AV1)) return min_t(u32, 4, inst->fw_min_count); else return inst->fw_min_count; @@ -1422,6 +1699,8 @@ static int output_min_count(struct iris_inst *inst) if (inst->codec == V4L2_PIX_FMT_VP9) output_min_count = 9; + else if (inst->codec == V4L2_PIX_FMT_AV1) + output_min_count = 11; return output_min_count; } @@ -1444,6 +1723,7 @@ u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) {BUF_PERSIST, iris_vpu_dec_persist_size }, {BUF_DPB, iris_vpu_dec_dpb_size }, {BUF_SCRATCH_1, iris_vpu_dec_scratch1_size }, + {BUF_PARTIAL, iris_vpu_dec_partial_size }, }; static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = { @@ -1510,14 +1790,20 @@ static u32 internal_buffer_count(struct iris_inst *inst, buffer_type == BUF_PERSIST) { return 1; } else if (buffer_type == BUF_COMV || buffer_type == BUF_NON_COMV) { - if (inst->codec == V4L2_PIX_FMT_H264 || inst->codec == V4L2_PIX_FMT_HEVC) + if (inst->codec == V4L2_PIX_FMT_H264 || + inst->codec == V4L2_PIX_FMT_HEVC || + inst->codec == V4L2_PIX_FMT_AV1) return 1; } + return 0; } static inline int iris_vpu_dpb_count(struct iris_inst *inst) { + if (inst->codec == V4L2_PIX_FMT_AV1) + return 11; + if (iris_split_mode_enabled(inst)) { return inst->fw_min_count ? inst->fw_min_count : inst->buffers[BUF_OUTPUT].min_count; @@ -1536,9 +1822,13 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type return MIN_BUFFERS; else return output_min_count(inst); + case BUF_NON_COMV: + if (inst->codec == V4L2_PIX_FMT_AV1) + return 0; + else + return 1; case BUF_BIN: case BUF_COMV: - case BUF_NON_COMV: case BUF_LINE: case BUF_PERSIST: return internal_buffer_count(inst, buffer_type); @@ -1546,6 +1836,7 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type case BUF_SCRATCH_2: case BUF_VPSS: case BUF_ARP: + case BUF_PARTIAL: return 1; /* internal buffer count needed by firmware is 1 */ case BUF_DPB: return iris_vpu_dpb_count(inst); diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h index 04f0b7400a1e4..13c7199fcf351 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h @@ -11,6 +11,7 @@ struct iris_inst; #define MIN_BUFFERS 4 #define DMA_ALIGNMENT 256 +#define HFI_ALIGNMENT_4096 4096 #define NUM_HW_PIC_BUF 32 #define LCU_MAX_SIZE_PELS 64 @@ -81,6 +82,22 @@ struct iris_inst; #define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE 384 #define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640 +#define AV1_CABAC_HDR_RATIO_HD_TOT 2 +#define AV1_CABAC_RES_RATIO_HD_TOT 2 +#define AV1D_LCU_MAX_SIZE_PELS 128 +#define AV1D_LCU_MIN_SIZE_PELS 64 +#define AV1D_MAX_TILE_COLS 64 +#define MAX_PE_NBR_DATA_LCU32_LINE_BUFFER_SIZE 192 +#define MAX_PE_NBR_DATA_LCU16_LINE_BUFFER_SIZE 96 +#define AV1D_NUM_HW_PIC_BUF 16 +#define AV1D_NUM_FRAME_HEADERS 16 +#define SIZE_AV1D_SEQUENCE_HEADER 768 +#define SIZE_AV1D_METADATA 512 +#define SIZE_AV1D_FRAME_HEADER 1280 +#define SIZE_AV1D_TILE_OFFSET 65536 +#define SIZE_AV1D_QM 3328 +#define SIZE_AV1D_PROB_TABLE 22784 + #define SIZE_SLICE_CMD_BUFFER (ALIGN(20480, 256)) #define SIZE_SPS_PPS_SLICE_HDR (2048 + 4096) #define SIZE_BSE_SLICE_CMD_BUF ((((8192 << 2) + 7) & (~7)) * 3) @@ -101,6 +118,15 @@ struct iris_inst; #define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT, 16)) #define NUM_MBS_720P (((ALIGN(1280, 16)) >> 4) * ((ALIGN(736, 16)) >> 4)) +#define BITS_PER_PIX 16 +#define NUM_LINES_LUMA 10 +#define NUM_LINES_CHROMA 6 +#define AV1D_LCU_MAX_SIZE_PELS 128 +#define AV1D_LCU_MIN_SIZE_PELS 64 +#define AV1D_MAX_TILE_COLS 64 +#define BITS_PER_CTRL_PACK 128 +#define NUM_CTRL_PACK_LCU 10 + static inline u32 size_h264d_lb_fe_top_data(u32 frame_width) { return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3; @@ -146,6 +172,96 @@ static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height) return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 128; } +static inline u32 size_av1d_lb_fe_top_data(u32 frame_width, u32 frame_height) +{ + return (ALIGN(frame_width, AV1D_LCU_MAX_SIZE_PELS) * + ((BITS_PER_PIX * NUM_LINES_LUMA) >> 3) + + ALIGN(frame_width, AV1D_LCU_MAX_SIZE_PELS) / 2 * + ((BITS_PER_PIX * NUM_LINES_CHROMA) >> 3) * 2); +} + +static inline u32 size_av1d_lb_fe_left_data(u32 frame_width, u32 frame_height) +{ + return (32 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 16) + + 16 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / 2 + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 8) * 2 + + 24 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 16) + + 24 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / 2 + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 12) * 2 + + 24 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 16) + + 16 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 16) + + 16 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / 2 + + ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS * 12) * 2); +} + +static inline u32 size_av1d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height) +{ + return (NUM_CTRL_PACK_LCU * ((frame_width + AV1D_LCU_MIN_SIZE_PELS - 1) / + AV1D_LCU_MIN_SIZE_PELS) * BITS_PER_CTRL_PACK / 8); +} + +static inline u32 size_av1d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height) +{ + return (16 * ((ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / 16) + + (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS)) + + 3 * 16 * (ALIGN(frame_height, AV1D_LCU_MAX_SIZE_PELS) / + AV1D_LCU_MIN_SIZE_PELS)); +} + +static inline u32 size_av1d_lb_se_top_ctrl(u32 frame_width, u32 frame_height) +{ + return (((frame_width + 7) / 8) * MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE); +} + +static inline u32 size_av1d_lb_se_left_ctrl(u32 frame_width, u32 frame_height) +{ + return (max(((frame_height + 15) / 16) * + MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE, + max(((frame_height + 31) / 32) * + MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, + ((frame_height + 63) / 64) * + MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE))); +} + +static inline u32 size_av1d_lb_pe_top_data(u32 frame_width, u32 frame_height) +{ + return (max(((frame_width + 15) / 16) * + MAX_PE_NBR_DATA_LCU16_LINE_BUFFER_SIZE, + max(((frame_width + 31) / 32) * + MAX_PE_NBR_DATA_LCU32_LINE_BUFFER_SIZE, + ((frame_width + 63) / 64) * + MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE))); +} + +static inline u32 size_av1d_lb_vsp_top(u32 frame_width, u32 frame_height) +{ + return (max(((frame_width + 63) / 64) * 1280, + ((frame_width + 127) / 128) * MAX_HEIGHT)); +} + +static inline u32 size_av1d_lb_recon_dma_metadata_wr(u32 frame_width, + u32 frame_height) +{ + return ((ALIGN(frame_height, 8) / (4 / 2)) * 64); +} + +static inline u32 size_av1d_qp(u32 frame_width, u32 frame_height) +{ + return size_h264d_qp(frame_width, frame_height); +} + u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); From 97ec620e51a1b9ef47b8cb48c6f206c14063ae77 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Oct 2025 19:46:22 +0530 Subject: [PATCH 079/659] 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 fe33f6b98d56c665e645d9bd7a2d6056df809bbd Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 10 Dec 2025 18:05:59 +0530 Subject: [PATCH 080/659] FROMLIST: media: iris: Add support for multiple clock sources vpu4 depends on more than one clock source. Thus far hardware versions up to vpu3x have been clocked by a single source. This adds support for multiple clocks by, - Adding a lookup table - Configuring OPP table for video device with different video clocks - Setting OPP for multiple clocks during dev_pm_opp_set_opp() This patch extends the support for multiple clocks in driver, which would be used in subsequent patch for kaanapali, when the platform data is prepared. Link: https://lore.kernel.org/linux-media/20251210-knp_video-v4-1-8d11d840358a@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- .../platform/qcom/iris/iris_platform_common.h | 1 + .../platform/qcom/iris/iris_platform_gen1.c | 7 +++++++ .../platform/qcom/iris/iris_platform_gen2.c | 9 +++++++++ .../platform/qcom/iris/iris_platform_sc7280.h | 5 +++++ drivers/media/platform/qcom/iris/iris_power.c | 2 +- drivers/media/platform/qcom/iris/iris_probe.c | 20 ++++++++----------- .../media/platform/qcom/iris/iris_resources.c | 16 +++++++++++++-- .../media/platform/qcom/iris/iris_resources.h | 1 + .../platform/qcom/iris/iris_vpu_common.c | 4 ++-- 9 files changed, 48 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 14a2f4dbe38ab..dbe85aa7e89e7 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -216,6 +216,7 @@ struct iris_platform_data { const char * const *opp_pd_tbl; unsigned int opp_pd_tbl_size; const struct platform_clk_data *clk_tbl; + const char * const *opp_clk_tbl; unsigned int clk_tbl_size; const char * const *clk_rst_tbl; unsigned int clk_rst_tbl_size; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 712515b0f3294..7abd18be3549f 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -289,6 +289,11 @@ static const struct platform_clk_data sm8250_clk_table[] = { {IRIS_HW_CLK, "vcodec0_core" }, }; +static const char * const sm8250_opp_clk_table[] = { + "vcodec0_core", + NULL, +}; + static struct tz_cp_config tz_cp_config_sm8250 = { .cp_start = 0, .cp_size = 0x25800000, @@ -349,6 +354,7 @@ const struct iris_platform_data sm8250_data = { .opp_pd_tbl_size = ARRAY_SIZE(sm8250_opp_pd_table), .clk_tbl = sm8250_clk_table, .clk_tbl_size = ARRAY_SIZE(sm8250_clk_table), + .opp_clk_tbl = sm8250_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu-1.0/venus.mbn", @@ -400,6 +406,7 @@ const struct iris_platform_data sc7280_data = { .opp_pd_tbl_size = ARRAY_SIZE(sc7280_opp_pd_table), .clk_tbl = sc7280_clk_table, .clk_tbl_size = ARRAY_SIZE(sc7280_clk_table), + .opp_clk_tbl = sc7280_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu20_p1.mbn", diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index b2d8559dd2b85..323d0f08ec8dd 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -734,6 +734,11 @@ static const struct platform_clk_data sm8550_clk_table[] = { {IRIS_HW_CLK, "vcodec0_core" }, }; +static const char * const sm8550_opp_clk_table[] = { + "vcodec0_core", + NULL, +}; + static struct ubwc_config_data ubwc_config_sm8550 = { .max_channels = 8, .mal_length = 32, @@ -878,6 +883,7 @@ const struct iris_platform_data sm8550_data = { .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), .clk_tbl = sm8550_clk_table, .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), + .opp_clk_tbl = sm8550_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu30_p4.mbn", @@ -979,6 +985,7 @@ const struct iris_platform_data sm8650_data = { .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), .clk_tbl = sm8550_clk_table, .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), + .opp_clk_tbl = sm8550_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu33_p4.mbn", @@ -1070,6 +1077,7 @@ const struct iris_platform_data sm8750_data = { .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), .clk_tbl = sm8750_clk_table, .clk_tbl_size = ARRAY_SIZE(sm8750_clk_table), + .opp_clk_tbl = sm8550_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu35_p4.mbn", @@ -1165,6 +1173,7 @@ const struct iris_platform_data qcs8300_data = { .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), .clk_tbl = sm8550_clk_table, .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), + .opp_clk_tbl = sm8550_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu30_p4_s6.mbn", diff --git a/drivers/media/platform/qcom/iris/iris_platform_sc7280.h b/drivers/media/platform/qcom/iris/iris_platform_sc7280.h index f1bef4d4bcfe8..0ec8f334df670 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_sc7280.h +++ b/drivers/media/platform/qcom/iris/iris_platform_sc7280.h @@ -23,4 +23,9 @@ static const struct platform_clk_data sc7280_clk_table[] = { {IRIS_HW_AHB_CLK, "vcodec_bus" }, }; +static const char * const sc7280_opp_clk_table[] = { + "vcodec_core", + NULL, +}; + #endif diff --git a/drivers/media/platform/qcom/iris/iris_power.c b/drivers/media/platform/qcom/iris/iris_power.c index dbca42df0910f..91aa21d4070eb 100644 --- a/drivers/media/platform/qcom/iris/iris_power.c +++ b/drivers/media/platform/qcom/iris/iris_power.c @@ -91,7 +91,7 @@ static int iris_set_clocks(struct iris_inst *inst) } core->power.clk_freq = freq; - ret = dev_pm_opp_set_rate(core->dev, freq); + ret = iris_opp_set_rate(core->dev, freq); mutex_unlock(&core->lock); return ret; diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index 9bc9b34c25765..ddaacda523ecb 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -40,8 +40,6 @@ static int iris_init_icc(struct iris_core *core) static int iris_init_power_domains(struct iris_core *core) { - const struct platform_clk_data *clk_tbl; - u32 clk_cnt, i; int ret; struct dev_pm_domain_attach_data iris_pd_data = { @@ -56,6 +54,11 @@ static int iris_init_power_domains(struct iris_core *core) .pd_flags = PD_FLAG_DEV_LINK_ON | PD_FLAG_REQUIRED_OPP, }; + struct dev_pm_opp_config iris_opp_clk_data = { + .clk_names = core->iris_platform_data->opp_clk_tbl, + .config_clks = dev_pm_opp_config_clks_simple, + }; + ret = devm_pm_domain_attach_list(core->dev, &iris_pd_data, &core->pmdomain_tbl); if (ret < 0) return ret; @@ -64,16 +67,9 @@ static int iris_init_power_domains(struct iris_core *core) if (ret < 0) return ret; - clk_tbl = core->iris_platform_data->clk_tbl; - clk_cnt = core->iris_platform_data->clk_tbl_size; - - for (i = 0; i < clk_cnt; i++) { - if (clk_tbl[i].clk_type == IRIS_HW_CLK) { - ret = devm_pm_opp_set_clkname(core->dev, clk_tbl[i].clk_name); - if (ret) - return ret; - } - } + ret = devm_pm_opp_set_config(core->dev, &iris_opp_clk_data); + if (ret) + return ret; return devm_pm_opp_of_add_table(core->dev); } diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c index 164490c49c95e..773f6548370a2 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.c +++ b/drivers/media/platform/qcom/iris/iris_resources.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -58,11 +59,22 @@ int iris_unset_icc_bw(struct iris_core *core) return icc_bulk_set_bw(core->icc_count, core->icc_tbl); } +int iris_opp_set_rate(struct device *dev, unsigned long freq) +{ + struct dev_pm_opp *opp __free(put_opp); + + opp = devfreq_recommended_opp(dev, &freq, 0); + if (IS_ERR(opp)) + return PTR_ERR(opp); + + return dev_pm_opp_set_opp(dev, opp); +} + int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev) { int ret; - ret = dev_pm_opp_set_rate(core->dev, ULONG_MAX); + ret = iris_opp_set_rate(core->dev, ULONG_MAX); if (ret) return ret; @@ -77,7 +89,7 @@ int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev) { int ret; - ret = dev_pm_opp_set_rate(core->dev, 0); + ret = iris_opp_set_rate(core->dev, 0); if (ret) return ret; diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h index f723dfe5bd81a..6bfbd2dc6db09 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.h +++ b/drivers/media/platform/qcom/iris/iris_resources.h @@ -8,6 +8,7 @@ struct iris_core; +int iris_opp_set_rate(struct device *dev, unsigned long freq); int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev); int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev); int iris_unset_icc_bw(struct iris_core *core); diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 515dd55a3377e..fef192a2de48f 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -270,7 +270,7 @@ void iris_vpu_power_off_hw(struct iris_core *core) void iris_vpu_power_off(struct iris_core *core) { - dev_pm_opp_set_rate(core->dev, 0); + iris_opp_set_rate(core->dev, 0); core->iris_platform_data->vpu_ops->power_off_hw(core); core->iris_platform_data->vpu_ops->power_off_controller(core); iris_unset_icc_bw(core); @@ -368,7 +368,7 @@ int iris_vpu_power_on(struct iris_core *core) freq = core->power.clk_freq ? core->power.clk_freq : (u32)ULONG_MAX; - dev_pm_opp_set_rate(core->dev, freq); + iris_opp_set_rate(core->dev, freq); core->iris_platform_data->set_preset_registers(core); From 5d8b46929012e4da08e458076db444fd418983da Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 10 Dec 2025 18:06:00 +0530 Subject: [PATCH 081/659] FROMLIST: media: iris: Add support for multiple TZ content protection(CP) configs vpu4 needs an additional configuration with respect to CP regions. Make the CP configuration as array such that the multiple configuration can be managed per platform. Link: https://lore.kernel.org/linux-media/20251210-knp_video-v4-2-8d11d840358a@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Reviewed-by: Bryan O'Donoghue Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- .../media/platform/qcom/iris/iris_firmware.c | 23 ++++++++++-------- .../platform/qcom/iris/iris_platform_common.h | 3 ++- .../platform/qcom/iris/iris_platform_gen1.c | 18 ++++++++------ .../platform/qcom/iris/iris_platform_gen2.c | 24 ++++++++++++------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index 679444327ed73..5f408024e967f 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -64,9 +64,9 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) int iris_fw_load(struct iris_core *core) { - struct tz_cp_config *cp_config = core->iris_platform_data->tz_cp_config_data; + const struct tz_cp_config *cp_config; const char *fwpath = NULL; - int ret; + int i, ret; ret = of_property_read_string_index(core->dev->of_node, "firmware-name", 0, &fwpath); @@ -85,14 +85,17 @@ int iris_fw_load(struct iris_core *core) return ret; } - ret = qcom_scm_mem_protect_video_var(cp_config->cp_start, - cp_config->cp_size, - cp_config->cp_nonpixel_start, - cp_config->cp_nonpixel_size); - if (ret) { - dev_err(core->dev, "protect memory failed\n"); - qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); - 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, + cp_config->cp_size, + cp_config->cp_nonpixel_start, + cp_config->cp_nonpixel_size); + if (ret) { + dev_err(core->dev, "qcom_scm_mem_protect_video_var failed: %d\n", ret); + qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); + return ret; + } } return ret; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index dbe85aa7e89e7..8acea81a22370 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -232,7 +232,8 @@ struct iris_platform_data { u32 inst_fw_caps_dec_size; const struct platform_inst_fw_cap *inst_fw_caps_enc; u32 inst_fw_caps_enc_size; - struct tz_cp_config *tz_cp_config_data; + const struct tz_cp_config *tz_cp_config_data; + u32 tz_cp_config_data_size; u32 core_arch; u32 hw_response_timeout; struct ubwc_config_data *ubwc_config; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 7abd18be3549f..df8e6bf9430ed 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -294,11 +294,13 @@ static const char * const sm8250_opp_clk_table[] = { NULL, }; -static struct tz_cp_config tz_cp_config_sm8250 = { - .cp_start = 0, - .cp_size = 0x25800000, - .cp_nonpixel_start = 0x01000000, - .cp_nonpixel_size = 0x24800000, +static const struct tz_cp_config tz_cp_config_sm8250[] = { + { + .cp_start = 0, + .cp_size = 0x25800000, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, }; static const u32 sm8250_vdec_input_config_param_default[] = { @@ -366,7 +368,8 @@ const struct iris_platform_data sm8250_data = { .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), .inst_fw_caps_enc = inst_fw_cap_sm8250_enc, .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), - .tz_cp_config_data = &tz_cp_config_sm8250, + .tz_cp_config_data = tz_cp_config_sm8250, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .num_vpp_pipe = 4, .max_session_count = 16, @@ -418,7 +421,8 @@ const struct iris_platform_data sc7280_data = { .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), .inst_fw_caps_enc = inst_fw_cap_sm8250_enc, .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), - .tz_cp_config_data = &tz_cp_config_sm8250, + .tz_cp_config_data = tz_cp_config_sm8250, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .num_vpp_pipe = 1, .no_aon = true, diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 323d0f08ec8dd..c3ff1f6fa566a 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -749,11 +749,13 @@ static struct ubwc_config_data ubwc_config_sm8550 = { .bank_spreading = 1, }; -static struct tz_cp_config tz_cp_config_sm8550 = { - .cp_start = 0, - .cp_size = 0x25800000, - .cp_nonpixel_start = 0x01000000, - .cp_nonpixel_size = 0x24800000, +static const struct tz_cp_config tz_cp_config_sm8550[] = { + { + .cp_start = 0, + .cp_size = 0x25800000, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, }; static const u32 sm8550_vdec_input_config_params_default[] = { @@ -895,7 +897,8 @@ const struct iris_platform_data sm8550_data = { .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_sm8550, + .tz_cp_config_data = tz_cp_config_sm8550, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, @@ -997,7 +1000,8 @@ const struct iris_platform_data sm8650_data = { .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_sm8550, + .tz_cp_config_data = tz_cp_config_sm8550, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, @@ -1089,7 +1093,8 @@ const struct iris_platform_data sm8750_data = { .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_sm8550, + .tz_cp_config_data = tz_cp_config_sm8550, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, @@ -1185,7 +1190,8 @@ const struct iris_platform_data qcs8300_data = { .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_sm8550, + .tz_cp_config_data = tz_cp_config_sm8550, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, From f06b4a9a18a9cbbd9787532774a29f521489cf6b Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 10 Dec 2025 18:06:01 +0530 Subject: [PATCH 082/659] FROMLIST: media: iris: Introduce buffer size calculations for vpu4 Introduces vp4 buffer size calculation for both encoder and decoder. Reuse the buffer size calculation which are common, while adding the vpu4 ones separately. Link: https://lore.kernel.org/linux-media/20251210-knp_video-v4-3-8d11d840358a@oss.qualcomm.com/ Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- .../platform/qcom/iris/iris_vpu_buffer.c | 342 ++++++++++++++++++ .../platform/qcom/iris/iris_vpu_buffer.h | 24 ++ 2 files changed, 366 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c index f4985790bae41..f0ddd54081169 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c @@ -1683,6 +1683,304 @@ static u32 iris_vpu_enc_vpss_size(struct iris_inst *inst) return hfi_buffer_vpss_enc(width, height, ds_enable, 0, 0); } +static inline u32 size_dpb_opb(u32 height, u32 lcu_size) +{ + u32 max_tile_height = ((height + lcu_size - 1) / lcu_size) * lcu_size + 8; + u32 dpb_opb = 3 * ((max_tile_height >> 3) * DMA_ALIGNMENT); + u32 num_luma_chrome_plane = 2; + + return ALIGN(dpb_opb, DMA_ALIGNMENT) * num_luma_chrome_plane; +} + +static u32 hfi_vpu4x_vp9d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 vp9_top_lb, vp9_fe_left_lb, vp9_se_left_lb, dpb_opb, vp9d_qp, num_lcu_per_pipe; + u32 lcu_size = 64; + + vp9_top_lb = ALIGN(size_vp9d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT); + vp9_top_lb += ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT); + vp9_top_lb += max3(DIV_ROUND_UP(frame_width, BUFFER_ALIGNMENT_16_BYTES) * + MAX_PE_NBR_DATA_LCU16_LINE_BUFFER_SIZE, + DIV_ROUND_UP(frame_width, BUFFER_ALIGNMENT_32_BYTES) * + MAX_PE_NBR_DATA_LCU32_LINE_BUFFER_SIZE, + DIV_ROUND_UP(frame_width, BUFFER_ALIGNMENT_64_BYTES) * + MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE); + vp9_top_lb = ALIGN(vp9_top_lb, DMA_ALIGNMENT); + vp9_top_lb += ALIGN((DMA_ALIGNMENT * DIV_ROUND_UP(frame_width, lcu_size)), + DMA_ALIGNMENT) * FE_TOP_CTRL_LINE_NUMBERS; + vp9_top_lb += ALIGN(DMA_ALIGNMENT * 8 * DIV_ROUND_UP(frame_width, lcu_size), + DMA_ALIGNMENT) * (FE_TOP_DATA_LUMA_LINE_NUMBERS + + FE_TOP_DATA_CHROMA_LINE_NUMBERS); + + num_lcu_per_pipe = (DIV_ROUND_UP(frame_height, lcu_size) / num_vpp_pipes) + + (DIV_ROUND_UP(frame_height, lcu_size) % num_vpp_pipes); + vp9_fe_left_lb = ALIGN((DMA_ALIGNMENT * num_lcu_per_pipe), DMA_ALIGNMENT) * + FE_LFT_CTRL_LINE_NUMBERS; + vp9_fe_left_lb += ((ALIGN((DMA_ALIGNMENT * 8 * num_lcu_per_pipe), DMA_ALIGNMENT) * + FE_LFT_DB_DATA_LINE_NUMBERS) + + ALIGN((DMA_ALIGNMENT * 3 * num_lcu_per_pipe), DMA_ALIGNMENT) + + ALIGN((DMA_ALIGNMENT * 4 * num_lcu_per_pipe), DMA_ALIGNMENT) + + (ALIGN((DMA_ALIGNMENT * 24 * num_lcu_per_pipe), DMA_ALIGNMENT) * + FE_LFT_LR_DATA_LINE_NUMBERS)); + vp9_fe_left_lb = vp9_fe_left_lb * num_vpp_pipes; + + vp9_se_left_lb = ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height), + DMA_ALIGNMENT); + dpb_opb = size_dpb_opb(frame_height, lcu_size); + vp9d_qp = ALIGN(size_vp9d_qp(frame_width, frame_height), DMA_ALIGNMENT); + + return vp9_top_lb + vp9_fe_left_lb + (vp9_se_left_lb * num_vpp_pipes) + + (dpb_opb * num_vpp_pipes) + vp9d_qp; +} + +static u32 hfi_vpu4x_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_min, + bool is_opb, u32 num_vpp_pipes) +{ + u32 lb_size = hfi_vpu4x_vp9d_lb_size(frame_width, frame_height, num_vpp_pipes); + u32 dpb_obp_size = 0, lcu_size = 64; + + if (is_opb) + dpb_obp_size = size_dpb_opb(frame_height, lcu_size) * num_vpp_pipes; + + return lb_size + dpb_obp_size; +} + +static u32 iris_vpu4x_dec_line_size(struct iris_inst *inst) +{ + u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; + u32 out_min_count = inst->buffers[BUF_OUTPUT].min_count; + struct v4l2_format *f = inst->fmt_src; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + bool is_opb = false; + + if (iris_split_mode_enabled(inst)) + is_opb = true; + + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_line_h265d(width, height, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_vpu4x_buffer_line_vp9d(width, height, out_min_count, is_opb, + num_vpp_pipes); + + return 0; +} + +static u32 hfi_vpu4x_buffer_persist_h265d(u32 rpu_enabled) +{ + return ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + H265_NUM_FRM_INFO * + H265_DISPLAY_BUF_SIZE + (H265_NUM_TILE * sizeof(u32)) + (NUM_HW_PIC_BUF * + (SIZE_SEI_USERDATA + SIZE_H265D_ARP + SIZE_THREE_DIMENSION_USERDATA)) + + rpu_enabled * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA), DMA_ALIGNMENT); +} + +static u32 hfi_vpu4x_buffer_persist_vp9d(void) +{ + return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) + + (ALIGN(hfi_iris3_vp9d_comv_size(), DMA_ALIGNMENT) * 2) + + ALIGN(MAX_SUPERFRAME_HEADER_LEN, DMA_ALIGNMENT) + + ALIGN(VP9_UDC_HEADER_BUF_SIZE, DMA_ALIGNMENT) + + ALIGN(VP9_NUM_FRAME_INFO_BUF * CCE_TILE_OFFSET_SIZE, DMA_ALIGNMENT) + + ALIGN(VP9_NUM_FRAME_INFO_BUF * VP9_FRAME_INFO_BUF_SIZE_VPU4X, DMA_ALIGNMENT) + + HDR10_HIST_EXTRADATA_SIZE; +} + +static u32 iris_vpu4x_dec_persist_size(struct iris_inst *inst) +{ + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_persist_h264d(); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_vpu4x_buffer_persist_h265d(0); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_vpu4x_buffer_persist_vp9d(); + + return 0; +} + +static u32 size_se_lb(u32 standard, u32 num_vpp_pipes_enc, + u32 frame_width_coded, u32 frame_height_coded) +{ + u32 se_tlb_size = ALIGN(frame_width_coded, DMA_ALIGNMENT); + u32 se_llb_size = (standard == HFI_CODEC_ENCODE_HEVC) ? + ((frame_height_coded + BUFFER_ALIGNMENT_32_BYTES - 1) / + BUFFER_ALIGNMENT_32_BYTES) * LOG2_16 * LLB_UNIT_SIZE : + ((frame_height_coded + BUFFER_ALIGNMENT_16_BYTES - 1) / + BUFFER_ALIGNMENT_16_BYTES) * LOG2_32 * LLB_UNIT_SIZE; + + se_llb_size = ALIGN(se_llb_size, BUFFER_ALIGNMENT_32_BYTES); + + if (num_vpp_pipes_enc > 1) + se_llb_size = ALIGN(se_llb_size + BUFFER_ALIGNMENT_512_BYTES, + DMA_ALIGNMENT) * num_vpp_pipes_enc; + + return ALIGN(se_tlb_size + se_llb_size, DMA_ALIGNMENT); +} + +static u32 size_te_lb(bool is_ten_bit, u32 num_vpp_pipes_enc, u32 width_in_lcus, + u32 frame_height_coded, u32 frame_width_coded) +{ + u32 num_pixel_10_bit = 3, num_pixel_8_bit = 2, num_pixel_te_llb = 3; + u32 te_llb_col_rc_size = ALIGN(32 * width_in_lcus / num_vpp_pipes_enc, + DMA_ALIGNMENT) * num_vpp_pipes_enc; + u32 te_tlb_recon_data_size = ALIGN((is_ten_bit ? num_pixel_10_bit : num_pixel_8_bit) * + frame_width_coded, DMA_ALIGNMENT); + u32 te_llb_recon_data_size = ((1 + is_ten_bit) * num_pixel_te_llb * frame_height_coded + + num_vpp_pipes_enc - 1) / num_vpp_pipes_enc; + te_llb_recon_data_size = ALIGN(te_llb_recon_data_size, DMA_ALIGNMENT) * num_vpp_pipes_enc; + + return ALIGN(te_llb_recon_data_size + te_llb_col_rc_size + te_tlb_recon_data_size, + DMA_ALIGNMENT); +} + +static inline u32 calc_fe_tlb_size(u32 size_per_lcu, bool is_ten_bit) +{ + u32 num_pixels_fe_tlb_10_bit = 128, num_pixels_fe_tlb_8_bit = 64; + + return is_ten_bit ? (num_pixels_fe_tlb_10_bit * (size_per_lcu + 1)) : + (size_per_lcu * num_pixels_fe_tlb_8_bit); +} + +static u32 size_fe_lb(bool is_ten_bit, u32 standard, u32 num_vpp_pipes_enc, + u32 frame_height_coded, u32 frame_width_coded) +{ + u32 log2_lcu_size, num_cu_in_height_pipe, num_cu_in_width, + fb_llb_db_ctrl_size, fb_llb_db_luma_size, fb_llb_db_chroma_size, + fb_tlb_db_ctrl_size, fb_tlb_db_luma_size, fb_tlb_db_chroma_size, + fb_llb_sao_ctrl_size, fb_llb_sao_luma_size, fb_llb_sao_chroma_size, + fb_tlb_sao_ctrl_size, fb_tlb_sao_luma_size, fb_tlb_sao_chroma_size, + fb_lb_top_sdc_size, fb_lb_se_ctrl_size, fe_tlb_size, size_per_lcu; + + log2_lcu_size = (standard == HFI_CODEC_ENCODE_HEVC) ? 5 : 4; + num_cu_in_height_pipe = ((frame_height_coded >> log2_lcu_size) + num_vpp_pipes_enc - 1) / + num_vpp_pipes_enc; + num_cu_in_width = frame_width_coded >> log2_lcu_size; + + size_per_lcu = 2; + fe_tlb_size = calc_fe_tlb_size(size_per_lcu, 1); + fb_llb_db_ctrl_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_height_pipe; + fb_llb_db_ctrl_size = ALIGN(fb_llb_db_ctrl_size, DMA_ALIGNMENT) * num_vpp_pipes_enc; + + size_per_lcu = (1 << (log2_lcu_size - 3)); + fe_tlb_size = calc_fe_tlb_size(size_per_lcu, is_ten_bit); + fb_llb_db_luma_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_height_pipe; + fb_llb_db_luma_size = ALIGN(fb_llb_db_luma_size, DMA_ALIGNMENT) * num_vpp_pipes_enc; + + size_per_lcu = ((1 << (log2_lcu_size - 4)) * 2); + fe_tlb_size = calc_fe_tlb_size(size_per_lcu, is_ten_bit); + fb_llb_db_chroma_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_height_pipe; + fb_llb_db_chroma_size = ALIGN(fb_llb_db_chroma_size, DMA_ALIGNMENT) * num_vpp_pipes_enc; + + size_per_lcu = 1; + fe_tlb_size = calc_fe_tlb_size(size_per_lcu, 1); + fb_tlb_db_ctrl_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_width; + fb_llb_sao_ctrl_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_height_pipe; + fb_llb_sao_ctrl_size = fb_llb_sao_ctrl_size * num_vpp_pipes_enc; + fb_tlb_sao_ctrl_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_width; + + size_per_lcu = ((1 << (log2_lcu_size - 3)) + 1); + fe_tlb_size = calc_fe_tlb_size(size_per_lcu, is_ten_bit); + fb_tlb_db_luma_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_width; + + size_per_lcu = (2 * ((1 << (log2_lcu_size - 4)) + 1)); + fe_tlb_size = calc_fe_tlb_size(size_per_lcu, is_ten_bit); + fb_tlb_db_chroma_size = ALIGN(fe_tlb_size, DMA_ALIGNMENT) * num_cu_in_width; + + fb_llb_sao_luma_size = BUFFER_ALIGNMENT_256_BYTES * num_vpp_pipes_enc; + fb_llb_sao_chroma_size = BUFFER_ALIGNMENT_256_BYTES * num_vpp_pipes_enc; + fb_tlb_sao_luma_size = BUFFER_ALIGNMENT_256_BYTES; + fb_tlb_sao_chroma_size = BUFFER_ALIGNMENT_256_BYTES; + fb_lb_top_sdc_size = ALIGN((FE_SDC_DATA_PER_BLOCK * (frame_width_coded >> 5)), + DMA_ALIGNMENT); + fb_lb_se_ctrl_size = ALIGN((SE_CTRL_DATA_PER_BLOCK * (frame_width_coded >> 5)), + DMA_ALIGNMENT); + + return fb_llb_db_ctrl_size + fb_llb_db_luma_size + fb_llb_db_chroma_size + + fb_tlb_db_ctrl_size + fb_tlb_db_luma_size + fb_tlb_db_chroma_size + + fb_llb_sao_ctrl_size + fb_llb_sao_luma_size + fb_llb_sao_chroma_size + + fb_tlb_sao_ctrl_size + fb_tlb_sao_luma_size + fb_tlb_sao_chroma_size + + fb_lb_top_sdc_size + fb_lb_se_ctrl_size; +} + +static u32 size_md_lb(u32 standard, u32 frame_width_coded, + u32 frame_height_coded, u32 num_vpp_pipes_enc) +{ + u32 md_tlb_size = ALIGN(frame_width_coded, DMA_ALIGNMENT); + u32 md_llb_size = (standard == HFI_CODEC_ENCODE_HEVC) ? + ((frame_height_coded + BUFFER_ALIGNMENT_32_BYTES - 1) / + BUFFER_ALIGNMENT_32_BYTES) * LOG2_16 * LLB_UNIT_SIZE : + ((frame_height_coded + BUFFER_ALIGNMENT_16_BYTES - 1) / + BUFFER_ALIGNMENT_16_BYTES) * LOG2_32 * LLB_UNIT_SIZE; + + md_llb_size = ALIGN(md_llb_size, BUFFER_ALIGNMENT_32_BYTES); + + if (num_vpp_pipes_enc > 1) + md_llb_size = ALIGN(md_llb_size + BUFFER_ALIGNMENT_512_BYTES, + DMA_ALIGNMENT) * num_vpp_pipes_enc; + + md_llb_size = ALIGN(md_llb_size, DMA_ALIGNMENT); + + return ALIGN(md_tlb_size + md_llb_size, DMA_ALIGNMENT); +} + +static u32 size_dma_opb_lb(u32 num_vpp_pipes_enc, u32 frame_width_coded, + u32 frame_height_coded) +{ + u32 opb_packet_bytes = 128, opb_bpp = 128, opb_size_per_row = 6; + u32 dma_opb_wr_tlb_y_size = DIV_ROUND_UP(frame_width_coded, 16) * opb_packet_bytes; + u32 dma_opb_wr_tlb_uv_size = DIV_ROUND_UP(frame_width_coded, 16) * opb_packet_bytes; + u32 dma_opb_wr2_tlb_y_size = ALIGN((opb_bpp * opb_size_per_row * frame_height_coded / 8), + DMA_ALIGNMENT) * num_vpp_pipes_enc; + u32 dma_opb_wr2_tlb_uv_size = ALIGN((opb_bpp * opb_size_per_row * frame_height_coded / 8), + DMA_ALIGNMENT) * num_vpp_pipes_enc; + + dma_opb_wr2_tlb_y_size = max(dma_opb_wr2_tlb_y_size, dma_opb_wr_tlb_y_size << 1); + dma_opb_wr2_tlb_uv_size = max(dma_opb_wr2_tlb_uv_size, dma_opb_wr_tlb_uv_size << 1); + + return ALIGN(dma_opb_wr_tlb_y_size + dma_opb_wr_tlb_uv_size + dma_opb_wr2_tlb_y_size + + dma_opb_wr2_tlb_uv_size, DMA_ALIGNMENT); +} + +static u32 hfi_vpu4x_buffer_line_enc(u32 frame_width, u32 frame_height, + bool is_ten_bit, u32 num_vpp_pipes_enc, + u32 lcu_size, u32 standard) +{ + u32 width_in_lcus = (frame_width + lcu_size - 1) / lcu_size; + u32 height_in_lcus = (frame_height + lcu_size - 1) / lcu_size; + u32 frame_width_coded = width_in_lcus * lcu_size; + u32 frame_height_coded = height_in_lcus * lcu_size; + + u32 se_lb_size = size_se_lb(standard, num_vpp_pipes_enc, frame_width_coded, + frame_height_coded); + u32 te_lb_size = size_te_lb(is_ten_bit, num_vpp_pipes_enc, width_in_lcus, + frame_height_coded, frame_width_coded); + u32 fe_lb_size = size_fe_lb(is_ten_bit, standard, num_vpp_pipes_enc, frame_height_coded, + frame_width_coded); + u32 md_lb_size = size_md_lb(standard, frame_width_coded, frame_height_coded, + num_vpp_pipes_enc); + u32 dma_opb_lb_size = size_dma_opb_lb(num_vpp_pipes_enc, frame_width_coded, + frame_height_coded); + u32 dse_lb_size = ALIGN((256 + (16 * (frame_width_coded >> 4))), DMA_ALIGNMENT); + u32 size_vpss_lb_enc = size_vpss_line_buf_vpu33(num_vpp_pipes_enc, frame_width_coded, + frame_height_coded); + + return se_lb_size + te_lb_size + fe_lb_size + md_lb_size + dma_opb_lb_size + + dse_lb_size + size_vpss_lb_enc; +} + +static u32 iris_vpu4x_enc_line_size(struct iris_inst *inst) +{ + u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; + u32 lcu_size = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; + struct v4l2_format *f = inst->fmt_dst; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + + return hfi_vpu4x_buffer_line_enc(width, height, 0, num_vpp_pipes, + lcu_size, inst->codec); +} + static int output_min_count(struct iris_inst *inst) { int output_min_count = 4; @@ -1783,6 +2081,50 @@ u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_typ return size; } +u32 iris_vpu4x_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) +{ + const struct iris_vpu_buf_type_handle *buf_type_handle_arr = NULL; + u32 size = 0, buf_type_handle_size = 0, i; + + static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle[] = { + {BUF_BIN, iris_vpu_dec_bin_size }, + {BUF_COMV, iris_vpu_dec_comv_size }, + {BUF_NON_COMV, iris_vpu_dec_non_comv_size }, + {BUF_LINE, iris_vpu4x_dec_line_size }, + {BUF_PERSIST, iris_vpu4x_dec_persist_size }, + {BUF_DPB, iris_vpu_dec_dpb_size }, + {BUF_SCRATCH_1, iris_vpu_dec_scratch1_size }, + }; + + static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = { + {BUF_BIN, iris_vpu_enc_bin_size }, + {BUF_COMV, iris_vpu_enc_comv_size }, + {BUF_NON_COMV, iris_vpu_enc_non_comv_size }, + {BUF_LINE, iris_vpu4x_enc_line_size }, + {BUF_ARP, iris_vpu_enc_arp_size }, + {BUF_VPSS, iris_vpu_enc_vpss_size }, + {BUF_SCRATCH_1, iris_vpu_enc_scratch1_size }, + {BUF_SCRATCH_2, iris_vpu_enc_scratch2_size }, + }; + + if (inst->domain == DECODER) { + buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle); + buf_type_handle_arr = dec_internal_buf_type_handle; + } else if (inst->domain == ENCODER) { + buf_type_handle_size = ARRAY_SIZE(enc_internal_buf_type_handle); + buf_type_handle_arr = enc_internal_buf_type_handle; + } + + for (i = 0; i < buf_type_handle_size; i++) { + if (buf_type_handle_arr[i].type == buffer_type) { + size = buf_type_handle_arr[i].handle(inst); + break; + } + } + + return size; +} + static u32 internal_buffer_count(struct iris_inst *inst, enum iris_buffer_type buffer_type) { diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h index 13c7199fcf351..12640eb5ed8c4 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h @@ -48,7 +48,12 @@ struct iris_inst; #define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4) #define VP9_PROB_TABLE_SIZE (3840) #define VP9_FRAME_INFO_BUF_SIZE (6144) +#define VP9_FRAME_INFO_BUF_SIZE_VPU4X (6400) +#define BUFFER_ALIGNMENT_16_BYTES 16 #define BUFFER_ALIGNMENT_32_BYTES 32 +#define BUFFER_ALIGNMENT_64_BYTES 64 +#define BUFFER_ALIGNMENT_256_BYTES 256 +#define BUFFER_ALIGNMENT_512_BYTES 512 #define CCE_TILE_OFFSET_SIZE ALIGN(32 * 4 * 4, BUFFER_ALIGNMENT_32_BYTES) #define MAX_SUPERFRAME_HEADER_LEN (34) #define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 @@ -67,6 +72,8 @@ struct iris_inst; #define H265_CABAC_HDR_RATIO_HD_TOT 2 #define H265_CABAC_RES_RATIO_HD_TOT 2 #define SIZE_H265D_VPP_CMD_PER_BUF (256) +#define SIZE_THREE_DIMENSION_USERDATA 768 +#define SIZE_H265D_ARP 9728 #define VPX_DECODER_FRAME_CONCURENCY_LVL (2) #define VPX_DECODER_FRAME_BIN_HDR_BUDGET 1 @@ -77,6 +84,18 @@ struct iris_inst; #define SIZE_H264D_HW_PIC_T (BIT(11)) +#define FE_LFT_CTRL_LINE_NUMBERS 4 +#define FE_LFT_DB_DATA_LINE_NUMBERS 2 +#define FE_LFT_LR_DATA_LINE_NUMBERS 4 +#define FE_TOP_CTRL_LINE_NUMBERS 3 +#define FE_TOP_DATA_LUMA_LINE_NUMBERS 2 +#define FE_TOP_DATA_CHROMA_LINE_NUMBERS 3 +#define FE_SDC_DATA_PER_BLOCK 16 +#define SE_CTRL_DATA_PER_BLOCK 2020 + +#define MAX_PE_NBR_DATA_LCU16_LINE_BUFFER_SIZE 96 +#define MAX_PE_NBR_DATA_LCU32_LINE_BUFFER_SIZE 192 + #define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 #define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 16 #define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE 384 @@ -113,6 +132,10 @@ struct iris_inst; #define HFI_BUFFER_ARP_ENC 204800 +#define LOG2_16 4 +#define LOG2_32 5 +#define LLB_UNIT_SIZE 16 + #define MAX_WIDTH 4096 #define MAX_HEIGHT 2304 #define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT, 16)) @@ -264,6 +287,7 @@ static inline u32 size_av1d_qp(u32 frame_width, u32 frame_height) u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); +u32 iris_vpu4x_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); #endif From 71ef4df2030ca55be45f5147a70a6851d5617671 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 10 Dec 2025 18:06:02 +0530 Subject: [PATCH 083/659] FROMLIST: media: iris: Move vpu register defines to common header file Some of vpu4 register defines are common with vpu3x. Move those into the common register defines header. This is done to reuse the defines for vpu4 in subsequent patch which enables the power sequence for vpu4. Link: https://lore.kernel.org/linux-media/20251210-knp_video-v4-4-8d11d840358a@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia Co-developed-by: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_vpu3x.c | 42 ------------- .../platform/qcom/iris/iris_vpu_common.c | 43 ------------- .../qcom/iris/iris_vpu_register_defines.h | 61 +++++++++++++++++++ 3 files changed, 61 insertions(+), 85 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c index 339776a0b4672..cd53bcda3b3e1 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c @@ -11,48 +11,6 @@ #include "iris_vpu_common.h" #include "iris_vpu_register_defines.h" -#define WRAPPER_TZ_BASE_OFFS 0x000C0000 -#define AON_BASE_OFFS 0x000E0000 -#define AON_MVP_NOC_RESET 0x0001F000 - -#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) -#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) -#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) -#define REQ_POWER_DOWN_PREP BIT(0) -#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) -#define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */ -#define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */ -#define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */ -#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88) -#define CORE_CLK_RUN 0x0 -/* VPU v3.5 */ -#define WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0 (WRAPPER_BASE_OFFS + 0x78) - -#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) -#define CTL_AXI_CLK_HALT BIT(0) -#define CTL_CLK_HALT BIT(1) - -#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) -#define RESET_HIGH BIT(0) - -#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160) -#define CORE_BRIDGE_SW_RESET BIT(0) -#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1) - -#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) -#define MSK_SIGNAL_FROM_TENSILICA BIT(0) -#define MSK_CORE_POWER_ON BIT(1) - -#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000) -#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1)) - -#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004) - -#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) - -#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) -#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) - #define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18) #define SW_RESET BIT(0) #define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20) diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index fef192a2de48f..50242fc6b4653 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -11,13 +11,6 @@ #include "iris_vpu_common.h" #include "iris_vpu_register_defines.h" -#define WRAPPER_TZ_BASE_OFFS 0x000C0000 -#define AON_BASE_OFFS 0x000E0000 - -#define CPU_IC_BASE_OFFS (CPU_BASE_OFFS) - -#define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C) -#define CLEAR_XTENSA2HOST_INTR BIT(0) #define CTRL_INIT (CPU_CS_BASE_OFFS + 0x48) #define CTRL_STATUS (CPU_CS_BASE_OFFS + 0x4C) @@ -35,42 +28,6 @@ #define UC_REGION_ADDR (CPU_CS_BASE_OFFS + 0x64) #define UC_REGION_SIZE (CPU_CS_BASE_OFFS + 0x68) -#define CPU_CS_H2XSOFTINTEN (CPU_CS_BASE_OFFS + 0x148) -#define HOST2XTENSA_INTR_ENABLE BIT(0) - -#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) -#define MSK_SIGNAL_FROM_TENSILICA BIT(0) -#define MSK_CORE_POWER_ON BIT(1) - -#define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x150) -#define CPU_IC_SOFTINT_H2A_SHFT 0x0 - -#define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C) -#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) -#define WRAPPER_INTR_STATUS_A2H_BMSK BIT(2) - -#define WRAPPER_INTR_MASK (WRAPPER_BASE_OFFS + 0x10) -#define WRAPPER_INTR_MASK_A2HWD_BMSK BIT(3) -#define WRAPPER_INTR_MASK_A2HCPU_BMSK BIT(2) - -#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) -#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) -#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) -#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) - -#define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10) -#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) -#define CTL_AXI_CLK_HALT BIT(0) -#define CTL_CLK_HALT BIT(1) - -#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) -#define RESET_HIGH BIT(0) - -#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) -#define REQ_POWER_DOWN_PREP BIT(0) - -#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) - static void iris_vpu_interrupt_init(struct iris_core *core) { u32 mask_val; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h index fe8a39e5e5a3f..72168b9ffa738 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h @@ -7,11 +7,72 @@ #define __IRIS_VPU_REGISTER_DEFINES_H__ #define VCODEC_BASE_OFFS 0x00000000 +#define AON_MVP_NOC_RESET 0x0001F000 #define CPU_BASE_OFFS 0x000A0000 #define WRAPPER_BASE_OFFS 0x000B0000 +#define WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define AON_BASE_OFFS 0x000E0000 + +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) + +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000) +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1)) + +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004) #define CPU_CS_BASE_OFFS (CPU_BASE_OFFS) +#define CPU_IC_BASE_OFFS (CPU_BASE_OFFS) + +#define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C) +#define CLEAR_XTENSA2HOST_INTR BIT(0) + +#define CPU_CS_H2XSOFTINTEN (CPU_CS_BASE_OFFS + 0x148) +#define HOST2XTENSA_INTR_ENABLE BIT(0) + +#define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x150) +#define CPU_IC_SOFTINT_H2A_SHFT 0x0 + +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160) +#define CORE_BRIDGE_SW_RESET BIT(0) +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1) + +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) +#define MSK_SIGNAL_FROM_TENSILICA BIT(0) +#define MSK_CORE_POWER_ON BIT(1) +#define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C) +#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) +#define WRAPPER_INTR_STATUS_A2H_BMSK BIT(2) + +#define WRAPPER_INTR_MASK (WRAPPER_BASE_OFFS + 0x10) +#define WRAPPER_INTR_MASK_A2HWD_BMSK BIT(3) +#define WRAPPER_INTR_MASK_A2HCPU_BMSK BIT(2) + +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) +#define REQ_POWER_DOWN_PREP BIT(0) + +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) +#define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */ +#define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */ +#define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */ + +#define WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0 (WRAPPER_BASE_OFFS + 0x78) #define WRAPPER_CORE_POWER_STATUS (WRAPPER_BASE_OFFS + 0x80) +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88) +#define CORE_CLK_RUN 0x0 + +#define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10) + +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) +#define CTL_AXI_CLK_HALT BIT(0) +#define CTL_CLK_HALT BIT(1) + +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) +#define RESET_HIGH BIT(0) + +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) #endif From d91c712a271fa5eeb9c766f2c97b166820fca80b Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 10 Dec 2025 18:06:03 +0530 Subject: [PATCH 084/659] FROMLIST: media: iris: Move vpu35 specific api to common to use for vpu4 Some of the sequence and calculations for vpu4 is identical to vpu35, namely power sequence for vpu controller and the clock frequency calculation. Move those to common file that can be shared for both vpu35 and vpu4. This patch prepares for power sequence for vpu4 which is added in subsequent patch. Link: https://lore.kernel.org/linux-media/20251210-knp_video-v4-5-8d11d840358a@oss.qualcomm.com/ Reviewed-by: Bryan O'Donoghue Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- drivers/media/platform/qcom/iris/iris_vpu3x.c | 157 +----------------- .../platform/qcom/iris/iris_vpu_common.c | 141 ++++++++++++++++ .../platform/qcom/iris/iris_vpu_common.h | 4 + 3 files changed, 151 insertions(+), 151 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c index cd53bcda3b3e1..fe4423b951b1e 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c @@ -16,8 +16,6 @@ #define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20) #define NOC_HALT BIT(0) #define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28) -#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL (AON_BASE_OFFS + 0x2C) -#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS (AON_BASE_OFFS + 0x30) static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core) { @@ -262,155 +260,12 @@ static void iris_vpu35_power_off_hw(struct iris_core *core) iris_disable_unprepare_clock(core, IRIS_AXI_CLK); } -static int iris_vpu35_power_off_controller(struct iris_core *core) -{ - u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; - unsigned int count = 0; - u32 val = 0; - bool handshake_done, handshake_busy; - int ret; - - writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH); - - writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); - - ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS, - val, val & BIT(0), 200, 2000); - if (ret) - goto disable_power; - - writel(0, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); - - /* Retry up to 1000 times as recommended by hardware documentation */ - do { - /* set MNoC to low power */ - writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); - - udelay(15); - - val = readl(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS); - - handshake_done = val & NOC_LPI_STATUS_DONE; - handshake_busy = val & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); - - if (handshake_done || !handshake_busy) - break; - - writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); - - udelay(15); - - } while (++count < 1000); - - if (!handshake_done && handshake_busy) - dev_err(core->dev, "LPI handshake timeout\n"); - - ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS, - val, val & BIT(0), 200, 2000); - if (ret) - goto disable_power; - - writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); - - writel(0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL); - - ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS, - val, val == 0, 200, 2000); - if (ret) - goto disable_power; - -disable_power: - iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); - iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK); - iris_disable_unprepare_clock(core, IRIS_AXI1_CLK); - - iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); - - reset_control_bulk_reset(clk_rst_tbl_size, core->resets); - - return 0; -} - -static int iris_vpu35_power_on_controller(struct iris_core *core) -{ - int ret; - - ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); - if (ret) - return ret; - - ret = iris_prepare_enable_clock(core, IRIS_AXI1_CLK); - if (ret) - goto err_disable_power; - - ret = iris_prepare_enable_clock(core, IRIS_CTRL_FREERUN_CLK); - if (ret) - goto err_disable_axi1_clk; - - ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK); - if (ret) - goto err_disable_ctrl_free_clk; - - return 0; - -err_disable_ctrl_free_clk: - iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK); -err_disable_axi1_clk: - iris_disable_unprepare_clock(core, IRIS_AXI1_CLK); -err_disable_power: - iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); - - return ret; -} - -static void iris_vpu35_program_bootup_registers(struct iris_core *core) -{ - writel(0x1, core->reg_base + WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0); -} - -static u64 iris_vpu3x_calculate_frequency(struct iris_inst *inst, size_t data_size) -{ - struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; - struct v4l2_format *inp_f = inst->fmt_src; - u32 height, width, mbs_per_second, mbpf; - u64 fw_cycles, fw_vpp_cycles; - u64 vsp_cycles, vpp_cycles; - u32 fps = DEFAULT_FPS; - - width = max(inp_f->fmt.pix_mp.width, inst->crop.width); - height = max(inp_f->fmt.pix_mp.height, inst->crop.height); - - mbpf = NUM_MBS_PER_FRAME(height, width); - mbs_per_second = mbpf * fps; - - fw_cycles = fps * caps->mb_cycles_fw; - fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp; - - vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value); - /* 21 / 20 is minimum overhead factor */ - vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); - - /* 1.059 is multi-pipe overhead */ - if (inst->fw_caps[PIPE].value > 1) - vpp_cycles += div_u64(vpp_cycles * 59, 1000); - - vsp_cycles = fps * data_size * 8; - vsp_cycles = div_u64(vsp_cycles, 2); - /* VSP FW overhead 1.05 */ - vsp_cycles = div_u64(vsp_cycles * 21, 20); - - if (inst->fw_caps[STAGE].value == STAGE_1) - vsp_cycles = vsp_cycles * 3; - - return max3(vpp_cycles, vsp_cycles, fw_cycles); -} - const struct vpu_ops iris_vpu3_ops = { .power_off_hw = iris_vpu3_power_off_hardware, .power_on_hw = iris_vpu_power_on_hw, .power_off_controller = iris_vpu_power_off_controller, .power_on_controller = iris_vpu_power_on_controller, - .calc_freq = iris_vpu3x_calculate_frequency, + .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, }; const struct vpu_ops iris_vpu33_ops = { @@ -418,14 +273,14 @@ const struct vpu_ops iris_vpu33_ops = { .power_on_hw = iris_vpu_power_on_hw, .power_off_controller = iris_vpu33_power_off_controller, .power_on_controller = iris_vpu_power_on_controller, - .calc_freq = iris_vpu3x_calculate_frequency, + .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, }; const struct vpu_ops iris_vpu35_ops = { .power_off_hw = iris_vpu35_power_off_hw, .power_on_hw = iris_vpu35_power_on_hw, - .power_off_controller = iris_vpu35_power_off_controller, - .power_on_controller = iris_vpu35_power_on_controller, - .program_bootup_registers = iris_vpu35_program_bootup_registers, - .calc_freq = iris_vpu3x_calculate_frequency, + .power_off_controller = iris_vpu35_vpu4x_power_off_controller, + .power_on_controller = iris_vpu35_vpu4x_power_on_controller, + .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers, + .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 50242fc6b4653..548e5f1727fdb 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -8,9 +8,12 @@ #include #include "iris_core.h" +#include "iris_instance.h" #include "iris_vpu_common.h" #include "iris_vpu_register_defines.h" +#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL (AON_BASE_OFFS + 0x2C) +#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS (AON_BASE_OFFS + 0x30) #define CTRL_INIT (CPU_CS_BASE_OFFS + 0x48) #define CTRL_STATUS (CPU_CS_BASE_OFFS + 0x4C) @@ -305,6 +308,144 @@ int iris_vpu_power_on_hw(struct iris_core *core) return ret; } +int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core) +{ + u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; + bool handshake_done, handshake_busy; + u32 count = 0, val = 0; + int ret; + + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH); + + writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); + + ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS, + val, val & BIT(0), 200, 2000); + if (ret) + goto disable_power; + + writel(0, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); + + /* Retry up to 1000 times as recommended by hardware documentation */ + do { + /* set MNoC to low power */ + writel(REQ_POWER_DOWN_PREP, core->reg_base + + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); + usleep_range(10, 20); + val = readl(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS); + + handshake_done = val & NOC_LPI_STATUS_DONE; + handshake_busy = val & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); + + if (handshake_done || !handshake_busy) + break; + + writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); + usleep_range(10, 20); + + } while (++count < 1000); + + if (!handshake_done && handshake_busy) + dev_err(core->dev, "LPI handshake timeout\n"); + + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS, + val, val & BIT(0), 200, 2000); + if (ret) + goto disable_power; + + writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); + + writel(0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL); + + readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS, + val, val == 0, 200, 2000); + +disable_power: + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); + iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK); + iris_disable_unprepare_clock(core, IRIS_AXI1_CLK); + + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); + + reset_control_bulk_reset(clk_rst_tbl_size, core->resets); + + return 0; +} + +int iris_vpu35_vpu4x_power_on_controller(struct iris_core *core) +{ + int ret; + + ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); + if (ret) + return ret; + + ret = iris_prepare_enable_clock(core, IRIS_AXI1_CLK); + if (ret) + goto err_disable_power; + + ret = iris_prepare_enable_clock(core, IRIS_CTRL_FREERUN_CLK); + if (ret) + goto err_disable_axi1_clk; + + ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK); + if (ret) + goto err_disable_ctrl_free_clk; + + return 0; + +err_disable_ctrl_free_clk: + iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK); +err_disable_axi1_clk: + iris_disable_unprepare_clock(core, IRIS_AXI1_CLK); +err_disable_power: + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); + + return ret; +} + +void iris_vpu35_vpu4x_program_bootup_registers(struct iris_core *core) +{ + writel(0x1, core->reg_base + WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0); +} + +u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_size) +{ + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; + struct v4l2_format *inp_f = inst->fmt_src; + u32 height, width, mbs_per_second, mbpf; + u64 fw_cycles, fw_vpp_cycles; + u64 vsp_cycles, vpp_cycles; + u32 fps = DEFAULT_FPS; + + width = max(inp_f->fmt.pix_mp.width, inst->crop.width); + height = max(inp_f->fmt.pix_mp.height, inst->crop.height); + + mbpf = NUM_MBS_PER_FRAME(height, width); + mbs_per_second = mbpf * fps; + + fw_cycles = fps * caps->mb_cycles_fw; + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp; + + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value); + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); + + /* 1.059 is multi-pipe overhead */ + if (inst->fw_caps[PIPE].value > 1) + vpp_cycles += div_u64(vpp_cycles * 59, 1000); + + vsp_cycles = fps * data_size * 8; + vsp_cycles = div_u64(vsp_cycles, 2); + /* VSP FW overhead 1.05 */ + vsp_cycles = div_u64(vsp_cycles * 21, 20); + + if (inst->fw_caps[STAGE].value == STAGE_1) + vsp_cycles = vsp_cycles * 3; + + return max3(vpp_cycles, vsp_cycles, fw_cycles); +} + int iris_vpu_power_on(struct iris_core *core) { u32 freq; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index d636e287457ad..7cf4304604cca 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -33,5 +33,9 @@ int iris_vpu_power_on(struct iris_core *core); int iris_vpu_power_off_controller(struct iris_core *core); void iris_vpu_power_off_hw(struct iris_core *core); void iris_vpu_power_off(struct iris_core *core); +int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core); +int iris_vpu35_vpu4x_power_on_controller(struct iris_core *core); +void iris_vpu35_vpu4x_program_bootup_registers(struct iris_core *core); +u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_size); #endif From 435be6599bd3cab768bf3826be4d37bbec088150 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 10 Dec 2025 18:06:04 +0530 Subject: [PATCH 085/659] FROMLIST: media: iris: Introduce vpu ops for vpu4 with necessary hooks Add power sequence for vpu4 by reusing from previous generation wherever possible. Hook up vpu4 op with vpu4 specific implemtation or resue from earlier generation wherever feasible, like clock calculation in this case. Link: https://lore.kernel.org/linux-media/20251210-knp_video-v4-6-8d11d840358a@oss.qualcomm.com/ Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- drivers/media/platform/qcom/iris/Makefile | 1 + .../platform/qcom/iris/iris_platform_common.h | 7 + drivers/media/platform/qcom/iris/iris_vpu4x.c | 369 ++++++++++++++++++ .../platform/qcom/iris/iris_vpu_common.h | 1 + 4 files changed, 378 insertions(+) create mode 100644 drivers/media/platform/qcom/iris/iris_vpu4x.c diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile index fad3be044e5fe..2abbd3aeb4af0 100644 --- a/drivers/media/platform/qcom/iris/Makefile +++ b/drivers/media/platform/qcom/iris/Makefile @@ -22,6 +22,7 @@ qcom-iris-objs += iris_buffer.o \ iris_venc.o \ iris_vpu2.o \ iris_vpu3x.o \ + iris_vpu4x.o \ iris_vpu_buffer.o \ iris_vpu_common.o \ diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 8acea81a22370..3ef30053deda4 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -57,6 +57,10 @@ enum platform_clk_type { IRIS_AXI1_CLK, IRIS_CTRL_FREERUN_CLK, IRIS_HW_FREERUN_CLK, + IRIS_BSE_HW_CLK, + IRIS_VPP0_HW_CLK, + IRIS_VPP1_HW_CLK, + IRIS_APV_HW_CLK, }; struct platform_clk_data { @@ -198,6 +202,9 @@ struct icc_vote_data { enum platform_pm_domain_type { IRIS_CTRL_POWER_DOMAIN, IRIS_HW_POWER_DOMAIN, + IRIS_VPP0_HW_POWER_DOMAIN, + IRIS_VPP1_HW_POWER_DOMAIN, + IRIS_APV_HW_POWER_DOMAIN, }; struct iris_platform_data { diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c b/drivers/media/platform/qcom/iris/iris_vpu4x.c new file mode 100644 index 0000000000000..a8db02ce5c5ec --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include + +#include "iris_instance.h" +#include "iris_vpu_common.h" +#include "iris_vpu_register_defines.h" + +#define AON_WRAPPER_MVP_NOC_RESET_SYNCRST (AON_MVP_NOC_RESET + 0x08) +#define CPU_CS_APV_BRIDGE_SYNC_RESET (CPU_BASE_OFFS + 0x174) +#define MVP_NOC_RESET_REQ_MASK 0x70103 +#define VPU_IDLE_BITS 0x7103 +#define WRAPPER_EFUSE_MONITOR (WRAPPER_BASE_OFFS + 0x08) + +#define APV_CLK_HALT BIT(1) +#define CORE_CLK_HALT BIT(0) +#define CORE_PWR_ON BIT(1) +#define DISABLE_VIDEO_APV_BIT BIT(27) +#define DISABLE_VIDEO_VPP1_BIT BIT(28) +#define DISABLE_VIDEO_VPP0_BIT BIT(29) + +static int iris_vpu4x_genpd_set_hwmode(struct iris_core *core, bool hw_mode, u32 efuse_value) +{ + int ret; + + ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], hw_mode); + if (ret) + return ret; + + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) { + ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs + [IRIS_VPP0_HW_POWER_DOMAIN], hw_mode); + if (ret) + goto restore_hw_domain_mode; + } + + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) { + ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs + [IRIS_VPP1_HW_POWER_DOMAIN], hw_mode); + if (ret) + goto restore_vpp0_domain_mode; + } + + if (!(efuse_value & DISABLE_VIDEO_APV_BIT)) { + ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs + [IRIS_APV_HW_POWER_DOMAIN], hw_mode); + if (ret) + goto restore_vpp1_domain_mode; + } + + return 0; + +restore_vpp1_domain_mode: + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) + dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VPP1_HW_POWER_DOMAIN], + !hw_mode); +restore_vpp0_domain_mode: + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) + dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VPP0_HW_POWER_DOMAIN], + !hw_mode); +restore_hw_domain_mode: + dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], !hw_mode); + + return ret; +} + +static int iris_vpu4x_power_on_apv(struct iris_core *core) +{ + int ret; + + ret = iris_enable_power_domains(core, + core->pmdomain_tbl->pd_devs[IRIS_APV_HW_POWER_DOMAIN]); + if (ret) + return ret; + + ret = iris_prepare_enable_clock(core, IRIS_APV_HW_CLK); + if (ret) + goto disable_apv_hw_power_domain; + + return 0; + +disable_apv_hw_power_domain: + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_APV_HW_POWER_DOMAIN]); + + return ret; +} + +static void iris_vpu4x_power_off_apv(struct iris_core *core) +{ + bool handshake_done, handshake_busy; + u32 value, count = 0; + int ret; + + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); + + if (value & APV_CLK_HALT) + writel(0x0, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); + + do { + writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); + usleep_range(10, 20); + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS); + + handshake_done = value & NOC_LPI_STATUS_DONE; + handshake_busy = value & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); + + if (handshake_done || !handshake_busy) + break; + + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); + usleep_range(10, 20); + + } while (++count < 1000); + + if (!handshake_done && handshake_busy) + dev_err(core->dev, "LPI handshake timeout\n"); + + writel(0x080200, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, + value, value & 0x080200, 200, 2000); + if (ret) + goto disable_clocks_and_power; + + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_SYNCRST); + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, + value, value == 0x0, 200, 2000); + if (ret) + goto disable_clocks_and_power; + + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + + CPU_CS_APV_BRIDGE_SYNC_RESET); + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_APV_BRIDGE_SYNC_RESET); + writel(0x0, core->reg_base + CPU_CS_APV_BRIDGE_SYNC_RESET); + +disable_clocks_and_power: + iris_disable_unprepare_clock(core, IRIS_APV_HW_CLK); + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_APV_HW_POWER_DOMAIN]); +} + +static void iris_vpu4x_ahb_sync_reset_apv(struct iris_core *core) +{ + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + + CPU_CS_APV_BRIDGE_SYNC_RESET); + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_APV_BRIDGE_SYNC_RESET); + writel(0x0, core->reg_base + CPU_CS_APV_BRIDGE_SYNC_RESET); +} + +static void iris_vpu4x_ahb_sync_reset_hardware(struct iris_core *core) +{ + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + + CPU_CS_AHB_BRIDGE_SYNC_RESET); + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); +} + +static int iris_vpu4x_enable_hardware_clocks(struct iris_core *core, u32 efuse_value) +{ + int ret; + + ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK); + if (ret) + return ret; + + ret = iris_prepare_enable_clock(core, IRIS_HW_FREERUN_CLK); + if (ret) + goto disable_axi_clock; + + ret = iris_prepare_enable_clock(core, IRIS_HW_CLK); + if (ret) + goto disable_hw_free_run_clock; + + ret = iris_prepare_enable_clock(core, IRIS_BSE_HW_CLK); + if (ret) + goto disable_hw_clock; + + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) { + ret = iris_prepare_enable_clock(core, IRIS_VPP0_HW_CLK); + if (ret) + goto disable_bse_hw_clock; + } + + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) { + ret = iris_prepare_enable_clock(core, IRIS_VPP1_HW_CLK); + if (ret) + goto disable_vpp0_hw_clock; + } + + return 0; + +disable_vpp0_hw_clock: + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) + iris_disable_unprepare_clock(core, IRIS_VPP0_HW_CLK); +disable_bse_hw_clock: + iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK); +disable_hw_clock: + iris_disable_unprepare_clock(core, IRIS_HW_CLK); +disable_hw_free_run_clock: + iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); +disable_axi_clock: + iris_disable_unprepare_clock(core, IRIS_AXI_CLK); + + return ret; +} + +static void iris_vpu4x_disable_hardware_clocks(struct iris_core *core, u32 efuse_value) +{ + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) + iris_disable_unprepare_clock(core, IRIS_VPP1_HW_CLK); + + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) + iris_disable_unprepare_clock(core, IRIS_VPP0_HW_CLK); + + iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK); + iris_disable_unprepare_clock(core, IRIS_HW_CLK); + iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); + iris_disable_unprepare_clock(core, IRIS_AXI_CLK); +} + +static int iris_vpu4x_power_on_hardware(struct iris_core *core) +{ + u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR); + int ret; + + ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); + if (ret) + return ret; + + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) { + ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs + [IRIS_VPP0_HW_POWER_DOMAIN]); + if (ret) + goto disable_hw_power_domain; + } + + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) { + ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs + [IRIS_VPP1_HW_POWER_DOMAIN]); + if (ret) + goto disable_vpp0_power_domain; + } + + ret = iris_vpu4x_enable_hardware_clocks(core, efuse_value); + if (ret) + goto disable_vpp1_power_domain; + + if (!(efuse_value & DISABLE_VIDEO_APV_BIT)) { + ret = iris_vpu4x_power_on_apv(core); + if (ret) + goto disable_hw_clocks; + + iris_vpu4x_ahb_sync_reset_apv(core); + } + + iris_vpu4x_ahb_sync_reset_hardware(core); + + ret = iris_vpu4x_genpd_set_hwmode(core, true, efuse_value); + if (ret) + goto disable_apv_power_domain; + + return 0; + +disable_apv_power_domain: + if (!(efuse_value & DISABLE_VIDEO_APV_BIT)) + iris_vpu4x_power_off_apv(core); +disable_hw_clocks: + iris_vpu4x_disable_hardware_clocks(core, efuse_value); +disable_vpp1_power_domain: + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs + [IRIS_VPP1_HW_POWER_DOMAIN]); +disable_vpp0_power_domain: + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs + [IRIS_VPP0_HW_POWER_DOMAIN]); +disable_hw_power_domain: + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); + + return ret; +} + +static void iris_vpu4x_power_off_hardware(struct iris_core *core) +{ + u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR); + bool handshake_done, handshake_busy; + u32 value, count = 0; + int ret; + + iris_vpu4x_genpd_set_hwmode(core, false, efuse_value); + + if (!(efuse_value & DISABLE_VIDEO_APV_BIT)) + iris_vpu4x_power_off_apv(core); + + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS); + + if (!(value & CORE_PWR_ON)) + goto disable_clocks_and_power; + + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); + + if (value & CORE_CLK_HALT) + writel(0x0, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); + + readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN, value, + value & VPU_IDLE_BITS, 2000, 20000); + + do { + writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); + usleep_range(10, 20); + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS); + + handshake_done = value & NOC_LPI_STATUS_DONE; + handshake_busy = value & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); + + if (handshake_done || !handshake_busy) + break; + + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); + usleep_range(10, 20); + + } while (++count < 1000); + + if (!handshake_done && handshake_busy) + dev_err(core->dev, "LPI handshake timeout\n"); + + writel(MVP_NOC_RESET_REQ_MASK, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, + value, value & MVP_NOC_RESET_REQ_MASK, 200, 2000); + if (ret) + goto disable_clocks_and_power; + + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_SYNCRST); + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, + value, value == 0x0, 200, 2000); + if (ret) + goto disable_clocks_and_power; + + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + + CPU_CS_AHB_BRIDGE_SYNC_RESET); + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); + +disable_clocks_and_power: + iris_vpu4x_disable_hardware_clocks(core, efuse_value); + + if (!(efuse_value & DISABLE_VIDEO_VPP1_BIT)) + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs + [IRIS_VPP1_HW_POWER_DOMAIN]); + + if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs + [IRIS_VPP0_HW_POWER_DOMAIN]); + + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); +} + +const struct vpu_ops iris_vpu4x_ops = { + .power_off_hw = iris_vpu4x_power_off_hardware, + .power_on_hw = iris_vpu4x_power_on_hardware, + .power_off_controller = iris_vpu35_vpu4x_power_off_controller, + .power_on_controller = iris_vpu35_vpu4x_power_on_controller, + .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers, + .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, +}; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index 7cf4304604cca..f6dffc613b822 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -12,6 +12,7 @@ extern const struct vpu_ops iris_vpu2_ops; extern const struct vpu_ops iris_vpu3_ops; extern const struct vpu_ops iris_vpu33_ops; extern const struct vpu_ops iris_vpu35_ops; +extern const struct vpu_ops iris_vpu4x_ops; struct vpu_ops { void (*power_off_hw)(struct iris_core *core); From fde168654082ff1ae9ad64d3da2f84dbf89a0aa7 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Fri, 31 Oct 2025 00:41:44 -0700 Subject: [PATCH 086/659] FROMLIST: dt-bindings: mailbox: qcom: Add IPCC support for Kaanapali and Glymur Platforms Document the Inter-Processor Communication Controller on the Qualcomm Kaanapali and Glymur Platforms, which will be used to route interrupts across various subsystems found on the SoC. Co-developed-by: Sibi Sankar Signed-off-by: Sibi Sankar Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251031-knp-ipcc-v3-1-62ffb4168dff@oss.qualcomm.com/ --- Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml b/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml index e5c423130db67..7c4d6170491db 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml @@ -24,6 +24,8 @@ properties: compatible: items: - enum: + - qcom,glymur-ipcc + - qcom,kaanapali-ipcc - qcom,milos-ipcc - qcom,qcs8300-ipcc - qcom,qdu1000-ipcc From 77f86ad3701cbbb5d3b018e8108a1d08b57d07dc Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Fri, 31 Oct 2025 00:41:45 -0700 Subject: [PATCH 087/659] FROMLIST: arm64: dts: qcom: Add header file for IPCC physical client IDs on Kaanapali platform On earlier platforms, Inter Process Communication Controller (IPCC) used virtual client IDs and performed virtual-to-physical mapping in hardware, so the IDs defined in dt-bindings/mailbox/qcom-ipcc.h are common across platforms. Physical client IDs instead of virtual client IDs are used for qcom new platforms like Kaanapali, which will be parsed by the devicetree and passed to hardware to use Physical client IDs directly. Since physical client IDs could vary across platforms, add a corresponding header file for the Kaanapali platform. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251031-knp-ipcc-v3-2-62ffb4168dff@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/kaanapali-ipcc.h | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/kaanapali-ipcc.h diff --git a/arch/arm64/boot/dts/qcom/kaanapali-ipcc.h b/arch/arm64/boot/dts/qcom/kaanapali-ipcc.h new file mode 100644 index 0000000000000..125375a4aac0a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/kaanapali-ipcc.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __DTS_KAANAPALI_MAILBOX_IPCC_H +#define __DTS_KAANAPALI_MAILBOX_IPCC_H + +/* Physical client IDs */ +#define IPCC_MPROC_AOP 0 +#define IPCC_MPROC_TZ 1 +#define IPCC_MPROC_MPSS 2 +#define IPCC_MPROC_LPASS 3 +#define IPCC_MPROC_SDC 4 +#define IPCC_MPROC_CDSP 5 +#define IPCC_MPROC_APSS 6 +#define IPCC_MPROC_SOCCP 13 +#define IPCC_MPROC_DCP 14 +#define IPCC_MPROC_SPSS 15 +#define IPCC_MPROC_TME 16 +#define IPCC_MPROC_WPSS 17 + +#define IPCC_COMPUTE_L0_CDSP 2 +#define IPCC_COMPUTE_L0_APSS 3 +#define IPCC_COMPUTE_L0_GPU 4 +#define IPCC_COMPUTE_L0_CVP 8 +#define IPCC_COMPUTE_L0_CAM 9 +#define IPCC_COMPUTE_L0_CAM1 10 +#define IPCC_COMPUTE_L0_DCP 11 +#define IPCC_COMPUTE_L0_VPU 12 +#define IPCC_COMPUTE_L0_SOCCP 16 + +#define IPCC_COMPUTE_L1_CDSP 2 +#define IPCC_COMPUTE_L1_APSS 3 +#define IPCC_COMPUTE_L1_GPU 4 +#define IPCC_COMPUTE_L1_CVP 8 +#define IPCC_COMPUTE_L1_CAM 9 +#define IPCC_COMPUTE_L1_CAM1 10 +#define IPCC_COMPUTE_L1_DCP 11 +#define IPCC_COMPUTE_L1_VPU 12 +#define IPCC_COMPUTE_L1_SOCCP 16 + +#define IPCC_PERIPH_CDSP 2 +#define IPCC_PERIPH_APSS 3 +#define IPCC_PERIPH_PCIE0 4 +#define IPCC_PERIPH_PCIE1 5 + +#define IPCC_FENCE_CDSP 2 +#define IPCC_FENCE_APSS 3 +#define IPCC_FENCE_GPU 4 +#define IPCC_FENCE_CVP 8 +#define IPCC_FENCE_CAM 8 +#define IPCC_FENCE_CAM1 10 +#define IPCC_FENCE_DCP 11 +#define IPCC_FENCE_VPU 20 +#define IPCC_FENCE_SOCCP 24 + +#endif From d178b308bb430e57de2545ff48b194facb0c2017 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Fri, 31 Oct 2025 00:41:46 -0700 Subject: [PATCH 088/659] FROMLIST: arm64: dts: qcom: Add header file for IPCC physical client IDs on Glymur platform Physical client IDs are used on Glymur Inter Process Communication Controller (IPCC), add a corresponding header file. Signed-off-by: Sibi Sankar Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251031-knp-ipcc-v3-3-62ffb4168dff@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/glymur-ipcc.h | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/glymur-ipcc.h diff --git a/arch/arm64/boot/dts/qcom/glymur-ipcc.h b/arch/arm64/boot/dts/qcom/glymur-ipcc.h new file mode 100644 index 0000000000000..700cd7114909f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur-ipcc.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __DTS_GLYMUR_MAILBOX_IPCC_H +#define __DTS_GLYMUR_MAILBOX_IPCC_H + +/* Glymur physical client IDs */ +#define IPCC_MPROC_AOP 0 +#define IPCC_MPROC_TZ 1 +#define IPCC_MPROC_MPSS 2 +#define IPCC_MPROC_LPASS 3 +#define IPCC_MPROC_SLPI 4 +#define IPCC_MPROC_SDC 5 +#define IPCC_MPROC_CDSP 6 +#define IPCC_MPROC_NPU 7 +#define IPCC_MPROC_APSS 8 +#define IPCC_MPROC_GPU 9 +#define IPCC_MPROC_ICP 11 +#define IPCC_MPROC_VPU 12 +#define IPCC_MPROC_PCIE0 13 +#define IPCC_MPROC_PCIE1 14 +#define IPCC_MPROC_PCIE2 15 +#define IPCC_MPROC_SPSS 16 +#define IPCC_MPROC_PCIE3 19 +#define IPCC_MPROC_PCIE4 20 +#define IPCC_MPROC_PCIE5 21 +#define IPCC_MPROC_PCIE6 22 +#define IPCC_MPROC_TME 23 +#define IPCC_MPROC_WPSS 24 +#define IPCC_MPROC_PCIE7 44 +#define IPCC_MPROC_SOCCP 46 + +#define IPCC_COMPUTE_L0_LPASS 0 +#define IPCC_COMPUTE_L0_CDSP 1 +#define IPCC_COMPUTE_L0_APSS 2 +#define IPCC_COMPUTE_L0_GPU 3 +#define IPCC_COMPUTE_L0_CVP 6 +#define IPCC_COMPUTE_L0_ICP 7 +#define IPCC_COMPUTE_L0_VPU 8 +#define IPCC_COMPUTE_L0_DPU 9 +#define IPCC_COMPUTE_L0_SOCCP 11 + +#define IPCC_COMPUTE_L1_LPASS 0 +#define IPCC_COMPUTE_L1_CDSP 1 +#define IPCC_COMPUTE_L1_APSS 2 +#define IPCC_COMPUTE_L1_GPU 3 +#define IPCC_COMPUTE_L1_CVP 6 +#define IPCC_COMPUTE_L1_ICP 7 +#define IPCC_COMPUTE_L1_VPU 8 +#define IPCC_COMPUTE_L1_DPU 9 +#define IPCC_COMPUTE_L1_SOCCP 11 + +#define IPCC_PERIPH_LPASS 0 +#define IPCC_PERIPH_APSS 1 +#define IPCC_PERIPH_PCIE0 2 +#define IPCC_PERIPH_PCIE1 3 +#define IPCC_PERIPH_PCIE2 6 +#define IPCC_PERIPH_PCIE3 7 +#define IPCC_PERIPH_PCIE4 8 +#define IPCC_PERIPH_PCIE5 9 +#define IPCC_PERIPH_PCIE6 10 +#define IPCC_PERIPH_PCIE7 11 +#define IPCC_PERIPH_SOCCP 13 +#define IPCC_PERIPH_WPSS 16 + +#endif From a56ff000d463b601b1c48031cb9b88b77d234d06 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 15 Dec 2025 01:07:22 -0800 Subject: [PATCH 089/659] FROMLIST: arm64: defconfig: enable clocks, interconnect and pinctrl for Qualcomm Kaanapali Enable necessary drivers for booting Qualcomm Kaanapali QRD and MTP boards. The serial engine must be properly setup before kernel reach "init", so UART driver and its dependencies needs to be built in, enable its dependency GCC, interconnect and pinctrl as built-in meanwhile enable TCSRCC as module. Link: https://lore.kernel.org/r/20251215-knp-dts-v4-2-1541bebeb89f@oss.qualcomm.com Reviewed-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov 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 45288ec9eaf73..851e2a21459b9 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -630,6 +630,7 @@ CONFIG_PINCTRL_IPQ5424=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_IPQ6018=y CONFIG_PINCTRL_IPQ9574=y +CONFIG_PINCTRL_KAANAPALI=y CONFIG_PINCTRL_MSM8916=y CONFIG_PINCTRL_MSM8953=y CONFIG_PINCTRL_MSM8976=y @@ -1397,6 +1398,8 @@ 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_KAANAPALI_GCC=y +CONFIG_CLK_KAANAPALI_TCSRCC=m CONFIG_CLK_X1E80100_CAMCC=m CONFIG_CLK_X1E80100_DISPCC=m CONFIG_CLK_X1E80100_GCC=y @@ -1762,6 +1765,7 @@ CONFIG_INTERCONNECT_IMX8MN=m CONFIG_INTERCONNECT_IMX8MQ=m CONFIG_INTERCONNECT_IMX8MP=y CONFIG_INTERCONNECT_QCOM=y +CONFIG_INTERCONNECT_QCOM_KAANAPALI=y CONFIG_INTERCONNECT_QCOM_MSM8916=m CONFIG_INTERCONNECT_QCOM_MSM8953=y CONFIG_INTERCONNECT_QCOM_MSM8996=y From 84a56a1af3dd5726933685701fc4c7d18ab35c40 Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Tue, 4 Nov 2025 17:35:07 +0800 Subject: [PATCH 090/659] 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 b38c5b187dd7b028aee6ef2ff7ce7ee53448c4ca Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 5 Nov 2025 14:26:27 +0530 Subject: [PATCH 091/659] 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 5b1c37c04134059585dc9ef279ba6ae4d310f19e Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Thu, 13 Nov 2025 14:59:19 +0530 Subject: [PATCH 092/659] 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 bbfe6a5e6567c9584c9da25985b496c5d6478691 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 14 Nov 2025 19:08:45 +0530 Subject: [PATCH 093/659] 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 2898e06cd6e8d4394f09980e37a66e050c4de371 Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Wed, 12 Nov 2025 11:29:07 +0800 Subject: [PATCH 094/659] 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 2f6c661ec4a0b..6a0b2eeba697e 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 2c37e9ee26d56af0fb1ee851809c828cd6060e47 Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Wed, 12 Nov 2025 12:01:17 +0800 Subject: [PATCH 095/659] 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 c774fde70657a169b1ba6cc5b9a82742748be3c3 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Wed, 19 Nov 2025 19:55:44 +0530 Subject: [PATCH 096/659] 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 33f8f2ca8ac90222552a87c3e6893e1a6e9ec49a Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 21 Nov 2025 10:01:00 +0530 Subject: [PATCH 097/659] 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 a475255e99cf92fab1d1702d3250572c48642db8 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 21 Nov 2025 13:32:46 +0530 Subject: [PATCH 098/659] 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 6a0b2eeba697e..cb256618f94c8 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 45e32e4311859da69528f3f7f15b683fa52bafa0 Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Thu, 20 Nov 2025 16:28:06 +0530 Subject: [PATCH 099/659] 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 851e2a21459b9..637393fa836ca 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -967,6 +967,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 b4102d01a3cdca21e17b56cc2065a80d076b7df1 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 27 Nov 2025 15:03:55 +0530 Subject: [PATCH 100/659] 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 df1a893dbc85e1a08bf4562198376deec6c6a1d1 Mon Sep 17 00:00:00 2001 From: Nikhil V Date: Thu, 27 Nov 2025 15:15:16 +0530 Subject: [PATCH 101/659] 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 a3d23553f04a1a564da87113089224e2a7e9c58b Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 28 Nov 2025 12:38:09 +0530 Subject: [PATCH 102/659] 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 cb256618f94c8..57062bc2671f7 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 9751c583c98085ec5df9c008cf9f9eb2deee9295 Mon Sep 17 00:00:00 2001 From: Jiaxing Li Date: Tue, 18 Nov 2025 00:16:10 +0800 Subject: [PATCH 103/659] 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 637393fa836ca..6e787a57ecb90 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1754,6 +1754,7 @@ CONFIG_OF_FPGA_REGION=m CONFIG_OF_OVERLAY=y CONFIG_TEE=y CONFIG_OPTEE=y +CONFIG_QCOMTEE=y CONFIG_MUX_GPIO=m CONFIG_MUX_MMIO=y CONFIG_SLIMBUS=m From 6c2c43577c5cab617038b25d1735e44b286c6bff Mon Sep 17 00:00:00 2001 From: Nikhil V Date: Thu, 20 Nov 2025 15:11:23 +0530 Subject: [PATCH 104/659] 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 bcdc3185a97045604c343ba4e2c7f5320d064e78 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 3 Dec 2025 10:12:17 +0530 Subject: [PATCH 105/659] 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 6e787a57ecb90..4913400060922 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1098,6 +1098,7 @@ CONFIG_SND_SOC_J721E_EVM=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 61ab8f77dc259ad32c4c0e5be909c3feca73a731 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Thu, 4 Dec 2025 18:20:29 +0530 Subject: [PATCH 106/659] 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 5faf2efe6a108c285ccdb8f92911b3f7eea435d3 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 25 Sep 2025 12:02:10 +0530 Subject: [PATCH 107/659] 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 Glymur CRD board to UART console with full USB support. Link: https://lore.kernel.org/lkml/20250925-v3_glymur_introduction-v1-2-24b601bbecc0@oss.qualcomm.com/ Signed-off-by: Pankaj Patil Nacked-by: Dmitry Baryshkov Signed-off-by: Sibi Sankar --- arch/arm64/configs/defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 4913400060922..5dd41f82948cc 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -624,6 +624,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 @@ -1400,6 +1401,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=y +CONFIG_CLK_GLYMUR_GCC=y +CONFIG_CLK_GLYMUR_TCSRCC=y CONFIG_CLK_KAANAPALI_GCC=y CONFIG_CLK_KAANAPALI_TCSRCC=m CONFIG_CLK_X1E80100_CAMCC=m @@ -1768,6 +1772,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 627f10e4590df68b342b77ee1d677a45879d43b1 Mon Sep 17 00:00:00 2001 From: Raghavender Reddy Bujala Date: Wed, 10 Dec 2025 16:16:53 +0530 Subject: [PATCH 108/659] 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 c512ab75cfddb72c2c2591298280ad8fb9cc35aa Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Mon, 15 Dec 2025 12:37:54 +0530 Subject: [PATCH 109/659] 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 ec99948cbacef9e535a020704a243a40577a08a7 Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Wed, 17 Dec 2025 18:42:40 +0530 Subject: [PATCH 110/659] 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 24ab2f786dfe65e62c275f0b0748a03f959d3036 Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya Date: Thu, 11 Dec 2025 16:41:21 +0530 Subject: [PATCH 111/659] 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 eb789e6fe46a49f3ae4261cc85919e94196fd709 Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Thu, 18 Dec 2025 15:10:56 +0530 Subject: [PATCH 112/659] 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 50167932c86a0e2ce4e77fd35f0f136f9be727c6 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Sun, 9 Nov 2025 20:07:19 +0530 Subject: [PATCH 113/659] 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 27b69f243901d3c5ae81d365005b2809afa6ec78 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Sun, 9 Nov 2025 20:07:21 +0530 Subject: [PATCH 114/659] 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 c2ccbb67f800c..e319a1894901c 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -858,7 +858,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 e090070626da6ce3f9c2aeecb697200748891015 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Sun, 9 Nov 2025 20:07:22 +0530 Subject: [PATCH 115/659] 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 f29a352b0288e..e405f0bef1f8d 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -935,6 +935,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 c76e5129a0aeb4d24aa236a7373fa8cfdc5bbf53 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Sat, 1 Nov 2025 09:29:38 +0530 Subject: [PATCH 116/659] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Add TC9563 PCIe switch node Add a node for the TC9563 PCIe switch, which has three downstream ports. Two embedded Ethernet devices are present on one of the downstream ports. As all these ports are present in the node represent the downstream ports and embedded endpoints. Power to the TC9563 is supplied through two LDO regulators, controlled by two GPIOs, which are added as fixed regulators. Configure the TC9563 through I2C. Link: https://lore.kernel.org/r/20251101-tc9563-v9-7-de3429f7787a@oss.qualcomm.com Reviewed-by: Bjorn Andersson Acked-by: Manivannan Sadhasivam Reviewed-by: Dmitry Baryshkov Signed-off-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 2 +- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 128 +++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index e319a1894901c..e846a521b7d52 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -2424,7 +2424,7 @@ status = "disabled"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index e405f0bef1f8d..c6386ad55106d 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -224,6 +224,30 @@ regulator-max-microvolt = <3700000>; }; + vdd_ntn_0p9: regulator-vdd-ntn-0p9 { + compatible = "regulator-fixed"; + regulator-name = "VDD_NTN_0P9"; + gpio = <&pm8350c_gpios 2 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <899400>; + regulator-max-microvolt = <899400>; + enable-active-high; + pinctrl-0 = <&ntn_0p9_en>; + pinctrl-names = "default"; + regulator-enable-ramp-delay = <4300>; + }; + + vdd_ntn_1p8: regulator-vdd-ntn-1p8 { + compatible = "regulator-fixed"; + regulator-name = "VDD_NTN_1P8"; + gpio = <&pm8350c_gpios 3 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + enable-active-high; + pinctrl-0 = <&ntn_1p8_en>; + pinctrl-names = "default"; + regulator-enable-ramp-delay = <10000>; + }; + thermal-zones { sdm-skin-thermal { thermal-sensors = <&pmk8350_adc_tm 3>; @@ -803,6 +827,78 @@ status = "okay"; }; +&pcie1_port0 { + 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 = <&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 = <&i2c0 0x77>; + + resx-gpios = <&pm8350c_gpios 1 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&tc9563_rsex_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; + }; + }; + }; +}; + &pm7325_gpios { kypd_vol_up_n: kypd-vol-up-n-state { pins = "gpio6"; @@ -1088,6 +1184,38 @@ }; }; +&pm8350c_gpios { + ntn_0p9_en: ntn-0p9-en-state { + pins = "gpio2"; + function = "normal"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; + + ntn_1p8_en: ntn-1p8-en-state { + pins = "gpio3"; + function = "normal"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; + + tc9563_rsex_n: tc9563-resx-state { + pins = "gpio1"; + function = "normal"; + + bias-disable; + input-disable; + output-enable; + power-source = <0>; + }; +}; + &tlmm { gpio-reserved-ranges = <32 2>, /* ADSP */ <48 4>; /* NFC */ From 07861e1da96496f66c9e14dad1f018e466b67565 Mon Sep 17 00:00:00 2001 From: Jianping Li Date: Mon, 17 Nov 2025 15:08:19 +0800 Subject: [PATCH 117/659] FROMLIST: arm64: dts: qcom: kodiak: Add memory region for audiopd Add reserved memory region for audio PD dynamic loading and remote heap requirement. Also add LPASS and ADSP_HEAP VMIDs. Link: https://lore.kernel.org/r/20251117070819.492-1-jianping.li@oss.qualcomm.com Signed-off-by: Jianping Li --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index e846a521b7d52..6ec2c549101a1 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -190,6 +190,11 @@ qcom,client-id = <1>; qcom,vmid = ; }; + + adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap@9cb80000 { + reg = <0x0 0x9cb80000 0x0 0x800000>; + no-map; + }; }; cpus { @@ -4431,6 +4436,9 @@ qcom,glink-channels = "fastrpcglink-apps-dsp"; label = "adsp"; qcom,non-secure-domain; + memory-region = <&adsp_rpc_remote_heap_mem>; + qcom,vmids = ; #address-cells = <1>; #size-cells = <0>; From 0e529863557a0804511ddc7085f780f6e89d8526 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Thu, 4 Dec 2025 18:51:53 +0530 Subject: [PATCH 118/659] FROMLIST: drm/msm/a6xx: Retrieve gmu core range by index Some GPUs like A612 doesn't use a named register range resource. This is because the reg-name property is discouraged when there is just a single resource. To address this, retrieve the 'gmu' register range by its index. It is always guaranteed to be at index 0. Signed-off-by: Akhil P Oommen Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251204-qcs615-spin-2-v4-1-f5a00c5b663f@oss.qualcomm.com --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 5903cd891b495..9662201cd2e9d 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -2029,21 +2029,19 @@ static int cxpd_notifier_cb(struct notifier_block *nb, return 0; } -static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, - const char *name, resource_size_t *start) +static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, resource_size_t *start) { + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *ret; - struct resource *res = platform_get_resource_byname(pdev, - IORESOURCE_MEM, name); if (!res) { - DRM_DEV_ERROR(&pdev->dev, "Unable to find the %s registers\n", name); + DRM_DEV_ERROR(&pdev->dev, "Unable to find the gmu core registers\n"); return ERR_PTR(-EINVAL); } ret = ioremap(res->start, resource_size(res)); if (!ret) { - DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s registers\n", name); + DRM_DEV_ERROR(&pdev->dev, "Unable to map the gmu core registers\n"); return ERR_PTR(-EINVAL); } @@ -2085,7 +2083,7 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) gmu->nr_clocks = ret; /* Map the GMU registers */ - gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu", &start); + gmu->mmio = a6xx_gmu_get_mmio(pdev, &start); if (IS_ERR(gmu->mmio)) { ret = PTR_ERR(gmu->mmio); goto err_mmio; @@ -2244,7 +2242,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) goto err_memory; /* Map the GMU registers */ - gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu", &start); + gmu->mmio = a6xx_gmu_get_mmio(pdev, &start); if (IS_ERR(gmu->mmio)) { ret = PTR_ERR(gmu->mmio); goto err_memory; From fc8359665e7d26bfa8f43f993923783f88c3de91 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Thu, 4 Dec 2025 18:51:54 +0530 Subject: [PATCH 119/659] FROMLIST: dt-bindings: display/msm: gpu: Simplify conditional schema logic JSON Schema conditionals can become complex and error-prone when combined with regex patterns. To improve readability and maintainability, replace nested if-else blocks with a flattened structure using explicit enums. Signed-off-by: Akhil P Oommen Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251204-qcs615-spin-2-v4-2-f5a00c5b663f@oss.qualcomm.com --- .../devicetree/bindings/display/msm/gpu.yaml | 56 ++++++++++++------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml index 826aafdcc20be..5c12b5aacf8f3 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml @@ -387,26 +387,42 @@ allOf: required: - clocks - clock-names - else: - if: - properties: - compatible: - contains: - oneOf: - - pattern: '^qcom,adreno-[67][0-9][0-9]\.[0-9]+$' - - pattern: '^qcom,adreno-[0-9a-f]{8}$' - - then: # Starting with A6xx, the clocks are usually defined in the GMU node - properties: - clocks: false - clock-names: false - - reg-names: - minItems: 1 - items: - - const: kgsl_3d0_reg_memory - - const: cx_mem - - const: cx_dbgc + + - if: + properties: + compatible: + contains: + enum: + - qcom,adreno-615.0 + - qcom,adreno-618.0 + - qcom,adreno-619.0 + - qcom,adreno-621.0 + - qcom,adreno-623.0 + - qcom,adreno-630.2 + - qcom,adreno-635.0 + - qcom,adreno-640.1 + - qcom,adreno-650.2 + - qcom,adreno-660.1 + - qcom,adreno-663.0 + - qcom,adreno-680.1 + - qcom,adreno-690.0 + - qcom,adreno-730.1 + - qcom,adreno-43030c00 + - qcom,adreno-43050a01 + - qcom,adreno-43050c01 + - qcom,adreno-43051401 + + then: # Starting with A6xx, the clocks are usually defined in the GMU node + properties: + clocks: false + clock-names: false + + reg-names: + minItems: 1 + items: + - const: kgsl_3d0_reg_memory + - const: cx_mem + - const: cx_dbgc examples: - | From d76230177f09aa1e992d4bbe5fec3a681c1a294c Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Thu, 4 Dec 2025 18:51:55 +0530 Subject: [PATCH 120/659] FROMLIST: dt-bindings: display/msm: gpu: Document A612 GPU A612 GPU has a new IP called RGMU (Reduced Graphics Management Unit) which replaces GMU. But it doesn't do clock or voltage scaling. So we need the gpu core clock in the GPU node along with the power domain to do clock and voltage scaling from the kernel. Update the bindings to describe this GPU. Signed-off-by: Akhil P Oommen Link: https://lore.kernel.org/r/20251204-qcs615-spin-2-v4-3-f5a00c5b663f@oss.qualcomm.com --- .../devicetree/bindings/display/msm/gpu.yaml | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml index 5c12b5aacf8f3..5d5ff4307ee7c 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml @@ -45,11 +45,11 @@ properties: - const: amd,imageon clocks: - minItems: 2 + minItems: 1 maxItems: 7 clock-names: - minItems: 2 + minItems: 1 maxItems: 7 reg: @@ -388,6 +388,32 @@ allOf: - clocks - clock-names + - if: + properties: + compatible: + contains: + const: qcom,adreno-612.0 + then: + properties: + clocks: + items: + - description: GPU Core clock + + clock-names: + items: + - const: core + + reg-names: + minItems: 1 + items: + - const: kgsl_3d0_reg_memory + - const: cx_mem + - const: cx_dbgc + + required: + - clocks + - clock-names + - if: properties: compatible: From 07409dbf497f0580b6a19acfacdf5417d7dd2caa Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Thu, 4 Dec 2025 18:51:56 +0530 Subject: [PATCH 121/659] FROMLIST: dt-bindings: display/msm/rgmu: Document A612 RGMU RGMU a.k.a Reduced Graphics Management Unit is a small state machine with the sole purpose of providing IFPC (Inter Frame Power Collapse) support. Compared to GMU, it doesn't manage GPU clock, voltage scaling, bw voting or any other functionalities. All it does is detect an idle GPU and toggle the GDSC switch. As it doesn't access DDR space, it doesn't require iommu. So far, only Adreno 612 GPU has an RGMU core. Document it in qcom,adreno-rgmu.yaml. Signed-off-by: Jie Zhang Signed-off-by: Akhil P Oommen Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251204-qcs615-spin-2-v4-4-f5a00c5b663f@oss.qualcomm.com --- .../display/msm/qcom,adreno-rgmu.yaml | 126 ++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 127 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml diff --git a/Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml new file mode 100644 index 0000000000000..bacc5b32e6d7b --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +%YAML 1.2 +--- + +$id: http://devicetree.org/schemas/display/msm/qcom,adreno-rgmu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RGMU attached to certain Adreno GPUs + +maintainers: + - Rob Clark + +description: + RGMU (Reduced Graphics Management Unit) IP is present in some GPUs that + belong to Adreno A6xx family. It is a small state machine that helps to + toggle the GX GDSC (connected to CX rail) to implement IFPC feature and save + power. + +properties: + compatible: + items: + - const: qcom,adreno-rgmu-612.0 + - const: qcom,adreno-rgmu + + reg: + items: + - description: Core RGMU registers + + clocks: + items: + - description: GMU clock + - description: GPU CX clock + - description: GPU AXI clock + - description: GPU MEMNOC clock + - description: GPU SMMU vote clock + + clock-names: + items: + - const: gmu + - const: cxo + - const: axi + - const: memnoc + - const: smmu_vote + + power-domains: + items: + - description: CX GDSC power domain + - description: GX GDSC power domain + + power-domain-names: + items: + - const: cx + - const: gx + + interrupts: + items: + - description: GMU OOB interrupt + - description: GMU interrupt + + interrupt-names: + items: + - const: oob + - const: gmu + + operating-points-v2: true + opp-table: + type: object + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + - power-domain-names + - interrupts + - interrupt-names + - operating-points-v2 + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + gmu@506a000 { + compatible = "qcom,adreno-rgmu-612.0", "qcom,adreno-rgmu"; + + reg = <0x05000000 0x90000>; + + 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>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 5b11839cba9de..ff92b9cc9435b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7982,6 +7982,7 @@ S: Maintained B: https://gitlab.freedesktop.org/drm/msm/-/issues T: git https://gitlab.freedesktop.org/drm/msm.git F: Documentation/devicetree/bindings/display/msm/gpu.yaml +F: Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml F: Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml F: drivers/gpu/drm/msm/adreno/ F: drivers/gpu/drm/msm/msm_gpu.* From 4e442d66cbf4dfb0d56b27198c250244fe047c04 Mon Sep 17 00:00:00 2001 From: Puranam V G Tejaswi Date: Wed, 5 Nov 2025 22:15:46 +0530 Subject: [PATCH 122/659] FROMLIST: arm64: dts: qcom: sa8775p: Add gpu and gmu nodes Add gpu and gmu nodes for sa8775p chipset. Also, add the speedbin qfprom node and wire it up with GPU node. Link: https://lore.kernel.org/r/20251105-a663-gpu-support-v7-2-1bcf7f151125@oss.qualcomm.com Signed-off-by: Puranam V G Tejaswi Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/lemans.dtsi | 119 +++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 0b154d57ba24e..883f9e0ab45c9 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -1098,6 +1098,18 @@ #mbox-cells = <2>; }; + qfprom: efuse@784000 { + compatible = "qcom,sa8775p-qfprom", "qcom,qfprom"; + reg = <0x0 0x00784000 0x0 0x3000>; + #address-cells = <1>; + #size-cells = <1>; + + gpu_speed_bin: gpu_speed_bin@240c { + reg = <0x240c 0x1>; + bits = <0 8>; + }; + }; + gpi_dma2: dma-controller@800000 { compatible = "qcom,sa8775p-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0x00800000 0x0 0x60000>; @@ -4135,6 +4147,113 @@ reg = <0x0 0x1fc0000 0x0 0x30000>; }; + gpu: gpu@3d00000 { + compatible = "qcom,adreno-663.0", "qcom,adreno"; + reg = <0x0 0x03d00000 0x0 0x40000>, + <0x0 0x03d9e000 0x0 0x1000>, + <0x0 0x03d61000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0xc00>, + <&adreno_smmu 1 0xc00>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "gfx-mem"; + #cooling-cells = <2>; + + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + + status = "disabled"; + + gpu_zap_shader: zap-shader { + memory-region = <&pil_gpu_mem>; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-405000000 { + opp-hz = /bits/ 64 <405000000>; + opp-level = ; + opp-peak-kBps = <5285156>; + opp-supported-hw = <0x3>; + }; + + opp-530000000 { + opp-hz = /bits/ 64 <530000000>; + opp-level = ; + opp-peak-kBps = <12484375>; + opp-supported-hw = <0x2>; + }; + + opp-676000000 { + opp-hz = /bits/ 64 <676000000>; + opp-level = ; + opp-peak-kBps = <8171875>; + opp-supported-hw = <0x1>; + }; + + opp-778000000 { + opp-hz = /bits/ 64 <778000000>; + opp-level = ; + opp-peak-kBps = <10687500>; + opp-supported-hw = <0x1>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-level = ; + opp-peak-kBps = <12484375>; + opp-supported-hw = <0x1>; + }; + }; + }; + + gmu: gmu@3d6a000 { + compatible = "qcom,adreno-gmu-663.0", "qcom,adreno-gmu"; + reg = <0x0 0x03d6a000 0x0 0x34000>, + <0x0 0x03de0000 0x0 0x10000>, + <0x0 0x0b290000 0x0 0x10000>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + 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_AHB_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", + "smmu_vote"; + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gpucc GPU_CC_GX_GDSC>; + power-domain-names = "cx", + "gx"; + iommus = <&adreno_smmu 5 0xc00>; + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-level = ; + }; + }; + }; + gpucc: clock-controller@3d90000 { compatible = "qcom,sa8775p-gpucc"; reg = <0x0 0x03d90000 0x0 0xa000>; From 8c47b94198798185dc17cb314f408ce70bec4ccf Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 5 Nov 2025 22:15:47 +0530 Subject: [PATCH 123/659] FROMLIST: arm64: dts: qcom: lemans: 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 reaching 105°C. Link: https://lore.kernel.org/r/20251105-a663-gpu-support-v7-3-1bcf7f151125@oss.qualcomm.com Signed-off-by: Gaurav Kohli Signed-off-by: Akhil P Oommen Reviewed-by: Konrad Dybcio --- arch/arm64/boot/dts/qcom/lemans.dtsi | 55 +++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 883f9e0ab45c9..14d9f31e7086d 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -21,6 +21,7 @@ #include #include #include +#include / { interrupt-parent = <&intc>; @@ -7514,8 +7515,15 @@ thermal-sensors = <&tsens0 5>; + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + trips { - trip-point0 { + gpuss0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -7534,8 +7542,15 @@ thermal-sensors = <&tsens0 6>; + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + trips { - trip-point0 { + gpuss1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -7554,8 +7569,15 @@ thermal-sensors = <&tsens0 7>; + cooling-maps { + map0 { + trip = <&gpuss2_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + trips { - trip-point0 { + gpuss2_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -7744,8 +7766,15 @@ thermal-sensors = <&tsens1 5>; + cooling-maps { + map0 { + trip = <&gpuss3_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + trips { - trip-point0 { + gpuss3_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -7764,8 +7793,15 @@ thermal-sensors = <&tsens1 6>; + cooling-maps { + map0 { + trip = <&gpuss4_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + trips { - trip-point0 { + gpuss4_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -7784,8 +7820,15 @@ thermal-sensors = <&tsens1 7>; + cooling-maps { + map0 { + trip = <&gpuss5_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + trips { - trip-point0 { + gpuss5_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; From 3e8efbf8cb6730bb97289877122cc9096b577554 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Wed, 5 Nov 2025 22:15:48 +0530 Subject: [PATCH 124/659] FROMLIST: arm64: dts: qcom: lemans-evk: Enable Adreno 663 GPU Enable GPU for lemans-evk platform and provide path for zap shader. Link: https://lore.kernel.org/r/20251105-a663-gpu-support-v7-4-1bcf7f151125@oss.qualcomm.com Reviewed-by: Dmitry Baryshkov Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index b40fa203e4a2f..28bf152f5fa8e 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -454,6 +454,14 @@ status = "okay"; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sa8775p/a663_zap.mbn"; +}; + &i2c18 { status = "okay"; From 97612c5b5e951f76c57ddbd594832520ac060f12 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Wed, 5 Nov 2025 22:15:49 +0530 Subject: [PATCH 125/659] FROMLIST: arm64: dts: qcom: qcs9100-ride: Enable Adreno 663 GPU Enable GPU on both qcs9100-ride platforms and provide the path for zap shader. Link: https://lore.kernel.org/r/20251105-a663-gpu-support-v7-5-1bcf7f151125@oss.qualcomm.com Reviewed-by: Dmitry Baryshkov Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi index c69aa2f41ce29..8fb7d1fc6d563 100644 --- a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi @@ -436,6 +436,14 @@ }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sa8775p/a663_zap.mbn"; +}; + &i2c11 { clock-frequency = <400000>; status = "okay"; From 1518ad0b648d8e1c838f57a96fecc907272c1283 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:23 +0530 Subject: [PATCH 126/659] 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 14d9f31e7086d..2c631a35e9385 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -699,6 +699,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 f0bd217c9883def060f17f82a4ddd63f74aed91b Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Wed, 17 Dec 2025 22:04:50 +0530 Subject: [PATCH 127/659] FROMLIST: arm64: dts: qcom: Add EL2 overlay for Lemans All the Lemans 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 Lemans 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/r/20251217-kvm_rproc_v9-v9-14-ab7ac03e0ff1@oss.qualcomm.com Signed-off-by: Mukesh Ojha --- arch/arm64/boot/dts/qcom/Makefile | 10 +++++++ arch/arm64/boot/dts/qcom/lemans-el2.dtso | 35 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/lemans-el2.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 6f34d5ed331c4..56efd90b7a5e6 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -37,6 +37,10 @@ lemans-evk-camera-dtbs := lemans-evk.dtb lemans-evk-camera.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb 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 dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb @@ -142,6 +146,12 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb + +qcs9100-ride-el2-dtbs := qcs9100-ride.dtb lemans-el2.dtbo +qcs9100-ride-r3-el2-dtbs := qcs9100-ride-r3.dtb lemans-el2.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-el2.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb diff --git a/arch/arm64/boot/dts/qcom/lemans-el2.dtso b/arch/arm64/boot/dts/qcom/lemans-el2.dtso new file mode 100644 index 0000000000000..ed615dce6c789 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-el2.dtso @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/* + * Lemans specific modifications required to boot in EL2. + */ + +/dts-v1/; +/plugin/; + +&iris { + status = "disabled"; +}; + +&remoteproc_adsp { + iommus = <&apps_smmu 0x3000 0x0>; +}; + +&remoteproc_cdsp0 { + iommus = <&apps_smmu 0x21c0 0x0400>; +}; + +&remoteproc_cdsp1 { + iommus = <&apps_smmu 0x29c0 0x0400>; +}; + +&remoteproc_gpdsp0 { + iommus = <&apps_smmu 0x38a0 0x0>; +}; + +&remoteproc_gpdsp1 { + iommus = <&apps_smmu 0x38c0 0x0>; +}; From 4f866a0037654d192859f48fa347d4a7163467d1 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Fri, 10 Oct 2025 17:01:21 +0530 Subject: [PATCH 128/659] FROMLIST: arm64: dts: qcom: lemans: Add edp reference clock for edp phy Add edp reference clock for edp phy on lemans chipset. Link:https://lore.kernel.org/all/20251013104806.6599-4-quic_riteshk@quicinc.com/ 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 2c631a35e9385..e5a58b727b3de 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -5170,9 +5170,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>; @@ -5189,9 +5191,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 2add41bfa6deafe77db97b36294d1e58938f3b0d Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Wed, 12 Nov 2025 12:08:26 +0530 Subject: [PATCH 129/659] 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 28bf152f5fa8e..e0c848bf981d5 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 { @@ -110,6 +111,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"; @@ -123,6 +135,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 { @@ -769,6 +850,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 5736df56e74d5b3719a7985533fcbb71d6c3ea3e Mon Sep 17 00:00:00 2001 From: Khalid Faisal Ansari Date: Sat, 15 Nov 2025 14:28:29 +0530 Subject: [PATCH 130/659] FROMLIST: arm64: dts: qcom: lemans-evk: Enable TPM (ST33) Enable ST33HTPM TPM over SPI16 on the LeMans IoT EVK by adding the required SPI and TPM nodes. Link: https://lore.kernel.org/all/20251114-enable-tpm-lemans-v1-1-c8d8b580ace7@oss.qualcomm.com/ Signed-off-by: Khalid Faisal Ansari --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index e0c848bf981d5..5ce20008db11d 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -746,6 +746,16 @@ status = "okay"; }; +&spi16 { + status = "okay"; + + tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +}; + &sdhc { vmmc-supply = <&vmmc_sdc>; vqmmc-supply = <&vreg_sdc>; From 4268d7eac9d0107e675aa8463d4bb9022560c93b Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:17 +0530 Subject: [PATCH 131/659] 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 f7787b0c20781a106f5c5a39bed73bc5bf3681f7 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:18 +0530 Subject: [PATCH 132/659] 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 5ce20008db11d..5d1b1d8c6cfa1 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -774,6 +774,7 @@ &serdes0 { phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; status = "okay"; }; From aa2856f0a2bc7ca1e654cf211395dfe404390ee0 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:19 +0530 Subject: [PATCH 133/659] 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 14056f296f4b700c44dd8409a486fc2f34f73e08 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Mon, 15 Dec 2025 10:24:51 +0530 Subject: [PATCH 134/659] FROMLIST: arm64: dts: qcom: lemans: Enable cpufreq cooling devices Add cooling-cells property to the CPU nodes to support cpufreq cooling devices. Signed-off-by: Gaurav Kohli Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251215045451.3150894-1-gaurav.kohli@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/lemans.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index e5a58b727b3de..c3df1c4cd9eda 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -55,6 +55,7 @@ qcom,freq-domain = <&cpufreq_hw 0>; next-level-cache = <&l2_0>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -84,6 +85,7 @@ qcom,freq-domain = <&cpufreq_hw 0>; next-level-cache = <&l2_1>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -108,6 +110,7 @@ qcom,freq-domain = <&cpufreq_hw 0>; next-level-cache = <&l2_2>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -132,6 +135,7 @@ qcom,freq-domain = <&cpufreq_hw 0>; next-level-cache = <&l2_3>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -156,6 +160,7 @@ qcom,freq-domain = <&cpufreq_hw 1>; next-level-cache = <&l2_4>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -186,6 +191,7 @@ qcom,freq-domain = <&cpufreq_hw 1>; next-level-cache = <&l2_5>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -210,6 +216,7 @@ qcom,freq-domain = <&cpufreq_hw 1>; next-level-cache = <&l2_6>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -234,6 +241,7 @@ qcom,freq-domain = <&cpufreq_hw 1>; next-level-cache = <&l2_7>; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY From fcc53810c92c4eb128f9a1f23e490fc3917c714f Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Sun, 23 Nov 2025 23:31:54 -0800 Subject: [PATCH 135/659] FROMLIST: dt-bindings: sram: Document qcom,kaanapali-imem and its child node On Qualcomm Kaanapali platform, IMEM is a block of SRAM shared across multiple IP blocks which can falk back to "mmio-sram". Documnent it and its child node "qcom,pil-reloc-info" which is used for collecting remoteproc ramdumps. Link: https://lore.kernel.org/r/20251123-knp-soc-binding-v4-1-42b349a66c59@oss.qualcomm.com Signed-off-by: Jingyi Wang Acked-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/sram/sram.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml index 7c1337e159f23..c451140962c86 100644 --- a/Documentation/devicetree/bindings/sram/sram.yaml +++ b/Documentation/devicetree/bindings/sram/sram.yaml @@ -34,6 +34,7 @@ properties: - nvidia,tegra186-sysram - nvidia,tegra194-sysram - nvidia,tegra234-sysram + - qcom,kaanapali-imem - qcom,rpm-msg-ram - rockchip,rk3288-pmu-sram @@ -89,6 +90,7 @@ patternProperties: - arm,juno-scp-shmem - arm,scmi-shmem - arm,scp-shmem + - qcom,pil-reloc-info - renesas,smp-sram - rockchip,rk3066-smp-sram - samsung,exynos4210-sysram From eefed01c1ddff68ea44a63078a93b7ff2b858852 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 24 Sep 2025 16:43:06 -0700 Subject: [PATCH 136/659] FROMLIST: dt-bindings: mfd: qcom,spmi-pmic: Document PMICs present on Kaanapali Document compatibles for the pmh0101, pmh0104, pmh0110 and pmk8850 SPMI PMICs. Signed-off-by: Jishnu Prakash Signed-off-by: Jingyi Wang Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20250924-knp-pmic-binding-v1-1-b9cce48b8460@oss.qualcomm.com/ --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 65c80e3b45008..fff2824c69d51 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -79,6 +79,9 @@ properties: - qcom,pmc8380 - qcom,pmd8028 - qcom,pmd9635 + - qcom,pmh0101 + - qcom,pmh0104 + - qcom,pmh0110 - qcom,pmi632 - qcom,pmi8950 - qcom,pmi8962 @@ -89,6 +92,7 @@ properties: - qcom,pmk8002 - qcom,pmk8350 - qcom,pmk8550 + - qcom,pmk8850 - qcom,pmm8155au - qcom,pmm8654au - qcom,pmp8074 From 2639935312cad26e6bc36331b52f91ebf2d90e92 Mon Sep 17 00:00:00 2001 From: Hrishabh Rajput Date: Tue, 18 Nov 2025 10:40:56 +0000 Subject: [PATCH 137/659] 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 1a6f85e463e06..c180b1432e3df 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2167,6 +2167,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; @@ -2433,6 +2483,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 2949741fcdc958db4503d4c9a7320359ccbff5b1 Mon Sep 17 00:00:00 2001 From: Hrishabh Rajput Date: Tue, 18 Nov 2025 10:40:57 +0000 Subject: [PATCH 138/659] 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 5b11839cba9de..6ccf293468fda 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3274,6 +3274,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 d3b9df7d466b0..53fc030229616 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -2362,4 +2362,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 ba52099b12539..d7e39ceceed0e 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 b28d9c7bbb3cb3ed7938717ddde32cc98615d165 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:14 +0530 Subject: [PATCH 139/659] 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 571c21b83da89c8b66df380b268f5b6b8e735d42 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:15 +0530 Subject: [PATCH 140/659] 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 cf5185056fb3ff692c89e1b1a05566e72bc0e391 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:16 +0530 Subject: [PATCH 141/659] 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 | 13 +++++++++---- 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, 40 insertions(+), 17 deletions(-) diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c index 41530b70cfc48..5d73dde585b1f 100644 --- a/drivers/power/reset/nvmem-reboot-mode.c +++ b/drivers/power/reset/nvmem-reboot-mode.c @@ -16,15 +16,20 @@ 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) { - int ret; struct nvmem_reboot_mode *nvmem_rbm; + u32 magic_32; + int ret; + + if (magic > U32_MAX) + return -EINVAL; + + magic_32 = magic; nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot); - ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic)); + 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 05c2c3a42654e6ea19c03f2e4af20d2e831e3ad9 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:17 +0530 Subject: [PATCH 142/659] 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 34a0324c11bbf535859cd61fdc9a170876010a65 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:18 +0530 Subject: [PATCH 143/659] 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 13d318e689ff0b1722aa684d59dd03ec11f0cf82 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:20 +0530 Subject: [PATCH 144/659] 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 7b7e77956157470a1c0925cdec114a0f1a423877 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Tue, 21 Oct 2025 23:00:26 -0700 Subject: [PATCH 145/659] dt-bindings: qcom,pdc: document Kaanapali Power Domain Controller Add a compatible for the Power Domain Controller on Kaanapali platforms. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251021-knp-pdc-v2-1-a38767f5bb8e@oss.qualcomm.com --- .../devicetree/bindings/interrupt-controller/qcom,pdc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml index 38d0c2d57dd6d..b26246de31862 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.yaml @@ -27,6 +27,7 @@ properties: items: - enum: - qcom,glymur-pdc + - qcom,kaanapali-pdc - qcom,qcs615-pdc - qcom,qcs8300-pdc - qcom,qdu1000-pdc From b5deb4a7465b91b6cea671f83ac097f0e0049167 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 18 Dec 2025 12:24:09 +0530 Subject: [PATCH 146/659] FROMLIST: media: iris: Add missing platform data entries for SM8750 Two platform-data fields for SM8750 were missed: - get_vpu_buffer_size = iris_vpu33_buf_size Without this, the driver fails to allocate the required internal buffers, leading to basic decode/encode failures during session bring-up. - max_core_mbps = ((7680 * 4320) / 256) * 60 Without this capability exposed, capability checks are incomplete and v4l2-compliance for encoder fails. Link: https://lore.kernel.org/linux-media/20251218-iris-sm8750-fix-v1-1-9a6df5cd6fd3@oss.qualcomm.com/ Fixes: a5925a2ce077 ("media: iris: add VPU33 specific encoding buffer calculation") Fixes: a6882431a138 ("media: iris: Add support for ENUM_FRAMESIZES/FRAMEINTERVALS for encoder") Cc: stable@vger.kernel.org Reviewed-by: Konrad Dybcio Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_platform_gen2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index c3ff1f6fa566a..bb0ff4e7b8040 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -1067,6 +1067,7 @@ const struct iris_platform_data sm8750_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_vpu33_buf_size, .vpu_ops = &iris_vpu35_ops, .set_preset_registers = iris_set_sm8550_preset_registers, .icc_tbl = sm8550_icc_table, @@ -1101,6 +1102,7 @@ const struct iris_platform_data sm8750_data = { .num_vpp_pipe = 4, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((7680 * 4320) / 256) * 60, .dec_input_config_params_default = sm8550_vdec_input_config_params_default, .dec_input_config_params_default_size = From 776fe08770380b70f8ec3d7a8878bf1846a106cb Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Mon, 15 Dec 2025 16:29:34 +0530 Subject: [PATCH 147/659] 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 c6386ad55106d..02fe5f5ab91cf 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 d19a4c1bd3a5c85722d13d63aa5e2542accfc2a0 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 10 Apr 2025 19:43:44 +0200 Subject: [PATCH 148/659] FROMLIST: soc: qcom: 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-v5 version of the structs. Unforunately, they are not versioned, so some elbow grease is necessary to determine which one is present. See for reference: v3: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/1d11897d2cfcc7b85f28ff74c445018dbbecac7a v4: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/f6e9aa549260bbc0bdcb156c2b05f48dc5963203 v5: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/blob/uefi.lnx.4.0.r31-rel/QcomModulePkg/Include/Protocol/DDRDetails.h?ref_type=heads Link: https://lore.kernel.org/r/20250410-topic-smem_dramc-v2-1-dead15264714@oss.qualcomm.com Reviewed-by: Bjorn Andersson Signed-off-by: Konrad Dybcio Signed-off-by: Vishnu Santhosh --- drivers/soc/qcom/Makefile | 3 +- drivers/soc/qcom/smem.c | 14 +- drivers/soc/qcom/smem.h | 9 ++ drivers/soc/qcom/smem_dramc.c | 287 ++++++++++++++++++++++++++++++++++ include/linux/soc/qcom/smem.h | 4 + 5 files changed, 315 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 c4c45f15dca4f..19a4b5557dc47 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); }; @@ -1230,17 +1235,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); hwspin_lock_free(__smem->hwlock); 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..6ded45fd55c2f --- /dev/null +++ b/drivers/soc/qcom/smem_dramc.c @@ -0,0 +1,287 @@ +// 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_DDR_REGION_NUM 6 +#define MAX_CHAN_NUM 8 +#define MAX_RANK_NUM 2 + +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, +}; + +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 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; + 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. + * + * If the function fails, the argument is left unmodified. + * + * Return: 0 on success, -ENODATA on failure. + */ +int qcom_smem_dram_get_hbb(void) +{ + return __dram ? __dram->hbb : -ENODATA; +} +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; + } +} + +/* 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; + else if (size == sizeof(struct ddr_details_v3) + sizeof(struct ddr_freq_table)) + return INFO_V3_WITH_14_FREQS; + else if (size == sizeof(struct ddr_details_v4)) + return INFO_V4; + else if (size == sizeof(struct ddr_details_v5) + 4 * sizeof(struct ddr_region_v5)) + return INFO_V5; + else if (size == sizeof(struct ddr_details_v5) + 6 * sizeof(struct ddr_region_v5)) + return INFO_V5_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); + +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: + smem_dram_parse_v5_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); + + /* 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 22ea4bf1d0fb65028b8886987e6a28b78f7a5376 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 6 Nov 2025 12:33:57 +0100 Subject: [PATCH 149/659] 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 150/659] 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 151/659] 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 152/659] 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 153/659] 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 154/659] 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 155/659] 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 156/659] 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 157/659] 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 158/659] 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 159/659] 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 88f1458e84e8ce08d1aae09f70a8b6087943439e Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 23 Dec 2025 17:07:14 +0530 Subject: [PATCH 160/659] 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 1651b6d6e0fa12e2bd16cb2623a875e675ce0420 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 23 Dec 2025 18:24:35 +0530 Subject: [PATCH 161/659] FROMLIST: drm/msm/a6xx: fix bogus hwcg register updates The hw clock gating register sequence consists of register value pairs that are written to the GPU during initialisation. The a690 hwcg sequence has two GMU registers in it that used to amount to random writes in the GPU mapping, but since commit 188db3d7fe66 ("drm/msm/a6xx: Rebase GMU register offsets") they trigger a fault as the updated offsets now lie outside the mapping. This in turn breaks boot of machines like the Lenovo ThinkPad X13s. Note that the updates of these GMU registers is already taken care of properly since commit 40c297eb245b ("drm/msm/a6xx: Set GMU CGC properties on a6xx too"), but for some reason these two entries were left in the table. Fixes: 5e7665b5e484 ("drm/msm/adreno: Add Adreno A690 support") Cc: stable@vger.kernel.org # 6.5 Cc: Bjorn Andersson Cc: Konrad Dybcio Signed-off-by: Johan Hovold Reviewed-by: Akhil P Oommen Link: https://lore.kernel.org/lkml/0e592574-9e8f-4bb0-b875-3a437fd340fb@oss.qualcomm.com/ --- drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c index 29107b3623464..4c2f739ee9b7c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c @@ -501,8 +501,6 @@ static const struct adreno_reglist a690_hwcg[] = { {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222}, {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111}, {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555}, - {REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111}, - {REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555}, {} }; From c3875d91bc790317fbfd048810402ebd4fa406b2 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Mon, 3 Jun 2024 13:06:48 +0530 Subject: [PATCH 162/659] FROMLIST: rpmsg: glink: Make glink smem interrupt wakeup capable There are certain usecases which require glink interrupt to be wakeup capable. For example if handset is in sleep state and usb charger is plugged in, dsp wakes up and sends glink interrupt to host for glink pmic channel communication. Glink is suppose to wakeup host processor completely for further glink data handling. IRQF_NO_SUSPEND does not gurantee complete wakeup, system may again enter sleep after interrupt handling and glink data may not be handled by pmic client driver. To ensure data handling by client configure glink smem device as wakeup source and attach glink interrupt as wakeup irq. Remove IRQF_NO_SUSPEND flag as it is no longer required. Link: https://lore.kernel.org/r/20240603073648.3475123-1-quic_deesin@quicinc.com Signed-off-by: Deepak Kumar Singh Signed-off-by: Vishnu Santhosh --- drivers/rpmsg/qcom_glink_smem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 7a982c60a8ddc..f1b553efab136 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -306,8 +307,7 @@ struct qcom_glink_smem *qcom_glink_smem_register(struct device *parent, smem->irq = of_irq_get(smem->dev.of_node, 0); ret = devm_request_irq(&smem->dev, smem->irq, qcom_glink_smem_intr, - IRQF_NO_SUSPEND | IRQF_NO_AUTOEN, - "glink-smem", smem); + IRQF_NO_AUTOEN, "glink-smem", smem); if (ret) { dev_err(&smem->dev, "failed to request IRQ\n"); goto err_put_dev; @@ -346,6 +346,8 @@ struct qcom_glink_smem *qcom_glink_smem_register(struct device *parent, smem->glink = glink; + device_init_wakeup(dev, true); + dev_pm_set_wake_irq(dev, smem->irq); enable_irq(smem->irq); return smem; @@ -365,6 +367,8 @@ void qcom_glink_smem_unregister(struct qcom_glink_smem *smem) struct qcom_glink *glink = smem->glink; disable_irq(smem->irq); + dev_pm_clear_wake_irq(&smem->dev); + device_init_wakeup(&smem->dev, false); qcom_glink_native_remove(glink); From d8bc255c945c15ff907782e1b949aa70f8762d1a Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:24 +0530 Subject: [PATCH 163/659] 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 c3df1c4cd9eda..a7aa9f08ce690 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -7155,6 +7155,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw0: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; remoteproc_cdsp1: remoteproc@2a300000 { @@ -7311,6 +7319,15 @@ }; }; }; + + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw1: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; remoteproc_adsp: remoteproc@30000000 { @@ -8035,7 +8052,7 @@ thermal-sensors = <&tsens2 5>; trips { - trip-point0 { + nsp_0_0_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8047,6 +8064,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 { @@ -8055,7 +8080,7 @@ thermal-sensors = <&tsens2 6>; trips { - trip-point0 { + nsp_0_1_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8067,6 +8092,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 { @@ -8075,7 +8108,7 @@ thermal-sensors = <&tsens2 7>; trips { - trip-point0 { + nsp_0_2_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8087,6 +8120,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 { @@ -8095,7 +8136,7 @@ thermal-sensors = <&tsens2 8>; trips { - trip-point0 { + nsp_1_0_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8107,6 +8148,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 { @@ -8115,7 +8164,7 @@ thermal-sensors = <&tsens2 9>; trips { - trip-point0 { + nsp_1_1_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8127,6 +8176,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 { @@ -8135,7 +8192,7 @@ thermal-sensors = <&tsens2 10>; trips { - trip-point0 { + nsp_1_2_0_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8147,6 +8204,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 { @@ -8289,7 +8354,7 @@ thermal-sensors = <&tsens3 5>; trips { - trip-point0 { + nsp_0_0_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8301,6 +8366,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 { @@ -8309,7 +8382,7 @@ thermal-sensors = <&tsens3 6>; trips { - trip-point0 { + nsp_0_1_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8321,6 +8394,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 { @@ -8329,7 +8410,7 @@ thermal-sensors = <&tsens3 7>; trips { - trip-point0 { + nsp_0_2_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8341,6 +8422,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 { @@ -8349,7 +8438,7 @@ thermal-sensors = <&tsens3 8>; trips { - trip-point0 { + nsp_1_0_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8361,6 +8450,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 { @@ -8369,7 +8466,7 @@ thermal-sensors = <&tsens3 9>; trips { - trip-point0 { + nsp_1_1_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8381,6 +8478,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 { @@ -8389,7 +8494,7 @@ thermal-sensors = <&tsens3 10>; trips { - trip-point0 { + nsp_1_2_1_alert0: trip-point0 { temperature = <105000>; hysteresis = <5000>; type = "passive"; @@ -8401,6 +8506,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 87b5b8c5526c30561b8b41c9b7f6d0bdff71287e Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:26 +0530 Subject: [PATCH 164/659] 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 6ec2c549101a1..c10d295ce5f90 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4788,6 +4788,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; usb_1: usb@a600000 { @@ -7595,12 +7603,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 { @@ -7613,12 +7635,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 bccaf34fdc6c52a523ad348e3945658d5c08b004 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 24 Dec 2025 18:34:18 +0530 Subject: [PATCH 165/659] 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 2f96b655ef10aa719115c18934f43219551ff14e Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Thu, 23 Oct 2025 12:28:39 +0530 Subject: [PATCH 166/659] 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 | 11 +++++++ 3 files changed, 59 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 1a6f85e463e06..4a3e32bbd0e6a 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2208,6 +2208,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_assert_valid_wq_ctx(u32 wq_ctx) { /* FW currently only supports a single wq_ctx (zero). diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index a56c8212cc0c4..48f2cb83228d6 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -173,6 +173,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 a55ca771286bf..7c177dec917da 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 { @@ -72,6 +74,15 @@ struct qcom_scm_pas_metadata { ssize_t size; }; +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); + + int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, struct qcom_scm_pas_metadata *ctx); void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); From 960a7bd80e98874877ec15fec9ef7285e1d01458 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 22 Sep 2025 20:34:20 -0700 Subject: [PATCH 167/659] FROMLIST: dt-bindings: mailbox: qcom-ipcc: Add bindings for physical client ids Physical client IDs instead of virtual client IDs are used for qcom new platforms in the Inter Process Communication Controller (IPCC) driver as virtual physical mapping logic is removed in HW. Add the bindings. Signed-off-by: Jingyi Wang Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20250922-ipcc-header-v1-1-f0b12715e118@oss.qualcomm.com/ --- include/dt-bindings/mailbox/qcom-ipcc.h | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/include/dt-bindings/mailbox/qcom-ipcc.h b/include/dt-bindings/mailbox/qcom-ipcc.h index fd85a79381b31..dc07ca27db09d 100644 --- a/include/dt-bindings/mailbox/qcom-ipcc.h +++ b/include/dt-bindings/mailbox/qcom-ipcc.h @@ -36,4 +36,52 @@ #define IPCC_CLIENT_GPDSP0 31 #define IPCC_CLIENT_GPDSP1 32 +/* Physical client IDs */ +#define IPCC_MPROC_AOP 0 +#define IPCC_MPROC_TZ 1 +#define IPCC_MPROC_MPSS 2 +#define IPCC_MPROC_LPASS 3 +#define IPCC_MPROC_SDC 4 +#define IPCC_MPROC_CDSP 5 +#define IPCC_MPROC_APSS 6 +#define IPCC_MPROC_SOCCP 13 +#define IPCC_MPROC_DCP 14 +#define IPCC_MPROC_SPSS 15 +#define IPCC_MPROC_TME 16 + +#define IPCC_COMPUTE_L0_CDSP 2 +#define IPCC_COMPUTE_L0_APSS 3 +#define IPCC_COMPUTE_L0_GPU 4 +#define IPCC_COMPUTE_L0_CVP 8 +#define IPCC_COMPUTE_L0_CAM 9 +#define IPCC_COMPUTE_L0_CAM1 10 +#define IPCC_COMPUTE_L0_DCP 11 +#define IPCC_COMPUTE_L0_VPU 12 +#define IPCC_COMPUTE_L0_SOCCP 16 + +#define IPCC_COMPUTE_L1_CDSP 2 +#define IPCC_COMPUTE_L1_APSS 3 +#define IPCC_COMPUTE_L1_GPU 4 +#define IPCC_COMPUTE_L1_CVP 8 +#define IPCC_COMPUTE_L1_CAM 9 +#define IPCC_COMPUTE_L1_CAM1 10 +#define IPCC_COMPUTE_L1_DCP 11 +#define IPCC_COMPUTE_L1_VPU 12 +#define IPCC_COMPUTE_L1_SOCCP 16 + +#define IPCC_PERIPH_CDSP 2 +#define IPCC_PERIPH_APSS 3 +#define IPCC_PERIPH_PCIE0 4 +#define IPCC_PERIPH_PCIE1 5 + +#define IPCC_FENCE_CDSP 2 +#define IPCC_FENCE_APSS 3 +#define IPCC_FENCE_GPU 4 +#define IPCC_FENCE_CVP 8 +#define IPCC_FENCE_CAM 8 +#define IPCC_FENCE_VPU 20 +#define IPCC_FENCE_SOCCP 24 +#define IPCC_FENCE_CAM1 10 +#define IPCC_FENCE_DCP 11 + #endif From 48714170dc4a486d6c17c502c203178d3bf31f22 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Oct 2025 19:46:29 +0530 Subject: [PATCH 168/659] 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 3ef30053deda4..fe4bc7ab2306d 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 bb0ff4e7b8040..a198c264ca1d8 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" @@ -866,6 +867,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 187f9e4912fd3c13c2ab312b4aac6acbe0018e8e Mon Sep 17 00:00:00 2001 From: Song Xue Date: Mon, 22 Sep 2025 19:10:24 +0530 Subject: [PATCH 169/659] 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/r/20250922-arm-psci-system_reset2-vendor-reboots-v15-14-7ce3a08878f1@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 be67eb173046f..71e12ac07c89c 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -493,6 +493,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 d1dbfa3bd81c3..d0fbd372406a8 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -555,7 +555,7 @@ }; }; - psci { + psci: psci { compatible = "arm,psci-1.0"; method = "smc"; From ee69d1da54334f58904b0fb660db15f7cc8e4be2 Mon Sep 17 00:00:00 2001 From: Viken Dadhaniya Date: Tue, 11 Nov 2025 22:33:50 +0530 Subject: [PATCH 170/659] FROMLIST: arm64: dts: qcom: talos: Drop opp-shared from QUP OPP table QUP devices are currently marked with opp-shared in their OPP table, causing the kernel to treat them as part of a shared OPP domain. This leads to the qcom_geni_serial driver failing to probe with error -EBUSY (-16). Remove the opp-shared property to ensure the OPP framework treats the QUP OPP table as device-specific, allowing the serial driver to probe successfully Link: https://lore.kernel.org/all/20251111170350.525832-1-viken.dadhaniya@oss.qualcomm.com/ Fixes: f6746dc9e379 ("arm64: dts: qcom: qcs615: Add QUPv3 configuration") Signed-off-by: Viken Dadhaniya --- arch/arm64/boot/dts/qcom/talos.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index d0fbd372406a8..4ef38fd4114df 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -537,7 +537,6 @@ qup_opp_table: opp-table-qup { compatible = "operating-points-v2"; - opp-shared; opp-75000000 { opp-hz = /bits/ 64 <75000000>; From cd9cd426c243dce142f8a1546e9cfcac0dc8fe7c Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Tue, 4 Nov 2025 09:33:25 +0800 Subject: [PATCH 171/659] FROMLIST: arm64: dts: qcom: talos: Add DisplayPort and QMP USB3-DP PHY Introduce DisplayPort controller node and associated QMP USB3-DP PHY for SM6150 SoC. Add data-lanes property to the DP endpoint and update clock assignments for proper DP integration. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20251104-add-displayport-support-to-qcs615-devicetree-v7-3-e51669170a6f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/talos.dtsi | 115 +++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index 4ef38fd4114df..b8fee8dd962dd 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -3854,6 +3855,7 @@ reg = <0>; dpu_intf0_out: endpoint { + remote-endpoint = <&mdss_dp0_in>; }; }; @@ -3886,6 +3888,89 @@ }; }; + mdss_dp0: displayport-controller@ae90000 { + compatible = "qcom,sm6150-dp", "qcom,sm8150-dp", "qcom,sm8350-dp"; + + reg = <0x0 0x0ae90000 0x0 0x200>, + <0x0 0x0ae90200 0x0 0x200>, + <0x0 0x0ae90400 0x0 0x600>, + <0x0 0x0ae90a00 0x0 0x600>, + <0x0 0x0ae91000 0x0 0x600>; + + interrupt-parent = <&mdss>; + interrupts = <12>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_DP_AUX_CLK>, + <&dispcc DISP_CC_MDSS_DP_LINK_CLK>, + <&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>, + <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>, + <&dispcc DISP_CC_MDSS_DP_PIXEL1_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel", + "stream_1_pixel"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>, + <&dispcc DISP_CC_MDSS_DP_PIXEL1_CLK_SRC>; + assigned-clock-parents = <&usb_qmpphy_2 QMP_USB43DP_DP_LINK_CLK>, + <&usb_qmpphy_2 QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_qmpphy_2 QMP_USB43DP_DP_VCO_DIV_CLK>; + + phys = <&usb_qmpphy_2 QMP_USB43DP_DP_PHY>; + phy-names = "dp"; + + operating-points-v2 = <&dp_opp_table>; + power-domains = <&rpmhpd RPMHPD_CX>; + + #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 { + data-lanes = <3 2 0 1>; + }; + }; + }; + + 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>; + }; + }; + }; + mdss_dsi0: dsi@ae94000 { compatible = "qcom,sm6150-dsi-ctrl", "qcom,mdss-dsi-ctrl"; reg = <0x0 0x0ae94000 0x0 0x400>; @@ -3981,8 +4066,8 @@ <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, <0>, - <0>, - <0>; + <&usb_qmpphy_2 QMP_USB43DP_DP_LINK_CLK>, + <&usb_qmpphy_2 QMP_USB43DP_DP_VCO_DIV_CLK>; #clock-cells = <1>; #reset-cells = <1>; @@ -4361,6 +4446,32 @@ status = "disabled"; }; + usb_qmpphy_2: phy@88e8000 { + compatible = "qcom,qcs615-qmp-usb3-dp-phy"; + reg = <0x0 0x088e8000 0x0 0x2000>; + + clocks = <&gcc GCC_USB2_SEC_PHY_AUX_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_CLK>, + <&gcc GCC_AHB2PHY_WEST_CLK>, + <&gcc GCC_USB2_SEC_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "cfg_ahb", + "pipe"; + + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >, + <&gcc GCC_USB3_DP_PHY_SEC_BCR>; + reset-names = "phy_phy", + "dp_phy"; + + #clock-cells = <1>; + #phy-cells = <1>; + + qcom,tcsr-reg = <&tcsr 0xbff0 0xb24c>; + + status = "disabled"; + }; + usb_1: usb@a6f8800 { compatible = "qcom,qcs615-dwc3", "qcom,dwc3"; reg = <0x0 0x0a6f8800 0x0 0x400>; From e724dfc9c1787e1f2a76b62f508076847419a505 Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Tue, 4 Nov 2025 09:33:26 +0800 Subject: [PATCH 172/659] FROMLIST: arm64: dts: qcom: qcs615-ride: Enable DisplayPort Add DP connector node and configure MDSS DisplayPort controller for QCS615 Ride platform. Include PHY supply settings to support DP output. Reviewed-by: Konrad Dybcio Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20251104-add-displayport-support-to-qcs615-devicetree-v7-4-e51669170a6f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/qcs615-ride.dts | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index 71e12ac07c89c..c425dc9c2ef3d 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -39,6 +39,20 @@ }; }; + dp0-connector { + compatible = "dp-connector"; + label = "DP0"; + type = "mini"; + + hpd-gpios = <&io_expander 8 GPIO_ACTIVE_HIGH>; + + port { + dp0_connector_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; + }; + }; + }; + dp-dsi0-connector { compatible = "dp-connector"; label = "DSI0"; @@ -423,6 +437,15 @@ 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"; @@ -631,6 +654,13 @@ status = "okay"; }; +&usb_qmpphy_2 { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + status = "okay"; +}; + &usb_1 { status = "okay"; }; From 4b7d2a6ffc90c8734659e57ee035eed673074b2b Mon Sep 17 00:00:00 2001 From: Yuanjie Yang Date: Wed, 17 Dec 2025 17:20:57 +0800 Subject: [PATCH 173/659] FROMLIST: arm64: dts: qcom: talos: Add PMU support Add the PMU node for talos platforms. Link: https://lore.kernel.org/all/20251217092057.462-1-yuanjie.yang@oss.qualcomm.com/ Signed-off-by: Yuanjie Yang --- arch/arm64/boot/dts/qcom/talos.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index b8fee8dd962dd..2e617ddad5b23 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -555,6 +555,16 @@ }; }; + pmu-a55 { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; + }; + + pmu-a76 { + compatible = "arm,cortex-a76-pmu"; + interrupts = ; + }; + psci: psci { compatible = "arm,psci-1.0"; method = "smc"; From ee968c96e4ef88242ddcf04c2f949ca51857af27 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Tue, 8 Jul 2025 14:55:00 +0800 Subject: [PATCH 174/659] BACKPORT: driver: bluetooth: hci_qca: Fix SSR (SubSystem Restart) fail when BT_EN is pulled up by hw On QCS9075 and QCA8275 platforms, the BT_EN pin is always pulled up by hw and cannot be controlled by the host. As a result, in case of a firmware crash, the host cannot trigger a cold reset. Instead, the BT controller performs a warm restart on its own, without reloading the firmware. This leads to the controller remaining in IBS_WAKE state, while the host expects it to be in sleep mode. The mismatch causes HCI reset commands to time out. Additionally, the driver does not clear internal flags QCA_SSR_TRIGGERED and QCA_IBS_DISABLED, which blocks the reset sequence. If the SSR duration exceeds 2 seconds, the host may enter TX sleep mode due to tx_idle_timeout, further preventing recovery. Also, memcoredump_flag is not cleared, so only the first SSR generates a coredump. Tell the driver that BT controller has undergone a proper restart sequence: - Clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED flags after SSR. - Add a 50ms delay to allow the controller to complete its warm reset. - Reset tx_idle_timer to prevent the host from entering TX sleep mode. - Clear memcoredump_flag to allow multiple coredump captures. Apply these steps only when HCI_QUIRK_NON_PERSISTENT_SETUP is not set, which indicates that BT_EN is defined in DTS and cannot be toggled. Refer to the comment in include/net/bluetooth/hci.h for details on HCI_QUIRK_NON_PERSISTENT_SETUP. Reviewed-by: Dmitry Baryshkov Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20251203033712.446632-2-shuai.zhang@oss.qualcomm.com/ --- drivers/bluetooth/hci_qca.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 29e391058fee5..3521402e5d2ec 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1652,6 +1652,39 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code) skb_queue_purge(&qca->rx_memdump_q); } + /* + * If the BT chip's bt_en pin is connected to a 3.3V power supply via + * hardware and always stays high, driver cannot control the bt_en pin. + * As a result, during SSR (SubSystem Restart), QCA_SSR_TRIGGERED and + * QCA_IBS_DISABLED flags cannot be cleared, which leads to a reset + * command timeout. + * Add an msleep delay to ensure controller completes the SSR process. + * + * Host will not download the firmware after SSR, controller to remain + * in the IBS_WAKE state, and the host needs to synchronize with it + * + * Since the bluetooth chip has been reset, clear the memdump state. + */ + if (!hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) { + /* + * When the SSR (SubSystem Restart) duration exceeds 2 seconds, + * it triggers host tx_idle_delay, which sets host TX state + * to sleep. Reset tx_idle_timer after SSR to prevent + * host enter TX IBS_Sleep mode. + */ + mod_timer(&qca->tx_idle_timer, jiffies + + msecs_to_jiffies(qca->tx_idle_delay)); + + /* Controller reset completion time is 50ms */ + msleep(50); + + clear_bit(QCA_SSR_TRIGGERED, &qca->flags); + clear_bit(QCA_IBS_DISABLED, &qca->flags); + + qca->tx_ibs_state = HCI_IBS_TX_AWAKE; + qca->memdump_state = QCA_MEMDUMP_IDLE; + } + clear_bit(QCA_HW_ERROR_EVENT, &qca->flags); /* From 7a39aa2dfb3fc633047dcfb654f7f0a25d0d17ff Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 8 Jan 2026 10:00:04 +0800 Subject: [PATCH 175/659] 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 d7d41b054b982..d6ff3406d386e 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 523d1709d45faf2392d21602e0f7897168cd26de Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 8 Jan 2026 11:28:06 +0800 Subject: [PATCH 176/659] 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 953003e32660b248aa654b038386f0178dd7bbc2 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 20 Nov 2025 21:48:54 +0800 Subject: [PATCH 177/659] FROMLIST: arm64: qcom: dts: sm8750: add coresight nodes Add CoreSight DT nodes for AOSS, QDSS, CDSP, and Modem blocks to enable the STM and TPDM sources to route trace data to the ETF for debugging. Link: https://lore.kernel.org/r/20251120-add-coresight-nodes-for-pakala-v3-1-03bb7651bc90@oss.qualcomm.com Reviewed-by: Abel Vesa Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 980 +++++++++++++++++++++++++++ 1 file changed, 980 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index 3f0b57f428bbb..f013198a1a0b0 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -3313,6 +3313,947 @@ #reset-cells = <1>; }; + stm@10002000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0x0 0x10002000 0x0 0x1000>, + <0x0 0x37280000 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>; + }; + }; + }; + }; + + 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@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 = <64>; + qcom,cmb-msrs-num = <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_in7>; + }; + }; + }; + }; + + tpdm@10800000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10800000 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@10803000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x10803000 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>; + }; + }; + }; + + out-ports { + port { + tpda_modem_out: endpoint { + remote-endpoint = <&funnel_modem_dl_in0>; + }; + }; + }; + }; + + funnel@10804000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x10804000 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>; + }; + }; + }; + }; + + cti@1080b000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x1080b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + tpdm@1082c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1082c000 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@10841000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10841000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_prng_out: endpoint { + remote-endpoint = <&tn_ag_in18>; + }; + }; + }; + }; + + tpdm@1084e000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1084e000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_mm_bcv_out: endpoint { + remote-endpoint = <&tpda_mm_in0>; + }; + }; + }; + }; + + tpdm@1084f000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1084f000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_mm_lmh_out: endpoint { + remote-endpoint = <&tpda_mm_in1>; + }; + }; + }; + }; + + tpdm@10850000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10850000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_mm_dpm_out: endpoint { + remote-endpoint = <&tpda_mm_in2>; + }; + }; + }; + }; + + tpda@10851000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x10851000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_mm_in0: endpoint { + remote-endpoint = <&tpdm_mm_bcv_out>; + }; + }; + + port@1 { + reg = <1>; + + tpda_mm_in1: endpoint { + remote-endpoint = <&tpdm_mm_lmh_out>; + }; + }; + + port@2 { + reg = <2>; + + tpda_mm_in2: endpoint { + remote-endpoint = <&tpdm_mm_dpm_out>; + }; + }; + }; + + out-ports { + port { + tpda_mm_out: endpoint { + remote-endpoint = <&tn_ag_in4>; + }; + }; + }; + }; + + tpdm@10980000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10980000 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>; + }; + }; + }; + }; + + tpda@10986000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x10986000 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>; + }; + }; + }; + + out-ports { + port { + tpda_cdsp_out: endpoint { + remote-endpoint = <&funnel_cdsp_in0>; + }; + }; + }; + }; + + funnel@10987000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x10987000 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>; + }; + }; + }; + }; + + cti@1098b000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x1098b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + tpdm@109a3000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a3000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_pmu_out: endpoint { + remote-endpoint = <&tn_ag_in29>; + }; + }; + }; + }; + + tpdm@109a4000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a4000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_ipcc_cmb_out: endpoint { + remote-endpoint = <&tn_ag_in28>; + }; + }; + }; + }; + + tpdm@109a5000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a5000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_dl_mm_out: endpoint { + remote-endpoint = <&tn_ag_in25>; + }; + }; + }; + }; + + tpdm@109a6000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a6000 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@109a7000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a7000 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@109a8000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a8000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_rdpm_cmb0_out: endpoint { + remote-endpoint = <&tn_ag_in30>; + }; + }; + }; + }; + + tpdm@109a9000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109a9000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_rdpm_cmb1_out: endpoint { + remote-endpoint = <&tn_ag_in31>; + }; + }; + }; + }; + + tpdm@109aa000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109aa000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_rdpm_cmb2_out: endpoint { + remote-endpoint = <&tn_ag_in32>; + }; + }; + }; + }; + + tn@109ab000 { + compatible = "qcom,coresight-tnoc", "arm,primecell"; + reg = <0x0 0x109ab000 0x0 0x4200>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@4 { + reg = <4>; + + tn_ag_in4: endpoint { + remote-endpoint = <&tpda_mm_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_prng_out>; + }; + }; + + port@13 { + reg = <0x13>; + + tn_ag_in19: endpoint { + remote-endpoint = <&tpdm_qm_out>; + }; + }; + + port@19 { + reg = <0x19>; + + tn_ag_in25: endpoint { + remote-endpoint = <&tpdm_dl_mm_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_cmb_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>; + }; + }; + }; + + out-ports { + port { + tn_ag_out: endpoint { + remote-endpoint = <&funnel_in0_in0>; + }; + }; + }; + }; + + tpdm@109d0000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x109d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_qm_out: endpoint { + remote-endpoint = <&tn_ag_in19>; + }; + }; + }; + }; + + funnel@10b04000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x10b04000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@6 { + reg = <6>; + + funnel_aoss_in6: endpoint { + remote-endpoint = <&tpda_aoss_out>; + }; + }; + + port@7 { + reg = <7>; + + funnel_aoss_in7: endpoint { + remote-endpoint = <&funnel_in0_out>; + }; + }; + + }; + + out-ports { + port { + funnel_aoss_out: endpoint { + remote-endpoint = <&tmc_etf_in>; + }; + }; + }; + }; + + tmc@10b05000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x10b05000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + tmc_etf_in: endpoint { + remote-endpoint = <&funnel_aoss_out>; + }; + }; + }; + }; + + tpda@10b08000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x10b08000 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_out>; + }; + }; + }; + + out-ports { + port { + tpda_aoss_out: endpoint { + remote-endpoint = <&funnel_aoss_in6>; + }; + }; + }; + }; + + tpdm@10b09000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10b09000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_swao_prio0_out: endpoint { + remote-endpoint = <&tpda_aoss_in0>; + }; + }; + }; + }; + + tpdm@10b0a000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10b0a000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_swao_prio1_out: endpoint { + remote-endpoint = <&tpda_aoss_in1>; + }; + }; + }; + }; + + tpdm@10b0b000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10b0b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_swao_prio2_out: endpoint { + remote-endpoint = <&tpda_aoss_in2>; + }; + }; + }; + }; + + tpdm@10b0c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10b0c000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + tpdm_swao_prio3_out: endpoint { + remote-endpoint = <&tpda_aoss_in3>; + }; + }; + }; + }; + + tpdm@10b0d000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x10b0d000 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_in4>; + }; + }; + }; + }; + apps_smmu: iommu@15000000 { compatible = "qcom,sm8750-smmu-500", "qcom,smmu-500", "arm,mmu-500"; reg = <0x0 0x15000000 0x0 0x100000>; @@ -4239,4 +5180,43 @@ , ; }; + + 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,dsb-element-bits = <32>; + + out-ports { + port { + tpdm_modem1_out: endpoint { + remote-endpoint = <&tpda_modem_in1>; + }; + }; + }; + }; }; From 33983c0f2e34475731736bbacd7f1956ee8cfdd2 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Tue, 9 Dec 2025 07:37:59 +0000 Subject: [PATCH 178/659] FROMLIST: arm64: dts: qcom: sm8750: add memory node for adsp fastrpc Add optional memory heap node that can be used for ADSP fastrpc. Link: https://lore.kernel.org/all/20251209-sm8750-fastrpc-adsp-v3-1-ccfff49a8af9@linaro.org/ Cc: Ekansh Gupta Cc: Srinivas Kandagatla Signed-off-by: Alexey Klimov Signed-off-by: Vinayak Katoch --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index f013198a1a0b0..d43f8d09736f5 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -524,6 +524,14 @@ reg = <0x0 0xff800000 0x0 0x800000>; no-map; }; + + adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap { + compatible = "shared-dma-pool"; + alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; + alignment = <0x0 0x400000>; + size = <0x0 0xc00000>; + reusable; + }; }; smp2p-adsp { From 1371e55cf99f9006ce299d3b878fd61a82466a07 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Tue, 9 Dec 2025 07:38:00 +0000 Subject: [PATCH 179/659] FROMLIST: arm64: dts: qcom: sm8750: add ADSP fastrpc-compute-cb nodes Add ADSP fastrpc nodes for sm8750 SoC. Link: https://lore.kernel.org/all/20251209-sm8750-fastrpc-adsp-v3-2-ccfff49a8af9@linaro.org/ Cc: Ekansh Gupta Cc: Srinivas Kandagatla Signed-off-by: Alexey Klimov Signed-off-by: Vinayak Katoch --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 61 ++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index d43f8d09736f5..597c1b89d52f3 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -2243,6 +2244,66 @@ }; }; }; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + memory-region = <&adsp_rpc_remote_heap_mem>; + qcom,vmids = ; + #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; + }; + }; }; }; From e5a99752fbd051081bd9a49f38b7a0eb6f2431c0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 6 Jan 2026 10:07:39 +0100 Subject: [PATCH 180/659] FROMLIST: arm64: dts: qcom: sm8750: Add Iris VPU v3.5 Add Iris video codec to SM8750 SoC, which comes with significantly different powering up sequence than previous SM8650, thus different clocks and resets. For consistency keep existing clock and clock-names naming, so the list shares common part. Link: https://lore.kernel.org/all/20260106-b4-sm8750-iris-dts-v4-1-97db1d1df3dd@oss.qualcomm.com/ Signed-off-by: Krzysztof Kozlowski --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 121 +++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index 597c1b89d52f3..e0948c1d8404a 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -2809,6 +2810,126 @@ }; }; + iris: video-codec@aa00000 { + compatible = "qcom,sm8750-iris"; + reg = <0x0 0x0aa00000 0x0 0xf0000>; + + 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>; + clock-names = "iface", + "core", + "vcodec0_core", + "iface1", + "core_freerun", + "vcodec0_core_freerun"; + + dma-coherent; + iommus = <&apps_smmu 0x1940 0>, + <&apps_smmu 0x1947 0>; + + 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"; + + interrupts = ; + + memory-region = <&video_mem>; + + operating-points-v2 = <&iris_opp_table>; + + power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>, + <&videocc VIDEO_CC_MVS0_GDSC>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_MMCX>; + power-domain-names = "venus", + "vcodec0", + "mxc", + "mmcx"; + + 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", + "vcodec0_core"; + + /* + * IRIS firmware is signed by vendors, only + * enable in 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>; + required-opps = <&rpmhpd_opp_low_svs_d1>, + <&rpmhpd_opp_low_svs_d1>; + }; + + opp-338000000 { + opp-hz = /bits/ 64 <338000000>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + }; + + opp-420000000 { + opp-hz = /bits/ 64 <420000000>; + required-opps = <&rpmhpd_opp_svs>, + <&rpmhpd_opp_svs>; + }; + + opp-444000000 { + opp-hz = /bits/ 64 <444000000>; + required-opps = <&rpmhpd_opp_svs_l1>, + <&rpmhpd_opp_svs_l1>; + }; + + opp-533333334 { + opp-hz = /bits/ 64 <533333334>; + required-opps = <&rpmhpd_opp_nom>, + <&rpmhpd_opp_nom>; + }; + + opp-570000000 { + opp-hz = /bits/ 64 <570000000>; + required-opps = <&rpmhpd_opp_nom_l1>, + <&rpmhpd_opp_nom_l1>; + }; + + opp-630000000 { + opp-hz = /bits/ 64 <630000000>; + required-opps = <&rpmhpd_opp_turbo>, + <&rpmhpd_opp_turbo>; + }; + }; + }; + + videocc: clock-controller@aaf0000 { + compatible = "qcom,sm8750-videocc"; + reg = <0x0 0x0aaf0000 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>; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sm8750-pdc", "qcom,pdc"; reg = <0x0 0x0b220000 0x0 0x10000>, <0x0 0x164400f0 0x0 0x64>; From ed782522c2c099347293f7cd3ffcdf32b9b0ea83 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 6 Jan 2026 10:07:40 +0100 Subject: [PATCH 181/659] FROMLIST: arm64: dts: qcom: sm8750-mtp: Enable Iris codec Enable on SM8750 MTP the Iris video codec for accelerated video encoding/decoding. Link: https://lore.kernel.org/all/20260106-b4-sm8750-iris-dts-v4-2-97db1d1df3dd@oss.qualcomm.com/ Signed-off-by: Krzysztof Kozlowski --- arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts index c8cb521b4c26c..d4885a530e689 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts @@ -925,6 +925,10 @@ }; }; +&iris { + status = "okay"; +}; + &lpass_vamacro { pinctrl-0 = <&dmic01_default>, <&dmic23_default>; pinctrl-names = "default"; From 2288dcfdc7d930acc8098c488dc51e4535d46f52 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 6 Jan 2026 10:07:41 +0100 Subject: [PATCH 182/659] FROMLIST: arm64: dts: qcom: sm8750-qrd: Enable Iris codec Enable on SM8750 QRD the Iris video codec for accelerated video encoding/decoding. Link: https://lore.kernel.org/all/20260106-b4-sm8750-iris-dts-v4-3-97db1d1df3dd@oss.qualcomm.com/ Signed-off-by: Krzysztof Kozlowski --- arch/arm64/boot/dts/qcom/sm8750-qrd.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts index b0cb61c5a6034..eb3b38be477b0 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts @@ -858,6 +858,10 @@ }; }; +&iris { + status = "okay"; +}; + &pm8550_flash { status = "okay"; From 582931cad6b38da14814b9605e512ce0e05646ee Mon Sep 17 00:00:00 2001 From: Jagadeesh Pagadala Date: Thu, 8 Jan 2026 14:14:29 +0530 Subject: [PATCH 183/659] 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 d2f2062172d0a705fb576ed234102e42d082e32c Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Mon, 5 Jan 2026 15:59:47 +0800 Subject: [PATCH 184/659] 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 68fb6ff3b9f297da25e6477fd1a7bdb04c32e6bf Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Thu, 8 Jan 2026 17:47:45 +0800 Subject: [PATCH 185/659] 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 d6ff3406d386e..285284c2bd7e0 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 3b9b422cb29d0478f55fe65f1880c8f741fb2e64 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 9 Jan 2026 14:42:21 +0800 Subject: [PATCH 186/659] 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 1c86d19ed7c7616f291772cc8e176f6d5e441c85 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 12 Jan 2026 11:30:00 +0800 Subject: [PATCH 187/659] 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 d9d5cb776a91e072cce2481d7f7cf4bd402856d1 Mon Sep 17 00:00:00 2001 From: Yongxing Mou Date: Mon, 17 Nov 2025 14:49:32 +0800 Subject: [PATCH 188/659] FROMLIST: arm64: dts: qcom: qcs8300: add display dt nodes for MDSS, DPU, DisplayPort and eDP PHY Add devicetree changes to enable MDSS display-subsystem, display-controller(DPU), DisplayPort controller and eDP PHY for Qualcomm QCS8300 platform. Link: https://lore.kernel.org/r/20251117-dts_qcs8300-v7-1-bf42d39e7828@oss.qualcomm.com Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Yongxing Mou --- arch/arm64/boot/dts/qcom/monaco.dtsi | 220 ++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 816fa2af8a9a6..e44fd5c33816a 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -4789,6 +4789,222 @@ #power-domain-cells = <1>; }; + mdss: display-subsystem@ae00000 { + compatible = "qcom,qcs8300-mdss"; + reg = <0x0 0x0ae00000 0x0 0x1000>; + reg-names = "mdss"; + + interrupts = ; + + clocks = <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_MDP_CLK>; + + resets = <&dispcc MDSS_DISP_CC_MDSS_CORE_BCR>; + + interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_MDP1 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"; + + power-domains = <&dispcc MDSS_DISP_CC_MDSS_CORE_GDSC>; + + iommus = <&apps_smmu 0x1000 0x402>; + + interrupt-controller; + #interrupt-cells = <1>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdss_mdp: display-controller@ae01000 { + compatible = "qcom,qcs8300-dpu", "qcom,sa8775p-dpu"; + reg = <0x0 0x0ae01000 0x0 0x8f000>, + <0x0 0x0aeb0000 0x0 0x2008>; + reg-names = "mdp", "vbif"; + + interrupts-extended = <&mdss 0>; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_MDP_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc MDSS_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_intf0_out: endpoint { + remote-endpoint = <&mdss_dp0_in>; + }; + }; + }; + + 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>; + }; + }; + }; + + mdss_dp0_phy: phy@aec2a00 { + compatible = "qcom,qcs8300-edp-phy", "qcom,sa8775p-edp-phy"; + + reg = <0x0 0x0aec2a00 0x0 0x19c>, + <0x0 0x0aec2200 0x0 0xec>, + <0x0 0x0aec2600 0x0 0xec>, + <0x0 0x0aec2000 0x0 0x1c8>; + + clocks = <&dispcc MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>; + clock-names = "aux", + "cfg_ahb"; + + power-domains = <&rpmhpd RPMHPD_MX>; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + mdss_dp0: displayport-controller@af54000 { + compatible = "qcom,qcs8300-dp", "qcom,sa8775p-dp"; + + reg = <0x0 0x0af54000 0x0 0x200>, + <0x0 0x0af54200 0x0 0x200>, + <0x0 0x0af55000 0x0 0xc00>, + <0x0 0x0af56000 0x0 0x09c>, + <0x0 0x0af57000 0x0 0x09c>, + <0x0 0x0af58000 0x0 0x09c>, + <0x0 0x0af59000 0x0 0x09c>, + <0x0 0x0af5a000 0x0 0x23c>, + <0x0 0x0af5b000 0x0 0x23c>; + + interrupts-extended = <&mdss 12>; + + clocks = <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK>, + <&dispcc 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 = <&dispcc MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC>, + <&dispcc MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC>; + assigned-clock-parents = <&mdss_dp0_phy 0>, + <&mdss_dp0_phy 1>, + <&mdss_dp0_phy 1>, + <&mdss_dp0_phy 1>, + <&mdss_dp0_phy 1>; + phys = <&mdss_dp0_phy>; + phy-names = "dp"; + + operating-points-v2 = <&dp_opp_table>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + + #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 { }; + }; + }; + + 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>; + }; + }; + }; + }; + dispcc: clock-controller@af00000 { compatible = "qcom,sa8775p-dispcc0"; reg = <0x0 0x0af00000 0x0 0x20000>; @@ -4796,7 +5012,9 @@ <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, - <0>, <0>, <0>, <0>, + <&mdss_dp0_phy 0>, + <&mdss_dp0_phy 1>, + <0>, <0>, <0>, <0>, <0>, <0>; power-domains = <&rpmhpd RPMHPD_MMCX>; #clock-cells = <1>; From 4a9cd5b52975749199ed0d0c228a5c59e2e05853 Mon Sep 17 00:00:00 2001 From: Yongxing Mou Date: Mon, 17 Nov 2025 14:49:33 +0800 Subject: [PATCH 189/659] FROMLIST: arm64: dts: qcom: qcs8300-ride: Enable Display Port Enable DPTX0 along with their corresponding PHYs for qcs8300-ride platform. Link: https://lore.kernel.org/r/20251117-dts_qcs8300-v7-2-bf42d39e7828@oss.qualcomm.com Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Yongxing Mou --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 9bcb869dd2706..4a8ac26846c6e 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -24,6 +24,18 @@ stdout-path = "serial0:115200n8"; }; + dp0-connector { + compatible = "dp-connector"; + label = "DP0"; + type = "full-size"; + + port { + dp0_connector_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; + }; + }; + }; + regulator-usb2-vbus { compatible = "regulator-fixed"; regulator-name = "USB2_VBUS"; @@ -317,6 +329,30 @@ status = "okay"; }; +&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 = <&dp0_connector_in>; +}; + +&mdss_dp0_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l4a>; + + status = "okay"; +}; + &qupv3_id_0 { status = "okay"; }; @@ -377,6 +413,12 @@ bias-pull-up; }; }; + + dp_hot_plug_det: dp-hot-plug-det-state { + pins = "gpio94"; + function = "edp0_hot"; + bias-disable; + }; }; &uart7 { From 7e442c4e52dd499d53594825182284144fd3cc39 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Fri, 22 Aug 2025 09:53:15 +0530 Subject: [PATCH 190/659] FROMLIST: dt-bindings: thermal: tsens: Add QCS8300 compatible Add compatibility string for the thermal sensors on QCS8300 platform. Link: https://lore.kernel.org/r/20250822042316.1762153-2-quic_gkohli@quicinc.com Signed-off-by: Gaurav Kohli Acked-by: Rob Herring (Arm) --- Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index 3c5256b0cd9f2..4d10b84254619 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -63,6 +63,7 @@ properties: - qcom,qcm2290-tsens - qcom,qcs8300-tsens - qcom,qcs615-tsens + - qcom,qcs8300-tsens - qcom,sa8255p-tsens - qcom,sa8775p-tsens - qcom,sar2130p-tsens From 3ce24fc874c90c469afc828630fae9e0386aaac1 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Fri, 22 Aug 2025 09:53:16 +0530 Subject: [PATCH 191/659] FROMLIST: arm64: dts: qcom: qcs8300: Enable TSENS support for QCS8300 SoC Add TSENS and thermal devicetree node for QCS8300 SoC. Link: https://lore.kernel.org/r/20250822042316.1762153-3-quic_gkohli@quicinc.com Signed-off-by: Gaurav Kohli --- arch/arm64/boot/dts/qcom/monaco.dtsi | 526 +++++++++++++++++++++++++++ 1 file changed, 526 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index e44fd5c33816a..b079daeba5abe 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -6436,6 +6436,532 @@ }; }; }; + + tsens2: thermal-sensor@c251000 { + compatible = "qcom,qcs8300-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c251000 0x0 0x1000>, + <0x0 0x0c224000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", "critical"; + #qcom,sensors = <10>; + #thermal-sensor-cells = <1>; + }; + + tsens3: thermal-sensor@c252000 { + compatible = "qcom,qcs8300-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c252000 0x0 0x1000>, + <0x0 0x0c225000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", "critical"; + #qcom,sensors = <10>; + #thermal-sensor-cells = <1>; + }; + + tsens0: thermal-sensor@c263000 { + compatible = "qcom,qcs8300-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c263000 0x0 0x1000>, + <0x0 0x0c222000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", "critical"; + #qcom,sensors = <10>; + #thermal-sensor-cells = <1>; + }; + + tsens1: thermal-sensor@c265000 { + compatible = "qcom,qcs8300-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c265000 0x0 0x1000>, + <0x0 0x0c223000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "uplow", "critical"; + #qcom,sensors = <10>; + #thermal-sensor-cells = <1>; + }; + }; + + thermal_zones: thermal-zones { + aoss-0-thermal { + thermal-sensors = <&tsens0 0>; + + trips { + aoss0-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-0-0-thermal { + thermal-sensors = <&tsens0 1>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-1-0-thermal { + thermal-sensors = <&tsens0 2>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-2-0-thermal { + thermal-sensors = <&tsens0 3>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-3-0-thermal { + thermal-sensors = <&tsens0 4>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-0-thermal { + thermal-sensors = <&tsens0 5>; + + trips { + gpuss0-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + audio-thermal { + thermal-sensors = <&tsens0 6>; + + trips { + audio-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + camss-0-thermal { + thermal-sensors = <&tsens0 7>; + + trips { + camss-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + pcie-0-thermal { + thermal-sensors = <&tsens0 8>; + + trips { + pcie-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpuss-0-0-thermal { + thermal-sensors = <&tsens0 9>; + + trips { + cpuss0-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-1-thermal { + thermal-sensors = <&tsens1 0>; + + trips { + aoss1-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-0-1-thermal { + thermal-sensors = <&tsens1 1>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-1-1-thermal { + thermal-sensors = <&tsens1 2>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-2-1-thermal { + thermal-sensors = <&tsens1 3>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-0-3-1-thermal { + thermal-sensors = <&tsens1 4>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-1-thermal { + thermal-sensors = <&tsens1 5>; + + trips { + gpuss1-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + video-thermal { + thermal-sensors = <&tsens1 6>; + + trips { + video-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + camss-1-thermal { + thermal-sensors = <&tsens1 7>; + + trips { + camss1-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + pcie-1-thermal { + thermal-sensors = <&tsens1 8>; + + trips { + pcie-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpuss-0-1-thermal { + thermal-sensors = <&tsens1 9>; + + trips { + cpuss0-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-2-thermal { + thermal-sensors = <&tsens2 0>; + + trips { + aoss2-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-0-0-thermal { + thermal-sensors = <&tsens2 1>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-1-0-thermal { + thermal-sensors = <&tsens2 2>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-2-0-thermal { + thermal-sensors = <&tsens2 3>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-3-0-thermal { + thermal-sensors = <&tsens2 4>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp-0-0-0-thermal { + thermal-sensors = <&tsens2 5>; + + trips { + nsp-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp-0-1-0-thermal { + thermal-sensors = <&tsens2 6>; + + trips { + nsp-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp-0-2-0-thermal { + thermal-sensors = <&tsens2 7>; + + trips { + nsp-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddrss-0-thermal { + thermal-sensors = <&tsens2 8>; + + trips { + ddrss-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpuss-1-0-thermal { + thermal-sensors = <&tsens2 9>; + + trips { + cpuss1-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-3-thermal { + thermal-sensors = <&tsens3 0>; + + trips { + aoss3-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-0-1-thermal { + thermal-sensors = <&tsens3 1>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-1-1-thermal { + thermal-sensors = <&tsens3 2>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-2-1-thermal { + thermal-sensors = <&tsens3 3>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu-1-3-1-thermal { + thermal-sensors = <&tsens3 4>; + + trips { + cpu-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp-0-0-1-thermal { + thermal-sensors = <&tsens3 5>; + + trips { + nsp-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp-0-1-1-thermal { + thermal-sensors = <&tsens3 6>; + + trips { + nsp-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp-0-2-1-thermal { + thermal-sensors = <&tsens3 7>; + + trips { + nsp-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddrss-1-thermal { + thermal-sensors = <&tsens3 8>; + + trips { + ddrss-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpuss-1-1-thermal { + thermal-sensors = <&tsens3 9>; + + trips { + cpuss1-critical { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; }; timer { From d99a1839d83fe2bd499561f574a05be5fbf18c68 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 3 Sep 2025 12:49:55 +0530 Subject: [PATCH 192/659] FROMLIST: arm64: dts: qcom: qcs8300: 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 reaching 115°C. Link: https://lore.kernel.org/r/20250903-a623-gpu-support-v5-4-5398585e2981@oss.qualcomm.com Signed-off-by: Gaurav Kohli Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/monaco.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index b079daeba5abe..9aa962f59468e 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -6547,12 +6547,25 @@ thermal-sensors = <&tsens0 5>; trips { + gpuss0_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss0-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; audio-thermal { @@ -6667,12 +6680,25 @@ thermal-sensors = <&tsens1 5>; trips { + gpuss1_alert0: trip-point0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss1-critical { temperature = <125000>; hysteresis = <1000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; video-thermal { From 807b6bc3d081e7fd33405cc764499c77079ff6e8 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 9 Nov 2025 20:07:24 +0530 Subject: [PATCH 193/659] 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 9aa962f59468e..d12f0a24be66f 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -732,6 +732,11 @@ #power-domain-cells = <0>; domain-idle-states = <&system_sleep>; }; + + reboot-mode { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; }; reserved-memory { From c9179ecf2f67c35e27f6614082e1244adc056d77 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Fri, 7 Nov 2025 21:55:21 +0530 Subject: [PATCH 194/659] FROMLIST: arm64: dts: qcom: qcs8300: Add support for camss Add changes to support the camera subsystem on the QCS8300. Link: https://lore.kernel.org/r/20251107162521.511536-3-quic_vikramsa@quicinc.com Reviewed-by: Konrad Dybcio Reviewed-by: Bryan O'Donoghue Signed-off-by: Vikram Sharma --- arch/arm64/boot/dts/qcom/monaco.dtsi | 172 +++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index d12f0a24be66f..5fe675606c061 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -4781,6 +4781,178 @@ #power-domain-cells = <1>; }; + camss: isp@ac78000 { + compatible = "qcom,qcs8300-camss"; + + reg = <0x0 0xac78000 0x0 0x1000>, + <0x0 0xac7a000 0x0 0xf00>, + <0x0 0xac7c000 0x0 0xf00>, + <0x0 0xac84000 0x0 0xf00>, + <0x0 0xac88000 0x0 0xf00>, + <0x0 0xac8c000 0x0 0xf00>, + <0x0 0xac90000 0x0 0xf00>, + <0x0 0xac94000 0x0 0xf00>, + <0x0 0xac9c000 0x0 0x2000>, + <0x0 0xac9e000 0x0 0x2000>, + <0x0 0xaca0000 0x0 0x2000>, + <0x0 0xacac000 0x0 0x400>, + <0x0 0xacad000 0x0 0x400>, + <0x0 0xacae000 0x0 0x400>, + <0x0 0xac4d000 0x0 0xf000>, + <0x0 0xac60000 0x0 0xf000>, + <0x0 0xac85000 0x0 0xd00>, + <0x0 0xac89000 0x0 0xd00>, + <0x0 0xac8d000 0x0 0xd00>, + <0x0 0xac91000 0x0 0xd00>, + <0x0 0xac95000 0x0 0xd00>; + reg-names = "csid_wrapper", + "csid0", + "csid1", + "csid_lite0", + "csid_lite1", + "csid_lite2", + "csid_lite3", + "csid_lite4", + "csiphy0", + "csiphy1", + "csiphy2", + "tpg0", + "tpg1", + "tpg2", + "vfe0", + "vfe1", + "vfe_lite0", + "vfe_lite1", + "vfe_lite2", + "vfe_lite3", + "vfe_lite4"; + + clocks = <&camcc CAM_CC_CAMNOC_AXI_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_LITE_CLK>, + <&camcc CAM_CC_CPAS_IFE_0_CLK>, + <&camcc CAM_CC_CPAS_IFE_1_CLK>, + <&camcc CAM_CC_CSID_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_CSID_CSIPHY_RX_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&gcc GCC_CAMERA_SF_AXI_CLK>, + <&camcc CAM_CC_ICP_AHB_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_axi", + "core_ahb", + "cpas_ahb", + "cpas_fast_ahb_clk", + "cpas_vfe_lite", + "cpas_vfe0", + "cpas_vfe1", + "csid", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "csiphy2", + "csiphy2_timer", + "csiphy_rx", + "gcc_axi_hf", + "gcc_axi_sf", + "icp_ahb", + "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", + "csid_lite0", + "csid_lite1", + "csid_lite2", + "csid_lite3", + "csid_lite4", + "csiphy0", + "csiphy1", + "csiphy2", + "tpg0", + "tpg1", + "tpg2", + "vfe0", + "vfe1", + "vfe_lite0", + "vfe_lite1", + "vfe_lite2", + "vfe_lite3", + "vfe_lite4"; + + 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>; + interconnect-names = "ahb", + "hf_0"; + + iommus = <&apps_smmu 0x2400 0x20>; + + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; + power-domain-names = "top"; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + }; + + port@1 { + reg = <1>; + }; + + port@2 { + reg = <2>; + }; + }; + }; + camcc: clock-controller@ade0000 { compatible = "qcom,qcs8300-camcc"; reg = <0x0 0x0ade0000 0x0 0x20000>; From c43f2ba69275b17811d72d35b7a70aa395c1c293 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Wed, 26 Nov 2025 13:40:56 +0530 Subject: [PATCH 195/659] 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 5fe675606c061..f3ebb15037c00 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -4781,6 +4781,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"; @@ -5294,6 +5405,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 fe7f93d121b0191ce57ff7b880d77995e25bb01e Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Wed, 26 Nov 2025 13:40:57 +0530 Subject: [PATCH 196/659] 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 6f34d5ed331c4..b1ba182a0d8d4 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -38,6 +38,10 @@ lemans-evk-camera-dtbs := lemans-evk.dtb lemans-evk-camera.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera.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 bb35893da73d1..b1d34c1248d36 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -76,6 +76,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 3490fa21540ac0285e845494260fd04bf307fc5a Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 28 Nov 2025 18:49:24 +0800 Subject: [PATCH 197/659] FROMLIST: arm64: dts: qcom: qcs8300: enable pcie0 Add configurations in devicetree for PCIe0, including registers, clocks, interrupts and phy setting sequence. Add PCIe lane equalization preset properties for 8 GT/s and 16GT/s Link: https://lore.kernel.org/r/20251128104928.4070050-3-ziyue.zhang@oss.qualcomm.com Reviewed-by: Manivannan Sadhasivam Reviewed-by: Konrad Dybcio Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/monaco.dtsi | 181 ++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index f3ebb15037c00..5076e09a746dd 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -909,7 +909,7 @@ #power-domain-cells = <1>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, - <0>, + <&pcie0_phy>, <0>, <0>, <0>, @@ -2261,6 +2261,185 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + pcie0: pci@1c00000 { + device_type = "pci"; + compatible = "qcom,pcie-qcs8300", "qcom,pcie-sa8775p"; + reg = <0x0 0x01c00000 0x0 0x3000>, + <0x0 0x40000000 0x0 0xf20>, + <0x0 0x40000f20 0x0 0xa8>, + <0x0 0x40001000 0x0 0x4000>, + <0x0 0x40100000 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 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <0>; + num-lanes = <2>; + + 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 GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + + assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_anoc MASTER_PCIE_0 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_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + iommu-map = <0x0 &pcie_smmu 0x0000 0x1>, + <0x100 &pcie_smmu 0x0001 0x1>; + + resets = <&gcc GCC_PCIE_0_BCR>, + <&gcc GCC_PCIE_0_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_0_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55>; + + operating-points-v2 = <&pcie0_opp_table>; + + status = "disabled"; + + pcie0_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <250000 1>; + }; + + /* GEN 1 x2 and GEN 2 x1 */ + opp-5000000 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <500000 1>; + }; + + /* GEN 2 x2 */ + opp-10000000 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <1000000 1>; + }; + + /* GEN 3 x1 */ + opp-8000000 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <984500 1>; + }; + + /* GEN 3 x2 and GEN 4 x1 */ + opp-16000000 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <1969000 1>; + }; + + /* GEN 4 x2 */ + opp-32000000 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + }; + }; + + pcieport0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + phys = <&pcie0_phy>; + }; + }; + + pcie0_phy: phy@1c04000 { + compatible = "qcom,qcs8300-qmp-gen4x2-pcie-phy"; + reg = <0x0 0x01c04000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_0_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_CLKREF_EN>, + <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_0_PIPE_CLK>, + <&gcc GCC_PCIE_0_PIPEDIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "phy"; + + assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + #clock-cells = <0>; + clock-output-names = "pcie_0_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + ufs_mem_hc: ufs@1d84000 { compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; reg = <0x0 0x01d84000 0x0 0x3000>; From 91d5a9f6f06c6e6290d3c4314322f7e6a6843384 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 28 Nov 2025 18:49:25 +0800 Subject: [PATCH 198/659] FROMLIST: arm64: dts: qcom: qcs8300-ride: enable pcie0 interface Add configurations in devicetree for PCIe0, board related gpios, PMIC regulators, etc for qcs8300-ride board. Link: https://lore.kernel.org/r/20251128104928.4070050-4-ziyue.zhang@oss.qualcomm.com Reviewed-by: Manivannan Sadhasivam Reviewed-by: Konrad Dybcio Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 4a8ac26846c6e..ea9c6acf9e855 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -353,6 +353,25 @@ status = "okay"; }; +&pcie0 { + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcieport0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l6a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + &qupv3_id_0 { status = "okay"; }; @@ -419,6 +438,29 @@ function = "edp0_hot"; bias-disable; }; + + pcie0_default_state: pcie0-default-state { + wake-pins { + pins = "gpio0"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio1"; + function = "pcie0_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio2"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; }; &uart7 { From a3c6938031400479760d216acd0629a383a87042 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 28 Nov 2025 18:49:26 +0800 Subject: [PATCH 199/659] FROMLIST: arm64: dts: qcom: qcs8300: enable pcie1 Add configurations in devicetree for PCIe1, including registers, clocks, interrupts and phy setting sequence. Add PCIe lane equalization preset properties for 8 GT/s and 16GT/s. Link: https://lore.kernel.org/r/20251128104928.4070050-5-ziyue.zhang@oss.qualcomm.com Acked-by: Konrad Dybcio Reviewed-by: Manivannan Sadhasivam Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/monaco.dtsi | 193 ++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 5076e09a746dd..6f7deb52d16c7 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -910,7 +910,7 @@ clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, <&pcie0_phy>, - <0>, + <&pcie1_phy>, <0>, <0>, <0>, @@ -2440,6 +2440,197 @@ status = "disabled"; }; + pcie1: pci@1c10000 { + device_type = "pci"; + compatible = "qcom,pcie-qcs8300", "qcom,pcie-sa8775p"; + reg = <0x0 0x01c10000 0x0 0x3000>, + <0x0 0x60000000 0x0 0xf20>, + <0x0 0x60000f20 0x0 0xa8>, + <0x0 0x60001000 0x0 0x4000>, + <0x0 0x60100000 0x0 0x100000>, + <0x0 0x01c13000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>, + <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x1fd00000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <1>; + num-lanes = <4>; + + 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 GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_1_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_1_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + + assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_anoc MASTER_PCIE_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_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + iommu-map = <0x0 &pcie_smmu 0x0080 0x1>, + <0x100 &pcie_smmu 0x0081 0x1>; + + resets = <&gcc GCC_PCIE_1_BCR>, + <&gcc GCC_PCIE_1_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_1_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>; + + operating-points-v2 = <&pcie1_opp_table>; + + status = "disabled"; + + pcie1_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <250000 1>; + }; + + /* GEN 1 x2 and GEN 2 x1 */ + opp-5000000 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <500000 1>; + }; + + /* GEN 1 x4 and GEN 2 x2 */ + opp-10000000 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <1000000 1>; + }; + + /* GEN 2 x4 */ + opp-20000000 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + }; + + /* GEN 3 x1 */ + opp-8000000 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <984500 1>; + }; + + /* GEN 3 x2 and GEN 4 x1 */ + opp-16000000 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <1969000 1>; + }; + + /* GEN 3 x4 and GEN 4 x2 */ + opp-32000000 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + }; + + /* GEN 4 x4 */ + opp-64000000 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + }; + }; + + pcieport1: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + phys = <&pcie1_phy>; + }; + }; + + pcie1_phy: phy@1c14000 { + compatible = "qcom,sa8775p-qmp-gen4x4-pcie-phy"; + reg = <0x0 0x01c14000 0x0 0x4000>; + + clocks = <&gcc GCC_PCIE_1_PHY_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_CLKREF_EN>, + <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_1_PIPE_CLK>, + <&gcc GCC_PCIE_1_PIPEDIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + resets = <&gcc GCC_PCIE_1_PHY_BCR>; + reset-names = "phy"; + + #clock-cells = <0>; + clock-output-names = "pcie_1_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + ufs_mem_hc: ufs@1d84000 { compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; reg = <0x0 0x01d84000 0x0 0x3000>; From 8ab5f37d4d57ea91a8422b519e7499e1b685018e Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 28 Nov 2025 18:49:27 +0800 Subject: [PATCH 200/659] FROMLIST: arm64: dts: qcom: qcs8300-ride: enable pcie1 interface Add configurations in devicetree for PCIe1, board related gpios, PMIC regulators, etc for qcs8300-ride platform. Link: https://lore.kernel.org/r/20251128104928.4070050-6-ziyue.zhang@oss.qualcomm.com Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index ea9c6acf9e855..4ca3bba163c82 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -372,6 +372,25 @@ status = "okay"; }; +&pcie1 { + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcieport1 { + reset-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l6a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + &qupv3_id_0 { status = "okay"; }; @@ -461,6 +480,29 @@ bias-pull-down; }; }; + + pcie1_default_state: pcie1-default-state { + wake-pins { + pins = "gpio21"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio22"; + function = "pcie1_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio23"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; }; &uart7 { From aece6423621ad2cc2eed565f74e317f81efce271 Mon Sep 17 00:00:00 2001 From: Sushrut Shree Trivedi Date: Fri, 28 Nov 2025 18:49:28 +0800 Subject: [PATCH 201/659] FROMLIST: arm64: dts: qcom: monaco-evk: Enable PCIe0 and PCIe1. PCIe0 is routed to an m.2 E key connector on the mainboard for wifi attaches while PCIe1 routes to a standard PCIe x4 expansion slot. Hence, enable the PCIe0 and PCIe1 controller and phy-nodes. Link: https://lore.kernel.org/r/20251128104928.4070050-7-ziyue.zhang@oss.qualcomm.com Signed-off-by: Sushrut Shree Trivedi Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 85 +++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index b1d34c1248d36..05ba655b1f9e7 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -410,6 +410,44 @@ status = "okay"; }; +&pcie0 { + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l6a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&pcie1 { + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l6a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&pcieport0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; +}; + +&pcieport1 { + reset-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; +}; + &qupv3_id_0 { firmware-name = "qcom/qcs8300/qupv3fw.elf"; status = "okay"; @@ -445,6 +483,30 @@ }; &tlmm { + + pcie0_default_state: pcie0-default-state { + wake-pins { + pins = "gpio0"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio1"; + function = "pcie0_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio2"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + ethernet0_default: ethernet0-default-state { ethernet0_mdc: ethernet0-mdc-pins { pins = "gpio5"; @@ -468,6 +530,29 @@ bias-pull-up; }; + pcie1_default_state: pcie1-default-state { + wake-pins { + pins = "gpio21"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio22"; + function = "pcie1_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio23"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + qup_i2c15_default: qup-i2c15-state { pins = "gpio91", "gpio92"; function = "qup1_se7"; From c8be94943b1617096538fb399bbe54bfd2412a4a Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Wed, 12 Nov 2025 21:51:47 -0800 Subject: [PATCH 202/659] 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/20251113055148.2729943-1-wei.zhang@oss.qualcomm.com Signed-off-by: Wei Zhang --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 108 ++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 4ca3bba163c82..f73bcf96a1a95 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -45,6 +45,88 @@ enable-active-high; regulator-always-on; }; + + vreg_conn_1p8: vreg-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_pa: vreg-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>; + }; + + 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>; + vddrfa0p95-supply = <&vreg_conn_1p8>; + vddrfa1p3-supply = <&vreg_conn_pa>; + vddrfa1p9-supply = <&vreg_conn_1p8>; + vddpcie1p3-supply = <&vreg_conn_pa>; + vddpcie1p9-supply = <&vreg_conn_1p8>; + + 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 { @@ -391,6 +473,25 @@ status = "okay"; }; +&pcieport0 { + 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"; + }; +}; + &qupv3_id_0 { status = "okay"; }; @@ -503,6 +604,13 @@ bias-pull-down; }; }; + + wlan_en_state: wlan-en-state { + pins = "gpio54"; + function = "gpio"; + bias-pull-up; + output-low; + }; }; &uart7 { From 14a9283c0450e2c7868bcc3e4390e48108b6b69a Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Thu, 13 Nov 2025 18:35:19 +0530 Subject: [PATCH 203/659] 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 05ba655b1f9e7..f4b3dfefb2e57 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -20,6 +20,7 @@ ethernet0 = ðernet0; i2c1 = &i2c1; serial0 = &uart7; + serial1 = &uart2; }; chosen { @@ -86,6 +87,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 { @@ -561,6 +642,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 e713359d144a0f3a84960261fca8d0f2e99005cc Mon Sep 17 00:00:00 2001 From: Khalid Faisal Ansari Date: Sat, 15 Nov 2025 14:45:57 +0530 Subject: [PATCH 204/659] FROMLIST: arm64: dts: qcom: monaco-evk: Enable TPM (ST33) Enable ST33HTPM TPM over SPI10 on the Monaco IoT EVK by adding the required SPI and TPM nodes. Link: https://lore.kernel.org/all/20251114-enable-tpm-monaco-v1-1-4ed566838698@oss.qualcomm.com/ Signed-off-by: Khalid Faisal Ansari --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index f4b3dfefb2e57..f8aabb4913aae 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -563,6 +563,16 @@ status = "okay"; }; +&spi10 { + status = "okay"; + + tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +}; + &tlmm { pcie0_default_state: pcie0-default-state { From d3257a8b8faf18e5ee4907e47b90c04a6d3fab04 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Thu, 13 Nov 2025 12:10:10 +0530 Subject: [PATCH 205/659] 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 | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index f73bcf96a1a95..6608854136994 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 { @@ -83,6 +84,7 @@ vddpcie1p3-supply = <&vreg_conn_pa>; vddpcie1p9-supply = <&vreg_conn_1p8>; + bt-enable-gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>; wlan-enable-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>; regulators { @@ -537,6 +539,13 @@ }; &tlmm { + 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"; @@ -613,6 +622,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 df330cdfceb746ef1fdbb05a5583976f42ee9648 Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Sun, 4 Jan 2026 19:14:41 +0530 Subject: [PATCH 206/659] 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/20260104134442.732876-5-quic_amakhija@quicinc.com Signed-off-by: Ayushi Makhija Reviewed-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/monaco.dtsi | 102 ++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 6f7deb52d16c7..e00010ea0fc3f 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 @@ -5516,9 +5517,18 @@ 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 { @@ -5546,6 +5556,94 @@ }; }; + 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>; + + #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 0x27c>; + 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"; @@ -5673,7 +5771,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 33948586cf66209e3d88c77e44169b9b966bee16 Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Sun, 4 Jan 2026 19:14:42 +0530 Subject: [PATCH 207/659] 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/20260104134442.732876-6-quic_amakhija@quicinc.com Signed-off-by: Ayushi Makhija Reviewed-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 177 ++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 6608854136994..b9d1b9be940f6 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_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; + }; + + 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_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_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_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; + }; + 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>; + }; + }; + }; + regulator-usb2-vbus { compatible = "regulator-fixed"; regulator-name = "USB2_VBUS"; @@ -400,6 +475,73 @@ 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"; @@ -437,6 +579,23 @@ 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>; +}; + &pcie0 { pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -498,6 +657,10 @@ status = "okay"; }; +&qupv3_id_1 { + status = "okay"; +}; + &remoteproc_adsp { firmware-name = "qcom/qcs8300/adsp.mbn"; status = "okay"; @@ -562,6 +725,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 d15812e66056575eba483bb66de29d823ebcdefe Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sun, 28 Dec 2025 19:10:38 +0530 Subject: [PATCH 208/659] 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 f8aabb4913aae..d351195634b91 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -33,6 +33,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>; @@ -408,6 +432,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"; @@ -487,6 +547,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"; }; @@ -529,6 +613,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 e00010ea0fc3f..e6a9af97fdc84 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -6109,6 +6109,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 c1bfb3f8e458a19b681bd97584bdb267554ace8c Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:20 +0530 Subject: [PATCH 209/659] 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 d351195634b91..519bc56824bd8 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -647,7 +647,8 @@ }; &serdes0 { - phy-supply = <&vreg_l4a>; + phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; status = "okay"; }; From be17a45359cc14c81cd991b43d3efea7ab4ce873 Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Mon, 24 Nov 2025 14:55:21 +0530 Subject: [PATCH 210/659] 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 b9d1b9be940f6..34d538e3993ef 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -678,6 +678,8 @@ &serdes0 { phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + status = "okay"; }; From cb64f6779c6d12946a2808ccb37e03b3368976ec Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 27 Nov 2025 17:28:29 +0530 Subject: [PATCH 211/659] 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 34d538e3993ef..9343d13da3339 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -610,7 +610,7 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l6a>; - vdda-pll-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l4a>; status = "okay"; }; From 16a51418c7f23332e4cc631572a82b3112b704e5 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Thu, 4 Dec 2025 09:41:58 +0530 Subject: [PATCH 212/659] FROMLIST: arm64: dts: qcom: monaco-evk: Enable AMC6821 fan controller Enable AMC6821 fan controller for monaco-evk platform and configure pwm polarity as inverted. Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251204041158.2613340-1-gaurav.kohli@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/monaco-evk.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 519bc56824bd8..ace3b3e42d9ef 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include #include @@ -474,6 +475,16 @@ status = "okay"; + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan { + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + eeprom0: eeprom@50 { compatible = "atmel,24c256"; reg = <0x50>; From 3a036576c5827ada3c42ce09b215ad7f32b7a046 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Mon, 8 Dec 2025 17:15:58 +0530 Subject: [PATCH 213/659] FROMLIST: arm64: dts: qcom: monaco: Enable cpufreq cooling devices Add cooling-cells property to the CPU nodes to support cpufreq cooling devices. Signed-off-by: Gaurav Kohli Link: https://lore.kernel.org/r/20251208114558.2343462-1-gaurav.kohli@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/monaco.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index e6a9af97fdc84..4110ca1e373bf 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -56,6 +56,7 @@ power-domain-names = "psci"; capacity-dmips-mhz = <1946>; dynamic-power-coefficient = <472>; + #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY @@ -80,6 +81,7 @@ power-domains = <&cpu_pd1>; power-domain-names = "psci"; capacity-dmips-mhz = <1946>; + #cooling-cells = <2>; dynamic-power-coefficient = <472>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; @@ -105,6 +107,7 @@ power-domains = <&cpu_pd2>; power-domain-names = "psci"; capacity-dmips-mhz = <1946>; + #cooling-cells = <2>; dynamic-power-coefficient = <507>; qcom,freq-domain = <&cpufreq_hw 2>; operating-points-v2 = <&cpu2_opp_table>; @@ -130,6 +133,7 @@ power-domains = <&cpu_pd3>; power-domain-names = "psci"; capacity-dmips-mhz = <1946>; + #cooling-cells = <2>; dynamic-power-coefficient = <507>; qcom,freq-domain = <&cpufreq_hw 2>; operating-points-v2 = <&cpu2_opp_table>; @@ -155,6 +159,7 @@ power-domains = <&cpu_pd4>; power-domain-names = "psci"; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; @@ -180,6 +185,7 @@ power-domains = <&cpu_pd5>; power-domain-names = "psci"; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; @@ -205,6 +211,7 @@ power-domains = <&cpu_pd6>; power-domain-names = "psci"; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; @@ -230,6 +237,7 @@ power-domains = <&cpu_pd7>; power-domain-names = "psci"; capacity-dmips-mhz = <1024>; + #cooling-cells = <2>; dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; From 03de422579b386fbe9a3f6aa4aa6c0d9d1e46424 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 3 Dec 2025 14:13:57 +0530 Subject: [PATCH 214/659] 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 4110ca1e373bf..8caca5ec8473b 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -7441,6 +7441,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; tsens2: thermal-sensor@c251000 { @@ -7819,36 +7827,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 { @@ -7939,36 +7989,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 ec47ebe33b25c41f0d35e0535f30aed25d696719 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 13 Jan 2026 19:00:16 +0530 Subject: [PATCH 215/659] 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 349f31bedfa17..427ad41bb4a52 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 0490d9a6655d559b50d44c009026dfe2351d044f Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 11 Dec 2025 00:32:24 +0530 Subject: [PATCH 216/659] FROMGIT: arm64: dts: qcom: SM8750: Enable CPUFreq support Add the cpucp mailbox, sram and SCMI nodes required to enable the CPUFreq support using the SCMI perf protocol on SM8750 SoCs. Git-commit: deed369e067b8406714154a6678a3e3d9b1c1131 Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git Reviewed-by: Konrad Dybcio Reviewed-by: Sibi Sankar Reviewed-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251211-sm8750-cpufreq-v1-2-394609e8d624@oss.qualcomm.com Signed-off-by: Jagadeesh Kona --- arch/arm64/boot/dts/qcom/sm8750.dtsi | 73 ++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index e0948c1d8404a..c361ee3c34d2c 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -37,8 +37,8 @@ reg = <0x0 0x0>; enable-method = "psci"; next-level-cache = <&l2_0>; - power-domains = <&cpu_pd0>; - power-domain-names = "psci"; + power-domains = <&cpu_pd0>, <&scmi_dvfs 0>; + power-domain-names = "psci", "perf"; l2_0: l2-cache { compatible = "cache"; @@ -53,8 +53,8 @@ reg = <0x0 0x100>; enable-method = "psci"; next-level-cache = <&l2_0>; - power-domains = <&cpu_pd1>; - power-domain-names = "psci"; + power-domains = <&cpu_pd1>, <&scmi_dvfs 0>; + power-domain-names = "psci", "perf"; }; cpu2: cpu@200 { @@ -63,8 +63,8 @@ reg = <0x0 0x200>; enable-method = "psci"; next-level-cache = <&l2_0>; - power-domains = <&cpu_pd2>; - power-domain-names = "psci"; + power-domains = <&cpu_pd2>, <&scmi_dvfs 0>; + power-domain-names = "psci", "perf"; }; cpu3: cpu@300 { @@ -73,8 +73,8 @@ reg = <0x0 0x300>; enable-method = "psci"; next-level-cache = <&l2_0>; - power-domains = <&cpu_pd3>; - power-domain-names = "psci"; + power-domains = <&cpu_pd3>, <&scmi_dvfs 0>; + power-domain-names = "psci", "perf"; }; cpu4: cpu@400 { @@ -83,8 +83,8 @@ reg = <0x0 0x400>; enable-method = "psci"; next-level-cache = <&l2_0>; - power-domains = <&cpu_pd4>; - power-domain-names = "psci"; + power-domains = <&cpu_pd4>, <&scmi_dvfs 0>; + power-domain-names = "psci", "perf"; }; cpu5: cpu@500 { @@ -93,8 +93,8 @@ reg = <0x0 0x500>; enable-method = "psci"; next-level-cache = <&l2_0>; - power-domains = <&cpu_pd5>; - power-domain-names = "psci"; + power-domains = <&cpu_pd5>, <&scmi_dvfs 0>; + power-domain-names = "psci", "perf"; }; cpu6: cpu@10000 { @@ -103,8 +103,8 @@ reg = <0x0 0x10000>; enable-method = "psci"; next-level-cache = <&l2_1>; - power-domains = <&cpu_pd6>; - power-domain-names = "psci"; + power-domains = <&cpu_pd6>, <&scmi_dvfs 1>; + power-domain-names = "psci", "perf"; l2_1: l2-cache { compatible = "cache"; @@ -119,8 +119,8 @@ reg = <0x0 0x10100>; enable-method = "psci"; next-level-cache = <&l2_1>; - power-domains = <&cpu_pd7>; - power-domain-names = "psci"; + power-domains = <&cpu_pd7>, <&scmi_dvfs 1>; + power-domain-names = "psci", "perf"; }; cpu-map { @@ -208,6 +208,21 @@ interconnects = <&aggre2_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; }; + + scmi { + compatible = "arm,scmi"; + mboxes = <&cpucp_mbox 0>, <&cpucp_mbox 2>; + mbox-names = "tx", "rx"; + shmem = <&cpu_scp_lpri0>, <&cpu_scp_lpri1>; + + #address-cells = <1>; + #size-cells = <0>; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + }; }; clk_virt: interconnect-0 { @@ -4874,6 +4889,13 @@ }; }; + cpucp_mbox: mailbox@16430000 { + compatible = "qcom,sm8750-cpucp-mbox", "qcom,x1e80100-cpucp-mbox"; + reg = <0x0 0x16430000 0x0 0x8000>, <0x0 0x17830000 0x0 0x8000>; + interrupts = ; + #mbox-cells = <1>; + }; + apps_rsc: rsc@16500000 { compatible = "qcom,rpmh-rsc"; reg = <0x0 0x16500000 0x0 0x10000>, @@ -5085,6 +5107,25 @@ }; }; + sram: sram@17b4e000 { + compatible = "mmio-sram"; + reg = <0x0 0x17b4e000 0x0 0x400>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x17b4e000 0x400>; + + cpu_scp_lpri0: scp-sram-section@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x200>; + }; + + cpu_scp_lpri1: scp-sram-section@200 { + compatible = "arm,scmi-shmem"; + reg = <0x200 0x200>; + }; + }; + /* cluster0 */ pmu@240b3400 { compatible = "qcom,sm8750-cpu-bwmon", "qcom,sdm845-bwmon"; From 5eed6874c406ee02b2ed80768edd7669d5db1f1f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Jan 2026 16:30:22 +0530 Subject: [PATCH 217/659] 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. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/all/20251216-sm8750-display-dts-v3-1-3889ace2ff0b@oss.qualcomm.com/ Signed-off-by: Yash Gupta --- 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 c361ee3c34d2c..c2e9da995f440 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 @@ -2945,6 +2947,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 b4ebc9f3e60b3d902dd05f7921b249709318caa1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 16 Dec 2025 17:47:32 +0100 Subject: [PATCH 218/659] FROMLIST: arm64: dts: qcom: sm8750-mtp: Enable display Enable display on MTP8750 board with Novatek NT37801 panel. Reviewed-by: Dmitry Baryshkov Signed-off-by: Krzysztof Kozlowski Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20251216-sm8750-display-dts-v3-2-3889ace2ff0b@oss.qualcomm.com/ Signed-off-by: Yash Gupta --- arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts index d4885a530e689..c3ae85498320f 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_active>; + pinctrl-1 = <&disp0_reset_n_suspend>, <&mdp_vsync_suspend>; + 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"; @@ -1198,6 +1240,34 @@ }; }; + 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; + }; + + mdp_vsync_active: mdp-vsync-active-state { + pins = "gpio86"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + mdp_vsync_suspend: mdp-vsync-suspend-state { + pins = "gpio86"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + wcd_default: wcd-reset-n-active-state { pins = "gpio101"; function = "gpio"; From 486a41c9cca3b010d1a93f0a3e968d8e13dd3915 Mon Sep 17 00:00:00 2001 From: Charan Teja Kalla Date: Tue, 9 Dec 2025 10:53:23 +0530 Subject: [PATCH 219/659] 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 12fb439bb180b4aa7f0aeb3764e6e051c422daad Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jan 2026 22:54:34 +0530 Subject: [PATCH 220/659] 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 5dd41f82948cc..ee663e3b37f0b 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1474,6 +1474,7 @@ CONFIG_SM_CAMCC_6350=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 @@ -1503,6 +1504,7 @@ CONFIG_SA_VIDEOCC_8775P=m CONFIG_SM_VIDEOCC_6350=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 5a0d33fc64e655fa5a057be7f73c254871b6276f Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Fri, 28 Nov 2025 15:55:07 +0530 Subject: [PATCH 221/659] UPSTREAM: arm64: dts: qcom: lemans-evk: Add OTG support for primary USB controller Enable OTG support for primary USB controller on EVK Platform. Add HD3SS3220 Type-C port controller present between Type-C port and SoC that provides role switch notifications to controller. Signed-off-by: Krishna Kurapati Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20251128102507.3206169-1-krishna.kurapati@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 108 +++++++++++++++++++++++- arch/arm64/boot/dts/qcom/lemans.dtsi | 20 +++++ 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 5d1b1d8c6cfa1..291e2e313f24d 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -39,6 +39,35 @@ stdout-path = "serial0:115200n8"; }; + connector-0 { + compatible = "usb-c-connector"; + label = "USB0-Type-C"; + data-role = "dual"; + power-role = "dual"; + + vbus-supply = <&vbus_supply_regulator_0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb0_con_hs_ep: endpoint { + remote-endpoint = <&usb_0_dwc3_hs>; + }; + }; + port@1 { + reg = <1>; + + usb0_con_ss_ep: endpoint { + remote-endpoint = <&hd3ss3220_in_ep>; + }; + }; + }; + }; + edp0-connector { compatible = "dp-connector"; label = "EDP0"; @@ -103,6 +132,15 @@ }; }; + vbus_supply_regulator_0: regulator-vbus-supply-0 { + compatible = "regulator-fixed"; + regulator-name = "vbus_supply_0"; + gpio = <&expander1 2 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + vmmc_sdc: regulator-vmmc-sdc { compatible = "regulator-fixed"; @@ -543,6 +581,43 @@ firmware-name = "qcom/sa8775p/a663_zap.mbn"; }; +&i2c11 { + status = "okay"; + + usb-typec@67 { + compatible = "ti,hd3ss3220"; + reg = <0x67>; + + interrupts-extended = <&pmm8654au_2_gpios 5 IRQ_TYPE_EDGE_FALLING>; + + id-gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&usb_id>, <&usb0_intr_state>; + pinctrl-names = "default"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hd3ss3220_in_ep: endpoint { + remote-endpoint = <&usb0_con_ss_ep>; + }; + }; + + port@1 { + reg = <1>; + + hd3ss3220_out_ep: endpoint { + remote-endpoint = <&usb_0_dwc3_ss>; + }; + }; + }; + }; +}; + &i2c18 { status = "okay"; @@ -696,6 +771,16 @@ status = "okay"; }; +&pmm8654au_2_gpios { + usb0_intr_state: usb0-intr-state { + pins = "gpio5"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; +}; + &qup_i2c19_default { drive-strength = <2>; bias-pull-up; @@ -846,11 +931,24 @@ }; }; + qup_i2c11_default: qup-i2c11-state { + pins = "gpio48", "gpio49"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up; + }; + sd_cd: sd-cd-state { pins = "gpio36"; function = "gpio"; bias-pull-up; }; + + usb_id: usb-id-state { + pins = "gpio50"; + function = "gpio"; + bias-pull-up; + }; }; &uart10 { @@ -897,11 +995,17 @@ }; &usb_0 { - dr_mode = "peripheral"; - status = "okay"; }; +&usb_0_dwc3_hs { + remote-endpoint = <&usb0_con_hs_ep>; +}; + +&usb_0_dwc3_ss { + remote-endpoint = <&hd3ss3220_out_ep>; +}; + &usb_0_hsphy { vdda-pll-supply = <&vreg_l7a>; vdda18-supply = <&vreg_l6c>; diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index a7aa9f08ce690..a6434095179dc 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -4052,7 +4052,27 @@ snps,dis-u1-entry-quirk; snps,dis-u2-entry-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 { + }; + }; + }; }; usb_1: usb@a800000 { From 7663fa79993dfbdc06ab1b059f3649c6194638d3 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:36 +0530 Subject: [PATCH 222/659] 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. Signed-off-by: Swati Agarwal Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20251220063537.3639535-4-swati.agarwal@oss.qualcomm.com/ --- 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 291e2e313f24d..92298c396fa80 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -62,7 +62,7 @@ reg = <1>; usb0_con_ss_ep: endpoint { - remote-endpoint = <&hd3ss3220_in_ep>; + remote-endpoint = <&hd3ss3220_0_in_ep>; }; }; }; @@ -602,7 +602,7 @@ port@0 { reg = <0>; - hd3ss3220_in_ep: endpoint { + hd3ss3220_0_in_ep: endpoint { remote-endpoint = <&usb0_con_ss_ep>; }; }; @@ -610,7 +610,7 @@ port@1 { reg = <1>; - hd3ss3220_out_ep: endpoint { + hd3ss3220_0_out_ep: endpoint { remote-endpoint = <&usb_0_dwc3_ss>; }; }; @@ -1003,7 +1003,7 @@ }; &usb_0_dwc3_ss { - remote-endpoint = <&hd3ss3220_out_ep>; + remote-endpoint = <&hd3ss3220_0_out_ep>; }; &usb_0_hsphy { From b1701204194caf67048c501eecf79feb0578c65c Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:37 +0530 Subject: [PATCH 223/659] FROMLIST: arm64: dts: qcom: lemans-evk: Enable secondary USB controller in host mode Enable secondary USB controller in host mode on lemans EVK Platform. For secondary USB Typec port, there is a genesys USB HUB GL3590 having 4 ports sitting in between SOC and HD3SS3220 Type-C port controller and SS lines run from the SoC through the hub to the Port controller. Mark the second USB controller as host only capable. Add HD3SS3220 Type-C port controller along with Type-c connector for controlling vbus supply. Signed-off-by: Swati Agarwal Link: https://lore.kernel.org/all/20251220063537.3639535-5-swati.agarwal@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 158 ++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 92298c396fa80..8fb419ea638a5 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -68,6 +68,47 @@ }; }; + connector-1 { + compatible = "usb-c-connector"; + label = "USB1-Type-C"; + data-role = "host"; + power-role = "dual"; + try-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"; @@ -141,6 +182,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"; @@ -616,6 +667,33 @@ }; }; }; + + 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>; + }; + }; + + }; + }; + }; &i2c18 { @@ -779,6 +857,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 { @@ -949,6 +1035,12 @@ function = "gpio"; bias-pull-up; }; + + usb1_id: usb1-id-state { + pins = "gpio51"; + function = "gpio"; + bias-pull-up; + }; }; &uart10 { @@ -1021,6 +1113,72 @@ 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>; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + usb_hub_2_1: endpoint { + remote-endpoint = <&usb1_hs_in>; + }; + }; + + }; + }; + + 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>; + }; + }; + + }; + }; +}; + +&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 be59082d0baeba741083bcad860168042ff6c672 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 15 Dec 2025 01:07:21 -0800 Subject: [PATCH 224/659] FROMLIST: dt-bindings: arm: qcom: Document Kaanapali SoC and its reference boards Document the Kaanapali SoC binding and the boards which use it. Acked-by: Krzysztof Kozlowski Signed-off-by: Jingyi Wang Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251215-knp-dts-v4-1-1541bebeb89f@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 d84bd3bca2010..da287cc9119b5 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -327,6 +327,12 @@ properties: - qcom,ipq9574-ap-al02-c9 - const: qcom,ipq9574 + - items: + - enum: + - qcom,kaanapali-mtp + - qcom,kaanapali-qrd + - const: qcom,kaanapali + - description: Sierra Wireless MangOH Green with WP8548 Module items: - const: swir,mangoh-green-wp8548 From 13bc431393093802e029cc146c280d48f58f64f4 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 15 Dec 2025 01:07:23 -0800 Subject: [PATCH 225/659] FROMLIST: arm64: dts: qcom: Introduce Kaanapali SoC Kaanapali is Snapdragon SoC from Qualcomm. Features added in this patch: - CPUs with PSCI idle states and cpufreq - Interrupt-controller with PDC wakeup support - Timers, TCSR Clock Controllers - Reserved Shared memory - GCC and RPMHCC - TLMM - Interconnect with CPU BWMONs - QuP with UART - SMMU - RPMhPD - UFS with Inline Crypto Engine - LLCC - Watchdog - SD Card - PCIe Written with help from Raviteja Laggyshetty (added interconnect nodes), Taniya Das (added Clock Controllers and cpufreq), Jishnu Prakash (added RPMhPD), Nitin Rawat (added UFS), Gaurav Kashyap (added ICE), Manish Pandey (added SD Card) and Qiang Yu (added PCIe). Co-developed-by: Tengfei Fan Signed-off-by: Tengfei Fan Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251215-knp-dts-v4-3-1541bebeb89f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 1606 +++++++++++++++++++++++ 1 file changed, 1606 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/kaanapali.dtsi diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi new file mode 100644 index 0000000000000..51f8b3e0749c3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -0,0 +1,1606 @@ +// 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 "kaanapali-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"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd0>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 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"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd1>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 0>; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x200>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd2>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 0>; + }; + + cpu3: cpu@300 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x300>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd3>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 0>; + }; + + cpu4: cpu@400 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x400>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd4>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 0>; + }; + + cpu5: cpu@500 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x500>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd5>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 0>; + }; + + cpu6: cpu@10000 { + device_type = "cpu"; + compatible = "qcom,oryon"; + reg = <0x0 0x10000>; + enable-method = "psci"; + next-level-cache = <&l2_1>; + power-domains = <&cpu_pd6>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 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"; + next-level-cache = <&l2_1>; + power-domains = <&cpu_pd7>; + power-domain-names = "psci"; + clocks = <&pdp_scmi_perf 1>; + }; + + 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>; + }; + }; + }; + + idle-states { + entry-method = "psci"; + + cluster0_c4: cpu-sleep-0 { + compatible = "arm,idle-state"; + idle-state-name = "retention"; + arm,psci-suspend-param = <0x00000004>; + entry-latency-us = <93>; + exit-latency-us = <129>; + min-residency-us = <560>; + }; + + cluster1_c4: cpu-sleep-1 { + compatible = "arm,idle-state"; + idle-state-name = "retention"; + arm,psci-suspend-param = <0x00000004>; + entry-latency-us = <172>; + exit-latency-us = <130>; + min-residency-us = <686>; + }; + }; + + domain-idle-states { + cluster_cl5: cluster-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x01000054>; + entry-latency-us = <2150>; + exit-latency-us = <1983>; + min-residency-us = <9144>; + }; + + 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-kaanapali", "qcom,scm"; + qcom,dload-mode = <&tcsr 0x19000>; + interconnects = <&aggre_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + }; + + scmi: scmi { + compatible = "arm,scmi"; + mboxes = <&pdp0_mbox 0>, <&pdp0_mbox 1>; + mbox-names = "tx", "rx"; + shmem = <&pdp_tx>, <&pdp_rx>; + + #address-cells = <1>; + #size-cells = <0>; + + pdp_scmi_perf: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + }; + }; + }; + + clk_virt: interconnect-0 { + compatible = "qcom,kaanapali-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect-1 { + compatible = "qcom,kaanapali-mc-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + memory@a0000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the size */ + reg = <0x0 0xa0000000 0x0 0x0>; + }; + + 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 = <&cluster_pd>; + domain-idle-states = <&cluster0_c4>; + }; + + cpu_pd1: power-domain-cpu1 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_c4>; + }; + + cpu_pd2: power-domain-cpu2 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_c4>; + }; + + cpu_pd3: power-domain-cpu3 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_c4>; + }; + + cpu_pd4: power-domain-cpu4 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_c4>; + }; + + cpu_pd5: power-domain-cpu5 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_c4>; + }; + + cpu_pd6: power-domain-cpu6 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster1_c4>; + }; + + cpu_pd7: power-domain-cpu7 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster1_c4>; + }; + + cluster_pd: power-domain-cluster { + #power-domain-cells = <0>; + domain-idle-states = <&cluster_cl5>; + power-domains = <&system_pd>; + }; + + 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@81300000 { + reg = <0x0 0x81300000 0x0 0x100000>; + no-map; + }; + + aop_cmd_db_mem: aop-cmd-db@81c60000 { + compatible = "qcom,cmd-db"; + reg = <0x0 0x81c60000 0x0 0x20000>; + no-map; + }; + + smem_mem: smem@81d00000 { + compatible = "qcom,smem"; + reg = <0x0 0x81d00000 0x0 0x200000>; + hwlocks = <&tcsr_mutex 3>; + no-map; + }; + + pdp_ns_shared_mem: pdp-ns-shared@81f00000 { + reg = <0x0 0x81f00000 0x0 0x100000>; + no-map; + }; + + dsm_partition_1_mem: dsm-partition-1@84a00000 { + reg = <0x0 0x84a00000 0x0 0x5500000>; + no-map; + }; + + dsm_partition_2_mem: dsm-partition-2@89f00000 { + reg = <0x0 0x89f00000 0x0 0xa80000>; + no-map; + }; + + mpss_mem: mpss@8aa00000 { + reg = <0x0 0x8aa00000 0x0 0xeb00000>; + no-map; + }; + + q6_mpss_dtb_mem: q6-mpss-dtb@99500000 { + reg = <0x0 0x99500000 0x0 0x80000>; + no-map; + }; + + ipa_fw_mem: ipa-fw@99580000 { + reg = <0x0 0x99580000 0x0 0x10000>; + no-map; + }; + + ipa_gsi_mem: ipa-gsi@99590000 { + reg = <0x0 0x99590000 0x0 0xa000>; + no-map; + }; + + gpu_microcode_mem: gpu-microcode@9959a000 { + reg = <0x0 0x9959a000 0x0 0x2000>; + no-map; + }; + + camera_mem: camera@99600000 { + reg = <0x0 0x99600000 0x0 0x800000>; + no-map; + }; + + camera_2_mem: camera-2@99e00000 { + reg = <0x0 0x99e00000 0x0 0x800000>; + no-map; + }; + + video_mem: video@9a600000 { + reg = <0x0 0x9a600000 0x0 0x800000>; + no-map; + }; + + cvp_mem: cvp@9ae00000 { + reg = <0x0 0x9ae00000 0x0 0x700000>; + no-map; + }; + + cdsp_mem: cdsp@9b500000 { + reg = <0x0 0x9b500000 0x0 0x1900000>; + no-map; + }; + + q6_cdsp_dtb_mem: q6-cdsp-dtb@9ce00000 { + reg = <0x0 0x9ce00000 0x0 0x80000>; + no-map; + }; + + soccp_mem: soccp@a03d0000 { + reg = <0x0 0xa03d0000 0x0 0x500000>; + no-map; + }; + + soccp_dtb_mem: soccp-dtb@a08d0000 { + reg = <0x0 0xa08d0000 0x0 0x40000>; + no-map; + }; + + q6_adsp_dtb_mem: q6-adsp-dtb@a1380000 { + reg = <0x0 0xa1380000 0x0 0x80000>; + no-map; + }; + + adspslpi_mem: adspslpi@a1400000 { + reg = <0x0 0xa1400000 0x0 0x4c00000>; + no-map; + }; + + rmtfs_mem: rmtfs@d7c00000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0xd7c00000 0x0 0x400000>; + no-map; + + qcom,client-id = <1>; + qcom,vmid = ; + }; + }; + + soc: soc@0 { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + + gcc: clock-controller@100000 { + compatible = "qcom,kaanapali-gcc"; + reg = <0x0 0x00100000 0x0 0x1f4200>; + + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>, + <&pcie0_phy>, + <&ufs_mem_phy 0>, + <&ufs_mem_phy 1>, + <&ufs_mem_phy 2>, + <0>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + 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"; + + iommus = <&apps_smmu 0xa3 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + 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>; + }; + + pcie0: pcie@1c00000 { + device_type = "pci"; + compatible = "qcom,kaanapali-pcie", "qcom,pcie-sm8550"; + reg = <0x0 0x01c00000 0x0 0x3000>, + <0x0 0x40000000 0x0 0xf1d>, + <0x0 0x40000f20 0x0 0xa8>, + <0x0 0x40001000 0x0 0x1000>, + <0x0 0x40100000 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 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x23d00000>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + clocks = <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>, + <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "ddrss_sf_tbu", + "noc_aggr", + "cnoc_sf_axi"; + + resets = <&gcc GCC_PCIE_0_BCR>, + <&gcc GCC_PCIE_0_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + interconnects = <&pcie_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &cnoc_main SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + power-domains = <&gcc GCC_PCIE_0_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; + + operating-points-v2 = <&pcie0_opp_table>; + + iommu-map = <0 &apps_smmu 0x1400 0x1>, + <0x100 &apps_smmu 0x1401 0x1>; + + interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0 0 0 0x7>; + #interrupt-cells = <1>; + + msi-map = <0x0 &gic_its 0x1400 0x1>, + <0x100 &gic_its 0x1401 0x1>; + msi-map-mask = <0xff00>; + max-link-speed = <3>; + linux,pci-domain = <0>; + num-lanes = <2>; + bus-range = <0x00 0xff>; + + dma-coherent; + + status = "disabled"; + + pcie0_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + }; + + /* GEN 1 x2 and GEN 2 x1 */ + opp-5000000 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + }; + + /* GEN 2 x2 */ + opp-10000000 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + }; + + /* GEN 3 x1 */ + opp-8000000 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <984500 1>; + }; + + /* GEN 3 x2 */ + opp-16000000 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <1969000 1>; + }; + }; + + pcie_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + phys = <&pcie0_phy>; + }; + }; + + pcie0_phy: phy@1c06000 { + compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy"; + reg = <0x0 0x01c06000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_0_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_0_CLKREF_EN>, + <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_0_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe"; + + assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>, + <&gcc GCC_PCIE_0_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie0_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + ufs_mem_phy: phy@1d80000 { + compatible = "qcom,kaanapali-qmp-ufs-phy", "qcom,sm8750-qmp-ufs-phy"; + reg = <0x0 0x01d80000 0x0 0x2000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>, + <&tcsr TCSR_UFS_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: ufs@1d84000 { + compatible = "qcom,kaanapali-ufshc", + "qcom,ufshc", + "jedec,ufs-2.0"; + 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 = <&aggre_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 0x60 0x0>; + dma-coherent; + + lanes-per-direction = <2>; + qcom,ice = <&ice>; + + 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_d1>; + }; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <100000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-403000000 { + opp-hz = /bits/ 64 <403000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <403000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + ice: crypto@1d88000 { + compatible = "qcom,kaanapali-inline-crypto-engine", + "qcom,inline-crypto-engine"; + reg = <0x0 0x01d88000 0x0 0x18000>; + + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + }; + + tcsr_mutex: hwlock@1f40000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x0 0x01f40000 0x0 0x20000>; + #hwlock-cells = <1>; + }; + + tcsr: clock-controller@1fc0000 { + compatible = "qcom,kaanapali-tcsr", "syscon"; + reg = <0x0 0x01fc0000 0x0 0x30000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + + lpass_lpiaon_noc: interconnect@7400000 { + compatible = "qcom,kaanapali-lpass-lpiaon-noc"; + reg = <0x0 0x07400000 0x0 0x19080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + lpass_lpicx_noc: interconnect@7420000 { + compatible = "qcom,kaanapali-lpass-lpicx-noc"; + reg = <0x0 0x07420000 0x0 0x44080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + lpass_ag_noc: interconnect@7f40000 { + compatible = "qcom,kaanapali-lpass-ag-noc"; + reg = <0x0 0x07f40000 0x0 0xe080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + sdhc_2: mmc@8804000 { + compatible = "qcom,kaanapali-sdhci", "qcom,sdhci-msm-v5"; + reg = <0x0 0x08804000 0x0 0x1000>; + + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", "core", "xo"; + + interconnects = <&aggre_noc MASTER_SDCC_2 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_SDCC_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "sdhc-ddr", "cpu-sdhc"; + + power-domains = <&rpmhpd RPMHPD_CX>; + operating-points-v2 = <&sdhc2_opp_table>; + + qcom,dll-config = <0x0007442c>; + qcom,ddr-config = <0x80040868>; + + iommus = <&apps_smmu 0x540 0x0>; + dma-coherent; + + resets = <&gcc GCC_SDCC2_BCR>; + status = "disabled"; + + sdhc2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-peak-kBps = <160000 100000>; + opp-avg-kBps = <50000 0>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-202000000 { + opp-hz = /bits/ 64 <202000000>; + opp-peak-kBps = <200000 120000>; + opp-avg-kBps = <104000 0>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + pdc: interrupt-controller@b220000 { + compatible = "qcom,kaanapali-pdc", "qcom,pdc"; + reg = <0x0 0x0b220000 0x0 0x10000>, + <0x0 0x179600f0 0x0 0xf4>; + + qcom,pdc-ranges = <0 745 38>, + <40 785 11>, + <51 527 4>, + <58 534 2>, + <61 537 20>, + <84 559 14>, + <98 609 32>, + <130 717 12>, + <142 251 5>, + <147 796 16>, + <163 783 2>, + <165 531 2>, + <167 536 1>, + <168 557 2>, + <170 415 1>, + <171 438 1>, + <172 579 1>, + <173 703 1>, + <174 708 1>, + <175 714 1>, + <176 68 1>, + <177 86 1>, + <178 96 1>, + <179 249 1>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; + }; + + aoss_qmp: power-management@c300000 { + compatible = "qcom,kaanapali-aoss-qmp", "qcom,aoss-qmp"; + reg = <0x0 0x0c300000 0x0 0x400>; + + 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>; + }; + + tlmm: pinctrl@f100000 { + compatible = "qcom,kaanapali-tlmm"; + reg = <0x0 0x0f100000 0x0 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 218>; + interrupt-controller; + #interrupt-cells = <2>; + wakeup-parent = <&pdc>; + + qup_uart7_default: qup-uart7-state { + /* TX, RX */ + pins = "gpio62", "gpio63"; + function = "qup1_se7"; + drive-strength = <2>; + bias-disable; + }; + + sdc2_default: sdc2-default-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <16>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <10>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <10>; + bias-pull-up; + }; + + card-detect-pins { + pins = "gpio55"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + sdc2_sleep: sdc2-sleep-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <2>; + bias-pull-up; + }; + + card-detect-pins { + pins = "gpio55"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + sram@14680000 { + compatible = "qcom,kaanapali-imem", "mmio-sram"; + reg = <0x0 0x14680000 0x0 0x1000>; + ranges = <0x0 0x0 0x14680000 0x1000>; + + no-memory-wc; + + #address-cells = <1>; + #size-cells = <1>; + + pil-sram@94c { + compatible = "qcom,pil-reloc-info"; + reg = <0x94c 0xc8>; + }; + }; + + apps_smmu: iommu@15000000 { + compatible = "qcom,kaanapali-smmu-500", "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x15000000 0x0 0x100000>; + + interrupts =, + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + + #iommu-cells = <2>; + #global-interrupts = <1>; + + dma-coherent; + }; + + intc: interrupt-controller@17000000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x17000000 0x0 0x10000>, + <0x0 0x17080000 0x0 0x200000>; + + interrupts = ; + + #interrupt-cells = <3>; + interrupt-controller; + + #redistributor-regions = <1>; + redistributor-stride = <0x0 0x40000>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic_its: msi-controller@17040000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x17040000 0x0 0x20000>; + + msi-controller; + #msi-cells = <1>; + }; + }; + + watchdog@17600000 { + compatible = "qcom,apss-wdt-kaanapali", "qcom,kpss-wdt"; + reg = <0x0 0x17600000 0x0 0x1000>; + clocks = <&sleep_clk>; + interrupts = ; + }; + + pdp0_mbox: mailbox@17610000 { + compatible = "qcom,kaanapali-cpucp-mbox", "qcom,x1e80100-cpucp-mbox"; + reg = <0x0 0x17610000 0x0 0x8000>, <0x0 0x19980000 0x0 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>; + frame-number = <0>; + interrupts = , + ; + }; + + frame@17813000 { + reg = <0x0 0x17813000 0x1000>; + frame-number = <1>; + interrupts = ; + status = "disabled"; + }; + + frame@17815000 { + reg = <0x0 0x17815000 0x1000>; + frame-number = <2>; + interrupts = ; + status = "disabled"; + }; + + frame@17817000 { + reg = <0x0 0x17817000 0x1000>; + frame-number = <3>; + interrupts = ; + status = "disabled"; + }; + + frame@17819000 { + reg = <0x0 0x17819000 0x1000>; + frame-number = <4>; + interrupts = ; + status = "disabled"; + }; + + frame@1781b000 { + reg = <0x0 0x1781b000 0x1000>; + frame-number = <5>; + interrupts = ; + status = "disabled"; + }; + + frame@1781d000 { + reg = <0x0 0x1781d000 0x1000>; + frame-number = <6>; + interrupts = ; + status = "disabled"; + }; + }; + + apps_rsc: rsc@18900000 { + compatible = "qcom,rpmh-rsc"; + reg = <0x0 0x18900000 0x0 0x10000>, + <0x0 0x18910000 0x0 0x10000>, + <0x0 0x18920000 0x0 0x10000>; + reg-names = "drv-0", + "drv-1", + "drv-2"; + interrupts = , + , + ; + + power-domains = <&system_pd>; + label = "apps_rsc"; + + qcom,tcs-offset = <0xd00>; + qcom,drv-id = <2>; + qcom,tcs-config = , + , + , + ; + + apps_bcm_voter: bcm-voter { + compatible = "qcom,bcm-voter"; + }; + + rpmhcc: clock-controller { + compatible = "qcom,kaanapali-rpmh-clk"; + #clock-cells = <1>; + clocks = <&xo_board>; + clock-names = "xo"; + }; + + rpmhpd: power-controller { + compatible = "qcom,kaanapali-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_low_svs_d3: opp-50 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_d2_1: opp-51 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_d2: opp-52 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_d1_1: opp-54 { + 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_l0: opp-76 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_l1: opp-80 { + opp-level = ; + }; + + rpmhpd_opp_low_svs_l2: opp-96 { + 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_svs_l2: opp-224 { + 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_l0: opp-400 { + opp-level = ; + }; + + rpmhpd_opp_turbo_l1: opp-416 { + opp-level = ; + }; + + rpmhpd_opp_turbo_l2: opp-432 { + opp-level = ; + }; + + rpmhpd_opp_turbo_l3: opp-448 { + opp-level = ; + }; + + rpmhpd_opp_turbo_l4: opp-452 { + opp-level = ; + }; + + rpmhpd_opp_turbo_l5: opp-456 { + opp-level = ; + }; + + rpmhpd_opp_super_turbo_no_cpr: opp-480 { + opp-level = ; + }; + }; + }; + }; + + nsp_noc: interconnect@260c0000 { + compatible = "qcom,kaanapali-nsp-noc"; + reg = <0x0 0x260c0000 0x0 0x21280>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + /* Cluster 0 */ + pmu@310b3400 { + compatible = "qcom,kaanapali-cpu-bwmon", "qcom,sdm845-bwmon"; + reg = <0x0 0x310b3400 0x0 0x600>; + + interrupts = ; + + interconnects = <&gem_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 = <2188000>; + }; + + opp-1 { + opp-peak-kBps = <5412000>; + }; + + opp-2 { + opp-peak-kBps = <6220000>; + }; + + opp-3 { + opp-peak-kBps = <6832000>; + }; + + opp-4 { + opp-peak-kBps = <8368000>; + }; + + opp-5 { + opp-peak-kBps = <10944000>; + }; + + opp-6 { + opp-peak-kBps = <12748000>; + }; + + opp-7 { + opp-peak-kBps = <14744000>; + }; + + opp-8 { + opp-peak-kBps = <16896000>; + }; + + opp-9 { + opp-peak-kBps = <19120000>; + }; + + opp-10 { + opp-peak-kBps = <21332000>; + }; + }; + }; + + /* Cluster 1 */ + pmu@310b7400 { + compatible = "qcom,kaanapali-cpu-bwmon", "qcom,sdm845-bwmon"; + reg = <0x0 0x310b7400 0x0 0x600>; + + interrupts = ; + + interconnects = <&gem_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>; + }; + + gem_noc: interconnect@31100000 { + compatible = "qcom,kaanapali-gem-noc"; + reg = <0x0 0x31100000 0x0 0x153080>; + qcom,bcm-voters = <&apps_bcm_voter>; + #interconnect-cells = <2>; + }; + + system-cache-controller@31800000 { + compatible = "qcom,kaanapali-llcc"; + reg = <0x0 0x31800000 0x0 0x200000>, + <0x0 0x32800000 0x0 0x200000>, + <0x0 0x31c00000 0x0 0x200000>, + <0x0 0x32c00000 0x0 0x200000>, + <0x0 0x34800000 0x0 0x200000>, + <0x0 0x34c00000 0x0 0x200000>; + reg-names = "llcc0_base", + "llcc1_base", + "llcc2_base", + "llcc3_base", + "llcc_broadcast_base", + "llcc_broadcast_and_base"; + + interrupts = ; + }; + + sram: sram@81f08000 { + compatible = "mmio-sram"; + reg = <0x0 0x81f08000 0x0 0x200>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x81f08000 0x200>; + + pdp_rx: scp-sram-section@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x80>; + }; + + pdp_tx: scp-sram-section@100 { + compatible = "arm,scmi-shmem"; + reg = <0x100 0x80>; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + + interrupts = , + , + , + ; + }; +}; From 9d3f20989caaf524e71c2e9aa1dc93b819c35c7a Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 15 Dec 2025 01:07:24 -0800 Subject: [PATCH 226/659] FROMLIST: arm64: dts: qcom: kaanapali: Add base MTP board Add initial support for Qualcomm Kaanapali MTP board which enables PCIe, SD Card, UFS and booting to shell with UART console. Written with help from Jishnu Prakash (added RPMhPD nodes), Nitin Rawat (added UFS), Manish Pandey (added SD Card) and Qiang Yu (added PCIe). Reviewed-by: Dmitry Baryshkov Signed-off-by: Jingyi Wang Reviewed-by: Abel Vesa Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251215-knp-dts-v4-4-1541bebeb89f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/kaanapali-mtp.dts | 754 +++++++++++++++++++++ 2 files changed, 755 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/kaanapali-mtp.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 6f34d5ed331c4..ac6c0178aae4b 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -30,6 +30,7 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp433.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp449.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp453.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb +dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb lemans-evk-camera-csi1-imx577-dtbs := lemans-evk.dtb lemans-evk-camera-csi1-imx577.dtbo diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts new file mode 100644 index 0000000000000..32a0825984346 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts @@ -0,0 +1,754 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include +#include "kaanapali.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. Kaanapali MTP"; + compatible = "qcom,kaanapali-mtp", "qcom,kaanapali"; + chassis-type = "handset"; + + aliases { + serial0 = &uart7; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <76800000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32764>; + #clock-cells = <0>; + }; + + bi_tcxo_div2: bi-tcxo-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-mult = <1>; + clock-div = <2>; + }; + + bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK_A>; + clock-mult = <1>; + clock-div = <2>; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <4000000>; + regulator-initial-mode = ; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <3552000>; + regulator-initial-mode = ; + }; + + vreg_l1b_1p8: ldo1 { + regulator-name = "vreg_l1b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3048000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4b_1p8: ldo4 { + regulator-name = "vreg_l4b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3148000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7b_1p8: ldo7 { + regulator-name = "vreg_l7b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8b_1p8: ldo8 { + regulator-name = "vreg_l8b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l11b_1p0: ldo11 { + regulator-name = "vreg_l11b_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1292000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l12b_1p8: ldo12 { + regulator-name = "vreg_l12b_1p8"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l14b_3p2: ldo14 { + regulator-name = "vreg_l14b_3p2"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l18b_1p2: ldo18 { + regulator-name = "vreg_l18b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-1 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "D_E0"; + + vreg_s10d_1p0: smps10 { + regulator-name = "vreg_s10d_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_l1d_1p2: ldo1 { + regulator-name = "vreg_l1d_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1256000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2d_0p9: ldo2 { + regulator-name = "vreg_l2d_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <958000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3d_0p8: ldo3 { + regulator-name = "vreg_l3d_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4d_1p2: ldo4 { + regulator-name = "vreg_l4d_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s6f_0p5: smps6 { + regulator-name = "vreg_s6f_0p5"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <570000>; + regulator-initial-mode = ; + }; + + vreg_s7f_1p2: smps7 { + regulator-name = "vreg_s7f_1p2"; + regulator-min-microvolt = <1224000>; + regulator-max-microvolt = <1372000>; + regulator-initial-mode = ; + }; + + vreg_s8f_1p8: smps8 { + regulator-name = "vreg_s8f_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + }; + + vreg_l1f_1p2: ldo1 { + regulator-name = "vreg_l1f_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2f_1p2: ldo2 { + regulator-name = "vreg_l2f_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3f_0p8: ldo3 { + regulator-name = "vreg_l3f_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4f_0p8: ldo4 { + regulator-name = "vreg_l4f_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "G_E0"; + + vreg_s7g_0p9: smps7 { + regulator-name = "vreg_s7g_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_s9g_1p0: smps9 { + regulator-name = "vreg_s9g_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_l1g_1p2: ldo1 { + regulator-name = "vreg_l1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2g_1p8: ldo2 { + regulator-name = "vreg_l2g_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3g_1p2: ldo3 { + regulator-name = "vreg_l3g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4g_0p9: ldo4 { + regulator-name = "vreg_l4g_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "I_E0"; + + vreg_s7i_0p9: smps7 { + regulator-name = "vreg_s7i_0p9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <972000>; + regulator-initial-mode = ; + }; + + vreg_l2i_1p2: ldo2 { + regulator-name = "vreg_l2i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3i_0p8: ldo3 { + regulator-name = "vreg_l3i_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-5 { + compatible = "qcom,pmh0104-rpmh-regulators"; + qcom,pmic-id = "J_E1"; + + vreg_s1j_0p8: smps1 { + regulator-name = "vreg_s1j_0p8"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + }; + + vreg_s2j_0p8: smps2 { + regulator-name = "vreg_s2j_0p8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_s3j_1p2: smps3 { + regulator-name = "vreg_s3j_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = ; + }; + + vreg_s4j_0p7: smps4 { + regulator-name = "vreg_s4j_0p7"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + }; + }; + + regulators-6 { + compatible = "qcom,pmr735d-rpmh-regulators"; + qcom,pmic-id = "K_E1"; + + vreg_l1k_0p8: ldo1 { + regulator-name = "vreg_l1k_0p8"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2k_0p7: ldo2 { + regulator-name = "vreg_l2k_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3k_1p2: ldo3 { + regulator-name = "vreg_l3k_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4k_1p0: ldo4 { + regulator-name = "vreg_l4k_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5k_0p7: ldo5 { + regulator-name = "vreg_l5k_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6k_1p7: ldo6 { + regulator-name = "vreg_l6k_1p7"; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7k_0p7: ldo7 { + regulator-name = "vreg_l7k_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <848000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-7 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "M_E1"; + + vreg_l1m_1p0: ldo1 { + regulator-name = "vreg_l1m_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2m_1p0: ldo2 { + regulator-name = "vreg_l2m_1p0"; + regulator-min-microvolt = <1096000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3m_2p8: ldo3 { + regulator-name = "vreg_l3m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2900000>; + regulator-initial-mode = ; + }; + + vreg_l4m_2p2: ldo4 { + regulator-name = "vreg_l4m_2p2"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <2200000>; + regulator-initial-mode = ; + }; + + vreg_l6m_2p8: ldo6 { + regulator-name = "vreg_l6m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l7m_2p8: ldo7 { + regulator-name = "vreg_l7m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + }; + + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "N_E1"; + + vreg_l1n_1p1: ldo1 { + regulator-name = "vreg_l1n_1p1"; + regulator-min-microvolt = <1096000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2n_1p2: ldo2 { + regulator-name = "vreg_l2n_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3n_1p8: ldo3 { + regulator-name = "vreg_l3n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l4n_1p8: ldo4 { + regulator-name = "vreg_l4n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l5n_2p8: ldo5 { + regulator-name = "vreg_l5n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l6n_2p8: ldo6 { + regulator-name = "vreg_l6n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l7n_3p3: ldo7 { + regulator-name = "vreg_l7n_3p3"; + regulator-min-microvolt = <3304000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = ; + }; + }; +}; + +&pcie0 { + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l1d_1p2>; + + status = "okay"; +}; + +&pcie_port0 { + wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l9b_2p9>; + vqmmc-supply = <&vreg_l8b_1p8>; + + bus-width = <4>; + no-sdio; + no-mmc; + + pinctrl-0 = <&sdc2_default>; + pinctrl-1 = <&sdc2_sleep>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <36 4>, /* NFC eSE SPI */ + <74 1>, /* eSE */ + <119 2>, /* SoCCP */ + <144 4>; /* CXM UART */ + + pcie0_default_state: pcie0-default-state { + perst-n-pins { + pins = "gpio102"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + clkreq-n-pins { + pins = "gpio103"; + function = "pcie0_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-n-pins { + pins = "gpio104"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; +}; + +&uart7 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 217 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1200000>; + vccq-supply = <&vreg_l4d_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l4g_0p9>; + vdda-pll-supply = <&vreg_l1d_1p2>; + + status = "okay"; +}; From e33cd62f26bcef387dd881ab85bea5491286dd4e Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 15 Dec 2025 01:07:25 -0800 Subject: [PATCH 227/659] FROMLIST: arm64: dts: qcom: kaanapali: Add base QRD board Add initial support for Qualcomm Kaanapali QRD board which enables SD Card, UFS and booting to shell with UART console. Written with help from Jishnu Prakash (added RPMhPD nodes), Nitin Rawat (added ufs) and Manish Pandey (added SD Card). Reviewed-by: Dmitry Baryshkov Signed-off-by: Jingyi Wang Reviewed-by: Abel Vesa Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20251215-knp-dts-v4-5-1541bebeb89f@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/kaanapali-qrd.dts | 712 +++++++++++++++++++++ 2 files changed, 713 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/kaanapali-qrd.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index ac6c0178aae4b..699d61d30280e 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -31,6 +31,7 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp449.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp453.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += kaanapali-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb lemans-evk-camera-csi1-imx577-dtbs := lemans-evk.dtb lemans-evk-camera-csi1-imx577.dtbo diff --git a/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts b/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts new file mode 100644 index 0000000000000..66b423a497b39 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts @@ -0,0 +1,712 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include +#include "kaanapali.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. Kaanapali QRD"; + compatible = "qcom,kaanapali-qrd", "qcom,kaanapali"; + chassis-type = "handset"; + + aliases { + serial0 = &uart7; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <76800000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32764>; + #clock-cells = <0>; + }; + + bi_tcxo_div2: bi-tcxo-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-mult = <1>; + clock-div = <2>; + }; + + bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK_A>; + clock-mult = <1>; + clock-div = <2>; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <4000000>; + regulator-initial-mode = ; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <3552000>; + regulator-initial-mode = ; + }; + + vreg_l1b_1p8: ldo1 { + regulator-name = "vreg_l1b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3048000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4b_1p8: ldo4 { + regulator-name = "vreg_l4b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3148000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7b_1p8: ldo7 { + regulator-name = "vreg_l7b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8b_1p8: ldo8 { + regulator-name = "vreg_l8b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l11b_1p0: ldo11 { + regulator-name = "vreg_l11b_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1292000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l12b_1p8: ldo12 { + regulator-name = "vreg_l12b_1p8"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l14b_3p2: ldo14 { + regulator-name = "vreg_l14b_3p2"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l18b_1p2: ldo18 { + regulator-name = "vreg_l18b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-1 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "D_E0"; + + vreg_s10d_1p0: smps10 { + regulator-name = "vreg_s10d_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_l1d_1p2: ldo1 { + regulator-name = "vreg_l1d_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1256000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2d_0p9: ldo2 { + regulator-name = "vreg_l2d_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <958000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3d_0p8: ldo3 { + regulator-name = "vreg_l3d_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4d_1p2: ldo4 { + regulator-name = "vreg_l4d_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s6f_0p5: smps6 { + regulator-name = "vreg_s6f_0p5"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <570000>; + regulator-initial-mode = ; + }; + + vreg_s7f_1p2: smps7 { + regulator-name = "vreg_s7f_1p2"; + regulator-min-microvolt = <1224000>; + regulator-max-microvolt = <1372000>; + regulator-initial-mode = ; + }; + + vreg_s8f_1p8: smps8 { + regulator-name = "vreg_s8f_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + }; + + vreg_l1f_1p2: ldo1 { + regulator-name = "vreg_l1f_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2f_1p2: ldo2 { + regulator-name = "vreg_l2f_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3f_0p8: ldo3 { + regulator-name = "vreg_l3f_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4f_0p8: ldo4 { + regulator-name = "vreg_l4f_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "G_E0"; + + vreg_s7g_0p9: smps7 { + regulator-name = "vreg_s7g_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_s9g_1p0: smps9 { + regulator-name = "vreg_s9g_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_l1g_1p2: ldo1 { + regulator-name = "vreg_l1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2g_1p8: ldo2 { + regulator-name = "vreg_l2g_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3g_1p2: ldo3 { + regulator-name = "vreg_l3g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4g_0p9: ldo4 { + regulator-name = "vreg_l4g_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "I_E0"; + + vreg_s7i_0p9: smps7 { + regulator-name = "vreg_s7i_0p9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <972000>; + regulator-initial-mode = ; + }; + + vreg_l2i_1p2: ldo2 { + regulator-name = "vreg_l2i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3i_0p8: ldo3 { + regulator-name = "vreg_l3i_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-5 { + compatible = "qcom,pmh0104-rpmh-regulators"; + qcom,pmic-id = "J_E1"; + + vreg_s1j_0p8: smps1 { + regulator-name = "vreg_s1j_0p8"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + }; + + vreg_s2j_0p8: smps2 { + regulator-name = "vreg_s2j_0p8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + }; + + vreg_s3j_1p2: smps3 { + regulator-name = "vreg_s3j_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = ; + }; + + vreg_s4j_0p7: smps4 { + regulator-name = "vreg_s4j_0p7"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + }; + }; + + regulators-6 { + compatible = "qcom,pmr735d-rpmh-regulators"; + qcom,pmic-id = "K_E1"; + + vreg_l1k_0p8: ldo1 { + regulator-name = "vreg_l1k_0p8"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2k_0p7: ldo2 { + regulator-name = "vreg_l2k_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3k_1p2: ldo3 { + regulator-name = "vreg_l3k_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4k_1p0: ldo4 { + regulator-name = "vreg_l4k_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5k_0p7: ldo5 { + regulator-name = "vreg_l5k_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6k_1p7: ldo6 { + regulator-name = "vreg_l6k_1p7"; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7k_0p7: ldo7 { + regulator-name = "vreg_l7k_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <848000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-7 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "M_E1"; + + vreg_l1m_1p0: ldo1 { + regulator-name = "vreg_l1m_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2m_1p0: ldo2 { + regulator-name = "vreg_l2m_1p0"; + regulator-min-microvolt = <1096000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3m_2p8: ldo3 { + regulator-name = "vreg_l3m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2900000>; + regulator-initial-mode = ; + }; + + vreg_l4m_2p2: ldo4 { + regulator-name = "vreg_l4m_2p2"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <2200000>; + regulator-initial-mode = ; + }; + + vreg_l6m_2p8: ldo6 { + regulator-name = "vreg_l6m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l7m_2p8: ldo7 { + regulator-name = "vreg_l7m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + }; + + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "N_E1"; + + vreg_l1n_1p1: ldo1 { + regulator-name = "vreg_l1n_1p1"; + regulator-min-microvolt = <1096000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2n_1p2: ldo2 { + regulator-name = "vreg_l2n_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3n_1p8: ldo3 { + regulator-name = "vreg_l3n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l4n_1p8: ldo4 { + regulator-name = "vreg_l4n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l5n_2p8: ldo5 { + regulator-name = "vreg_l5n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l6n_2p8: ldo6 { + regulator-name = "vreg_l6n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + }; + + vreg_l7n_3p3: ldo7 { + regulator-name = "vreg_l7n_3p3"; + regulator-min-microvolt = <3304000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = ; + }; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l9b_2p9>; + vqmmc-supply = <&vreg_l8b_1p8>; + + bus-width = <4>; + no-sdio; + no-mmc; + + pinctrl-0 = <&sdc2_default>; + pinctrl-1 = <&sdc2_sleep>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <36 4>, /* NFC eSE SPI */ + <74 1>, /* eSE */ + <119 2>, /* SoCCP */ + <144 4>; /* CXM UART */ +}; + +&uart7 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 217 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1200000>; + vccq-supply = <&vreg_l4d_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l4g_0p9>; + vdda-pll-supply = <&vreg_l1d_1p2>; + + status = "okay"; +}; From e737dd00d9a1c7472b2717b691b6b9bae3669418 Mon Sep 17 00:00:00 2001 From: Yongxing Mou Date: Mon, 19 Jan 2026 15:47:00 +0800 Subject: [PATCH 228/659] 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 bfdd7ec7444f273bcac00f7fac6ea6e02e39d357 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Mon, 19 Jan 2026 14:35:46 +0800 Subject: [PATCH 229/659] Bluetooth: hci_qca: Remove the old upstream changes Remove the old upstream changes; the upstream has already merged the newer version of the changes. Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20250825113858.4017780-1-quic_shuaz@quicinc.com/ --- drivers/bluetooth/hci_qca.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 3521402e5d2ec..cd40b51e22afb 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1686,24 +1686,6 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code) } clear_bit(QCA_HW_ERROR_EVENT, &qca->flags); - - /* - * If the SoC always enables the bt_en pin via hardware and the driver - * cannot control the bt_en pin of the SoC chip, then during SSR, - * the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits cannot be cleared. - * This leads to a reset command timeout failure. - * - * To address this, clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits - * after the coredump collection is complete. - * Also, add msleep delay to wait for controller to complete SSR. - */ - if (!hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) { - clear_bit(QCA_SSR_TRIGGERED, &qca->flags); - clear_bit(QCA_IBS_DISABLED, &qca->flags); - qca->tx_ibs_state = HCI_IBS_TX_AWAKE; - qca->memdump_state = QCA_MEMDUMP_IDLE; - msleep(50); - } } static void qca_reset(struct hci_dev *hdev) From 46c6608ed2d3f3c8616f5980cb0b739c907e0ba8 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Tue, 6 Jan 2026 12:35:02 +0800 Subject: [PATCH 230/659] UPSTREAM: driver: bluetooth: btqca: move WCN7850 workaround to the caller WCN7850 will first attempt to use ELF_TYPE_PATCH, and if that fails, it will fall back to TLV_TYPE_PATCH. To code uniformity, move WCN7850 workaround to the caller. Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20260106043503.534557-2-shuai.zhang@oss.qualcomm.com/ --- drivers/bluetooth/btqca.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 7c958d6065bec..0af3e2109f310 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -581,28 +581,11 @@ static int qca_download_firmware(struct hci_dev *hdev, ret = request_firmware(&fw, config->fwname, &hdev->dev); if (ret) { - /* For WCN6750, if mbn file is not present then check for - * tlv file. - */ - if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) { - bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)", - config->fwname, ret); - config->type = TLV_TYPE_PATCH; - snprintf(config->fwname, sizeof(config->fwname), - "qca/msbtfw%02x.tlv", rom_ver); - bt_dev_info(hdev, "QCA Downloading %s", config->fwname); - ret = request_firmware(&fw, config->fwname, &hdev->dev); - if (ret) { - bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", - config->fwname, ret); - return ret; - } - } /* If the board-specific file is missing, try loading the default * one, unless that was attempted already. */ - else if (config->type == TLV_TYPE_NVM && - qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) { + if (config->type == TLV_TYPE_NVM && + qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) { bt_dev_info(hdev, "QCA Downloading %s", config->fwname); ret = request_firmware(&fw, config->fwname, &hdev->dev); if (ret) { @@ -861,8 +844,22 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, } err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + /* For WCN6750, if mbn file is not present then check for + * tlv file. + */ + if (err < 0 && soc_type == QCA_WCN6750) { + bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)", + config.fwname, err); + config.type = TLV_TYPE_PATCH; + snprintf(config.fwname, sizeof(config.fwname), + "qca/msbtfw%02x.tlv", rom_ver); + bt_dev_info(hdev, "QCA Downloading %s", config.fwname); + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + } + if (err < 0) { - bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + config.fwname, err); return err; } From f901c31718fc2b4f093c13c9b6881940cfcb972c Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 24 Sep 2025 17:17:37 -0700 Subject: [PATCH 231/659] 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 | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 51f8b3e0749c3..f8cf63b1562a6 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -887,6 +888,160 @@ #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 0x20f0000 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>; + }; + lpass_lpiaon_noc: interconnect@7400000 { compatible = "qcom,kaanapali-lpass-lpiaon-noc"; reg = <0x0 0x07400000 0x0 0x19080>; From 65d248124f18ef053e842616e536cb6813187ea8 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 8 Jan 2026 09:42:56 +0530 Subject: [PATCH 232/659] 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 b9c252aa6fe08..a51dab62ecef6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2527,6 +2527,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 c6da3d2c179b71879f73c8be08babe610298dd73 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 24 Dec 2025 12:35:01 +0200 Subject: [PATCH 233/659] 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. Link: https://lore.kernel.org/r/20251224-phy-qcom-pcie-add-glymur-v3-1-57396145bc22@oss.qualcomm.com Signed-off-by: Abel Vesa Reviewed-by: Krzysztof Kozlowski --- .../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 f81f41bfdc62a5e12b2675900feb05e2cfbd2293 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 24 Dec 2025 12:35:02 +0200 Subject: [PATCH 234/659] 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. Link: https://lore.kernel.org/r/20251224-phy-qcom-pcie-add-glymur-v3-2-57396145bc22@oss.qualcomm.com Signed-off-by: Abel Vesa Reviewed-by: Dmitry Baryshkov --- 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 9fec10b97a1d16a36712cb29b1e8cab931c29743 Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Fri, 17 Oct 2025 18:33:40 -0700 Subject: [PATCH 235/659] FROMLIST: dt-bindings: PCI: qcom: Document the Glymur PCIe Controller On the Qualcomm Glymur platform the PCIe host is compatible with the DWC controller present on the X1E80100 platform. So document the PCIe controllers found on Glymur and use the X1E80100 compatible string as a fallback in the schema. Link: https://lore.kernel.org/all/20251017-glymur_pcie-v5-3-82d0c4bd402b@oss.qualcomm.com/ Signed-off-by: Prudhvi Yarlagadda Signed-off-by: Wenbin Yao Acked-by: Rob Herring (Arm) Signed-off-by: Qiang Yu --- .../devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml index 62c674ca0cf74..3d3b9f309a738 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml @@ -16,7 +16,12 @@ description: properties: compatible: - const: qcom,pcie-x1e80100 + oneOf: + - const: qcom,pcie-x1e80100 + - items: + - enum: + - qcom,glymur-pcie + - const: qcom,pcie-x1e80100 reg: minItems: 6 From 3e450000ad02b8f69900094db49b76a13a19af93 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 24 Nov 2025 02:24:34 -0800 Subject: [PATCH 236/659] 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 | 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 2b3be35ea0e8a..c8d27d7d491e9 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml @@ -147,6 +147,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-qmp-gen3x2-pcie-phy - qcom,qcs615-qmp-gen3x1-pcie-phy - qcom,sar2130p-qmp-gen3x2-pcie-phy - qcom,sc8180x-qmp-pcie-phy @@ -181,6 +182,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 @@ -206,6 +208,7 @@ allOf: enum: - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy + - qcom,kaanapali-qmp-gen3x2-pcie-phy - qcom,sm8550-qmp-gen4x2-pcie-phy - qcom,sm8650-qmp-gen4x2-pcie-phy - qcom,x1e80100-qmp-gen3x2-pcie-phy From 91cbdbf7a9f2970b2ae36e93e55ce4a977a932f1 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 24 Nov 2025 02:24:35 -0800 Subject: [PATCH 237/659] FROMLIST: phy: qcom-qmp: qserdes-txrx: Add complete QMP PCIe PHY v8 register offsets Kaanapali SoC uses QMP PHY with version v8 for PCIe Gen3 x2, but requires a completely unique qserdes-txrx register offsets compared to existing v8 offsets. Hence, add a dedicated header file containing the FULL SET of qserdes-txrx register definitions required for Kaanapali's PCIe PHY operation. Link:https://lore.kernel.org/all/20251124-kaanapali-pcie-phy-v4-2-d04ee9cca83b@oss.qualcomm.com/ Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Reviewed-by: Neil Armstrong Signed-off-by: Qiang Yu --- .../phy-qcom-qmp-qserdes-txrx-pcie-v8.h | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h new file mode 100644 index 0000000000000..181846e08c0f0 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_ +#define QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_ + +#define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX 0x030 +#define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX 0x034 +#define QSERDES_V8_PCIE_TX_LANE_MODE_1 0x07c +#define QSERDES_V8_PCIE_TX_LANE_MODE_2 0x080 +#define QSERDES_V8_PCIE_TX_LANE_MODE_3 0x084 +#define QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN 0x0b4 +#define QSERDES_V8_PCIE_TX_TX_BAND0 0x0e0 +#define QSERDES_V8_PCIE_TX_TX_BAND1 0x0e4 +#define QSERDES_V8_PCIE_TX_SEL_10B_8B 0x0f4 +#define QSERDES_V8_PCIE_TX_SEL_20B_10B 0x0f8 +#define QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN 0x058 +#define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1 0x118 +#define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2 0x11c +#define QSERDES_V8_PCIE_TX_PHPRE_CTRL 0x128 +#define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3 0x148 +#define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4 0x14c + +#define QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4 0x0dc +#define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3 0x0ec +#define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4 0x0f0 +#define QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS 0x0f4 +#define QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1 0x170 +#define QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL 0x178 +#define QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4 0x1b4 +#define QSERDES_V8_PCIE_RX_SIGDET_ENABLES 0x1d8 +#define QSERDES_V8_PCIE_RX_SIGDET_LVL 0x1e0 +#define QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL 0x0b8 +#define QSERDES_V8_PCIE_RX_RX_BAND_CTRL0 0x0bc +#define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0 0x0c4 +#define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1 0x0c8 +#define QSERDES_V8_PCIE_RX_SVS_MODE_CTRL 0x0b4 +#define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1 0x058 +#define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2 0x05c +#define QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3 0x084 +#define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3 0x098 +#define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3 0x0ac +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0 0x218 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1 0x21c +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2 0x220 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4 0x228 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7 0x234 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0 0x260 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1 0x264 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2 0x268 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3 0x26c +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4 0x270 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0 0x284 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1 0x288 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2 0x28c +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3 0x290 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4 0x294 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5 0x298 +#define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32 0x31c +#define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4 0x320 +#define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB 0x11c +#define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB 0x120 +#define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23 0x108 +#define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4 0x10c +#define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3 0x198 +#define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4 0x19c +#define QSERDES_V8_PCIE_RX_GM_CAL 0x1a0 + +#endif From a8ff27b73fa8614f3d0017005380beb5418ba5e4 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 24 Nov 2025 02:24:36 -0800 Subject: [PATCH 238/659] FROMLIST: phy: qcom-qmp: pcs-pcie: Add v8 register offsets Kaanapali SoC uses QMP phy with version v8 for PCIe Gen3 x2. Add the new PCS PCIE specific offsets in a dedicated header file. Link: https://lore.kernel.org/all/20251124-kaanapali-pcie-phy-v4-3-d04ee9cca83b@oss.qualcomm.com/ Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Reviewed-by: Neil Armstrong Signed-off-by: Qiang Yu --- .../phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h new file mode 100644 index 0000000000000..1e06aa9d73d58 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_PCIE_V8_H_ +#define QCOM_PHY_QMP_PCS_PCIE_V8_H_ + +/* Only for QMP V8 PHY - PCIE PCS registers */ + +#define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2 0x00c +#define QPHY_PCIE_V8_PCS_TX_RX_CONFIG 0x018 +#define QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE 0x01c +#define QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS 0x090 +#define QPHY_PCIE_V8_PCS_EQ_CONFIG1 0x0a0 +#define QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME 0x0f0 +#define QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME 0x0f4 +#define QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5 0x108 +#define QPHY_PCIE_V8_PCS_G4_PRE_GAIN 0x15c +#define QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB 0x170 +#define QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN 0x178 +#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1 0x17c +#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3 0x184 +#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5 0x18c +#define QPHY_PCIE_V8_PCS_RX_SIGDET_LVL 0x190 +#define QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5 0x1ac +#define QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL 0x1b8 +#define QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5 0x1c0 +#define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6 0x1d0 +#define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1 0x1dc +#define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2 0x1e0 +#define QPHY_PCIE_V8_PCS_EQ_CONFIG4 0x1f8 +#define QPHY_PCIE_V8_PCS_EQ_CONFIG5 0x1fc +#endif From e856a6a26b76815a73e3fffd1f105daaddb4c68a Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 24 Nov 2025 02:24:37 -0800 Subject: [PATCH 239/659] FROMLIST: phy: qcom-qmp: qserdes-com: Add some more v8 register offsets Some qserdes-com register offsets for the v8 PHY were previously omitted, as they were not needed by earlier v8 PHY initialization sequences. Add these missing v8 register offsets now required to support PCIe QMP PHY on Kaanapali platform. Link: https://lore.kernel.org/all/20251124-kaanapali-pcie-phy-v4-4-d04ee9cca83b@oss.qualcomm.com/ Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Reviewed-by: Neil Armstrong Signed-off-by: Qiang Yu --- drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h index d3b2292257bc5..d8ac4c4a2c316 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h @@ -33,6 +33,7 @@ #define QSERDES_V8_COM_CP_CTRL_MODE0 0x070 #define QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 #define QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 +#define QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c #define QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 #define QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 #define QSERDES_V8_COM_DEC_START_MODE0 0x088 @@ -40,6 +41,7 @@ #define QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 #define QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 #define QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 +#define QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1 0x09c #define QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 #define QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac #define QSERDES_V8_COM_BG_TIMER 0x0bc @@ -47,13 +49,22 @@ #define QSERDES_V8_COM_SSC_PER1 0x0cc #define QSERDES_V8_COM_SSC_PER2 0x0d0 #define QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define QSERDES_V8_COM_CLK_ENABLE1 0x0e0 +#define QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 +#define QSERDES_V8_COM_PLL_IVCO 0x0f4 #define QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 #define QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 #define QSERDES_V8_COM_RESETSM_CNTRL 0x118 +#define QSERDES_V8_COM_LOCK_CMP_EN 0x120 #define QSERDES_V8_COM_LOCK_CMP_CFG 0x124 #define QSERDES_V8_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_V8_COM_CLK_SELECT 0x164 #define QSERDES_V8_COM_CORE_CLK_EN 0x170 #define QSERDES_V8_COM_CMN_CONFIG_1 0x174 +#define QSERDES_V8_COM_CMN_MISC_1 0x184 +#define QSERDES_V8_COM_CMN_MODE 0x188 +#define QSERDES_V8_COM_VCO_DC_LEVEL_CTRL 0x198 +#define QSERDES_V8_COM_PLL_SPARE_FOR_ECO 0x2b4 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac From d9f9599c6801d504ef3e87e8d83aa67fec64496b Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 24 Nov 2025 02:24:38 -0800 Subject: [PATCH 240/659] FROMLIST: phy: qcom: qmp-pcie: add QMP PCIe PHY tables for Kaanapali Add QMP PCIe PHY support for the Kaanapali platform. Link: https://lore.kernel.org/r/20251124-kaanapali-pcie-phy-v4-5-d04ee9cca83b@oss.qualcomm.com Signed-off-by: Jingyi Wang Reviewed-by: Abel Vesa Reviewed-by: Neil Armstrong Signed-off-by: Qiang Yu --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 194 +++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index f65a8b9586c48..fed2fc9bb3110 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -37,6 +37,9 @@ #include "phy-qcom-qmp-pcs-pcie-v6_30.h" #include "phy-qcom-qmp-pcs-v6_30.h" #include "phy-qcom-qmp-pcie-qhp.h" +#include "phy-qcom-qmp-qserdes-com-v8.h" +#include "phy-qcom-qmp-pcs-pcie-v8.h" +#include "phy-qcom-qmp-qserdes-txrx-pcie-v8.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 @@ -100,6 +103,13 @@ static const unsigned int pciephy_v7_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL, }; +static const unsigned int pciephy_v8_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V8_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V8_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V8_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_PCS_POWER_DOWN_CONTROL, +}; + static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_START_CTRL] = QPHY_V8_50_PCS_START_CONTROL, [QPHY_PCS_STATUS] = QPHY_V8_50_PCS_STATUS1, @@ -3067,6 +3077,149 @@ static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_ep_pcs_misc_tbl[] QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), }; +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0x93), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01), + + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xf8), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MISC_1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MODE, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_SPARE_FOR_ECO, 0x02), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_2, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_3, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_10B_8B, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_20B_10B, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3, 0x53), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PHPRE_CTRL, 0x20), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL, 0x89), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4, 0x2d), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_LVL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_BAND_CTRL0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SVS_MODE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2, 0x42), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0, 0xc2), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1, 0xc2), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0, 0xe4), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1, 0x63), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3, 0x99), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4, 0x67), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2, 0x28), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3, 0x9f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4, 0x48), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_GM_CAL, 0x0d), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB, 0x17), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_SIGDET_LVL, 0xcc), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL, 0x40), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1, 0x04), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2, 0x02), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG4, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG5, 0x22), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_TX_RX_CONFIG, 0xc0), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2, 0x1d), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG1, 0x16), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5, 0x02), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1, 0x03), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3, 0x28), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5, 0x0f), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5, 0xf2), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5, 0xf2), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6, 0x1f), +}; + struct qmp_pcie_offsets { u16 serdes; u16 pcs; @@ -3363,6 +3516,16 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = { .ln_shrd = 0x8000, }; +static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_0 = { + .serdes = 0x1000, + .pcs = 0x1400, + .pcs_misc = 0x1800, + .tx = 0x0000, + .rx = 0x0200, + .tx2 = 0x0800, + .rx2 = 0x0a00, +}; + static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = { .serdes = 0x8000, .pcs = 0x9000, @@ -4425,6 +4588,34 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = { .phy_status = PHYSTATUS_4_20, }; +static const struct qmp_phy_cfg qmp_v8_gen3x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v8_0, + + .tbls = { + .serdes = kaanapali_qmp_gen3x2_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_serdes_tbl), + .tx = kaanapali_qmp_gen3x2_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_tx_tbl), + .rx = kaanapali_qmp_gen3x2_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_rx_tbl), + .pcs = kaanapali_qmp_gen3x2_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc = kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl), + }, + + .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 const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = { .lanes = 4, @@ -5228,6 +5419,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { }, { .compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy", .data = &ipq9574_gen3x2_pciephy_cfg, + }, { + .compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy", + .data = &qmp_v8_gen3x2_pciephy_cfg, }, { .compatible = "qcom,msm8998-qmp-pcie-phy", .data = &msm8998_pciephy_cfg, From 4cff31be02c7cce3434b096cb6cba4c11fc7f3c7 Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Sat, 10 Jan 2026 01:27:51 +0530 Subject: [PATCH 241/659] 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 518aeb54113a9214e14bd7886a2a3b69bacccb94 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Mon, 12 Jan 2026 13:05:20 +0530 Subject: [PATCH 242/659] 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 8fb419ea638a5..e446a10a882f6 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -236,63 +236,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 { @@ -1058,14 +1001,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 714533cb2e02e3f695b5c5a0e71c75df5ecc863b Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Wed, 21 Jan 2026 11:37:55 +0530 Subject: [PATCH 243/659] 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 3e7f0669aead2c7623372db0f60b55cf812c1b7a Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:42:55 -0800 Subject: [PATCH 244/659] 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 2dd479cf48217..31dffd02125a3 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 a4b93e1717827cbbcd3c82b55bf6cd60af7c7665 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:42:56 -0800 Subject: [PATCH 245/659] 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 31dffd02125a3..1a216ea3b1273 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 f49b4e58db7029ec5bca70acaa6514a532adfe47 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 5 Nov 2025 17:49:10 +0530 Subject: [PATCH 246/659] FROMLIST: dt-bindings: soundwire: qcom: Add SoundWire v2.2.0 compatible Add qcom,soundwire-v2.2.0 to the list of supported Qualcomm SoundWire controller versions. This version falls back to qcom,soundwire-v2.0.0 if not explicitly handled by the driver. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Prasad Kumpatla Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/all/20251105-knp-audio-v2-v4-1-ae0953f02b44@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml index 003023729fb8c..9447a2f371b56 100644 --- a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml +++ b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml @@ -27,6 +27,7 @@ properties: - items: - enum: - qcom,soundwire-v2.1.0 + - qcom,soundwire-v2.2.0 - const: qcom,soundwire-v2.0.0 reg: From fb6f4cf04ea2e0999f495b2b714fed94ffb78549 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Wed, 14 Jan 2026 22:49:03 -0800 Subject: [PATCH 247/659] 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. Reviewed-by: Konrad Dybcio Signed-off-by: Jie Gan Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-1-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- 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 f8cf63b1562a6..dcd2a27aff16d 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -1235,6 +1235,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>; @@ -1758,4 +2866,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 5f9535b474805146e158b4b934c58f0131a125c9 Mon Sep 17 00:00:00 2001 From: Jyothi Kumar Seerapu Date: Wed, 14 Jan 2026 22:49:04 -0800 Subject: [PATCH 248/659] 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 Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-2-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- 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 dcd2a27aff16d..72fd72c2d5cd0 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -469,102 +470,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 { @@ -1172,6 +2763,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"; @@ -1180,6 +3256,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 757f790f7140ea375459476d821499a39b6d9ca0 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Wed, 14 Jan 2026 22:49:05 -0800 Subject: [PATCH 249/659] 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 critical trip at 125°C Signed-off-by: Manaf Meethalavalappu Pallikunhi Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-3-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 745 ++++++++++++++++++++++++ 1 file changed, 745 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 72fd72c2d5cd0..4de3d479e3036 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -2738,6 +2738,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>; @@ -4950,6 +5034,667 @@ }; }; + thermal-zones { + cpullc-0-0-thermal { + thermal-sensors = <&tsens0 0>; + + trips { + cpullc-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-0-1-thermal { + thermal-sensors = <&tsens0 1>; + + trips { + cpullc-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-0-thermal { + thermal-sensors = <&tsens0 2>; + + trips { + qmx-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-1-thermal { + thermal-sensors = <&tsens0 3>; + + trips { + qmx-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-2-thermal { + thermal-sensors = <&tsens0 4>; + + trips { + qmx-0-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-0-0-thermal { + thermal-sensors = <&tsens1 0>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-1-0-thermal { + thermal-sensors = <&tsens1 2>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-2-0-thermal { + thermal-sensors = <&tsens1 4>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-3-0-thermal { + thermal-sensors = <&tsens1 6>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-4-0-thermal { + thermal-sensors = <&tsens1 8>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-5-0-thermal { + thermal-sensors = <&tsens1 10>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-1-0-thermal { + thermal-sensors = <&tsens2 0>; + + trips { + cpullc-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-1-1-thermal { + thermal-sensors = <&tsens2 1>; + + trips { + cpullc-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-0-thermal { + thermal-sensors = <&tsens2 2>; + + trips { + qmx-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-1-thermal { + thermal-sensors = <&tsens2 3>; + + trips { + qmx-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-2-thermal { + thermal-sensors = <&tsens2 4>; + + trips { + qmx-1-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-3-thermal { + thermal-sensors = <&tsens2 5>; + + trips { + qmx-1-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-4-thermal { + thermal-sensors = <&tsens2 6>; + + trips { + qmx-1-4-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-0-0-thermal { + thermal-sensors = <&tsens3 0>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-1-0-thermal { + thermal-sensors = <&tsens3 2>; + + trips { + 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-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-0-thermal { + thermal-sensors = <&tsens4 0>; + + trips { + nsphvx-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-1-thermal { + thermal-sensors = <&tsens4 1>; + + trips { + nsphvx-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-2-thermal { + thermal-sensors = <&tsens4 2>; + + trips { + nsphvx-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphvx-3-thermal { + thermal-sensors = <&tsens4 3>; + + trips { + nsphvx-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-0-thermal { + thermal-sensors = <&tsens4 4>; + + trips { + nsphmx-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-1-thermal { + thermal-sensors = <&tsens4 5>; + + trips { + nsphmx-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-2-thermal { + thermal-sensors = <&tsens4 6>; + + trips { + nsphmx-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nsphmx-3-thermal { + thermal-sensors = <&tsens4 7>; + + trips { + nsphmx-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-0-thermal { + thermal-sensors = <&tsens5 0>; + + trips { + gpuss-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-1-thermal { + thermal-sensors = <&tsens5 1>; + + trips { + gpuss-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-2-thermal { + thermal-sensors = <&tsens5 2>; + + trips { + gpuss-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-3-thermal { + thermal-sensors = <&tsens5 3>; + + trips { + gpuss-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-4-thermal { + thermal-sensors = <&tsens5 4>; + + trips { + gpuss-4-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-5-thermal { + thermal-sensors = <&tsens5 5>; + + trips { + gpuss-5-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-6-thermal { + thermal-sensors = <&tsens5 6>; + + trips { + gpuss-6-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-7-thermal { + thermal-sensors = <&tsens5 7>; + + trips { + gpuss-7-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-8-thermal { + thermal-sensors = <&tsens5 8>; + + trips { + gpuss-8-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-9-thermal { + thermal-sensors = <&tsens5 9>; + + trips { + gpuss-9-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-10-thermal { + thermal-sensors = <&tsens5 10>; + + trips { + gpuss-10-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + ddr-thermal { + thermal-sensors = <&tsens5 11>; + + trips { + ddr-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-0-thermal { + thermal-sensors = <&tsens6 0>; + + trips { + mdmss-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-1-thermal { + thermal-sensors = <&tsens6 1>; + trips { + mdmss-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-2-thermal { + thermal-sensors = <&tsens6 2>; + + trips { + mdmss-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-3-thermal { + thermal-sensors = <&tsens6 3>; + + trips { + mdmss-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + camera-0-thermal { + thermal-sensors = <&tsens6 4>; + + trips { + camera-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + camera-1-thermal { + thermal-sensors = <&tsens6 5>; + + trips { + camera-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + video-thermal { + thermal-sensors = <&tsens6 6>; + + trips { + video-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; From ada97c6c338b4b12f5d5f9c4aa4c1adfacc9330a Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:49:06 -0800 Subject: [PATCH 250/659] 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 Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-4-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 351 ++++++++++++++++++++++++ 1 file changed, 351 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 4de3d479e3036..cbf0d0dbda2ff 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -444,6 +444,95 @@ }; }; + 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-modem { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_MPSS + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_MPSS + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <435>, <428>; + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + smp2p_modem_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_modem_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + + ipa_smp2p_out: ipa-ap-to-modem { + qcom,entry-name = "ipa"; + #qcom,smem-state-cells = <1>; + }; + + ipa_smp2p_in: ipa-modem-to-ap { + qcom,entry-name = "ipa"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + soc: soc@0 { compatible = "simple-bus"; @@ -2633,6 +2722,111 @@ #power-domain-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>; @@ -4915,6 +5109,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 cb1ea8b211b1c45d87142a89eea05c8a05b04a58 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 14 Jan 2026 22:49:07 -0800 Subject: [PATCH 251/659] 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. Reviewed-by: Konrad Dybcio Signed-off-by: Prasad Kumpatla Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-5-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 396 ++++++++++++++++++++++++ 1 file changed, 396 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index cbf0d0dbda2ff..f346fe1dab757 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include "kaanapali-ipcc.h" @@ -2824,6 +2826,400 @@ 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"; + }; + + 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; + }; }; }; From 7713801b8bb62e090d51a72e63fca1149b53d374 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:49:08 -0800 Subject: [PATCH 252/659] FROMLIST: arm64: dts: qcom: kaanapali-mtp: Enable ADSP and CDSP Enable ADSP and CDSP on Kaanapali MTP board. Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-6-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- 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 0dc268522f1216e6cca7af3734851a12f58846a4 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 14 Jan 2026 22:49:09 -0800 Subject: [PATCH 253/659] FROMLIST: arm64: dts: qcom: kaanapali-qrd: Enable ADSP and CDSP Enable ADSP and CDSP on Kaanapali QRD board. Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-7-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- 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 4d3cfe4733aa7ee47538def0f734c629f413cd0b Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 14 Jan 2026 22:49:10 -0800 Subject: [PATCH 254/659] 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 Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-8-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- 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..f6ca4d0ff504f 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"; + + 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>; + }; + }; + + 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>; + }; + }; + + 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>; + }; + }; + + 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>; + }; + }; + }; + + 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 { @@ -684,6 +793,14 @@ reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; }; +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + + vdd-micb-supply = <&vreg_l10b_1p8>; + qcom,dmic-sample-rate = <4800000>; +}; + &remoteproc_adsp { firmware-name = "qcom/kaanapali/adsp.mbn", "qcom/kaanapali/adsp_dtb.mbn"; @@ -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 c3ff3fc9f8f2aab4813819282b72298763d547eb Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 14 Jan 2026 22:49:11 -0800 Subject: [PATCH 255/659] 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 Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/all/20260114-knp-dts-misc-v3-9-a6cc9e45de93@oss.qualcomm.com/ Signed-off-by: Yijie Yang --- arch/arm64/boot/dts/qcom/kaanapali.dtsi | 85 +++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index f346fe1dab757..f998e22716524 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi @@ -3,7 +3,12 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ +#include +#include +#include #include +#include +#include #include #include #include @@ -1595,6 +1600,24 @@ <&rpmhcc RPMH_IPA_CLK>; }; + cambistmclkcc: clock-controller@1760000 { + compatible = "qcom,kaanapali-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>; + }; + mmss_noc: interconnect@1780000 { compatible = "qcom,kaanapali-mmss-noc"; reg = <0x0 0x01780000 0x0 0x5b800>; @@ -2724,6 +2747,30 @@ #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 0x3d90000 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>; @@ -3294,6 +3341,44 @@ }; }; + camcc: clock-controller@956d000 { + compatible = "qcom,kaanapali-camcc"; + reg = <0x0 0x956d000 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 0x9ba2000 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 46ba3da05b863328639a7394e46a9d507ca9e114 Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Fri, 28 Nov 2025 10:35:31 +0530 Subject: [PATCH 256/659] 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/r/20251128050534.437755-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 ee652ef01534a..679cd8997a000 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; @@ -987,6 +988,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; @@ -1089,18 +1091,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]) { @@ -1122,9 +1116,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 62d78e6d1a80e271702ce32e9cebbfc639292f9d Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Fri, 28 Nov 2025 10:35:32 +0530 Subject: [PATCH 257/659] 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/r/20251128050534.437755-3-ekansh.gupta@oss.qualcomm.com Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 679cd8997a000..f7fb44a8e9c0e 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -22,6 +22,7 @@ #include #include #include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -37,7 +38,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" @@ -489,7 +490,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); @@ -625,7 +626,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); @@ -2451,7 +2452,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 253ac691a74d9d1c54baa1d0b3fa74c7874dd162 Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Fri, 28 Nov 2025 10:35:33 +0530 Subject: [PATCH 258/659] FROMLIST: misc: fastrpc: Expand context ID mask for DSP polling mode support Current FastRPC message context uses a 12-bit mask where the upper 8 bits represent the context ID from idr_alloc_cyclic and the lower 4 bits represent the PD type. This layout works for normal FastRPC calls but fails for polling mode because DSP expects a 16-bit context with an additional async mode bit. To enable polling mode support from DSP(DSP writes to poll memory), DSP expects a 16-bit context where the upper 8 bits are context ID, the lower 4 bits are PD type and the 5th bit from the end denotes async mode(not yet upstreamed). If this bit is set, DSP disables polling. With the current design, odd context IDs set this bit, causing DSP to skip poll memory updates. Update the context mask to ensure a hole which won't get populated, ensuring polling mode works as expected. This is not a bug and the change is added to support polling mode. Link: https://lore.kernel.org/r/20251128050534.437755-4-ekansh.gupta@oss.qualcomm.com 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 f7fb44a8e9c0e..222ff15e04bd7 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -38,7 +38,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 a471773a336d3cb927d49ffc0bd0bb67e4cc844b Mon Sep 17 00:00:00 2001 From: Ekansh Gupta Date: Fri, 28 Nov 2025 10:35:34 +0530 Subject: [PATCH 259/659] 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/r/20251128050534.437755-5-ekansh.gupta@oss.qualcomm.com Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 139 ++++++++++++++++++++++++++++++++++-- include/uapi/misc/fastrpc.h | 9 +++ 2 files changed, 141 insertions(+), 7 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 222ff15e04bd7..d95d31d27b826 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #define ADSP_DOMAIN_ID (0) @@ -38,6 +40,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) @@ -106,6 +109,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 { u64 addr; /* physical address */ u64 size; /* size of contiguous region */ @@ -236,8 +245,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; @@ -301,6 +316,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 */ @@ -894,7 +911,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; } @@ -990,6 +1008,7 @@ 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 *)(ctx->fdlist + FASTRPC_MAX_FDLIST + FASTRPC_MAX_CRCLIST); args = (uintptr_t)ctx->buf->virt + metalen; rlen = pkt_size - metalen; ctx->rpra = rpra; @@ -1158,6 +1177,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) @@ -1193,16 +1281,25 @@ 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 */ @@ -1780,6 +1877,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}; @@ -2134,6 +2255,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; @@ -2465,6 +2589,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, ctx->retval = rsp->retval; complete(&ctx->work); + ctx->is_work_done = true; /* * The DMA buffer associated with the context cannot be freed in diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index c6e2925f47e69..3207c42fb3180 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) /** @@ -66,6 +67,8 @@ 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; @@ -133,6 +136,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 5648b72d58edd690036e3d3c7073ec38a5275f6b Mon Sep 17 00:00:00 2001 From: Abhinaba Rakshit Date: Sat, 17 Jan 2026 02:06:18 +0530 Subject: [PATCH 260/659] FROMGIT: arm64: dts: qcom: lemans: add QCrypto node Add Qualcomm Crypto Engine device node for LeMans platform. QCE and Crypto DMA nodes patch was applied as part of the commit 7ff3da43ef44 ("arm64: dts: qcom: sa8775p: add QCrypto nodes"), however was partially reverted by commit 92979f12a201 ("arm64: dts: qcom: sa8775p: Partially revert "arm64: dts: qcom: sa8775p: add QCrypto nodes"") due to compatible-string being miss-matched against schema. Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20251224-enable-qualcomm-crypto-engine-for-lemans-v2-1-a707e3d38765@oss.qualcomm.com/ Signed-off-by: Abhinaba Rakshit --- arch/arm64/boot/dts/qcom/lemans.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index a6434095179dc..6358d5ce34c57 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -2795,6 +2795,18 @@ <&apps_smmu 0x481 0x00>; }; + crypto: crypto@1dfa000 { + compatible = "qcom,sa8775p-qce", "qcom,sm8150-qce", "qcom,qce"; + reg = <0x0 0x01dfa000 0x0 0x6000>; + dmas = <&cryptobam 4>, <&cryptobam 5>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu 0x480 0x0>, + <&apps_smmu 0x481 0x0>; + interconnects = <&aggre2_noc MASTER_CRYPTO_CORE0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "memory"; + }; + ctcu@4001000 { compatible = "qcom,sa8775p-ctcu"; reg = <0x0 0x04001000 0x0 0x1000>; From 89fcb63e9564e903fe8b51aa377dd935c320ff89 Mon Sep 17 00:00:00 2001 From: Debraj Mukhopadhyay Date: Fri, 18 Jul 2025 16:32:17 +0530 Subject: [PATCH 261/659] FROMLIST: 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/r/20250718110217.1929526-1-quic_dmukhopa@quicinc.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 --- drivers/mmc/core/crypto.c | 2 +- drivers/mmc/host/sdhci-msm.c | 6 ++++++ include/linux/mmc/host.h | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) 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 3b85233131b38..14d97d9fa719c 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1952,6 +1952,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; } @@ -2529,6 +2530,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..ff439d30704c4 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -463,6 +463,11 @@ struct mmc_host { #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 */ +#ifdef CONFIG_MMC_CRYPTO +#define MMC_CAP2_CRYPTO_NO_REPROG (1 << 29) /* Host handles inline crypto key reprogramming */ +#else +#define MMC_CAP2_CRYPTO_NO_REPROG 0 +#endif bool uhs2_sd_tran; /* UHS-II flag for SD_TRAN state */ bool uhs2_app_cmd; /* UHS-II flag for APP command */ From e95f0f762286463fbf47d03435a9b81212590060 Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Fri, 2 Jan 2026 18:10:18 +0530 Subject: [PATCH 262/659] 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 14d97d9fa719c..d9338387edd58 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; /* @@ -2013,9 +2008,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 f8afd2eb32961b6c334674233165f742dbef46b2 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 13:51:12 +0530 Subject: [PATCH 263/659] 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 c3408dcf5d205..1c2416117d4ce 100644 --- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml @@ -28,12 +28,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 @@ -45,6 +53,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 c8cd148d89a716b38683085df84c2cd496c797ea Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:25:10 +0530 Subject: [PATCH 264/659] 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 0b154d57ba24e..ab4c16ce0aa65 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -2753,7 +2753,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 58fb470ac832c2d170ff642ebb6a3e63e07f4120 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Fri, 23 Jan 2026 18:46:25 +0530 Subject: [PATCH 265/659] 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 816fa2af8a9a6..295c8aa500f7e 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -2347,7 +2347,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>; }; tcsr_mutex: hwlock@1f40000 { From 460fc01c68ed08b818df5c0a570429df5b29292b Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:27:25 +0530 Subject: [PATCH 266/659] 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 1faf1190ad30c526e7ee6a78bb5cb8d74cb7b3e5 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 16:15:04 +0530 Subject: [PATCH 267/659] 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 c2ccbb67f800c..7a61ee08d59fd 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -2574,7 +2574,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 657460d28de6619a8cec6d083c1b9d3b2daed1ac Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:30:05 +0530 Subject: [PATCH 268/659] 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 c3b27742763fad9f1948dcfec8c9132f9a8d836a Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:31:52 +0530 Subject: [PATCH 269/659] 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 2ca9e50ef5994..7eb161eafc471 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 fee54e7092bf57ca4627db6708e96b394019747f Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:32:31 +0530 Subject: [PATCH 270/659] 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 07ae74851621f..67902cbab4240 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 a4da184ad480efdae012521a1e4d1f24fea69f6d Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 14:33:19 +0530 Subject: [PATCH 271/659] 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 3f0b57f428bbb..454cb8d80ae39 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -2058,7 +2058,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 5c53b58f4ebbdc2b97f442b6758fb74df96884dc Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Tue, 20 Jan 2026 15:28:59 +0530 Subject: [PATCH 272/659] 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 edce7a97529d832a044532db27c03879d148bc41 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Tue, 7 Oct 2025 07:32:25 +0530 Subject: [PATCH 273/659] FROMLIST: ASoC: soc-pcm: Fix mute and unmute control for non-dynamic DAI links In setups where the same codec DAI is reused across multiple DAI links, mute controls via `snd_soc_dai_digital_mute()` is skipped for non-dynamic links. The trigger operations are not invoked when `dai_link->dynamic == 0`, and mute controls is currently conditioned only on `snd_soc_dai_mute_is_ctrled_at_trigger()`. This patch ensures that mute and unmute is applied explicitly for non-dynamic links. Link: https://lore.kernel.org/linux-sound/20251007023325.853640-1-mohammad.rafi.shaik@oss.qualcomm.com/ Fixes: f0220575e65a ("ASoC: soc-dai: add flag to mute and unmute stream during trigger") Cc: stable@vger.kernel.org Signed-off-by: Mohammad Rafi Shaik --- sound/soc/soc-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 6b134962c71c7..12033d0635d7c 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -961,7 +961,7 @@ static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd, SND_SOC_DAPM_STREAM_START); for_each_rtd_dais(rtd, i, dai) { - if (!snd_soc_dai_mute_is_ctrled_at_trigger(dai)) + if (!snd_soc_dai_mute_is_ctrled_at_trigger(dai) || !rtd->dai_link->dynamic) snd_soc_dai_digital_mute(dai, 0, substream->stream); } @@ -1019,7 +1019,7 @@ static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd, soc_pcm_set_dai_params(dai, NULL); if (snd_soc_dai_stream_active(dai, substream->stream) == 1) { - if (!snd_soc_dai_mute_is_ctrled_at_trigger(dai)) + if (!snd_soc_dai_mute_is_ctrled_at_trigger(dai) || !rtd->dai_link->dynamic) snd_soc_dai_digital_mute(dai, 1, substream->stream); } } From ccd62f1b338cdb380f711793c54dea27a7817eaa Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 10 Dec 2025 12:21:55 +0530 Subject: [PATCH 274/659] 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 61556335a20098c89f6f45aee47381994bd67986 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 10 Dec 2025 12:21:56 +0530 Subject: [PATCH 275/659] 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 3250a8c41b9398e5da1af23670cff2fe126b4e57 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Tue, 30 Dec 2025 15:55:08 +0530 Subject: [PATCH 276/659] FROMLIST: soc: qcom: pd-mapper: Add support for SA8775P and QCS8300 Add support for the Qualcomm SA8775P and QCS8300 SoC to the protection domain mapper. SA8775P and QCS8300 shares the same protection domain configuration as SM8550, except charger_pd and mpss_pd. Add an entry to the kernel, to avoid the need for userspace to provide this service. Link: https://lore.kernel.org/all/20251230102508.1491296-1-mohammad.rafi.shaik@oss.qualcomm.com/ Signed-off-by: Mohammad Rafi Shaik --- drivers/soc/qcom/qcom_pd_mapper.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index 1bcbe69688d2b..82a923d419149 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -401,6 +401,14 @@ 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, + &adsp_sensor_pd, + &cdsp_root_pd, + NULL, +}; + static const struct qcom_pdm_domain_data *sc7180_domains[] = { &adsp_audio_pd, &adsp_root_pd_pdr, @@ -572,6 +580,8 @@ 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 = sa8775p_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 d78cd6a77aa9bc097134e2a1eaa6d79354ce313f Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 20 Jan 2026 16:49:13 +0100 Subject: [PATCH 277/659] FROMGIT: gpio: shared: propagate configuration to pinctrl Just toggling the descriptor's "requested" flag is not enough. We need to properly request it in order to potentially propagate any configuration to pinctrl via the .request() callback. We must not take the reference to the device at this point (the device is not ready but we're also requesting the device's own descriptor) so make the _commit() variants of request and free functions available to GPIO core in order to use them instead of their regular counterparts. This fixes an audio issue reported on one of the Qualcomm platforms. Fixes: a060b8c511ab ("gpiolib: implement low-level, shared GPIO support") Reviewed-by: Linus Walleij Tested-by: Ravi Hothi Link: https://lore.kernel.org/r/20260120154913.61991-1-bartosz.golaszewski@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-shared.c | 16 +++++++++++----- drivers/gpio/gpiolib.c | 4 ++-- drivers/gpio/gpiolib.h | 2 ++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c index 17343fdc97584..9e65442034393 100644 --- a/drivers/gpio/gpiolib-shared.c +++ b/drivers/gpio/gpiolib-shared.c @@ -515,7 +515,7 @@ int gpio_device_setup_shared(struct gpio_device *gdev) { struct gpio_shared_entry *entry; struct gpio_shared_ref *ref; - unsigned long *flags; + struct gpio_desc *desc; int ret; list_for_each_entry(entry, &gpio_shared_list, list) { @@ -543,15 +543,17 @@ int gpio_device_setup_shared(struct gpio_device *gdev) if (list_count_nodes(&entry->refs) <= 1) continue; - flags = &gdev->descs[entry->offset].flags; + desc = &gdev->descs[entry->offset]; - __set_bit(GPIOD_FLAG_SHARED, flags); + __set_bit(GPIOD_FLAG_SHARED, &desc->flags); /* * Shared GPIOs are not requested via the normal path. Make * them inaccessible to anyone even before we register the * chip. */ - __set_bit(GPIOD_FLAG_REQUESTED, flags); + ret = gpiod_request_commit(desc, "shared"); + if (ret) + return ret; pr_debug("GPIO %u owned by %s is shared by multiple consumers\n", entry->offset, gpio_device_get_label(gdev)); @@ -562,8 +564,10 @@ int gpio_device_setup_shared(struct gpio_device *gdev) ref->con_id ?: "(none)"); ret = gpio_shared_make_adev(gdev, entry, ref); - if (ret) + if (ret) { + gpiod_free_commit(desc); return ret; + } } } @@ -579,6 +583,8 @@ void gpio_device_teardown_shared(struct gpio_device *gdev) if (!device_match_fwnode(&gdev->dev, entry->fwnode)) continue; + gpiod_free_commit(&gdev->descs[entry->offset]); + list_for_each_entry(ref, &entry->refs, list) { guard(mutex)(&ref->lock); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index fe2d107b0a844..1578cf3a8c74e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2453,7 +2453,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); * on each other, and help provide better diagnostics in debugfs. * They're called even less than the "set direction" calls. */ -static int gpiod_request_commit(struct gpio_desc *desc, const char *label) +int gpiod_request_commit(struct gpio_desc *desc, const char *label) { unsigned int offset; int ret; @@ -2515,7 +2515,7 @@ int gpiod_request(struct gpio_desc *desc, const char *label) return ret; } -static void gpiod_free_commit(struct gpio_desc *desc) +void gpiod_free_commit(struct gpio_desc *desc) { unsigned long flags; diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 77f6f2936dc26..3abb90385829e 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -244,7 +244,9 @@ DEFINE_CLASS(gpio_chip_guard, struct gpio_desc *desc) int gpiod_request(struct gpio_desc *desc, const char *label); +int gpiod_request_commit(struct gpio_desc *desc, const char *label); void gpiod_free(struct gpio_desc *desc); +void gpiod_free_commit(struct gpio_desc *desc); static inline int gpiod_request_user(struct gpio_desc *desc, const char *label) { From ba288833d899eb18acb7fc463bd0788957a67ff1 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Wed, 15 Oct 2025 18:31:29 +0530 Subject: [PATCH 278/659] FROMLIST: dt-bindings: media: qcom,qcs8300-camss: Add missing power supplies Add support for vdda-phy-supply and vdda-pll-supply in the QCS8300 CAMSS binding to reflect camera sensor hardware requirements. Co-developed-by: Nihal Kumar Gupta Signed-off-by: Nihal Kumar Gupta Signed-off-by: Vikram Sharma Link: https://lore.kernel.org/all/20251015130130.2790829-1-quic_vikramsa@quicinc.com --- .../bindings/media/qcom,qcs8300-camss.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml b/Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml index 80a4540a22dc2..dce0a1fcb10c6 100644 --- a/Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml @@ -120,6 +120,14 @@ properties: items: - const: top + vdda-phy-supply: + description: + Phandle to a regulator supply to PHY core block. + + vdda-pll-supply: + description: + Phandle to 1.8V regulator supply to PHY refclk pll block. + ports: $ref: /schemas/graph.yaml#/properties/ports @@ -160,6 +168,8 @@ required: - power-domains - power-domain-names - ports + - vdda-phy-supply + - vdda-pll-supply additionalProperties: false @@ -328,6 +338,9 @@ examples: power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>; power-domain-names = "top"; + vdda-phy-supply = <&vreg_l4a_0p88>; + vdda-pll-supply = <&vreg_l1c_1p2>; + ports { #address-cells = <1>; #size-cells = <0>; From 4b20d79e0cdb0b62f3914d9caff5bcfd4f0f9e79 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Wed, 15 Oct 2025 18:43:01 +0530 Subject: [PATCH 279/659] FROMLIST: dt-bindings: i2c: qcom-cci: Document qcs8300 compatible The three instances of CCI found on the QCS8300 are functionally the same as on a number of existing Qualcomm SoCs. Introduce a new SoC-specific compatible string "qcom,qcs8300-cci" with a common fallback. Signed-off-by: Nihal Kumar Gupta Signed-off-by: Vikram Sharma Reviewed-by: Bryan O'Donoghue Acked-by: Rob Herring (Arm) Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/all/20251015131303.2797800-1-quic_vikramsa@quicinc.com --- 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 a3fe1eea6aece..399a09409e071 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -28,6 +28,7 @@ properties: - enum: - qcom,kaanapali-cci - qcom,qcm2290-cci + - qcom,qcs8300-cci - qcom,sa8775p-cci - qcom,sc7280-cci - qcom,sc8280xp-cci @@ -133,6 +134,7 @@ allOf: enum: - qcom,kaanapali-cci - qcom,qcm2290-cci + - qcom,qcs8300-cci - qcom,sm8750-cci then: properties: From d8e79e54c0a637d70125f03b0745f2a3fcb3dfd2 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Tue, 6 Jan 2026 12:35:03 +0800 Subject: [PATCH 280/659] UPSTREAM: driver: bluetooth: btqca: Add WCN6855 firmware priority selection feature Historically, WCN685x and QCA2066 shared the same firmware files. Now, changes are planned for the firmware that will make it incompatible with QCA2066, so a new firmware name is required for WCN685x. Test Steps: - Boot device - Check the BTFW loading status via dmesg Sanity pass and Test Log: QCA Downloading qca/wcnhpbftfw21.tlv Direct firmware load for qca/wcnhpbftfw21.tlv failed with error -2 QCA Downloading qca/hpbftfw21.tlv Signed-off-by: Shuai Zhang Link: https://lore.kernel.org/all/20260106043503.534557-3-shuai.zhang@oss.qualcomm.com/ --- drivers/bluetooth/btqca.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 0af3e2109f310..74f820e89655e 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -830,8 +830,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/msbtfw%02x.mbn", rom_ver); break; case QCA_WCN6855: + /* Due to historical reasons, WCN685x chip has been using firmware + * without the "wcn" prefix. The mapping between the chip and its + * corresponding firmware has now been corrected. + */ snprintf(config.fwname, sizeof(config.fwname), - "qca/hpbtfw%02x.tlv", rom_ver); + "qca/wcnhpbtfw%02x.tlv", rom_ver); break; case QCA_WCN7850: snprintf(config.fwname, sizeof(config.fwname), @@ -855,6 +859,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/msbtfw%02x.tlv", rom_ver); bt_dev_info(hdev, "QCA Downloading %s", config.fwname); err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + } else if (err < 0 && !rampatch_name && soc_type == QCA_WCN6855) { + snprintf(config.fwname, sizeof(config.fwname), + "qca/hpbtfw%02x.tlv", rom_ver); + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); } if (err < 0) { @@ -920,7 +928,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, case QCA_WCN6855: qca_read_fw_board_id(hdev, &boardid); qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), - "hpnv", soc_type, ver, rom_ver, boardid); + "wcnhpnv", soc_type, ver, rom_ver, boardid); break; case QCA_WCN7850: qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), @@ -933,8 +941,15 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, } err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + if (err < 0 && !firmware_name && soc_type == QCA_WCN6855) { + qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), + "hpnv", soc_type, ver, rom_ver, boardid); + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + } + if (err < 0) { - bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + config.fwname, err); return err; } From 6f9e05ba46c49a9a3de5f44cb0b29f5316ba171d Mon Sep 17 00:00:00 2001 From: Hangxiang Ma Date: Mon, 12 Jan 2026 00:11:09 -0800 Subject: [PATCH 281/659] FROMGIT: media: camss: csiphy: Make CSIPHY status macro cross-platform The current value of '0xb0' that represents the offset to the status registers within the common registers of the CSIPHY has been changed on the newer SOCs and it requires generalizing the macro using a new variable 'common_status_offset'. This variable is initialized in the csiphy_init() function. Link: https://lore.kernel.org/all/20260112-camss-extended-csiphy-macro-v2-1-ee7342f2aaf5@oss.qualcomm.com/ Signed-off-by: Hangxiang Ma Reviewed-by: Bryan O'Donoghue --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 19 +++++++++++++------ .../media/platform/qcom/camss/camss-csiphy.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 619abbf607813..d70d4f6117988 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -46,7 +46,8 @@ #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_STATUSn(offset, n) ((offset) + 0xb0 + 0x4 * (n)) +#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, common_status_offset, n) \ + ((offset) + (common_status_offset) + 0x4 * (n)) #define CSIPHY_DEFAULT_PARAMS 0 #define CSIPHY_LANE_ENABLE 1 @@ -810,13 +811,17 @@ static void csiphy_hw_version_read(struct csiphy_device *csiphy, CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 6)); hw_version = readl_relaxed(csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, 12)); + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, + regs->common_status_offset, 12)); hw_version |= readl_relaxed(csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, 13)) << 8; + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, + regs->common_status_offset, 13)) << 8; hw_version |= readl_relaxed(csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, 14)) << 16; + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, + regs->common_status_offset, 14)) << 16; hw_version |= readl_relaxed(csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, 15)) << 24; + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, + regs->common_status_offset, 15)) << 24; dev_dbg(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version); } @@ -845,7 +850,8 @@ static irqreturn_t csiphy_isr(int irq, void *dev) for (i = 0; i < 11; i++) { int c = i + 22; u8 val = readl_relaxed(csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, i)); + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->offset, + regs->common_status_offset, i)); writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, c)); @@ -1086,6 +1092,7 @@ static int csiphy_init(struct csiphy_device *csiphy) csiphy->regs = regs; regs->offset = 0x800; + regs->common_status_offset = 0xb0; switch (csiphy->camss->res->version) { case CAMSS_845: diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 895f80003c441..2d5054819df7f 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -90,6 +90,7 @@ struct csiphy_device_regs { const struct csiphy_lane_regs *lane_regs; int lane_array_size; u32 offset; + u32 common_status_offset; }; struct csiphy_device { From e15d7932048cb72b8ad51b533a5b55e514017d78 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Fri, 14 Nov 2025 16:26:49 +0800 Subject: [PATCH 282/659] FROMGIT: media: qcom: camss: Add support for regulator init_load_uA in CSIPHY Some Qualcomm regulators are configured with initial mode as HPM (High Power Mode), which may lead to higher power consumption. To reduce power usage, it's preferable to set the initial mode to LPM (Low Power Mode). To ensure the regulator can switch from LPM to HPM when needed, this patch adds current load configuration for CAMSS CSIPHY. This allows the regulator framework to scale the mode dynamically based on the load requirement. The current default value for current is uninitialized or random. To address this, initial current values are added for the following platforms: MSM8916, MSM8939, MSM8953, MSM8996, QCM2290, SDM670, SM8250, SC7280, SM8550, SM8650, QCS8300, SA8775P and X1E80100. For SDM660, SDM845, SC8280XP the value is set to 0, indicating that no default current value is configured, the other values are derived from the power grid. Link: https://lore.kernel.org/all/20251114082649.4240-1-wenmeng.liu@oss.qualcomm.com/ Signed-off-by: Wenmeng Liu --- .../media/platform/qcom/camss/camss-csid.c | 18 +- .../media/platform/qcom/camss/camss-csiphy.c | 19 +- drivers/media/platform/qcom/camss/camss.c | 328 ++++++++++++++---- drivers/media/platform/qcom/camss/camss.h | 2 +- 4 files changed, 265 insertions(+), 102 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 5284b5857368c..ed1820488c987 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -1187,24 +1187,12 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, /* Regulator */ for (i = 0; i < ARRAY_SIZE(res->regulators); i++) { - if (res->regulators[i]) + if (res->regulators[i].supply) csid->num_supplies++; } - if (csid->num_supplies) { - csid->supplies = devm_kmalloc_array(camss->dev, - csid->num_supplies, - sizeof(*csid->supplies), - GFP_KERNEL); - if (!csid->supplies) - return -ENOMEM; - } - - for (i = 0; i < csid->num_supplies; i++) - csid->supplies[i].supply = res->regulators[i]; - - ret = devm_regulator_bulk_get(camss->dev, csid->num_supplies, - csid->supplies); + ret = devm_regulator_bulk_get_const(camss->dev, csid->num_supplies, + res->regulators, &csid->supplies); if (ret) return ret; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index a734fb7dde0a4..62623393f4144 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -695,24 +695,13 @@ int msm_csiphy_subdev_init(struct camss *camss, /* CSIPHY supplies */ for (i = 0; i < ARRAY_SIZE(res->regulators); i++) { - if (res->regulators[i]) + if (res->regulators[i].supply) csiphy->num_supplies++; } - if (csiphy->num_supplies) { - csiphy->supplies = devm_kmalloc_array(camss->dev, - csiphy->num_supplies, - sizeof(*csiphy->supplies), - GFP_KERNEL); - if (!csiphy->supplies) - return -ENOMEM; - } - - for (i = 0; i < csiphy->num_supplies; i++) - csiphy->supplies[i].supply = res->regulators[i]; - - ret = devm_regulator_bulk_get(camss->dev, csiphy->num_supplies, - csiphy->supplies); + if (csiphy->num_supplies > 0) + ret = devm_regulator_bulk_get_const(camss->dev, csiphy->num_supplies, + res->regulators, &csiphy->supplies); return ret; } diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index fcc2b2c3cba07..6cfb71fcd861c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -73,7 +73,9 @@ static const struct camss_subdev_resources csiphy_res_8x16[] = { static const struct camss_subdev_resources csid_res_8x16[] = { /* CSID0 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 40000 } + }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, .clock_rate = { { 0 }, @@ -95,7 +97,9 @@ static const struct camss_subdev_resources csid_res_8x16[] = { /* CSID1 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 40000 } + }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, .clock_rate = { { 0 }, @@ -157,7 +161,9 @@ static const struct camss_subdev_resources vfe_res_8x16[] = { static const struct camss_subdev_resources csiphy_res_8x39[] = { /* CSIPHY0 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 40000 } + }, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, .clock_rate = { { 0 }, { 40000000, 80000000 }, @@ -174,7 +180,9 @@ static const struct camss_subdev_resources csiphy_res_8x39[] = { /* CSIPHY1 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 40000 } + }, .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, .clock_rate = { { 0 }, { 40000000, 80000000 }, @@ -300,7 +308,9 @@ static const struct camss_subdev_resources vfe_res_8x39[] = { static const struct camss_subdev_resources csid_res_8x53[] = { /* CSID0 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 9900 } + }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, .clock_rate = { { 0 }, @@ -323,7 +333,9 @@ static const struct camss_subdev_resources csid_res_8x53[] = { /* CSID1 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 9900 } + }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, .clock_rate = { { 0 }, @@ -346,7 +358,9 @@ static const struct camss_subdev_resources csid_res_8x53[] = { /* CSID2 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 9900 } + }, .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, .clock_rate = { { 0 }, @@ -507,7 +521,9 @@ static const struct camss_subdev_resources csiphy_res_8x96[] = { static const struct camss_subdev_resources csid_res_8x96[] = { /* CSID0 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 80160 } + }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, .clock_rate = { { 0 }, @@ -529,7 +545,9 @@ static const struct camss_subdev_resources csid_res_8x96[] = { /* CSID1 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 80160 } + }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, .clock_rate = { { 0 }, @@ -551,7 +569,9 @@ static const struct camss_subdev_resources csid_res_8x96[] = { /* CSID2 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 80160 } + }, .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, .clock_rate = { { 0 }, @@ -573,7 +593,9 @@ static const struct camss_subdev_resources csid_res_8x96[] = { /* CSID3 */ { - .regulators = { "vdda" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 80160 } + }, .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", "csi3", "csi3_phy", "csi3_pix", "csi3_rdi" }, .clock_rate = { { 0 }, @@ -661,7 +683,10 @@ static const struct camss_subdev_resources vfe_res_8x96[] = { static const struct camss_subdev_resources csiphy_res_2290[] = { /* CSIPHY0 */ { - .regulators = { "vdd-csiphy-1p2", "vdd-csiphy-1p8" }, + .regulators = { + { .supply = "vdd-csiphy-1p2", .init_load_uA = 26700 }, + { .supply = "vdd-csiphy-1p8", .init_load_uA = 2600 } + }, .clock = { "top_ahb", "ahb", "csiphy0", "csiphy0_timer" }, .clock_rate = { { 0 }, { 0 }, @@ -678,7 +703,10 @@ static const struct camss_subdev_resources csiphy_res_2290[] = { /* CSIPHY1 */ { - .regulators = { "vdd-csiphy-1p2", "vdd-csiphy-1p8" }, + .regulators = { + { .supply = "vdd-csiphy-1p2", .init_load_uA = 26700 }, + { .supply = "vdd-csiphy-1p8", .init_load_uA = 2600 } + }, .clock = { "top_ahb", "ahb", "csiphy1", "csiphy1_timer" }, .clock_rate = { { 0 }, { 0 }, @@ -854,7 +882,10 @@ static const struct camss_subdev_resources csiphy_res_660[] = { static const struct camss_subdev_resources csid_res_660[] = { /* CSID0 */ { - .regulators = { "vdda", "vdd_sec" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 0 }, + { .supply = "vdd_sec", .init_load_uA = 0 } + }, .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi", "cphy_csid0" }, @@ -879,7 +910,10 @@ static const struct camss_subdev_resources csid_res_660[] = { /* CSID1 */ { - .regulators = { "vdda", "vdd_sec" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 0 }, + { .supply = "vdd_sec", .init_load_uA = 0 } + }, .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi", "cphy_csid1" }, @@ -904,7 +938,10 @@ static const struct camss_subdev_resources csid_res_660[] = { /* CSID2 */ { - .regulators = { "vdda", "vdd_sec" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 0 }, + { .supply = "vdd_sec", .init_load_uA = 0 } + }, .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", "csi2", "csi2_phy", "csi2_pix", "csi2_rdi", "cphy_csid2" }, @@ -929,7 +966,10 @@ static const struct camss_subdev_resources csid_res_660[] = { /* CSID3 */ { - .regulators = { "vdda", "vdd_sec" }, + .regulators = { + { .supply = "vdda", .init_load_uA = 0 }, + { .supply = "vdd_sec", .init_load_uA = 0 } + }, .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb", "csi3", "csi3_phy", "csi3_pix", "csi3_rdi", "cphy_csid3" }, @@ -1026,7 +1066,10 @@ static const struct camss_subdev_resources vfe_res_660[] = { static const struct camss_subdev_resources csiphy_res_670[] = { /* CSIPHY0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 42800 }, + { .supply = "vdda-pll", .init_load_uA = 13900 } + }, .clock = { "soc_ahb", "cpas_ahb", "csiphy0", "csiphy0_timer" }, .clock_rate = { { 0 }, @@ -1044,7 +1087,10 @@ static const struct camss_subdev_resources csiphy_res_670[] = { /* CSIPHY1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 42800 }, + { .supply = "vdda-pll", .init_load_uA = 13900 } + }, .clock = { "soc_ahb", "cpas_ahb", "csiphy1", "csiphy1_timer" }, .clock_rate = { { 0 }, @@ -1062,7 +1108,10 @@ static const struct camss_subdev_resources csiphy_res_670[] = { /* CSIPHY2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 42800 }, + { .supply = "vdda-pll", .init_load_uA = 13900 } + }, .clock = { "soc_ahb", "cpas_ahb", "csiphy2", "csiphy2_timer" }, .clock_rate = { { 0 }, @@ -1302,7 +1351,10 @@ static const struct camss_subdev_resources csiphy_res_845[] = { static const struct camss_subdev_resources csid_res_845[] = { /* CSID0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", "soc_ahb", "vfe0", "vfe0_src", "vfe0_cphy_rx", "csi0", @@ -1327,7 +1379,10 @@ static const struct camss_subdev_resources csid_res_845[] = { /* CSID1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", "soc_ahb", "vfe1", "vfe1_src", "vfe1_cphy_rx", "csi1", @@ -1352,7 +1407,10 @@ static const struct camss_subdev_resources csid_res_845[] = { /* CSID2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", "soc_ahb", "vfe_lite", "vfe_lite_src", "vfe_lite_cphy_rx", "csi2", @@ -1464,7 +1522,10 @@ static const struct camss_subdev_resources vfe_res_845[] = { static const struct camss_subdev_resources csiphy_res_8250[] = { /* CSIPHY0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 17500 }, + { .supply = "vdda-pll", .init_load_uA = 10000 } + }, .clock = { "csiphy0", "csiphy0_timer" }, .clock_rate = { { 400000000 }, { 300000000 } }, @@ -1478,7 +1539,10 @@ static const struct camss_subdev_resources csiphy_res_8250[] = { }, /* CSIPHY1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 17500 }, + { .supply = "vdda-pll", .init_load_uA = 10000 } + }, .clock = { "csiphy1", "csiphy1_timer" }, .clock_rate = { { 400000000 }, { 300000000 } }, @@ -1492,7 +1556,10 @@ static const struct camss_subdev_resources csiphy_res_8250[] = { }, /* CSIPHY2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 17500 }, + { .supply = "vdda-pll", .init_load_uA = 10000 } + }, .clock = { "csiphy2", "csiphy2_timer" }, .clock_rate = { { 400000000 }, { 300000000 } }, @@ -1506,7 +1573,10 @@ static const struct camss_subdev_resources csiphy_res_8250[] = { }, /* CSIPHY3 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 17500 }, + { .supply = "vdda-pll", .init_load_uA = 10000 } + }, .clock = { "csiphy3", "csiphy3_timer" }, .clock_rate = { { 400000000 }, { 300000000 } }, @@ -1520,7 +1590,10 @@ static const struct camss_subdev_resources csiphy_res_8250[] = { }, /* CSIPHY4 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 17500 }, + { .supply = "vdda-pll", .init_load_uA = 10000 } + }, .clock = { "csiphy4", "csiphy4_timer" }, .clock_rate = { { 400000000 }, { 300000000 } }, @@ -1534,7 +1607,10 @@ static const struct camss_subdev_resources csiphy_res_8250[] = { }, /* CSIPHY5 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 17500 }, + { .supply = "vdda-pll", .init_load_uA = 10000 } + }, .clock = { "csiphy5", "csiphy5_timer" }, .clock_rate = { { 400000000 }, { 300000000 } }, @@ -1748,7 +1824,10 @@ static const struct resources_icc icc_res_sm8250[] = { static const struct camss_subdev_resources csiphy_res_7280[] = { /* CSIPHY0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 16100 }, + { .supply = "vdda-pll", .init_load_uA = 9000 } + }, .clock = { "csiphy0", "csiphy0_timer" }, .clock_rate = { { 300000000, 400000000 }, @@ -1763,7 +1842,10 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { }, /* CSIPHY1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 16100 }, + { .supply = "vdda-pll", .init_load_uA = 9000 } + }, .clock = { "csiphy1", "csiphy1_timer" }, .clock_rate = { { 300000000, 400000000 }, @@ -1778,7 +1860,10 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { }, /* CSIPHY2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 16100 }, + { .supply = "vdda-pll", .init_load_uA = 9000 } + }, .clock = { "csiphy2", "csiphy2_timer" }, .clock_rate = { { 300000000, 400000000 }, @@ -1793,7 +1878,10 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { }, /* CSIPHY3 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 16100 }, + { .supply = "vdda-pll", .init_load_uA = 9000 } + }, .clock = { "csiphy3", "csiphy3_timer" }, .clock_rate = { { 300000000, 400000000 }, @@ -1808,7 +1896,10 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { }, /* CSIPHY4 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 16100 }, + { .supply = "vdda-pll", .init_load_uA = 9000 } + }, .clock = { "csiphy4", "csiphy4_timer" }, .clock_rate = { { 300000000, 400000000 }, @@ -2121,7 +2212,10 @@ static const struct camss_subdev_resources csiphy_res_sc8280xp[] = { static const struct camss_subdev_resources csid_res_sc8280xp[] = { /* CSID0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2137,7 +2231,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2153,7 +2250,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2169,7 +2269,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID3 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2185,7 +2288,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID_LITE0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2201,7 +2307,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID_LITE1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2217,7 +2326,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID_LITE2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2233,7 +2345,10 @@ static const struct camss_subdev_resources csid_res_sc8280xp[] = { }, /* CSID_LITE3 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 0 }, + { .supply = "vdda-pll", .init_load_uA = 0 } + }, .clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" }, .clock_rate = { { 400000000, 480000000, 600000000 }, { 0 }, @@ -2434,7 +2549,10 @@ static const struct resources_icc icc_res_sc8280xp[] = { static const struct camss_subdev_resources csiphy_res_8550[] = { /* CSIPHY0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 32200 }, + { .supply = "vdda-pll", .init_load_uA = 18000 } + }, .clock = { "csiphy0", "csiphy0_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2448,7 +2566,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 32200 }, + { .supply = "vdda-pll", .init_load_uA = 18000 } + }, .clock = { "csiphy1", "csiphy1_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2462,7 +2583,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 32200 }, + { .supply = "vdda-pll", .init_load_uA = 18000 } + }, .clock = { "csiphy2", "csiphy2_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2476,7 +2600,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY3 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 32200 }, + { .supply = "vdda-pll", .init_load_uA = 18000 } + }, .clock = { "csiphy3", "csiphy3_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2490,7 +2617,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY4 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 37900 }, + { .supply = "vdda-pll", .init_load_uA = 18600 } + }, .clock = { "csiphy4", "csiphy4_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2504,7 +2634,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY5 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 32200 }, + { .supply = "vdda-pll", .init_load_uA = 18000 } + }, .clock = { "csiphy5", "csiphy5_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2518,7 +2651,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY6 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 37900 }, + { .supply = "vdda-pll", .init_load_uA = 18600 } + }, .clock = { "csiphy6", "csiphy6_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2532,7 +2668,10 @@ static const struct camss_subdev_resources csiphy_res_8550[] = { }, /* CSIPHY7 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 32200 }, + { .supply = "vdda-pll", .init_load_uA = 18000 } + }, .clock = { "csiphy7", "csiphy7_timer" }, .clock_rate = { { 400000000, 480000000 }, { 400000000 } }, @@ -2763,7 +2902,10 @@ static const struct resources_icc icc_res_sm8550[] = { static const struct camss_subdev_resources csiphy_res_sm8650[] = { /* CSIPHY0 */ { - .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", }, + .regulators = { + { .supply = "vdd-csiphy01-0p9", .init_load_uA = 88000 }, + { .supply = "vdd-csiphy01-1p2", .init_load_uA = 17800 }, + }, .clock = { "csiphy0", "csiphy0_timer" }, .clock_rate = { { 400000000 }, { 400000000 } }, @@ -2777,7 +2919,10 @@ static const struct camss_subdev_resources csiphy_res_sm8650[] = { }, /* CSIPHY1 */ { - .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", }, + .regulators = { + { .supply = "vdd-csiphy01-0p9", .init_load_uA = 88000 }, + { .supply = "vdd-csiphy01-1p2", .init_load_uA = 17800 }, + }, .clock = { "csiphy1", "csiphy1_timer" }, .clock_rate = { { 400000000 }, { 400000000 } }, @@ -2791,7 +2936,10 @@ static const struct camss_subdev_resources csiphy_res_sm8650[] = { }, /* CSIPHY2 */ { - .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", }, + .regulators = { + { .supply = "vdd-csiphy24-0p9", .init_load_uA = 147000 }, + { .supply = "vdd-csiphy24-1p2", .init_load_uA = 24400 }, + }, .clock = { "csiphy2", "csiphy2_timer" }, .clock_rate = { { 400000000 }, { 400000000 } }, @@ -2805,7 +2953,10 @@ static const struct camss_subdev_resources csiphy_res_sm8650[] = { }, /* CSIPHY3 */ { - .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", }, + .regulators = { + { .supply = "vdd-csiphy35-0p9", .init_load_uA = 88000 }, + { .supply = "vdd-csiphy35-1p2", .init_load_uA = 17800 }, + }, .clock = { "csiphy3", "csiphy3_timer" }, .clock_rate = { { 400000000 }, { 400000000 } }, @@ -2819,7 +2970,10 @@ static const struct camss_subdev_resources csiphy_res_sm8650[] = { }, /* CSIPHY4 */ { - .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", }, + .regulators = { + { .supply = "vdd-csiphy24-0p9", .init_load_uA = 147000 }, + { .supply = "vdd-csiphy24-1p2", .init_load_uA = 24400 }, + }, .clock = { "csiphy4", "csiphy4_timer" }, .clock_rate = { { 400000000 }, { 400000000 } }, @@ -2833,7 +2987,10 @@ static const struct camss_subdev_resources csiphy_res_sm8650[] = { }, /* CSIPHY5 */ { - .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", }, + .regulators = { + { .supply = "vdd-csiphy35-0p9", .init_load_uA = 88000 }, + { .supply = "vdd-csiphy35-1p2", .init_load_uA = 17800 }, + }, .clock = { "csiphy5", "csiphy5_timer" }, .clock_rate = { { 400000000 }, { 400000000 } }, @@ -3074,7 +3231,10 @@ static const struct resources_icc icc_res_sm8650[] = { static const struct camss_subdev_resources csiphy_res_8300[] = { /* CSIPHY0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy0", "csiphy0_timer" }, .clock_rate = { @@ -3092,7 +3252,10 @@ static const struct camss_subdev_resources csiphy_res_8300[] = { }, /* CSIPHY1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy1", "csiphy1_timer" }, .clock_rate = { @@ -3110,7 +3273,10 @@ static const struct camss_subdev_resources csiphy_res_8300[] = { }, /* CSIPHY2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy2", "csiphy2_timer" }, .clock_rate = { @@ -3131,7 +3297,10 @@ static const struct camss_subdev_resources csiphy_res_8300[] = { static const struct camss_subdev_resources csiphy_res_8775p[] = { /* CSIPHY0 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy0", "csiphy0_timer"}, .clock_rate = { { 400000000 }, @@ -3148,7 +3317,10 @@ static const struct camss_subdev_resources csiphy_res_8775p[] = { }, /* CSIPHY1 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy1", "csiphy1_timer"}, .clock_rate = { { 400000000 }, @@ -3165,7 +3337,10 @@ static const struct camss_subdev_resources csiphy_res_8775p[] = { }, /* CSIPHY2 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy2", "csiphy2_timer"}, .clock_rate = { { 400000000 }, @@ -3182,7 +3357,10 @@ static const struct camss_subdev_resources csiphy_res_8775p[] = { }, /* CSIPHY3 */ { - .regulators = { "vdda-phy", "vdda-pll" }, + .regulators = { + { .supply = "vdda-phy", .init_load_uA = 15900 }, + { .supply = "vdda-pll", .init_load_uA = 8900 } + }, .clock = { "csiphy_rx", "csiphy3", "csiphy3_timer"}, .clock_rate = { { 400000000 }, @@ -3535,8 +3713,10 @@ static const struct resources_icc icc_res_sa8775p[] = { static const struct camss_subdev_resources csiphy_res_x1e80100[] = { /* CSIPHY0 */ { - .regulators = { "vdd-csiphy-0p8", - "vdd-csiphy-1p2" }, + .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 } }, @@ -3550,8 +3730,10 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { }, /* CSIPHY1 */ { - .regulators = { "vdd-csiphy-0p8", - "vdd-csiphy-1p2" }, + .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 } }, @@ -3565,8 +3747,10 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { }, /* CSIPHY2 */ { - .regulators = { "vdd-csiphy-0p8", - "vdd-csiphy-1p2" }, + .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 } }, @@ -3580,8 +3764,10 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { }, /* CSIPHY4 */ { - .regulators = { "vdd-csiphy-0p8", - "vdd-csiphy-1p2" }, + .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 } }, diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 9d9a62640e25d..e34f06b4e1536 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -44,7 +44,7 @@ #define CAMSS_INIT_BUF_COUNT 2 struct camss_subdev_resources { - char *regulators[CAMSS_RES_MAX]; + struct regulator_bulk_data regulators[CAMSS_RES_MAX]; char *clock[CAMSS_RES_MAX]; char *clock_for_reset[CAMSS_RES_MAX]; u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX]; From 668bf834cd625c15b01c1bf5802701bf0df0f209 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 20 Oct 2025 17:02:27 +0300 Subject: [PATCH 283/659] FROMGIT: media: qcom: camss: Do not enable cpas fast ahb clock for SM8550 VFE lite The clock is needed to stream images over a full VFE IP on SM8550 CAMSS, and it should not be enabled, when an image stream is routed over any of two lite VFE IPs on the SoC. Link: https://lore.kernel.org/all/20251020140227.2264634-1-vladimir.zapolskiy@linaro.org/ Signed-off-by: Vladimir Zapolskiy Acked-by: Bryan O'Donoghue --- drivers/media/platform/qcom/camss/camss.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 6cfb71fcd861c..9122568f9b0ae 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -2843,12 +2843,11 @@ static const struct camss_subdev_resources vfe_res_8550[] = { /* VFE3 lite */ { .regulators = {}, - .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe_lite_ahb", + .clock = { "gcc_axi_hf", "cpas_ahb", "vfe_lite_ahb", "vfe_lite", "cpas_ife_lite", "camnoc_axi" }, .clock_rate = { { 0 }, { 80000000 }, { 300000000, 400000000 }, - { 300000000, 400000000 }, { 400000000, 480000000 }, { 300000000, 400000000 }, { 300000000, 400000000 } }, @@ -2865,12 +2864,11 @@ static const struct camss_subdev_resources vfe_res_8550[] = { /* VFE4 lite */ { .regulators = {}, - .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb_clk", "vfe_lite_ahb", + .clock = { "gcc_axi_hf", "cpas_ahb", "vfe_lite_ahb", "vfe_lite", "cpas_ife_lite", "camnoc_axi" }, .clock_rate = { { 0 }, { 80000000 }, { 300000000, 400000000 }, - { 300000000, 400000000 }, { 400000000, 480000000 }, { 300000000, 400000000 }, { 300000000, 400000000 } }, From fd42b10d7d891165113d7d16fafa0ef9d03d3fad Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Thu, 11 Dec 2025 14:59:39 +0100 Subject: [PATCH 284/659] FROMGIT: media: qcom: camss: csid-340: Fix unused variables The CSID driver has some unused variables and function parameters that are no longer needed (due to refactoring). Clean up those unused elements: - Remove the `vc` parameter from `__csid_configure_rx()`. - Drop the unused `lane_cnt` variable. - Adjust call to `__csid_configure_rx()` accordingly. Link: https://lore.kernel.org/all/20251211135939.1779544-1-loic.poulain@oss.qualcomm.com/ Signed-off-by: Loic Poulain Reviewed-by: Bryan O'Donoghue Reviewed-by: Vladimir Zapolskiy --- drivers/media/platform/qcom/camss/camss-csid-340.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid-340.c b/drivers/media/platform/qcom/camss/camss-csid-340.c index 22a30510fb792..2b50f9b96a34e 100644 --- a/drivers/media/platform/qcom/camss/camss-csid-340.c +++ b/drivers/media/platform/qcom/camss/camss-csid-340.c @@ -55,8 +55,7 @@ #define CSID_RDI_CTRL_HALT_AT_FRAME_BOUNDARY 0 #define CSID_RDI_CTRL_RESUME_AT_FRAME_BOUNDARY 1 -static void __csid_configure_rx(struct csid_device *csid, - struct csid_phy_config *phy, int vc) +static void __csid_configure_rx(struct csid_device *csid, struct csid_phy_config *phy) { u32 val; @@ -81,13 +80,9 @@ static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats, csid->res->formats->nformats, input_format->code); - u8 lane_cnt = csid->phy.lane_cnt; u8 dt_id; u32 val; - if (!lane_cnt) - lane_cnt = 4; - /* * DT_ID is a two bit bitfield that is concatenated with * the four least significant bits of the five bit VC @@ -120,10 +115,11 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) { int i; + __csid_configure_rx(csid, &csid->phy); + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) { if (csid->phy.en_vc & BIT(i)) { __csid_configure_rdi_stream(csid, enable, i); - __csid_configure_rx(csid, &csid->phy, i); __csid_ctrl_rdi(csid, enable, i); } } From 08e5c99acedc1224136ab11bb11321aa19a08c40 Mon Sep 17 00:00:00 2001 From: Alper Ak Date: Mon, 29 Dec 2025 10:52:17 +0300 Subject: [PATCH 285/659] FROMGIT: media: qcom: camss: vfe: Fix out-of-bounds access in vfe_isr_reg_update() vfe_isr() iterates using MSM_VFE_IMAGE_MASTERS_NUM(7) as the loop bound and passes the index to vfe_isr_reg_update(). However, vfe->line[] array is defined with VFE_LINE_NUM_MAX(4): struct vfe_line line[VFE_LINE_NUM_MAX]; When index is 4, 5, 6, the access to vfe->line[line_id] exceeds the array bounds and resulting in out-of-bounds memory access. Fix this by using separate loops for output lines and write masters. Fixes: 4edc8eae715c ("media: camss: Add initial support for VFE hardware version Titan 480") Link: https://lore.kernel.org/all/20251229075217.24679-1-alperyasinak1@gmail.com/ Signed-off-by: Alper Ak Reviewed-by: Bryan O'Donoghue --- drivers/media/platform/qcom/camss/camss-vfe-480.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c index 4feea590a47bc..d73f733fde045 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-480.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c @@ -202,11 +202,13 @@ static irqreturn_t vfe_isr(int irq, void *dev) writel_relaxed(status, vfe->base + VFE_BUS_IRQ_CLEAR(0)); writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL); - /* Loop through all WMs IRQs */ - for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) { + for (i = 0; i < MAX_VFE_OUTPUT_LINES; i++) { if (status & BUS_IRQ_MASK_0_RDI_RUP(vfe, i)) vfe_isr_reg_update(vfe, i); + } + /* Loop through all WMs IRQs */ + for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) { if (status & BUS_IRQ_MASK_0_COMP_DONE(vfe, RDI_COMP_GROUP(i))) vfe_buf_done(vfe, i); } From 152303a8ed5ecb5ed6625e1fed14efceb795943b Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 20 Nov 2025 02:46:03 +0200 Subject: [PATCH 286/659] FROMGIT: media: qcom: camss: change internals of endpoint parsing to fwnode handling Since a few called V4L2 functions operate with fwnode arguments the change from OF device nodes to fwnodes brings a simplification to the code. The camss_parse_endpoint_node() function is called once by camss_probe(), and there is no use of knowing a number of asynchronously registered remote devices, so it makes sense to remove the related computation from the function. Link: https://lore.kernel.org/all/20251120004604.2573803-2-vladimir.zapolskiy@linaro.org/ Tested-by: Loic Poulain Signed-off-by: Vladimir Zapolskiy --- drivers/media/platform/qcom/camss/camss.c | 49 +++++++++++------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 9122568f9b0ae..8e0809202362c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4206,16 +4206,16 @@ static const struct parent_dev_ops vfe_parent_dev_ops = { }; /* - * camss_of_parse_endpoint_node - Parse port endpoint node - * @dev: Device - * @node: Device node to be parsed + * camss_parse_endpoint_node - Parse port endpoint node + * @dev: CAMSS device + * @ep: Device endpoint to be parsed * @csd: Parsed data from port endpoint node * * Return 0 on success or a negative error code on failure */ -static int camss_of_parse_endpoint_node(struct device *dev, - struct device_node *node, - struct camss_async_subdev *csd) +static int camss_parse_endpoint_node(struct device *dev, + struct fwnode_handle *ep, + struct camss_async_subdev *csd) { struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; struct v4l2_mbus_config_mipi_csi2 *mipi_csi2; @@ -4223,7 +4223,7 @@ static int camss_of_parse_endpoint_node(struct device *dev, unsigned int i; int ret; - ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); + ret = v4l2_fwnode_endpoint_parse(ep, &vep); if (ret) return ret; @@ -4258,49 +4258,46 @@ static int camss_of_parse_endpoint_node(struct device *dev, } /* - * camss_of_parse_ports - Parse ports node - * @dev: Device - * @notifier: v4l2_device notifier data + * camss_parse_ports - Parse ports node + * @dev: CAMSS device * - * Return number of "port" nodes found in "ports" node + * Return 0 on success or a negative error code on failure */ -static int camss_of_parse_ports(struct camss *camss) +static int camss_parse_ports(struct camss *camss) { struct device *dev = camss->dev; - struct device_node *node = NULL; - struct device_node *remote = NULL; - int ret, num_subdevs = 0; + struct fwnode_handle *fwnode = dev_fwnode(dev), *ep; + int ret; - for_each_endpoint_of_node(dev->of_node, node) { + fwnode_graph_for_each_endpoint(fwnode, ep) { struct camss_async_subdev *csd; + struct fwnode_handle *remote; - remote = of_graph_get_remote_port_parent(node); + remote = fwnode_graph_get_remote_port_parent(ep); if (!remote) { dev_err(dev, "Cannot get remote parent\n"); ret = -EINVAL; goto err_cleanup; } - csd = v4l2_async_nf_add_fwnode(&camss->notifier, - of_fwnode_handle(remote), + csd = v4l2_async_nf_add_fwnode(&camss->notifier, remote, struct camss_async_subdev); - of_node_put(remote); + fwnode_handle_put(remote); if (IS_ERR(csd)) { ret = PTR_ERR(csd); goto err_cleanup; } - ret = camss_of_parse_endpoint_node(dev, node, csd); + ret = camss_parse_endpoint_node(dev, ep, csd); if (ret < 0) goto err_cleanup; - - num_subdevs++; } - return num_subdevs; + return 0; err_cleanup: - of_node_put(node); + fwnode_handle_put(ep); + return ret; } @@ -4857,7 +4854,7 @@ static int camss_probe(struct platform_device *pdev) pm_runtime_enable(dev); - ret = camss_of_parse_ports(camss); + ret = camss_parse_ports(camss); if (ret < 0) goto err_v4l2_device_unregister; From 906731a0317dfbbe523ece94efceee6909b92754 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 20 Nov 2025 02:46:04 +0200 Subject: [PATCH 287/659] FROMGIT: media: qcom: camss: use a handy v4l2_async_nf_add_fwnode_remote() function Another code simplification makes parsing of remote endpoints easy. Link: https://lore.kernel.org/all/20251120004604.2573803-3-vladimir.zapolskiy@linaro.org/ Tested-by: Loic Poulain Signed-off-by: Vladimir Zapolskiy --- drivers/media/platform/qcom/camss/camss.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 8e0809202362c..7f44b60bcd72c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4271,18 +4271,9 @@ static int camss_parse_ports(struct camss *camss) fwnode_graph_for_each_endpoint(fwnode, ep) { struct camss_async_subdev *csd; - struct fwnode_handle *remote; - remote = fwnode_graph_get_remote_port_parent(ep); - if (!remote) { - dev_err(dev, "Cannot get remote parent\n"); - ret = -EINVAL; - goto err_cleanup; - } - - 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; From 15580c77171bf211b86ce2fa9675a7fda37e676d Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Mon, 12 Jan 2026 16:04:52 +0800 Subject: [PATCH 288/659] FROMGIT: media: dt-bindings: Add qcom,sm6150-camss Add bindings for the Camera Subsystem on the SM6150 SoC The SM6150 platform provides: - 2 x VFE (version 170), each with 3 RDI - 1 x VFE Lite (version 170), each with 4 RDI - 2 x CSID (version 170) - 1 x CSID Lite (version 170) - 3 x CSIPHY (version 2.0.0) - 1 x BPS (Bayer Processing Segment) - 1 x ICP (Imaging Control Processor) - 1 x IPE (Image Postprocessing Engine) - 1 x JPEG Encoder/Decoder - 1 x LRME (Low Resolution Motion Estimation) Link: https://lore.kernel.org/all/20260112-sm6150-camss-v4-1-0cd576d627f7@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue --- .../bindings/media/qcom,sm6150-camss.yaml | 439 ++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,sm6150-camss.yaml diff --git a/Documentation/devicetree/bindings/media/qcom,sm6150-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm6150-camss.yaml new file mode 100644 index 0000000000000..ba7b0acb9128b --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,sm6150-camss.yaml @@ -0,0 +1,439 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,sm6150-camss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SM6150 Camera Subsystem (CAMSS) + +maintainers: + - Wenmeng Liu + +description: + This binding describes the camera subsystem hardware found on SM6150 + Qualcomm SoCs. It includes submodules such as CSIPHY (CSI Physical layer) + and CSID (CSI Decoder), which comply with the MIPI CSI2 protocol. + + The subsystem also integrates a set of real-time image processing engines + and their associated configuration modules, as well as non-real-time engines. + +properties: + compatible: + const: qcom,sm6150-camss + + reg: + items: + - description: Registers for CSID 0 + - description: Registers for CSID 1 + - description: Registers for CSID Lite + - description: Registers for CSIPHY 0 + - description: Registers for CSIPHY 1 + - description: Registers for CSIPHY 2 + - description: Registers for VFE 0 + - description: Registers for VFE 1 + - description: Registers for VFE Lite + - description: Registers for BPS (Bayer Processing Segment) + - description: Registers for CAMNOC + - description: Registers for CPAS CDM + - description: Registers for CPAS TOP + - description: Registers for ICP (Imaging Control Processor) CSR (Control and Status Registers) + - description: Registers for ICP QGIC (Qualcomm Generic Interrupt Controller) + - description: Registers for ICP SIERRA ((A5 subsystem communication)) + - description: Registers for IPE (Image Postprocessing Engine) 0 + - description: Registers for JPEG DMA + - description: Registers for JPEG ENC + - description: Registers for LRME (Low Resolution Motion Estimation) + + reg-names: + items: + - const: csid0 + - const: csid1 + - const: csid_lite + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: vfe0 + - const: vfe1 + - const: vfe_lite + - const: bps + - const: camnoc + - const: cpas_cdm + - const: cpas_top + - const: icp_csr + - const: icp_qgic + - const: icp_sierra + - const: ipe0 + - const: jpeg_dma + - const: jpeg_enc + - const: lrme + + clocks: + maxItems: 33 + + clock-names: + items: + - const: gcc_ahb + - const: gcc_axi_hf + - const: camnoc_axi + - const: cpas_ahb + - const: csiphy0 + - const: csiphy0_timer + - const: csiphy1 + - const: csiphy1_timer + - const: csiphy2 + - const: csiphy2_timer + - const: soc_ahb + - const: vfe0 + - const: vfe0_axi + - const: vfe0_cphy_rx + - const: vfe0_csid + - const: vfe1 + - const: vfe1_axi + - const: vfe1_cphy_rx + - const: vfe1_csid + - const: vfe_lite + - const: vfe_lite_cphy_rx + - const: vfe_lite_csid + - const: bps + - const: bps_ahb + - const: bps_axi + - const: bps_areg + - const: icp + - const: ipe0 + - const: ipe0_ahb + - const: ipe0_areg + - const: ipe0_axi + - const: jpeg + - const: lrme + + interrupts: + maxItems: 15 + + interrupt-names: + items: + - const: csid0 + - const: csid1 + - const: csid_lite + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: vfe0 + - const: vfe1 + - const: vfe_lite + - const: camnoc + - const: cdm + - const: icp + - const: jpeg_dma + - const: jpeg_enc + - const: lrme + + interconnects: + maxItems: 4 + + interconnect-names: + items: + - const: ahb + - const: hf_0 + - const: hf_1 + - const: sf_mnoc + + iommus: + items: + - description: Camera IFE 0 non-protected stream + - description: Camera IFE 1 non-protected stream + - description: Camera IFE 3 non-protected stream + - description: Camera CDM non-protected stream + - description: Camera LRME read non-protected stream + - description: Camera IPE 0 read non-protected stream + - description: Camera BPS read non-protected stream + - description: Camera IPE 0 write non-protected stream + - description: Camera BPS write non-protected stream + - description: Camera LRME write non-protected stream + - description: Camera JPEG read non-protected stream + - description: Camera JPEG write non-protected stream + - description: Camera ICP stream + + power-domains: + items: + - description: + IFE0 GDSC - Image Front End, Global Distributed Switch Controller. + - description: + IFE1 GDSC - Image Front End, Global Distributed Switch Controller. + - description: + Titan GDSC - Titan ISP Block, Global Distributed Switch Controller. + - description: + Titan BPS - Bayer Processing Segment, Global Distributed Switch Controller. + - description: + IPE GDSC - Image Postprocessing Engine, Global Distributed Switch Controller. + + power-domain-names: + items: + - const: ife0 + - const: ife1 + - const: top + - const: bps + - const: ipe + + vdd-csiphy-1p2-supply: + description: + Phandle to a 1.2V regulator supply to CSI PHYs. + + vdd-csiphy-1p8-supply: + description: + Phandle to 1.8V regulator supply to CSI PHYs pll block. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + patternProperties: + "^port@[0-2]$": + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + + description: + Input port for receiving CSI data from a CSIPHY. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interrupts + - interrupt-names + - interconnects + - interconnect-names + - iommus + - power-domains + - power-domain-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + 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"; + + vdd-csiphy-1p2-supply = <&vreg_l11a_1p2>; + vdd-csiphy-1p8-supply = <&vreg_l12a_1p8>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + csiphy_ep0: endpoint { + data-lanes = <0 1>; + remote-endpoint = <&sensor_ep>; + }; + }; + }; + }; + }; From f1ecd84b35619e3b94105062aac35273aaee290e Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Mon, 12 Jan 2026 16:04:53 +0800 Subject: [PATCH 289/659] FROMGIT: media: qcom: camss: add support for SM6150 camss The camera subsystem for SM6150 which is based on Spectra 230. For SM6150: - VFE and CSID version: 170 (vfe170, csid170) - CSIPHY version: csiphy-v2.0.1 (14nm) Link: https://lore.kernel.org/all/20260112-sm6150-camss-v4-2-0cd576d627f7@oss.qualcomm.com/ Reviewed-by: Vladimir Zapolskiy Signed-off-by: Wenmeng Liu Reviewed-by: Bryan O'Donoghue --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 2 + drivers/media/platform/qcom/camss/camss-vfe.c | 2 + drivers/media/platform/qcom/camss/camss.c | 198 ++++++++++++++++++ drivers/media/platform/qcom/camss/camss.h | 1 + 4 files changed, 203 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index d70d4f6117988..4154832745525 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -1010,6 +1010,7 @@ static bool csiphy_is_gen2(u32 version) switch (version) { case CAMSS_2290: + case CAMSS_6150: case CAMSS_7280: case CAMSS_8250: case CAMSS_8280XP: @@ -1100,6 +1101,7 @@ static int csiphy_init(struct csiphy_device *csiphy) regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845); break; case CAMSS_2290: + case CAMSS_6150: regs->lane_regs = &lane_regs_qcm2290[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_qcm2290); break; diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 9c7ad8aa40588..5baf0e3d4bc46 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -342,6 +342,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, break; case CAMSS_660: case CAMSS_2290: + case CAMSS_6150: case CAMSS_7280: case CAMSS_8x96: case CAMSS_8250: @@ -2001,6 +2002,7 @@ static int vfe_bpl_align(struct vfe_device *vfe) int ret = 8; switch (vfe->camss->res->version) { + case CAMSS_6150: case CAMSS_7280: case CAMSS_8250: case CAMSS_8280XP: diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 7f44b60bcd72c..00b87fd9afbd8 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -1519,6 +1519,190 @@ static const struct camss_subdev_resources vfe_res_845[] = { } }; +static const struct camss_subdev_resources csiphy_res_sm6150[] = { + /* CSIPHY0 */ + { + .regulators = { + { .supply = "vdd-csiphy-1p2", .init_load_uA = 35000 }, + { .supply = "vdd-csiphy-1p8", .init_load_uA = 5000 } + }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 269333333, 384000000 }, + { 269333333 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY1 */ + { + .regulators = { + { .supply = "vdd-csiphy-1p2", .init_load_uA = 35000 }, + { .supply = "vdd-csiphy-1p8", .init_load_uA = 5000 } + }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 269333333, 384000000 }, + { 269333333 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, + /* CSIPHY2 */ + { + .regulators = { + { .supply = "vdd-csiphy-1p2", .init_load_uA = 35000 }, + { .supply = "vdd-csiphy-1p8", .init_load_uA = 5000 } + }, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 269333333, 384000000 }, + { 269333333 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845 + } + }, +}; + +static const struct camss_subdev_resources csid_res_sm6150[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "vfe0_cphy_rx", "vfe0_csid" }, + .clock_rate = { { 269333333, 384000000 }, + { 320000000, 540000000 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID1 */ + { + .regulators = {}, + .clock = { "vfe1_cphy_rx", "vfe1_csid" }, + .clock_rate = { { 269333333, 384000000 }, + { 320000000, 540000000 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .is_lite = false, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, + /* CSID2 */ + { + .regulators = {}, + .clock = { "vfe_lite_cphy_rx", "vfe_lite_csid" }, + .clock_rate = { { 269333333, 384000000 }, + { 320000000, 540000000 } }, + .reg = { "csid_lite" }, + .interrupt = { "csid_lite" }, + .csid = { + .is_lite = true, + .hw_ops = &csid_ops_gen2, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_gen2 + } + }, +}; + +static const struct camss_subdev_resources vfe_res_sm6150[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "camnoc_axi", "cpas_ahb", "soc_ahb", + "vfe0", "vfe0_axi"}, + .clock_rate = { { 0 }, + { 0 }, + { 80000000 }, + { 37500000, 40000000 }, + { 360000000, 432000000, 540000000, 600000000 }, + { 265000000, 426000000 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE1 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "camnoc_axi", "cpas_ahb", "soc_ahb", + "vfe1", "vfe1_axi"}, + .clock_rate = { { 0 }, + { 0 }, + { 80000000 }, + { 37500000, 40000000 }, + { 360000000, 432000000, 540000000, 600000000 }, + { 265000000, 426000000 } }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .is_lite = false, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, + /* VFE2 */ + { + .regulators = {}, + .clock = { "gcc_axi_hf", "camnoc_axi", "cpas_ahb", "soc_ahb", + "vfe_lite" }, + .clock_rate = { { 0 }, + { 0 }, + { 80000000 }, + { 37500000, 40000000 }, + { 360000000, 432000000, 540000000, 600000000 } }, + .reg = { "vfe_lite" }, + .interrupt = { "vfe_lite" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_170, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + } + }, +}; + +static const struct resources_icc icc_res_sm6150[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "hf_0", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + static const struct camss_subdev_resources csiphy_res_8250[] = { /* CSIPHY0 */ { @@ -5036,6 +5220,19 @@ static const struct camss_resources sdm845_resources = { .vfe_num = ARRAY_SIZE(vfe_res_845), }; +static const struct camss_resources sm6150_resources = { + .version = CAMSS_6150, + .pd_name = "top", + .csiphy_res = csiphy_res_sm6150, + .csid_res = csid_res_sm6150, + .vfe_res = vfe_res_sm6150, + .icc_res = icc_res_sm6150, + .icc_path_num = ARRAY_SIZE(icc_res_sm6150), + .csiphy_num = ARRAY_SIZE(csiphy_res_sm6150), + .csid_num = ARRAY_SIZE(csid_res_sm6150), + .vfe_num = ARRAY_SIZE(vfe_res_sm6150), +}; + static const struct camss_resources sm8250_resources = { .version = CAMSS_8250, .pd_name = "top", @@ -5131,6 +5328,7 @@ static const struct of_device_id camss_dt_match[] = { { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources }, { .compatible = "qcom,sdm670-camss", .data = &sdm670_resources }, { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources }, + { .compatible = "qcom,sm6150-camss", .data = &sm6150_resources }, { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources }, { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources }, { .compatible = "qcom,sm8650-camss", .data = &sm8650_resources }, diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index e34f06b4e1536..6d048414c919e 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -80,6 +80,7 @@ enum pm_domain { enum camss_version { CAMSS_660, CAMSS_2290, + CAMSS_6150, CAMSS_7280, CAMSS_8x16, CAMSS_8x39, From 7ed36f2441f17ec2498a3464cb4773a52b165da0 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:53 +0800 Subject: [PATCH 290/659] 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 f3fc39abfea8be877c525e05cf3a77f1d2b84f27 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Fri, 23 Jan 2026 17:19:55 +0800 Subject: [PATCH 291/659] 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 84e6e6d35e5160bf676c70f2cfeb6456d8cff150 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Fri, 23 Jan 2026 17:19:56 +0800 Subject: [PATCH 292/659] 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 c776d86719e98f2560a65d3300519a11df19c7e0 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Thu, 27 Nov 2025 19:10:33 +0530 Subject: [PATCH 293/659] 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/20251127134036.209905-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 7f2393a88cae99613005240ef421caefb3ee50d2 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Thu, 27 Nov 2025 19:10:34 +0530 Subject: [PATCH 294/659] 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 Link: https://lore.kernel.org/all/20251127134036.209905-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 50c9b7be3f31b..e308f08a104be 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -133,6 +133,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 5c0e48cd543e7f8dc4c41e4bcd4a486bd2730e1d Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Thu, 27 Nov 2025 19:10:35 +0530 Subject: [PATCH 295/659] 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/20251127134036.209905-4-jishnu.prakash@oss.qualcomm.com/ Signed-off-by: Jishnu Prakash --- drivers/iio/adc/Kconfig | 30 + drivers/iio/adc/Makefile | 2 + drivers/iio/adc/qcom-adc5-gen3-common.c | 107 +++ drivers/iio/adc/qcom-spmi-adc5-gen3.c | 767 ++++++++++++++++++ include/linux/iio/adc/qcom-adc5-gen3-common.h | 216 +++++ 5 files changed, 1122 insertions(+) create mode 100644 drivers/iio/adc/qcom-adc5-gen3-common.c 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 58a14e6833f60..da201a9a69507 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1319,6 +1319,36 @@ config QCOM_SPMI_ADC5 To compile this driver as a module, choose M here: the module will be called qcom-spmi-adc5. +config QCOM_ADC5_GEN3_COMMON + tristate + +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 QCOM_ADC5_GEN3_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 d008f78dc010a..236daf2457ade 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -110,8 +110,10 @@ obj-$(CONFIG_NPCM_ADC) += npcm_adc.o obj-$(CONFIG_PAC1921) += pac1921.o obj-$(CONFIG_PAC1934) += pac1934.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o +obj-$(CONFIG_QCOM_ADC5_GEN3_COMMON) += qcom-adc5-gen3-common.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-adc5-gen3-common.c b/drivers/iio/adc/qcom-adc5-gen3-common.c new file mode 100644 index 0000000000000..46bb09424f22a --- /dev/null +++ b/drivers/iio/adc/qcom-adc5-gen3-common.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Code shared between the main and auxiliary Qualcomm PMIC voltage ADCs + * of type ADC5 Gen3. + */ + +#include +#include +#include +#include + +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"); + +/* + * 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, count; + u8 status = 0; + + for (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"); + +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"); + +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"); + +MODULE_DESCRIPTION("Qualcomm ADC5 Gen3 common functionality"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("QCOM_SPMI_ADC5_GEN3"); 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..effd4bd499899 --- /dev/null +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -0,0 +1,767 @@ +// 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 + +#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. + * @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; + /* + * lock for access to the peripheral, to prevent concurrent requests + * from multiple clients. + */ + struct mutex lock; + const struct adc5_data *data; + unsigned int n_tm_channels; + struct auxiliary_device *tm_aux; +}; + +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; +} + +#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 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 adc_tm5_auxiliary_drv *adrv_tm; + 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; + } + + adrv_tm = container_of(adev->dev.driver, + struct adc_tm5_auxiliary_drv, + adrv.driver); + + if (!adrv_tm->tm_event_notify) { + dev_err(dev, "adc_tm auxiliary driver not initialized\n"); + return IRQ_HANDLED; + } + + adrv_tm->tm_event_notify(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 i, v_channel; + + for (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_TEMP_ALARM_LITE] = 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) { + dev_err(dev, "No ADC channels found\n"); + return -EINVAL; + } + + 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 i, 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 (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"); + +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, i; + 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; + + 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; + + platform_set_drvdata(pdev, indio_dev); + init_completion(&adc->complete); + ret = devm_mutex_init(dev, &adc->lock); + if (ret) + return ret; + + for (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..b496615ead3e3 --- /dev/null +++ b/include/linux/iio/adc/qcom-adc5-gen3-common.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Code shared between 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 + +#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_TEMP_ALARM_LITE 0x18 +#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 + +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; +}; + +/** + * struct tm5_aux_dev_wrapper - wrapper structure around TM auxiliary driver + * @adrv: TM auxiliary driver structure. + * @tm_event_notify: TM callback to be called by parent driver. + */ +struct adc_tm5_auxiliary_drv { + struct auxiliary_driver adrv; + void (*tm_event_notify)(struct auxiliary_device *adev); +}; + +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); + +#endif /* QCOM_ADC5_GEN3_COMMON_H */ From eaefc127fa1a2d81319bfa675e198c9d5f60e3d7 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Thu, 27 Nov 2025 19:10:36 +0530 Subject: [PATCH 296/659] 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. Link: https://lore.kernel.org/all/20251127134036.209905-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 | 530 ++++++++++++++++++ 3 files changed, 540 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..c6cc8ef76f7e1 --- /dev/null +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5-gen3.c @@ -0,0 +1,530 @@ +// 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 "../thermal_hwmon.h" + +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 withcommon 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; +}; + +static int get_sdam_from_irq(struct adc_tm5_gen3_chip *adc_tm5, int irq) +{ + int i; + + for (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); + struct adc_tm5_gen3_channel_props *chan_prop; + u8 tm_status[2] = { }; + u8 buf[16] = { }; + int sdam_index = -1; + int i, ret; + + for (i = 0; i < adc_tm5->nchannels; i++) { + bool upper_set, lower_set; + int temp, offset; + u16 code = 0; + + chan_prop = &adc_tm5->chan_props[i]; + offset = chan_prop->tm_chan_index; + + adc5_gen3_mutex_lock(adc_tm5->dev); + 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) { + adc5_gen3_mutex_unlock(adc_tm5->dev); + break; + } + } + + upper_set = ((tm_status[0] & BIT(offset)) && chan_prop->high_thr_en); + lower_set = ((tm_status[1] & BIT(offset)) && chan_prop->low_thr_en); + adc5_gen3_mutex_unlock(adc_tm5->dev); + + if (!(upper_set || lower_set)) + continue; + + code = get_unaligned_le16(&buf[2 * offset]); + pr_debug("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)); +} + +static int adc_tm5_gen3_disable_channel(struct adc_tm5_gen3_channel_props *prop) +{ + return _adc_tm5_gen3_disable_channel(prop); +} + +#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; + int ret; + + 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); + + adc5_gen3_mutex_lock(adc_tm5->dev); + if (high_temp == INT_MAX && low_temp <= -INT_MAX) + ret = adc_tm5_gen3_disable_channel(prop); + else + ret = adc_tm5_gen3_configure(prop, low_temp, high_temp); + adc5_gen3_mutex_unlock(adc_tm5->dev); + + return ret; +} + +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) +{ + unsigned int i, channel; + struct thermal_zone_device *tzd; + int ret; + + for (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_warn(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; + int i; + + adc5_gen3_mutex_lock(adc_tm5->dev); + /* Disable all available TM channels */ + for (i = 0; i < adc_tm5->nchannels; i++) + _adc_tm5_gen3_disable_channel(&adc_tm5->chan_props[i]); + + adc5_gen3_mutex_unlock(adc_tm5->dev); +} + +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 i, 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 (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 (tm_event_notify) exposed from this driver to handle it. + */ + for (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); + + /* + * 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 adc_tm5_auxiliary_drv adctm5gen3_auxiliary_drv = { + .adrv = { + .id_table = adctm5_auxiliary_id_table, + .probe = adc_tm5_probe, + }, + .tm_event_notify = adctm_event_handler, +}; + +static int __init adctm5_init_module(void) +{ + return auxiliary_driver_register(&adctm5gen3_auxiliary_drv.adrv); +} + +static void __exit adctm5_exit_module(void) +{ + auxiliary_driver_unregister(&adctm5gen3_auxiliary_drv.adrv); +} + +module_init(adctm5_init_module); +module_exit(adctm5_exit_module); + +MODULE_DESCRIPTION("SPMI PMIC Thermal Monitor ADC driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("QCOM_SPMI_ADC5_GEN3"); From 41a77c6ad780e6aa4809e969cbbeec5c3343e031 Mon Sep 17 00:00:00 2001 From: Abhinaba Rakshit Date: Fri, 16 Jan 2026 17:08:39 +0530 Subject: [PATCH 297/659] FROMGIT: arm64: dts: qcom: monaco: add QCrypto node Add Qualcomm Crypto Engine device node for Monaco platform. QCE and Crypto DMA nodes patch was applied as part of commit a86d84409947 ("arm64: dts: qcom: qcs8300: add QCrypto nodes"), however was partially reverted by commit cdc117c40537 ("arm64: dts: qcom: qcs8300: Partially revert "arm64: dts: qcom: qcs8300: add QCrypto nodes"") due to compatible string being mismatched against schema. Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20251224-enable-qualcomm-crypto-engine-for-monaco-v3-1-6073430bbc13@oss.qualcomm.com/ Signed-off-by: Abhinaba Rakshit --- arch/arm64/boot/dts/qcom/monaco.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 8caca5ec8473b..afd391fb74f2b 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -2734,6 +2734,18 @@ clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; }; + crypto: crypto@1dfa000 { + compatible = "qcom,qcs8300-qce", "qcom,sm8150-qce", "qcom,qce"; + reg = <0x0 0x01dfa000 0x0 0x6000>; + dmas = <&cryptobam 4>, <&cryptobam 5>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu 0x480 0x0>, + <&apps_smmu 0x481 0x0>; + interconnects = <&aggre2_noc MASTER_CRYPTO_CORE0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "memory"; + }; + tcsr_mutex: hwlock@1f40000 { compatible = "qcom,tcsr-mutex"; reg = <0x0 0x01f40000 0x0 0x20000>; From 02fdded1047f4a65082e9ee523dec4af032d99bc Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Fri, 23 Jan 2026 13:32:49 +0530 Subject: [PATCH 298/659] 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 81aefcefbf30a5be7823f7ce102b7e508a3403c8 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Tue, 27 Jan 2026 17:32:06 +0530 Subject: [PATCH 299/659] 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 4bb11fd3175d4d89a067411371d2d5d0e05fdb5f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 17 Nov 2025 15:51:35 +0100 Subject: [PATCH 300/659] FROMLIST: drm/msm: adreno: fix deferencing ifpc_reglist when not declared On plaforms with an a7xx GPU not supporting IFPC, the ifpc_reglist if still deferenced in a7xx_patch_pwrup_reglist() which causes a kernel crash: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008 ... pc : a6xx_hw_init+0x155c/0x1e4c [msm] lr : a6xx_hw_init+0x9a8/0x1e4c [msm] ... Call trace: a6xx_hw_init+0x155c/0x1e4c [msm] (P) msm_gpu_hw_init+0x58/0x88 [msm] adreno_load_gpu+0x94/0x1fc [msm] msm_open+0xe4/0xf4 [msm] drm_file_alloc+0x1a0/0x2e4 [drm] drm_client_init+0x7c/0x104 [drm] drm_fbdev_client_setup+0x94/0xcf0 [drm_client_lib] drm_client_setup+0xb4/0xd8 [drm_client_lib] msm_drm_kms_post_init+0x2c/0x3c [msm] msm_drm_init+0x1a4/0x228 [msm] msm_drm_bind+0x30/0x3c [msm] ... Check the validity of ifpc_reglist before deferencing the table to setup the register values. Fixes: a6a0157cc68e ("drm/msm/a6xx: Enable IFPC on Adreno X1-85") Signed-off-by: Neil Armstrong Reviewed-by: Akhil P Oommen Link: https://lore.kernel.org/r/20251117-topic-sm8x50-fix-a6xx-non-ifpc-v1-1-e4473cbf5903@linaro.org --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0200a7e71cdf5..7e71f6bb5283b 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -873,15 +873,17 @@ static void a7xx_patch_pwrup_reglist(struct msm_gpu *gpu) lock->gpu_req = lock->cpu_req = lock->turn = 0; reglist = adreno_gpu->info->a6xx->ifpc_reglist; - lock->ifpc_list_len = reglist->count; + if (reglist) { + lock->ifpc_list_len = reglist->count; - /* - * For each entry in each of the lists, write the offset and the current - * register value into the GPU buffer - */ - for (i = 0; i < reglist->count; i++) { - *dest++ = reglist->regs[i]; - *dest++ = gpu_read(gpu, reglist->regs[i]); + /* + * For each entry in each of the lists, write the offset and the current + * register value into the GPU buffer + */ + for (i = 0; i < reglist->count; i++) { + *dest++ = reglist->regs[i]; + *dest++ = gpu_read(gpu, reglist->regs[i]); + } } reglist = adreno_gpu->info->a6xx->pwrup_reglist; From a33192f3d5fb39d88ea59a15adffcd7f198df65a Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Tue, 27 Jan 2026 15:59:30 +0800 Subject: [PATCH 301/659] 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 0251934412a63354a0247b9750e121120dfe68a0 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Tue, 20 Jan 2026 09:30:10 +0000 Subject: [PATCH 302/659] 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 303/659] 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 304/659] 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 c18f558d0d87f5c3576b3d7481b239fb85b58a66 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 19 Jan 2026 13:51:00 +0530 Subject: [PATCH 305/659] 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 b1ba182a0d8d4..7721c4cfd578d 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -39,6 +39,10 @@ dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera.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 @@ -143,6 +147,10 @@ qcs6490-rb3gen2-industrial-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2 dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.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 f7d2f9657ed9bab8263c2e6237811f80b69c7c8c Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 27 Jan 2026 14:01:00 +0530 Subject: [PATCH 306/659] 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 06720376a8bc5ff39daf33a473fe7bbdee027979 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 2 Dec 2025 15:56:25 +0530 Subject: [PATCH 307/659] FROMLIST: clk: qcom: clk-alpha-pll: Add support for Rivian ELU PLL Add clock ops for Rivian ELU PLL, add the register offsets for supporting the PLL. Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251202-sm8750_camcc-v1-1-b3f7ef6723f1@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.c | 14 ++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 6aeba40358c11..8586649d76f8a 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -243,6 +243,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x28, [PLL_OFF_TEST_CTL_U] = 0x2c, }, + [CLK_ALPHA_PLL_TYPE_RIVIAN_ELU] = { + [PLL_OFF_OPMODE] = 0x04, + [PLL_OFF_STATUS] = 0x0c, + [PLL_OFF_L_VAL] = 0x10, + [PLL_OFF_USER_CTL] = 0x14, + [PLL_OFF_USER_CTL_U] = 0x18, + [PLL_OFF_CONFIG_CTL] = 0x1c, + [PLL_OFF_CONFIG_CTL_U] = 0x20, + [PLL_OFF_CONFIG_CTL_U1] = 0x24, + [PLL_OFF_CONFIG_CTL_U2] = 0x28, + [PLL_OFF_TEST_CTL] = 0x2c, + [PLL_OFF_TEST_CTL_U] = 0x30, + }, [CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, @@ -3002,6 +3015,7 @@ void qcom_clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regm clk_taycan_elu_pll_configure(pll, regmap, pll->config); break; case CLK_ALPHA_PLL_TYPE_RIVIAN_EVO: + case CLK_ALPHA_PLL_TYPE_RIVIAN_ELU: clk_rivian_evo_pll_configure(pll, regmap, pll->config); break; case CLK_ALPHA_PLL_TYPE_TRION: diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 0903a05b18ccc..b4492197419a7 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -31,6 +31,7 @@ enum { CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, + CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, CLK_ALPHA_PLL_TYPE_STROMER, @@ -208,6 +209,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; extern const struct clk_ops clk_alpha_pll_pongo_elu_ops; extern const struct clk_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 extern const struct clk_ops clk_alpha_pll_regera_ops; extern const struct clk_ops clk_alpha_pll_slew_ops; From f8b12125f268c55b3e35cbef00596ce60fe12e60 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 2 Dec 2025 15:56:26 +0530 Subject: [PATCH 308/659] FROMLIST: dt-bindings: clock: qcom: Add camera clock controller for SM8750 SoC Add device tree bindings for the camera clock controller on Qualcomm SM8750 platform. The camera clock controller is split between camcc and cambist. The cambist controls the mclks of the camera clock controller. Link: https://lore.kernel.org/r/20251202-sm8750_camcc-v1-2-b3f7ef6723f1@oss.qualcomm.com Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sm8450-camcc.yaml | 5 + .../clock/qcom,sm8750-cambistmclkcc.h | 30 ++++ include/dt-bindings/clock/qcom,sm8750-camcc.h | 151 ++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h create mode 100644 include/dt-bindings/clock/qcom,sm8750-camcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index c1e06f39431e6..8e3baba5270b3 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -9,6 +9,7 @@ title: Qualcomm Camera Clock & Reset Controller on SM8450 maintainers: - Vladimir Zapolskiy - Jagadeesh Kona + - Taniya Das description: | Qualcomm camera clock control module provides the clocks, resets and power @@ -18,6 +19,8 @@ description: | include/dt-bindings/clock/qcom,sm8450-camcc.h include/dt-bindings/clock/qcom,sm8550-camcc.h include/dt-bindings/clock/qcom,sm8650-camcc.h + include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h + include/dt-bindings/clock/qcom,sm8750-camcc.h properties: compatible: @@ -26,6 +29,8 @@ properties: - qcom,sm8475-camcc - qcom,sm8550-camcc - qcom,sm8650-camcc + - qcom,sm8750-cambistmclkcc + - qcom,sm8750-camcc clocks: items: diff --git a/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h b/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h new file mode 100644 index 0000000000000..51615bee307fd --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h @@ -0,0 +1,30 @@ +/* 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_CAM_BIST_MCLK_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_SM8750_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_MCLK0_CLK 0 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_PLL0 16 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 17 +#define CAM_BIST_MCLK_CC_SLEEP_CLK_SRC 18 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8750-camcc.h b/include/dt-bindings/clock/qcom,sm8750-camcc.h new file mode 100644 index 0000000000000..dae788247afe8 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-camcc.h @@ -0,0 +1,151 @@ +/* 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_CAM_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SM8750_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK 6 +#define CAM_CC_CAMNOC_NRT_OFE_HDR_CLK 7 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 8 +#define CAM_CC_CAMNOC_RT_AXI_CLK 9 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK 12 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 13 +#define CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK 14 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 15 +#define CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK 16 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 17 +#define CAM_CC_CAMNOC_XO_CLK 18 +#define CAM_CC_CCI_0_CLK 19 +#define CAM_CC_CCI_0_CLK_SRC 20 +#define CAM_CC_CCI_1_CLK 21 +#define CAM_CC_CCI_1_CLK_SRC 22 +#define CAM_CC_CCI_2_CLK 23 +#define CAM_CC_CCI_2_CLK_SRC 24 +#define CAM_CC_CORE_AHB_CLK 25 +#define CAM_CC_CPHY_RX_CLK_SRC 26 +#define CAM_CC_CRE_AHB_CLK 27 +#define CAM_CC_CRE_CLK 28 +#define CAM_CC_CRE_CLK_SRC 29 +#define CAM_CC_CSI0PHYTIMER_CLK 30 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 31 +#define CAM_CC_CSI1PHYTIMER_CLK 32 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 33 +#define CAM_CC_CSI2PHYTIMER_CLK 34 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 35 +#define CAM_CC_CSI3PHYTIMER_CLK 36 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 37 +#define CAM_CC_CSI4PHYTIMER_CLK 38 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 39 +#define CAM_CC_CSI5PHYTIMER_CLK 40 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 41 +#define CAM_CC_CSID_CLK 42 +#define CAM_CC_CSID_CLK_SRC 43 +#define CAM_CC_CSID_CSIPHY_RX_CLK 44 +#define CAM_CC_CSIPHY0_CLK 45 +#define CAM_CC_CSIPHY1_CLK 46 +#define CAM_CC_CSIPHY2_CLK 47 +#define CAM_CC_CSIPHY3_CLK 48 +#define CAM_CC_CSIPHY4_CLK 49 +#define CAM_CC_CSIPHY5_CLK 50 +#define CAM_CC_DRV_AHB_CLK 51 +#define CAM_CC_DRV_XO_CLK 52 +#define CAM_CC_FAST_AHB_CLK_SRC 53 +#define CAM_CC_GDSC_CLK 54 +#define CAM_CC_ICP_0_AHB_CLK 55 +#define CAM_CC_ICP_0_CLK 56 +#define CAM_CC_ICP_0_CLK_SRC 57 +#define CAM_CC_ICP_1_AHB_CLK 58 +#define CAM_CC_ICP_1_CLK 59 +#define CAM_CC_ICP_1_CLK_SRC 60 +#define CAM_CC_IFE_LITE_AHB_CLK 61 +#define CAM_CC_IFE_LITE_CLK 62 +#define CAM_CC_IFE_LITE_CLK_SRC 63 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 64 +#define CAM_CC_IFE_LITE_CSID_CLK 65 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 66 +#define CAM_CC_IPE_NPS_AHB_CLK 67 +#define CAM_CC_IPE_NPS_CLK 68 +#define CAM_CC_IPE_NPS_CLK_SRC 69 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 70 +#define CAM_CC_IPE_PPS_CLK 71 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 72 +#define CAM_CC_JPEG_0_CLK 73 +#define CAM_CC_JPEG_1_CLK 74 +#define CAM_CC_JPEG_CLK_SRC 75 +#define CAM_CC_OFE_AHB_CLK 76 +#define CAM_CC_OFE_ANCHOR_CLK 77 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 78 +#define CAM_CC_OFE_CLK_SRC 79 +#define CAM_CC_OFE_HDR_CLK 80 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 81 +#define CAM_CC_OFE_MAIN_CLK 82 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 83 +#define CAM_CC_PLL0 84 +#define CAM_CC_PLL0_OUT_EVEN 85 +#define CAM_CC_PLL0_OUT_ODD 86 +#define CAM_CC_PLL1 87 +#define CAM_CC_PLL1_OUT_EVEN 88 +#define CAM_CC_PLL2 89 +#define CAM_CC_PLL2_OUT_EVEN 90 +#define CAM_CC_PLL3 91 +#define CAM_CC_PLL3_OUT_EVEN 92 +#define CAM_CC_PLL4 93 +#define CAM_CC_PLL4_OUT_EVEN 94 +#define CAM_CC_PLL5 95 +#define CAM_CC_PLL5_OUT_EVEN 96 +#define CAM_CC_PLL6 97 +#define CAM_CC_PLL6_OUT_EVEN 98 +#define CAM_CC_PLL6_OUT_ODD 99 +#define CAM_CC_QDSS_DEBUG_CLK 100 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 101 +#define CAM_CC_QDSS_DEBUG_XO_CLK 102 +#define CAM_CC_SLEEP_CLK 103 +#define CAM_CC_SLEEP_CLK_SRC 104 +#define CAM_CC_SLOW_AHB_CLK_SRC 105 +#define CAM_CC_TFE_0_BAYER_CLK 106 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_0_CLK_SRC 108 +#define CAM_CC_TFE_0_MAIN_CLK 109 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_1_BAYER_CLK 111 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_1_CLK_SRC 113 +#define CAM_CC_TFE_1_MAIN_CLK 114 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TFE_2_BAYER_CLK 116 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 117 +#define CAM_CC_TFE_2_CLK_SRC 118 +#define CAM_CC_TFE_2_MAIN_CLK 119 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 120 +#define CAM_CC_XO_CLK_SRC 121 + +/* CAM_CC power domains */ +#define CAM_CC_TITAN_TOP_GDSC 0 +#define CAM_CC_IPE_0_GDSC 1 +#define CAM_CC_OFE_GDSC 2 +#define CAM_CC_TFE_0_GDSC 3 +#define CAM_CC_TFE_1_GDSC 4 +#define CAM_CC_TFE_2_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif From 155396eb57c9d2c5a9057e782d4c49a030c42e35 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 2 Dec 2025 15:56:27 +0530 Subject: [PATCH 309/659] FROMLIST: clk: qcom: camcc: Add camera clock controller driver for SM8750 SoC Add support for the Camera Clock Controller (CAMCC) on the SM8750 platform. The CAMCC block on SM8750 includes both the primary camera clock controller and the Camera BIST clock controller, which provides the functional MCLK required for camera operations. Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251202-sm8750_camcc-v1-3-b3f7ef6723f1@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/cambistmclkcc-sm8750.c | 454 ++++ drivers/clk/qcom/camcc-sm8750.c | 2710 +++++++++++++++++++++++ 4 files changed, 3175 insertions(+) create mode 100644 drivers/clk/qcom/cambistmclkcc-sm8750.c create mode 100644 drivers/clk/qcom/camcc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a284ba040b78b..6adcc52a3bf54 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1069,6 +1069,16 @@ config SM_CAMCC_8650 Support for the camera clock controller on SM8650 devices. Say Y if you want to support camera devices and camera functionality. +config SM_CAMCC_8750 + tristate "SM8750 Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8750 + help + Support for the camera clock controller on SM8750 devices. + The camera clock controller has a separate cambist controller which + controls the mclk of the camera clocks. + Say Y if you want to support camera devices and camera functionality. + config SM_DISPCC_4450 tristate "SM4450 Display Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 0ac8a9055a432..42b399c151214 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -136,6 +136,7 @@ obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o obj-$(CONFIG_SM_CAMCC_8650) += camcc-sm8650.o +obj-$(CONFIG_SM_CAMCC_8750) += cambistmclkcc-sm8750.o camcc-sm8750.o obj-$(CONFIG_SM_CAMCC_MILOS) += camcc-milos.o obj-$(CONFIG_SM_DISPCC_4450) += dispcc-sm4450.o obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o diff --git a/drivers/clk/qcom/cambistmclkcc-sm8750.c b/drivers/clk/qcom/cambistmclkcc-sm8750.c new file mode 100644 index 0000000000000..952581f86db5b --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-sm8750.c @@ -0,0 +1,454 @@ +// 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 "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, + P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct pll_vco rivian_elu_vco[] = { + { 833000000, 1125000000, 0 }, + { 777000000, 1062000000, 1 }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_elu_vco, + .num_vco = ARRAY_SIZE(rivian_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_elu_ops, + }, + }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_1[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_1[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = { + F(12000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 8), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4), + F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = { + .cmd_rcgr = 0x401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = { + .cmd_rcgr = 0x4070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = { + .cmd_rcgr = 0x408c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = { + .cmd_rcgr = 0x40a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = { + .cmd_rcgr = 0x40c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_sleep_clk_src = { + .cmd_rcgr = 0x40e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_1, + .freq_tbl = ftbl_cam_bist_mclk_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_sleep_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk0_clk = { + .halt_reg = 0x4018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk1_clk = { + .halt_reg = 0x4034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk2_clk = { + .halt_reg = 0x4050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk3_clk = { + .halt_reg = 0x406c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x406c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk4_clk = { + .halt_reg = 0x4088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk5_clk = { + .halt_reg = 0x40a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk6_clk = { + .halt_reg = 0x40c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk7_clk = { + .halt_reg = 0x40dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *cam_bist_mclk_cc_sm8750_clocks[] = { + [CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr, + [CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr, + [CAM_BIST_MCLK_CC_SLEEP_CLK_SRC] = &cam_bist_mclk_cc_sleep_clk_src.clkr, +}; + +static struct clk_alpha_pll *cam_bist_mclk_cc_sm8750_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = { + 0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = { + .alpha_plls = cam_bist_mclk_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_plls), + .clk_cbcrs = cam_bist_mclk_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_critical_cbcrs), +}; + +static struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { + .config = &cam_bist_mclk_cc_sm8750_regmap_config, + .clks = cam_bist_mclk_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_sm8750_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_sm8750_match_table); + +static int cam_bist_mclk_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_sm8750_desc); +} + +static struct platform_driver cam_bist_mclk_cc_sm8750_driver = { + .probe = cam_bist_mclk_cc_sm8750_probe, + .driver = { + .name = "cambistmclkcc-sm8750", + .of_match_table = cam_bist_mclk_cc_sm8750_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC SM8750 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-sm8750.c b/drivers/clk/qcom/camcc-sm8750.c new file mode 100644 index 0000000000000..c09fa75be4576 --- /dev/null +++ b/drivers/clk/qcom/camcc-sm8750.c @@ -0,0 +1,2710 @@ +// 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_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL6_OUT_ODD, + P_SLEEP_CLK, +}; + +static const struct pll_vco taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_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 = "cam_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_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_TAYCAN_ELU], + .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_taycan_elu_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_TAYCAN_ELU], + .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_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x22, + .alpha = 0xa2aa, + .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 cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_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 = "cam_cc_pll1", + .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_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_TAYCAN_ELU], + .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_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x23, + .alpha = 0x4aaa, + .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 cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_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 = "cam_cc_pll2", + .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_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .alpha = 0x8777, + .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 cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_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 = "cam_cc_pll3", + .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_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_TAYCAN_ELU], + .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_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .alpha = 0x8777, + .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 cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_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 = "cam_cc_pll4", + .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_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .alpha = 0x8777, + .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 cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_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 = "cam_cc_pll5", + .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_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_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 = "cam_cc_pll6", + .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_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_TAYCAN_ELU], + .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_taycan_elu_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_odd = { + .offset = 0x6000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll6_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_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_ODD, 4 }, + { 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_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_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .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_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_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 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8_ao[] = { + { P_BI_TCXO_AO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_rt_axi_clk_src = { + .cmd_rcgr = 0x112e8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_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(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x1126c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .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 = 0x11288, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .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 struct clk_rcg2 cam_cc_cci_2_clk_src = { + .cmd_rcgr = 0x112a4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_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(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 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 = 0x11068, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cphy_rx_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_cre_clk_src[] = { + F(137142857, P_CAM_CC_PLL6_OUT_EVEN, 3.5, 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_cre_clk_src = { + .cmd_rcgr = 0x111ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x10000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_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_csi1phytimer_clk_src = { + .cmd_rcgr = 0x10024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_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_csi2phytimer_clk_src = { + .cmd_rcgr = 0x10044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_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_csi3phytimer_clk_src = { + .cmd_rcgr = 0x10064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_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_csi4phytimer_clk_src = { + .cmd_rcgr = 0x10084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_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_csi5phytimer_clk_src = { + .cmd_rcgr = 0x100a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_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_csid_clk_src = { + .cmd_rcgr = 0x112c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_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_fast_ahb_clk_src[] = { + F(213333333, P_CAM_CC_PLL6_OUT_ODD, 1.5, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 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 = 0x100dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .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_0_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 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_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x11214, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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_icp_1_clk_src = { + .cmd_rcgr = 0x1123c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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 struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x11150, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_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_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x1117c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_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_ipe_nps_clk_src[] = { + F(332500000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x10190, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_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 struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x111d0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .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_ofe_clk_src[] = { + F(338800000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(484000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(586000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(688000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(841000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ofe_clk_src = { + .cmd_rcgr = 0x1011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_qdss_debug_clk_src[] = { + F(40000000, P_CAM_CC_PLL6_OUT_ODD, 8, 0, 0), + F(60000000, P_CAM_CC_PLL6_OUT_EVEN, 8, 0, 0), + F(120000000, P_CAM_CC_PLL0_OUT_EVEN, 5, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x1132c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .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 = 0x11380, + .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(56470588, P_CAM_CC_PLL6_OUT_EVEN, 8.5, 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 = 0x10100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .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_tfe_0_clk_src[] = { + F(360280000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_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 const struct freq_tbl ftbl_cam_cc_tfe_1_clk_src[] = { + F(360280000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_1_clk_src = { + .cmd_rcgr = 0x11098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_2_clk_src[] = { + F(360280000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_2_clk_src = { + .cmd_rcgr = 0x11100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .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_AO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x11364, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8_ao, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_8_ao, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x113ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x113ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_cam_top_fast_ahb_clk = { + .halt_reg = 0x1139c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1139c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_dcd_xo_clk = { + .halt_reg = 0x11320, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11320, + .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_nrt_axi_clk = { + .halt_reg = 0x11310, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x11310, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x11310, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_cre_clk = { + .halt_reg = 0x111c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ipe_nps_clk = { + .halt_reg = 0x101b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_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_camnoc_nrt_ofe_anchor_clk = { + .halt_reg = 0x10158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10158, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_hdr_clk = { + .halt_reg = 0x1016c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1016c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_main_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_camnoc_nrt_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x11300, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11300, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_ife_lite_clk = { + .halt_reg = 0x11178, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11178, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_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_camnoc_rt_tfe_0_bayer_clk = { + .halt_reg = 0x11054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_0_main_clk = { + .halt_reg = 0x11040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_bayer_clk = { + .halt_reg = 0x110d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_main_clk = { + .halt_reg = 0x110c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_bayer_clk = { + .halt_reg = 0x1113c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1113c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_main_clk = { + .halt_reg = 0x11128, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11128, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_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 = 0x11324, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11324, + .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 = 0x11284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11284, + .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 = 0x112a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112a0, + .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_cci_2_clk = { + .halt_reg = 0x112bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_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 = 0x11360, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x11360, + .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_cre_ahb_clk = { + .halt_reg = 0x111cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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_cre_clk = { + .halt_reg = 0x111c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_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 = 0x10018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10018, + .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 = 0x1003c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1003c, + .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 = 0x1005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1005c, + .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 = 0x1007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1007c, + .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 = 0x1009c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1009c, + .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 = 0x100bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100bc, + .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 = 0x112d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112d8, + .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 = 0x10020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10020, + .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 = 0x1001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1001c, + .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 = 0x10040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10040, + .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 = 0x10060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10060, + .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 = 0x10080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10080, + .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 = 0x100a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100a0, + .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 = 0x100c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100c0, + .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_0_ahb_clk = { + .halt_reg = 0x11264, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11264, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_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_0_clk = { + .halt_reg = 0x1122c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1122c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x11268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11268, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_1_clk = { + .halt_reg = 0x11254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_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 = 0x111a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111a8, + .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 = 0x11168, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11168, + .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 = 0x111a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111a4, + .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 = 0x11194, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11194, + .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 = 0x101d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101d4, + .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 = 0x101a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101a8, + .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 = 0x101d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101d8, + .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 = 0x101bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101bc, + .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 = 0x101dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101dc, + .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_0_clk = { + .halt_reg = 0x111e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_0_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_jpeg_1_clk = { + .halt_reg = 0x111f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_1_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_ofe_ahb_clk = { + .halt_reg = 0x10118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_ofe_anchor_clk = { + .halt_reg = 0x10148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_fast_ahb_clk = { + .halt_reg = 0x100f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_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_ofe_hdr_clk = { + .halt_reg = 0x1015c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1015c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_fast_ahb_clk = { + .halt_reg = 0x100fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_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_ofe_main_clk = { + .halt_reg = 0x10134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_fast_ahb_clk = { + .halt_reg = 0x100f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_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_qdss_debug_clk = { + .halt_reg = 0x11344, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11344, + .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 = 0x11348, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11348, + .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_tfe_0_bayer_clk = { + .halt_reg = 0x11044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_fast_ahb_clk = { + .halt_reg = 0x11064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_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_tfe_0_main_clk = { + .halt_reg = 0x11030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_fast_ahb_clk = { + .halt_reg = 0x11060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_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_tfe_1_bayer_clk = { + .halt_reg = 0x110c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_fast_ahb_clk = { + .halt_reg = 0x110e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_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_tfe_1_main_clk = { + .halt_reg = 0x110b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_fast_ahb_clk = { + .halt_reg = 0x110e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_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_tfe_2_bayer_clk = { + .halt_reg = 0x1112c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1112c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_fast_ahb_clk = { + .halt_reg = 0x1114c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1114c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_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_tfe_2_main_clk = { + .halt_reg = 0x11118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_fast_ahb_clk = { + .halt_reg = 0x11148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_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 gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x1134c, + .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_ipe_0_gdsc = { + .gdscr = 0x1017c, + .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 gdsc cam_cc_ofe_gdsc = { + .gdscr = 0x100c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ofe_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_tfe_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_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_tfe_1_gdsc = { + .gdscr = 0x11084, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_2_gdsc = { + .gdscr = 0x110ec, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_sm8750_clocks[] = { + [CAM_CC_CAM_TOP_AHB_CLK] = &cam_cc_cam_top_ahb_clk.clkr, + [CAM_CC_CAM_TOP_FAST_AHB_CLK] = &cam_cc_cam_top_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_NRT_CRE_CLK] = &cam_cc_camnoc_nrt_cre_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_NPS_CLK] = &cam_cc_camnoc_nrt_ipe_nps_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK] = &cam_cc_camnoc_nrt_ofe_anchor_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_HDR_CLK] = &cam_cc_camnoc_nrt_ofe_hdr_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK] = &cam_cc_camnoc_nrt_ofe_main_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.clkr, + [CAM_CC_CAMNOC_RT_IFE_LITE_CLK] = &cam_cc_camnoc_rt_ife_lite_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_0_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_0_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_1_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_1_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_2_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_2_main_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_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_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_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.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_0_CLK] = &cam_cc_jpeg_0_clk.clkr, + [CAM_CC_JPEG_1_CLK] = &cam_cc_jpeg_1_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_OFE_AHB_CLK] = &cam_cc_ofe_ahb_clk.clkr, + [CAM_CC_OFE_ANCHOR_CLK] = &cam_cc_ofe_anchor_clk.clkr, + [CAM_CC_OFE_ANCHOR_FAST_AHB_CLK] = &cam_cc_ofe_anchor_fast_ahb_clk.clkr, + [CAM_CC_OFE_CLK_SRC] = &cam_cc_ofe_clk_src.clkr, + [CAM_CC_OFE_HDR_CLK] = &cam_cc_ofe_hdr_clk.clkr, + [CAM_CC_OFE_HDR_FAST_AHB_CLK] = &cam_cc_ofe_hdr_fast_ahb_clk.clkr, + [CAM_CC_OFE_MAIN_CLK] = &cam_cc_ofe_main_clk.clkr, + [CAM_CC_OFE_MAIN_FAST_AHB_CLK] = &cam_cc_ofe_main_fast_ahb_clk.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_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_PLL5] = &cam_cc_pll5.clkr, + [CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr, + [CAM_CC_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL6_OUT_ODD] = &cam_cc_pll6_out_odd.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_TFE_0_BAYER_CLK] = &cam_cc_tfe_0_bayer_clk.clkr, + [CAM_CC_TFE_0_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_0_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_CLK_SRC] = &cam_cc_tfe_0_clk_src.clkr, + [CAM_CC_TFE_0_MAIN_CLK] = &cam_cc_tfe_0_main_clk.clkr, + [CAM_CC_TFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_0_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_BAYER_CLK] = &cam_cc_tfe_1_bayer_clk.clkr, + [CAM_CC_TFE_1_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_1_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_CLK_SRC] = &cam_cc_tfe_1_clk_src.clkr, + [CAM_CC_TFE_1_MAIN_CLK] = &cam_cc_tfe_1_main_clk.clkr, + [CAM_CC_TFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_1_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_BAYER_CLK] = &cam_cc_tfe_2_bayer_clk.clkr, + [CAM_CC_TFE_2_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_2_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_CLK_SRC] = &cam_cc_tfe_2_clk_src.clkr, + [CAM_CC_TFE_2_MAIN_CLK] = &cam_cc_tfe_2_main_clk.clkr, + [CAM_CC_TFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_2_main_fast_ahb_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_sm8750_gdscs[] = { + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_OFE_GDSC] = &cam_cc_ofe_gdsc, + [CAM_CC_TFE_0_GDSC] = &cam_cc_tfe_0_gdsc, + [CAM_CC_TFE_1_GDSC] = &cam_cc_tfe_1_gdsc, + [CAM_CC_TFE_2_GDSC] = &cam_cc_tfe_2_gdsc, +}; + +static const struct qcom_reset_map cam_cc_sm8750_resets[] = { + [CAM_CC_DRV_BCR] = { 0x113bc }, + [CAM_CC_ICP_BCR] = { 0x11210 }, + [CAM_CC_IPE_0_BCR] = { 0x10178 }, + [CAM_CC_OFE_BCR] = { 0x100c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x11328 }, + [CAM_CC_TFE_0_BCR] = { 0x11000 }, + [CAM_CC_TFE_1_BCR] = { 0x11080 }, + [CAM_CC_TFE_2_BCR] = { 0x110e8 }, +}; + +static struct clk_alpha_pll *cam_cc_sm8750_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, +}; + +static u32 cam_cc_sm8750_critical_cbcrs[] = { + 0x113c4, /* CAM_CC_DRV_AHB_CLK */ + 0x113c0, /* CAM_CC_DRV_XO_CLK */ + 0x1137c, /* CAM_CC_GDSC_CLK */ + 0x11398, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1601c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_sm8750_driver_data = { + .alpha_plls = cam_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_sm8750_plls), + .clk_cbcrs = cam_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sm8750_critical_cbcrs), +}; + +static struct qcom_cc_desc cam_cc_sm8750_desc = { + .config = &cam_cc_sm8750_regmap_config, + .clks = cam_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sm8750_clocks), + .resets = cam_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(cam_cc_sm8750_resets), + .gdscs = cam_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sm8750_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_sm8750_driver_data, +}; + +static const struct of_device_id cam_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sm8750_match_table); + +static int cam_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_sm8750_desc); +} + +static struct platform_driver cam_cc_sm8750_driver = { + .probe = cam_cc_sm8750_probe, + .driver = { + .name = "camcc-sm8750", + .of_match_table = cam_cc_sm8750_match_table, + }, +}; + +module_platform_driver(cam_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI CAMCC SM8750 Driver"); +MODULE_LICENSE("GPL"); From b9843bbd5615e47f310f929be9b9640ea60c5782 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:24 +0530 Subject: [PATCH 310/659] FROMLIST: clk: qcom: rpmh: Update the clock suffix for Glymur The current RPMh VRM clock definitions do not accurately represent the hardware mapping of these clocks. While there is no functional impact, this update aligns the definitions with the hardware convention by adding the appropriate suffix to indicate the clock divider and the E0 variant for the C3A_E0, C4A_E0, C5A_E0, and C8A_E0 resources on Glymur. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-1-3af118262289@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rpmh.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 1a98b3a0c528c..a2185a6f321fb 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -390,10 +390,10 @@ DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4); DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2); -DEFINE_CLK_RPMH_VRM(clk3, _a, "C3A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk4, _a, "C4A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk5, _a, "C5A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk8, _a, "C8A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk3, _a1_e0, "C3A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk4, _a1_e0, "C4A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk5, _a1_e0, "C5A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk8, _a1_e0, "C8A_E0", 1); DEFINE_CLK_RPMH_BCM(ce, "CE0"); DEFINE_CLK_RPMH_BCM(hwkm, "HK0"); @@ -888,12 +888,12 @@ static const struct clk_rpmh_desc clk_rpmh_sm8750 = { static struct clk_hw *glymur_rpmh_clocks[] = { [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, - [RPMH_RF_CLK3] = &clk_rpmh_clk3_a.hw, - [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a_ao.hw, - [RPMH_RF_CLK4] = &clk_rpmh_clk4_a.hw, - [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a_ao.hw, - [RPMH_RF_CLK5] = &clk_rpmh_clk5_a.hw, - [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a1_e0.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a1_e0_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a1_e0.hw, + [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a1_e0_ao.hw, + [RPMH_RF_CLK5] = &clk_rpmh_clk5_a1_e0.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a1_e0_ao.hw, }; static const struct clk_rpmh_desc clk_rpmh_glymur = { From 61d4da7e1b4cfe3578a2500c44f48a14a0124de7 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:25 +0530 Subject: [PATCH 311/659] FROMLIST: clk: qcom: rpmh: Add support for Kaanapali rpmh clocks Add the RPMH clocks present in Kaanapali SoC. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-2-3af118262289@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rpmh.c | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index a2185a6f321fb..10e84ada48eed 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -390,11 +390,22 @@ DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4); DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2); +DEFINE_CLK_RPMH_VRM(clk1, _a1_e0, "C1A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk2, _a1_e0, "C2A_E0", 1); DEFINE_CLK_RPMH_VRM(clk3, _a1_e0, "C3A_E0", 1); DEFINE_CLK_RPMH_VRM(clk4, _a1_e0, "C4A_E0", 1); DEFINE_CLK_RPMH_VRM(clk5, _a1_e0, "C5A_E0", 1); DEFINE_CLK_RPMH_VRM(clk8, _a1_e0, "C8A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk3, _a2_e0, "C3A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk4, _a2_e0, "C4A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk5, _a2_e0, "C5A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk6, _a2_e0, "C6A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk7, _a2_e0, "C7A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk8, _a2_e0, "C8A_E0", 2); + +DEFINE_CLK_RPMH_VRM(clk11, _a4_e0, "C11A_E0", 4); + DEFINE_CLK_RPMH_BCM(ce, "CE0"); DEFINE_CLK_RPMH_BCM(hwkm, "HK0"); DEFINE_CLK_RPMH_BCM(ipa, "IP0"); @@ -901,6 +912,34 @@ static const struct clk_rpmh_desc clk_rpmh_glymur = { .num_clks = ARRAY_SIZE(glymur_rpmh_clocks), }; +static struct clk_hw *kaanapali_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_DIV_CLK1] = &clk_rpmh_clk11_a4_e0.hw, + [RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2_e0.hw, + [RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_e0_ao.hw, + [RPMH_LN_BB_CLK2] = &clk_rpmh_clk7_a2_e0.hw, + [RPMH_LN_BB_CLK2_A] = &clk_rpmh_clk7_a2_e0_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2_e0.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_e0_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_clk1_a1_e0.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_clk1_a1_e0_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_clk2_a1_e0.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_clk2_a1_e0_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a2_e0.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a2_e0_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0_ao.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_kaanapali = { + .clks = kaanapali_rpmh_clocks, + .num_clks = ARRAY_SIZE(kaanapali_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -991,6 +1030,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur}, + { .compatible = "qcom,kaanapali-rpmh-clk", .data = &clk_rpmh_kaanapali}, { .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos}, { .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615}, { .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000}, From 7a580510b9db1b18c8f97c313e6436f9fca3ceae Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:26 +0530 Subject: [PATCH 312/659] FROMLIST: clk: qcom: Add TCSR clock driver for Kaanapali Add the TCSR clock controller that provides the refclks on Kaanapali platform for PCIe, USB and UFS subsystems. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-3-3af118262289@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 8 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/tcsrcc-kaanapali.c | 141 ++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 drivers/clk/qcom/tcsrcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 6adcc52a3bf54..9c1eb05872a95 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,14 @@ 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_KAANAPALI_TCSRCC + tristate "Kaanapali TCSR Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the TCSR clock controller on Kaanapali devices. + Say Y if you want to use peripheral devices such as PCIe, USB, UFS. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 42b399c151214..64fa68b91f9cf 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_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/tcsrcc-kaanapali.c b/drivers/clk/qcom/tcsrcc-kaanapali.c new file mode 100644 index 0000000000000..4da77367c9e03 --- /dev/null +++ b/drivers/clk/qcom/tcsrcc-kaanapali.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-branch.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" + +enum { + DT_BI_TCXO_PAD, +}; + +static struct clk_branch tcsr_pcie_0_clkref_en = { + .halt_reg = 0x15044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x15044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_0_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb3_clkref_en = { + .halt_reg = 0x1504c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1504c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_ufs_clkref_en = { + .halt_reg = 0x15054, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x15054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_ufs_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_clkref_en = { + .halt_reg = 0x1505c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1505c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *tcsr_cc_kaanapali_clocks[] = { + [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, + [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, + [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, + [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, +}; + +static const struct regmap_config tcsr_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x3d000, + .fast_io = true, +}; + +static const struct qcom_cc_desc tcsr_cc_kaanapali_desc = { + .config = &tcsr_cc_kaanapali_regmap_config, + .clks = tcsr_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(tcsr_cc_kaanapali_clocks), +}; + +static const struct of_device_id tcsr_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-tcsr" }, + { } +}; +MODULE_DEVICE_TABLE(of, tcsr_cc_kaanapali_match_table); + +static int tcsr_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &tcsr_cc_kaanapali_desc); +} + +static struct platform_driver tcsr_cc_kaanapali_driver = { + .probe = tcsr_cc_kaanapali_probe, + .driver = { + .name = "tcsr_cc-kaanapali", + .of_match_table = tcsr_cc_kaanapali_match_table, + }, +}; + +static int __init tcsr_cc_kaanapali_init(void) +{ + return platform_driver_register(&tcsr_cc_kaanapali_driver); +} +subsys_initcall(tcsr_cc_kaanapali_init); + +static void __exit tcsr_cc_kaanapali_exit(void) +{ + platform_driver_unregister(&tcsr_cc_kaanapali_driver); +} +module_exit(tcsr_cc_kaanapali_exit); + +MODULE_DESCRIPTION("QTI TCSR_CC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 521c13e3b249e6ec28f768a6cf088f1d95f57817 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:27 +0530 Subject: [PATCH 313/659] FROMLIST: clk: qcom: Add support for Global clock controller on Kaanapali Add support for Global clock controller for Kaanapali Qualcomm SoC. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-4-3af118262289@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-kaanapali.c | 3541 ++++++++++++++++++++++++++++++ 3 files changed, 3551 insertions(+) create mode 100644 drivers/clk/qcom/gcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9c1eb05872a95..f8b42e53bb1cc 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_KAANAPALI_GCC + tristate "Kaanapali Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on Kaanapali devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + config CLK_KAANAPALI_TCSRCC tristate "Kaanapali TCSR Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 64fa68b91f9cf..b13497abe9d2c 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_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c new file mode 100644 index 0000000000000..182b152df14c2 --- /dev/null +++ b/drivers/clk/qcom/gcc-kaanapali.c @@ -0,0 +1,3541 @@ +// 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 "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, + DT_PCIE_0_PIPE_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, + DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_GCC_GPLL0_OUT_EVEN, + P_GCC_GPLL0_OUT_MAIN, + P_GCC_GPLL1_OUT_MAIN, + P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL7_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, + P_PCIE_0_PIPE_CLK, + P_SLEEP_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +static struct clk_alpha_pll gcc_gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gcc_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_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 = "gcc_gpll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static struct clk_alpha_pll gcc_gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll9 = { + .offset = 0x9000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL1_OUT_MAIN, 4 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll1.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll7.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL9_OUT_MAIN, 2 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll9.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_12[] = { + { .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = { + .reg = 0x6b090, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_0_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77068, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_RX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770ec, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_RX_SYMBOL_1_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77058, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x39074, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_12, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0x6b094, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_0_phy_aux_clk_src = { + .cmd_rcgr = 0x6b0ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_aux_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_phy_rchng_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = { + .cmd_rcgr = 0x6b078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = { + .cmd_rcgr = 0x17008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = { + .cmd_rcgr = 0x17024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = { + .cmd_rcgr = 0x17040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = { + .cmd_rcgr = 0x1705c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = { + .cmd_rcgr = 0x17078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(250000000, P_GCC_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_qspi_ref_clk_src_init = { + .name = "gcc_qupv3_wrap1_qspi_ref_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_qspi_ref_clk_src = { + .cmd_rcgr = 0x188c0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_qspi_ref_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s0_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x182a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s4_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x183dc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18518, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { + .cmd_rcgr = 0x18654, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { + .cmd_rcgr = 0x18790, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .name = "gcc_qupv3_wrap2_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { + .cmd_rcgr = 0x1e014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .name = "gcc_qupv3_wrap2_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { + .cmd_rcgr = 0x1e150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .name = "gcc_qupv3_wrap2_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { + .cmd_rcgr = 0x1e28c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .name = "gcc_qupv3_wrap2_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { + .cmd_rcgr = 0x1e3c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .name = "gcc_qupv3_wrap2_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { + .cmd_rcgr = 0x1e504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap3_ibi_ctrl_0_clk_src[] = { + F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_ibi_ctrl_0_clk_src = { + .cmd_rcgr = 0xa877c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap3_ibi_ctrl_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s0_clk_src_init = { + .name = "gcc_qupv3_wrap3_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s0_clk_src = { + .cmd_rcgr = 0xa8014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s1_clk_src_init = { + .name = "gcc_qupv3_wrap3_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s1_clk_src = { + .cmd_rcgr = 0xa8150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s2_clk_src_init = { + .name = "gcc_qupv3_wrap3_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s2_clk_src = { + .cmd_rcgr = 0xa828c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s3_clk_src_init = { + .name = "gcc_qupv3_wrap3_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s3_clk_src = { + .cmd_rcgr = 0xa83c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s4_clk_src_init = { + .name = "gcc_qupv3_wrap3_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s4_clk_src = { + .cmd_rcgr = 0xa8504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap3_s5_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(128000000, P_GCC_GPLL0_OUT_MAIN, 1, 16, 75), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap3_s5_clk_src_init = { + .name = "gcc_qupv3_wrap3_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s5_clk_src = { + .cmd_rcgr = 0xa8640, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap3_s5_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s0_clk_src_init = { + .name = "gcc_qupv3_wrap4_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s0_clk_src = { + .cmd_rcgr = 0xa9014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s1_clk_src_init = { + .name = "gcc_qupv3_wrap4_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s1_clk_src = { + .cmd_rcgr = 0xa9150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s2_clk_src_init = { + .name = "gcc_qupv3_wrap4_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s2_clk_src = { + .cmd_rcgr = 0xa928c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s3_clk_src_init = { + .name = "gcc_qupv3_wrap4_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s3_clk_src = { + .cmd_rcgr = 0xa93c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s4_clk_src_init = { + .name = "gcc_qupv3_wrap4_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s4_clk_src = { + .cmd_rcgr = 0xa9504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x1601c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x7708c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x770c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x770a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GCC_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x39034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x3904c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x39078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap1_s2_clk_src = { + .reg = 0x1828c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0x39064, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_axi_clk = { + .halt_reg = 0x10068, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x10068, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x770f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0x39094, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0x26014, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_sf_axi_clk = { + .halt_reg = 0x26028, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_pcie_anoc_ahb_clk = { + .halt_reg = 0x10050, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x10050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_pcie_anoc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x39090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cnoc_pcie_sf_axi_clk = { + .halt_reg = 0x10058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cnoc_pcie_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_pcie_sf_qtb_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x1007c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_pcie_sf_qtb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x2701c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_sf_axi_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x27008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_sf_axi_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0_clk = { + .halt_reg = 0x9f008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0c_clk = { + .halt_reg = 0x9f01c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0c_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gemnoc_gfx_clk = { + .halt_reg = 0x71010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gemnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x6b044, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x6b040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x6b030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_aux_clk = { + .halt_reg = 0x6b054, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_rchng_clk = { + .halt_reg = 0x6b074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b064, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { + .halt_reg = 0x6b01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_cmd_ahb_clk = { + .halt_reg = 0x26010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_cmd_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x2600c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2600c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2600c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_dcp_sf_ahb_clk = { + .halt_reg = 0x27030, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x27030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_disp_dcp_sf_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_ahb_clk = { + .halt_reg = 0x71008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_gpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_ahb_clk = { + .halt_reg = 0x6b018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cv_cpu_ahb_clk = { + .halt_reg = 0x32014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cv_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cvp_ahb_clk = { + .halt_reg = 0x32008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cvp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_v_cpu_ahb_clk = { + .halt_reg = 0x32010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_v_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x3200c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3200c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3200c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_core_clk = { + .halt_reg = 0x23004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s0_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s1_clk = { + .halt_reg = 0x17020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s2_clk = { + .halt_reg = 0x1703c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s3_clk = { + .halt_reg = 0x17058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s4_clk = { + .halt_reg = 0x17074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s_ahb_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x2315c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x23148, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_qspi_ref_clk = { + .halt_reg = 0x188bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_qspi_ref_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x18140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x1827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x18290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x183cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x18508, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s6_clk = { + .halt_reg = 0x18644, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s7_clk = { + .halt_reg = 0x18780, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_2x_clk = { + .halt_reg = 0x232b4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_clk = { + .halt_reg = 0x232a0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s0_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s1_clk = { + .halt_reg = 0x1e140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s2_clk = { + .halt_reg = 0x1e27c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s3_clk = { + .halt_reg = 0x1e3b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s4_clk = { + .halt_reg = 0x1e4f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_core_2x_clk = { + .halt_reg = 0x2340c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_core_clk = { + .halt_reg = 0x233f8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_ibi_ctrl_1_clk = { + .halt_reg = 0xa8774, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8774, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_ibi_ctrl_2_clk = { + .halt_reg = 0xa8778, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8778, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s0_clk = { + .halt_reg = 0xa8004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s1_clk = { + .halt_reg = 0xa8140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s2_clk = { + .halt_reg = 0xa827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s3_clk = { + .halt_reg = 0xa83b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s4_clk = { + .halt_reg = 0xa84f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s5_clk = { + .halt_reg = 0xa8630, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_core_2x_clk = { + .halt_reg = 0x23564, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_core_clk = { + .halt_reg = 0x23550, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s0_clk = { + .halt_reg = 0xa9004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s1_clk = { + .halt_reg = 0xa9140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s2_clk = { + .halt_reg = 0xa927c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s3_clk = { + .halt_reg = 0xa93b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s4_clk = { + .halt_reg = 0xa94f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_axi_clk = { + .halt_reg = 0x23140, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23140, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_m_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x23144, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23144, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = { + .halt_reg = 0x23298, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23298, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = { + .halt_reg = 0x2329c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2329c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_ibi_1_ahb_clk = { + .halt_reg = 0xa876c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa876c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_ibi_1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_ibi_2_ahb_clk = { + .halt_reg = 0xa8770, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8770, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_ibi_2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_m_ahb_clk = { + .halt_reg = 0x233f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x233f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_s_ahb_clk = { + .halt_reg = 0x233f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x233f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_4_m_ahb_clk = { + .halt_reg = 0x23548, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23548, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_4_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_4_s_ahb_clk = { + .halt_reg = 0x2354c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2354c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_4_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x16014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc4_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77028, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x7707c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7707c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7707c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x770bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x77030, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_reg = 0x770d8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x770d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x7702c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7702c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x7706c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7706c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7706c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x39018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x3902c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3902c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x39028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0x39068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x3906c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3906c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x39070, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x39070, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x32018, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x32018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi1_clk = { + .halt_reg = 0x3202c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x3202c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3202c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gcc_pcie_0_gdsc = { + .gdscr = 0x6b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .collapse_ctrl = 0x5214c, + .collapse_mask = BIT(0), + .pd = { + .name = "gcc_pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_0_phy_gdsc = { + .gdscr = 0x6c000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .collapse_ctrl = 0x5214c, + .collapse_mask = BIT(2), + .pd = { + .name = "gcc_pcie_0_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_ufs_mem_phy_gdsc = { + .gdscr = 0x9e000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_ufs_mem_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_ufs_phy_gdsc = { + .gdscr = 0x77004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_prim_gdsc = { + .gdscr = 0x39004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb3_phy_gdsc = { + .gdscr = 0x50018, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb3_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_kaanapali_clocks[] = { + [GCC_AGGRE_NOC_PCIE_AXI_CLK] = &gcc_aggre_noc_pcie_axi_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, + [GCC_CFG_NOC_PCIE_ANOC_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_ahb_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CNOC_PCIE_SF_AXI_CLK] = &gcc_cnoc_pcie_sf_axi_clk.clkr, + [GCC_DDRSS_PCIE_SF_QTB_CLK] = &gcc_ddrss_pcie_sf_qtb_clk.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_SF_AXI_CLK] = &gcc_disp_sf_axi_clk.clkr, + [GCC_EVA_AXI0_CLK] = &gcc_eva_axi0_clk.clkr, + [GCC_EVA_AXI0C_CLK] = &gcc_eva_axi0c_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPLL0] = &gcc_gpll0.clkr, + [GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr, + [GCC_GPLL1] = &gcc_gpll1.clkr, + [GCC_GPLL4] = &gcc_gpll4.clkr, + [GCC_GPLL7] = &gcc_gpll7.clkr, + [GCC_GPLL9] = &gcc_gpll9.clkr, + [GCC_GPU_GEMNOC_GFX_CLK] = &gcc_gpu_gemnoc_gfx_clk.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PHY_AUX_CLK] = &gcc_pcie_0_phy_aux_clk.clkr, + [GCC_PCIE_0_PHY_AUX_CLK_SRC] = &gcc_pcie_0_phy_aux_clk_src.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK] = &gcc_pcie_0_phy_rchng_clk.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK_SRC] = &gcc_pcie_0_phy_rchng_clk_src.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_PIPE_CLK_SRC] = &gcc_pcie_0_pipe_clk_src.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_QUPV3_I2C_CORE_CLK] = &gcc_qupv3_i2c_core_clk.clkr, + [GCC_QUPV3_I2C_S0_CLK] = &gcc_qupv3_i2c_s0_clk.clkr, + [GCC_QUPV3_I2C_S0_CLK_SRC] = &gcc_qupv3_i2c_s0_clk_src.clkr, + [GCC_QUPV3_I2C_S1_CLK] = &gcc_qupv3_i2c_s1_clk.clkr, + [GCC_QUPV3_I2C_S1_CLK_SRC] = &gcc_qupv3_i2c_s1_clk_src.clkr, + [GCC_QUPV3_I2C_S2_CLK] = &gcc_qupv3_i2c_s2_clk.clkr, + [GCC_QUPV3_I2C_S2_CLK_SRC] = &gcc_qupv3_i2c_s2_clk_src.clkr, + [GCC_QUPV3_I2C_S3_CLK] = &gcc_qupv3_i2c_s3_clk.clkr, + [GCC_QUPV3_I2C_S3_CLK_SRC] = &gcc_qupv3_i2c_s3_clk_src.clkr, + [GCC_QUPV3_I2C_S4_CLK] = &gcc_qupv3_i2c_s4_clk.clkr, + [GCC_QUPV3_I2C_S4_CLK_SRC] = &gcc_qupv3_i2c_s4_clk_src.clkr, + [GCC_QUPV3_I2C_S_AHB_CLK] = &gcc_qupv3_i2c_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_REF_CLK] = &gcc_qupv3_wrap1_qspi_ref_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_REF_CLK_SRC] = &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr, + [GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr, + [GCC_QUPV3_WRAP1_S7_CLK] = &gcc_qupv3_wrap1_s7_clk.clkr, + [GCC_QUPV3_WRAP1_S7_CLK_SRC] = &gcc_qupv3_wrap1_s7_clk_src.clkr, + [GCC_QUPV3_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr, + [GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr, + [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr, + [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr, + [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr, + [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr, + [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr, + [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr, + [GCC_QUPV3_WRAP3_CORE_2X_CLK] = &gcc_qupv3_wrap3_core_2x_clk.clkr, + [GCC_QUPV3_WRAP3_CORE_CLK] = &gcc_qupv3_wrap3_core_clk.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_0_CLK_SRC] = &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_1_CLK] = &gcc_qupv3_wrap3_ibi_ctrl_1_clk.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_2_CLK] = &gcc_qupv3_wrap3_ibi_ctrl_2_clk.clkr, + [GCC_QUPV3_WRAP3_S0_CLK] = &gcc_qupv3_wrap3_s0_clk.clkr, + [GCC_QUPV3_WRAP3_S0_CLK_SRC] = &gcc_qupv3_wrap3_s0_clk_src.clkr, + [GCC_QUPV3_WRAP3_S1_CLK] = &gcc_qupv3_wrap3_s1_clk.clkr, + [GCC_QUPV3_WRAP3_S1_CLK_SRC] = &gcc_qupv3_wrap3_s1_clk_src.clkr, + [GCC_QUPV3_WRAP3_S2_CLK] = &gcc_qupv3_wrap3_s2_clk.clkr, + [GCC_QUPV3_WRAP3_S2_CLK_SRC] = &gcc_qupv3_wrap3_s2_clk_src.clkr, + [GCC_QUPV3_WRAP3_S3_CLK] = &gcc_qupv3_wrap3_s3_clk.clkr, + [GCC_QUPV3_WRAP3_S3_CLK_SRC] = &gcc_qupv3_wrap3_s3_clk_src.clkr, + [GCC_QUPV3_WRAP3_S4_CLK] = &gcc_qupv3_wrap3_s4_clk.clkr, + [GCC_QUPV3_WRAP3_S4_CLK_SRC] = &gcc_qupv3_wrap3_s4_clk_src.clkr, + [GCC_QUPV3_WRAP3_S5_CLK] = &gcc_qupv3_wrap3_s5_clk.clkr, + [GCC_QUPV3_WRAP3_S5_CLK_SRC] = &gcc_qupv3_wrap3_s5_clk_src.clkr, + [GCC_QUPV3_WRAP4_CORE_2X_CLK] = &gcc_qupv3_wrap4_core_2x_clk.clkr, + [GCC_QUPV3_WRAP4_CORE_CLK] = &gcc_qupv3_wrap4_core_clk.clkr, + [GCC_QUPV3_WRAP4_S0_CLK] = &gcc_qupv3_wrap4_s0_clk.clkr, + [GCC_QUPV3_WRAP4_S0_CLK_SRC] = &gcc_qupv3_wrap4_s0_clk_src.clkr, + [GCC_QUPV3_WRAP4_S1_CLK] = &gcc_qupv3_wrap4_s1_clk.clkr, + [GCC_QUPV3_WRAP4_S1_CLK_SRC] = &gcc_qupv3_wrap4_s1_clk_src.clkr, + [GCC_QUPV3_WRAP4_S2_CLK] = &gcc_qupv3_wrap4_s2_clk.clkr, + [GCC_QUPV3_WRAP4_S2_CLK_SRC] = &gcc_qupv3_wrap4_s2_clk_src.clkr, + [GCC_QUPV3_WRAP4_S3_CLK] = &gcc_qupv3_wrap4_s3_clk.clkr, + [GCC_QUPV3_WRAP4_S3_CLK_SRC] = &gcc_qupv3_wrap4_s3_clk_src.clkr, + [GCC_QUPV3_WRAP4_S4_CLK] = &gcc_qupv3_wrap4_s4_clk.clkr, + [GCC_QUPV3_WRAP4_S4_CLK_SRC] = &gcc_qupv3_wrap4_s4_clk_src.clkr, + [GCC_QUPV3_WRAP_1_M_AXI_CLK] = &gcc_qupv3_wrap_1_m_axi_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_IBI_1_AHB_CLK] = &gcc_qupv3_wrap_3_ibi_1_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_IBI_2_AHB_CLK] = &gcc_qupv3_wrap_3_ibi_2_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_M_AHB_CLK] = &gcc_qupv3_wrap_3_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_S_AHB_CLK] = &gcc_qupv3_wrap_3_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_4_M_AHB_CLK] = &gcc_qupv3_wrap_4_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_4_S_AHB_CLK] = &gcc_qupv3_wrap_4_s_ahb_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_QMIP_CAMERA_CMD_AHB_CLK] = &gcc_qmip_camera_cmd_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QMIP_GPU_AHB_CLK] = &gcc_qmip_gpu_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_DCP_SF_AHB_CLK] = &gcc_qmip_disp_dcp_sf_ahb_clk.clkr, + [GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CV_CPU_AHB_CLK] = &gcc_qmip_video_cv_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, +}; + +static struct gdsc *gcc_kaanapali_gdscs[] = { + [GCC_PCIE_0_GDSC] = &gcc_pcie_0_gdsc, + [GCC_PCIE_0_PHY_GDSC] = &gcc_pcie_0_phy_gdsc, + [GCC_UFS_MEM_PHY_GDSC] = &gcc_ufs_mem_phy_gdsc, + [GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc, + [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc, + [GCC_USB3_PHY_GDSC] = &gcc_usb3_phy_gdsc, +}; + +static const struct qcom_reset_map gcc_kaanapali_resets[] = { + [GCC_CAMERA_BCR] = { 0x26000 }, + [GCC_DISPLAY_BCR] = { 0x27000 }, + [GCC_EVA_AXI0_CLK_ARES] = { 0x9f008, 2 }, + [GCC_EVA_AXI0C_CLK_ARES] = { 0x9f01c, 2 }, + [GCC_EVA_BCR] = { 0x9f000 }, + [GCC_GPU_BCR] = { 0x71000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 }, + [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 }, + [GCC_PCIE_RSCC_BCR] = { 0x11000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 }, + [GCC_QUPV3_WRAPPER_3_BCR] = { 0xa8000 }, + [GCC_QUPV3_WRAPPER_4_BCR] = { 0xa9000 }, + [GCC_QUPV3_WRAPPER_I2C_BCR] = { 0x17000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0x39000 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 }, + [GCC_VIDEO_AXI1_CLK_ARES] = { 0x3202c, 2 }, + [GCC_VIDEO_BCR] = { 0x32000 }, + [GCC_VIDEO_XO_CLK_ARES] = { 0x32040, 2 }, +}; + +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_ref_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s4_clk_src), +}; + +static u32 gcc_kaanapali_critical_cbcrs[] = { + 0xa0004, /* GCC_CAM_BIST_MCLK_AHB_CLK */ + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x2603c, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x9f004, /* GCC_EVA_AHB_CLK */ + 0x9f024, /* GCC_EVA_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */ + 0x52010, /* GCC_PCIE_RSCC_XO_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32040, /* GCC_VIDEO_XO_CLK */ +}; + +static const struct regmap_config gcc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1f41f0, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); +} + +static struct qcom_cc_driver_data gcc_kaanapali_driver_data = { + .clk_cbcrs = gcc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_kaanapali_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc gcc_kaanapali_desc = { + .config = &gcc_kaanapali_regmap_config, + .clks = gcc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(gcc_kaanapali_clocks), + .resets = gcc_kaanapali_resets, + .num_resets = ARRAY_SIZE(gcc_kaanapali_resets), + .gdscs = gcc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_kaanapali_gdscs), + .driver_data = &gcc_kaanapali_driver_data, +}; + +static const struct of_device_id gcc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_kaanapali_match_table); + +static int gcc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_kaanapali_desc); +} + +static struct platform_driver gcc_kaanapali_driver = { + .probe = gcc_kaanapali_probe, + .driver = { + .name = "gcc-kaanapali", + .of_match_table = gcc_kaanapali_match_table, + }, +}; + +static int __init gcc_kaanapali_init(void) +{ + return platform_driver_register(&gcc_kaanapali_driver); +} +subsys_initcall(gcc_kaanapali_init); + +static void __exit gcc_kaanapali_exit(void) +{ + platform_driver_unregister(&gcc_kaanapali_driver); +} +module_exit(gcc_kaanapali_exit); + +MODULE_DESCRIPTION("QTI GCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 0722655c75af527ec06753bf312084e67ce95eba Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 25 Nov 2025 23:15:10 +0530 Subject: [PATCH 314/659] FROMLIST: clk: qcom: clk-alpha-pll: Update the PLL support for cal_l Recent QCOM PLLs require the CAL_L field to be programmed according to specific hardware recommendations, rather than using the legacy default value of 0x44. Hardcoding this value can lead to suboptimal or incorrect behavior on newer platforms. To address this, introduce a `cal_l` field in the PLL configuration structure, allowing CAL_L to be set explicitly based on platform requirements. This improves flexibility and ensures correct PLL initialization across different hardware variants. Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251125-kaanapali-mmcc-v2-v2-1-fb44e78f300b@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.c | 6 +++++- drivers/clk/qcom/clk-alpha-pll.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 8586649d76f8a..3fbdee6e67f9c 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -2351,7 +2351,11 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma return; } - lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + if (config->cal_l) + lval |= config->cal_l << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + else + lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval); clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index b4492197419a7..25ae61eed1955 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -129,6 +129,7 @@ struct clk_alpha_pll_postdiv { struct alpha_pll_config { u32 l; + u32 cal_l; u32 alpha; u32 alpha_hi; u32 config_ctl_val; From 1e39c500b0b8588fd067d919412200288df40503 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 25 Nov 2025 23:15:11 +0530 Subject: [PATCH 315/659] FROMLIST: clk: qcom: clk-alpha-pll: Add support for controlling Pongo EKO_T PLL Add clock ops for Pongo EKO_T PLL, add the pll ops for supporting the PLL. Signed-off-by: Jingyi Wang Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251125-kaanapali-mmcc-v2-v2-2-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 25ae61eed1955..090bd029035cd 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -28,6 +28,7 @@ enum { CLK_ALPHA_PLL_TYPE_LUCID_EVO, CLK_ALPHA_PLL_TYPE_LUCID_OLE, CLK_ALPHA_PLL_TYPE_PONGO_ELU, + CLK_ALPHA_PLL_TYPE_PONGO_EKO_T = CLK_ALPHA_PLL_TYPE_PONGO_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, @@ -208,6 +209,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; #define clk_alpha_pll_postdiv_taycan_eko_t_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_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops #define clk_alpha_pll_rivian_elu_ops clk_alpha_pll_rivian_evo_ops From ca5e0725db91e037b4f7a2d94bdde57cb1fe8626 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 25 Nov 2025 23:15:12 +0530 Subject: [PATCH 316/659] 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 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 090bd029035cd..b942c17bdda06 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -33,6 +33,7 @@ enum { CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, + CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T = CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, CLK_ALPHA_PLL_TYPE_STROMER, @@ -211,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 From 541df384f4fc0c9ca2d0c3bc4c5008a60760436c Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 11 Dec 2025 00:32:23 +0530 Subject: [PATCH 317/659] FROMGIT: dt-bindings: mailbox: qcom: Document SM8750 CPUCP mailbox controller Document CPU Control Processor (CPUCP) mailbox controller for Qualcomm SM8750 SoCs. It is software compatible with X1E80100 CPUCP mailbox controller hence fallback to it. Git-commit: 65ce09d2f164a3d91b5802ecd0783aa2c9a208c0 Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251211-sm8750-cpufreq-v1-1-394609e8d624@oss.qualcomm.com Signed-off-by: Jagadeesh Kona --- Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml index 9122c3d2dc30f..9d99af46e531a 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml @@ -19,6 +19,7 @@ properties: - items: - enum: - qcom,glymur-cpucp-mbox + - qcom,sm8750-cpucp-mbox - const: qcom,x1e80100-cpucp-mbox - enum: - qcom,x1e80100-cpucp-mbox From b54a267134eddb2eeb2584636ca16c3eec79f187 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:07 +0530 Subject: [PATCH 318/659] FROMLIST: dt-bindings: clock: qcom: document Kaanapali DISPCC clock controller Document device tree bindings for display clock controller for Qualcomm Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-4-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sm8550-dispcc.yaml | 2 + .../dt-bindings/clock/qcom,kaanapali-dispcc.h | 109 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-dispcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml index 30e4b46315752..591ce91b8d54d 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml @@ -15,6 +15,7 @@ description: | domains on SM8550, SM8650, SM8750 and few other platforms. See also: + - include/dt-bindings/clock/qcom,kaanapali-dispcc.h - include/dt-bindings/clock/qcom,sm8550-dispcc.h - include/dt-bindings/clock/qcom,sm8650-dispcc.h - include/dt-bindings/clock/qcom,sm8750-dispcc.h @@ -23,6 +24,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-dispcc - qcom,sar2130p-dispcc - qcom,sm8550-dispcc - qcom,sm8650-dispcc diff --git a/include/dt-bindings/clock/qcom,kaanapali-dispcc.h b/include/dt-bindings/clock/qcom,kaanapali-dispcc.h new file mode 100644 index 0000000000000..05146f9dfe077 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-dispcc.h @@ -0,0 +1,109 @@ +/* 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_DISP_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_KAANAPALI_H + +/* DISP_CC clocks */ +#define DISP_CC_ESYNC0_CLK 0 +#define DISP_CC_ESYNC0_CLK_SRC 1 +#define DISP_CC_ESYNC1_CLK 2 +#define DISP_CC_ESYNC1_CLK_SRC 3 +#define DISP_CC_MDSS_ACCU_SHIFT_CLK 4 +#define DISP_CC_MDSS_AHB1_CLK 5 +#define DISP_CC_MDSS_AHB_CLK 6 +#define DISP_CC_MDSS_AHB_CLK_SRC 7 +#define DISP_CC_MDSS_AHB_SWI_CLK 8 +#define DISP_CC_MDSS_AHB_SWI_DIV_CLK_SRC 9 +#define DISP_CC_MDSS_BYTE0_CLK 10 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 11 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 12 +#define DISP_CC_MDSS_BYTE0_INTF_CLK 13 +#define DISP_CC_MDSS_BYTE1_CLK 14 +#define DISP_CC_MDSS_BYTE1_CLK_SRC 15 +#define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 16 +#define DISP_CC_MDSS_BYTE1_INTF_CLK 17 +#define DISP_CC_MDSS_DPTX0_AUX_CLK 18 +#define DISP_CC_MDSS_DPTX0_AUX_CLK_SRC 19 +#define DISP_CC_MDSS_DPTX0_CRYPTO_CLK 20 +#define DISP_CC_MDSS_DPTX0_LINK_CLK 21 +#define DISP_CC_MDSS_DPTX0_LINK_CLK_SRC 22 +#define DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC 23 +#define DISP_CC_MDSS_DPTX0_LINK_INTF_CLK 24 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK 25 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC 26 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK 27 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC 28 +#define DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK 29 +#define DISP_CC_MDSS_DPTX1_AUX_CLK 30 +#define DISP_CC_MDSS_DPTX1_AUX_CLK_SRC 31 +#define DISP_CC_MDSS_DPTX1_CRYPTO_CLK 32 +#define DISP_CC_MDSS_DPTX1_LINK_CLK 33 +#define DISP_CC_MDSS_DPTX1_LINK_CLK_SRC 34 +#define DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC 35 +#define DISP_CC_MDSS_DPTX1_LINK_INTF_CLK 36 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK 37 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC 38 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK 39 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC 40 +#define DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK 41 +#define DISP_CC_MDSS_DPTX2_AUX_CLK 42 +#define DISP_CC_MDSS_DPTX2_AUX_CLK_SRC 43 +#define DISP_CC_MDSS_DPTX2_CRYPTO_CLK 44 +#define DISP_CC_MDSS_DPTX2_LINK_CLK 45 +#define DISP_CC_MDSS_DPTX2_LINK_CLK_SRC 46 +#define DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC 47 +#define DISP_CC_MDSS_DPTX2_LINK_INTF_CLK 48 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK 49 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC 50 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK 51 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC 52 +#define DISP_CC_MDSS_DPTX3_AUX_CLK 53 +#define DISP_CC_MDSS_DPTX3_AUX_CLK_SRC 54 +#define DISP_CC_MDSS_DPTX3_CRYPTO_CLK 55 +#define DISP_CC_MDSS_DPTX3_LINK_CLK 56 +#define DISP_CC_MDSS_DPTX3_LINK_CLK_SRC 57 +#define DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC 58 +#define DISP_CC_MDSS_DPTX3_LINK_INTF_CLK 59 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK 60 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC 61 +#define DISP_CC_MDSS_ESC0_CLK 62 +#define DISP_CC_MDSS_ESC0_CLK_SRC 63 +#define DISP_CC_MDSS_ESC1_CLK 64 +#define DISP_CC_MDSS_ESC1_CLK_SRC 65 +#define DISP_CC_MDSS_MDP1_CLK 66 +#define DISP_CC_MDSS_MDP_CLK 67 +#define DISP_CC_MDSS_MDP_CLK_SRC 68 +#define DISP_CC_MDSS_MDP_LUT1_CLK 69 +#define DISP_CC_MDSS_MDP_LUT_CLK 70 +#define DISP_CC_MDSS_MDP_SS_IP_CLK 71 +#define DISP_CC_MDSS_NON_GDSC_AHB_CLK 72 +#define DISP_CC_MDSS_PCLK0_CLK 73 +#define DISP_CC_MDSS_PCLK0_CLK_SRC 74 +#define DISP_CC_MDSS_PCLK1_CLK 75 +#define DISP_CC_MDSS_PCLK1_CLK_SRC 76 +#define DISP_CC_MDSS_PCLK2_CLK 77 +#define DISP_CC_MDSS_PCLK2_CLK_SRC 78 +#define DISP_CC_MDSS_VSYNC1_CLK 79 +#define DISP_CC_MDSS_VSYNC_CLK 80 +#define DISP_CC_MDSS_VSYNC_CLK_SRC 81 +#define DISP_CC_OSC_CLK 82 +#define DISP_CC_OSC_CLK_SRC 83 +#define DISP_CC_PLL0 84 +#define DISP_CC_PLL1 85 +#define DISP_CC_PLL2 86 +#define DISP_CC_SLEEP_CLK 87 +#define DISP_CC_XO_CLK 88 + +/* DISP_CC power domains */ +#define DISP_CC_MDSS_CORE_GDSC 0 +#define DISP_CC_MDSS_CORE_INT2_GDSC 1 + +/* DISP_CC resets */ +#define DISP_CC_MDSS_CORE_BCR 0 +#define DISP_CC_MDSS_CORE_INT2_BCR 1 +#define DISP_CC_MDSS_RSCC_BCR 2 + +#endif From ebf5c5800a87add3b4c80e367de9c20cb4d0e6ed Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:08 +0530 Subject: [PATCH 319/659] FROMLIST: dt-bindings: clock: qcom: Add support for CAMCC for Kaanapali Update the compatible and the bindings for CAMCC support on Kaanapali SoC. Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-5-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sm8450-camcc.yaml | 6 + .../clock/qcom,kaanapali-cambistmclkcc.h | 33 ++++ .../dt-bindings/clock/qcom,kaanapali-camcc.h | 147 ++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h create mode 100644 include/dt-bindings/clock/qcom,kaanapali-camcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index 8e3baba5270b3..8492a7ef73245 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -16,6 +16,8 @@ description: | domains on SM8450. See also: + include/dt-bindings/clock/qcom,kaanapali-camcc.h + include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h include/dt-bindings/clock/qcom,sm8450-camcc.h include/dt-bindings/clock/qcom,sm8550-camcc.h include/dt-bindings/clock/qcom,sm8650-camcc.h @@ -25,6 +27,8 @@ description: | properties: compatible: enum: + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc - qcom,sm8450-camcc - qcom,sm8475-camcc - qcom,sm8550-camcc @@ -68,6 +72,8 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc - qcom,sc8280xp-camcc - qcom,sm8450-camcc - qcom,sm8550-camcc diff --git a/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h b/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h new file mode 100644 index 0000000000000..ddb083b5289ec --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h @@ -0,0 +1,33 @@ +/* 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_CAM_BIST_MCLK_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_KAANAPALI_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_DEBUG_CLK 0 +#define CAM_BIST_MCLK_CC_DEBUG_DIV_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK0_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 16 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 17 +#define CAM_BIST_MCLK_CC_PLL0 18 +#define CAM_BIST_MCLK_CC_PLL_TEST_CLK 19 +#define CAM_BIST_MCLK_CC_PLL_TEST_DIV_CLK_SRC 20 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 21 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-camcc.h b/include/dt-bindings/clock/qcom,kaanapali-camcc.h new file mode 100644 index 0000000000000..58835136b356a --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-camcc.h @@ -0,0 +1,147 @@ +/* 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_CAM_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_KAANAPALI_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 6 +#define CAM_CC_CAMNOC_RT_AXI_CLK 7 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 8 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 9 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 10 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 12 +#define CAM_CC_CAMNOC_XO_CLK 13 +#define CAM_CC_CCI_0_CLK 14 +#define CAM_CC_CCI_0_CLK_SRC 15 +#define CAM_CC_CCI_1_CLK 16 +#define CAM_CC_CCI_1_CLK_SRC 17 +#define CAM_CC_CCI_2_CLK 18 +#define CAM_CC_CCI_2_CLK_SRC 19 +#define CAM_CC_CORE_AHB_CLK 20 +#define CAM_CC_CPHY_RX_CLK_SRC 21 +#define CAM_CC_CRE_AHB_CLK 22 +#define CAM_CC_CRE_CLK 23 +#define CAM_CC_CRE_CLK_SRC 24 +#define CAM_CC_CSI0PHYTIMER_CLK 25 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 26 +#define CAM_CC_CSI1PHYTIMER_CLK 27 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 28 +#define CAM_CC_CSI2PHYTIMER_CLK 29 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 30 +#define CAM_CC_CSI3PHYTIMER_CLK 31 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 32 +#define CAM_CC_CSI4PHYTIMER_CLK 33 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 34 +#define CAM_CC_CSI5PHYTIMER_CLK 35 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 36 +#define CAM_CC_CSID_CLK 37 +#define CAM_CC_CSID_CLK_SRC 38 +#define CAM_CC_CSID_CSIPHY_RX_CLK 39 +#define CAM_CC_CSIPHY0_CLK 40 +#define CAM_CC_CSIPHY1_CLK 41 +#define CAM_CC_CSIPHY2_CLK 42 +#define CAM_CC_CSIPHY3_CLK 43 +#define CAM_CC_CSIPHY4_CLK 44 +#define CAM_CC_CSIPHY5_CLK 45 +#define CAM_CC_DRV_AHB_CLK 46 +#define CAM_CC_DRV_XO_CLK 47 +#define CAM_CC_FAST_AHB_CLK_SRC 48 +#define CAM_CC_GDSC_CLK 49 +#define CAM_CC_ICP_0_AHB_CLK 50 +#define CAM_CC_ICP_0_CLK 51 +#define CAM_CC_ICP_0_CLK_SRC 52 +#define CAM_CC_ICP_1_AHB_CLK 53 +#define CAM_CC_ICP_1_CLK 54 +#define CAM_CC_ICP_1_CLK_SRC 55 +#define CAM_CC_IFE_LITE_AHB_CLK 56 +#define CAM_CC_IFE_LITE_CLK 57 +#define CAM_CC_IFE_LITE_CLK_SRC 58 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 59 +#define CAM_CC_IFE_LITE_CSID_CLK 60 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 61 +#define CAM_CC_IPE_NPS_AHB_CLK 62 +#define CAM_CC_IPE_NPS_CLK 63 +#define CAM_CC_IPE_NPS_CLK_SRC 64 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 65 +#define CAM_CC_IPE_PPS_CLK 66 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 67 +#define CAM_CC_JPEG_CLK 68 +#define CAM_CC_JPEG_CLK_SRC 69 +#define CAM_CC_OFE_AHB_CLK 70 +#define CAM_CC_OFE_ANCHOR_CLK 71 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 72 +#define CAM_CC_OFE_CLK_SRC 73 +#define CAM_CC_OFE_HDR_CLK 74 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 75 +#define CAM_CC_OFE_MAIN_CLK 76 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 77 +#define CAM_CC_PLL0 78 +#define CAM_CC_PLL0_OUT_EVEN 79 +#define CAM_CC_PLL0_OUT_ODD 80 +#define CAM_CC_PLL1 81 +#define CAM_CC_PLL1_OUT_EVEN 82 +#define CAM_CC_PLL2 83 +#define CAM_CC_PLL2_OUT_EVEN 84 +#define CAM_CC_PLL3 85 +#define CAM_CC_PLL3_OUT_EVEN 86 +#define CAM_CC_PLL4 87 +#define CAM_CC_PLL4_OUT_EVEN 88 +#define CAM_CC_PLL5 89 +#define CAM_CC_PLL5_OUT_EVEN 90 +#define CAM_CC_PLL6 91 +#define CAM_CC_PLL6_OUT_EVEN 92 +#define CAM_CC_PLL6_OUT_ODD 93 +#define CAM_CC_PLL7 94 +#define CAM_CC_PLL7_OUT_EVEN 95 +#define CAM_CC_QDSS_DEBUG_CLK 96 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 97 +#define CAM_CC_QDSS_DEBUG_XO_CLK 98 +#define CAM_CC_SLEEP_CLK 99 +#define CAM_CC_SLOW_AHB_CLK_SRC 100 +#define CAM_CC_TFE_0_BAYER_CLK 101 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 102 +#define CAM_CC_TFE_0_CLK_SRC 103 +#define CAM_CC_TFE_0_MAIN_CLK 104 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 105 +#define CAM_CC_TFE_1_BAYER_CLK 106 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_1_CLK_SRC 108 +#define CAM_CC_TFE_1_MAIN_CLK 109 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_2_BAYER_CLK 111 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_2_CLK_SRC 113 +#define CAM_CC_TFE_2_MAIN_CLK 114 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TRACENOC_TPDM_1_CMB_CLK 116 +#define CAM_CC_XO_CLK_SRC 117 + +/* CAM_CC power domains */ +#define CAM_CC_IPE_0_GDSC 0 +#define CAM_CC_OFE_GDSC 1 +#define CAM_CC_TFE_0_GDSC 2 +#define CAM_CC_TFE_1_GDSC 3 +#define CAM_CC_TFE_2_GDSC 4 +#define CAM_CC_TITAN_TOP_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif From b6abbe6e3fed9ba56d7975c70694ce7f80f08d35 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:09 +0530 Subject: [PATCH 320/659] FROMLIST: dt-bindings: clock: qcom: Add Kaanapali video clock controller Add device tree bindings for the video clock controller on Qualcomm Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-6-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sm8450-videocc.yaml | 3 + .../clock/qcom,kaanapali-videocc.h | 58 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-videocc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index b31bd83355293..e6beebd6a36ee 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,kaanapali-videocc.h include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h include/dt-bindings/clock/qcom,sm8750-videocc.h @@ -22,6 +23,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8475-videocc - qcom,sm8550-videocc @@ -61,6 +63,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8550-videocc - qcom,sm8750-videocc diff --git a/include/dt-bindings/clock/qcom,kaanapali-videocc.h b/include/dt-bindings/clock/qcom,kaanapali-videocc.h new file mode 100644 index 0000000000000..cc0d41b895c92 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-videocc.h @@ -0,0 +1,58 @@ +/* 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_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_KAANAPALI_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_FREERUN_CLK 4 +#define VIDEO_CC_MVS0_SHIFT_CLK 5 +#define VIDEO_CC_MVS0_VPP0_CLK 6 +#define VIDEO_CC_MVS0_VPP0_FREERUN_CLK 7 +#define VIDEO_CC_MVS0_VPP1_CLK 8 +#define VIDEO_CC_MVS0_VPP1_FREERUN_CLK 9 +#define VIDEO_CC_MVS0A_CLK 10 +#define VIDEO_CC_MVS0A_CLK_SRC 11 +#define VIDEO_CC_MVS0A_FREERUN_CLK 12 +#define VIDEO_CC_MVS0B_CLK 13 +#define VIDEO_CC_MVS0B_CLK_SRC 14 +#define VIDEO_CC_MVS0B_FREERUN_CLK 15 +#define VIDEO_CC_MVS0C_CLK 16 +#define VIDEO_CC_MVS0C_CLK_SRC 17 +#define VIDEO_CC_MVS0C_FREERUN_CLK 18 +#define VIDEO_CC_MVS0C_SHIFT_CLK 19 +#define VIDEO_CC_PLL0 20 +#define VIDEO_CC_PLL1 21 +#define VIDEO_CC_PLL2 22 +#define VIDEO_CC_PLL3 23 +#define VIDEO_CC_SLEEP_CLK 24 +#define VIDEO_CC_TS_XO_CLK 25 +#define VIDEO_CC_XO_CLK 26 +#define VIDEO_CC_XO_CLK_SRC 27 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0A_GDSC 0 +#define VIDEO_CC_MVS0_GDSC 1 +#define VIDEO_CC_MVS0_VPP1_GDSC 2 +#define VIDEO_CC_MVS0_VPP0_GDSC 3 +#define VIDEO_CC_MVS0C_GDSC 4 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_BCR 1 +#define VIDEO_CC_MVS0_VPP0_BCR 2 +#define VIDEO_CC_MVS0_VPP1_BCR 3 +#define VIDEO_CC_MVS0A_BCR 4 +#define VIDEO_CC_MVS0C_CLK_ARES 5 +#define VIDEO_CC_MVS0C_BCR 6 +#define VIDEO_CC_MVS0_FREERUN_CLK_ARES 7 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 8 +#define VIDEO_CC_XO_CLK_ARES 9 + +#endif From ccf5edacf01df329244070daa9247df6f2effc69 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:10 +0530 Subject: [PATCH 321/659] FROMLIST: dt-bindings: clock: qcom: document the Kaanapali GPU Clock Controller Qualcomm GX(graphics) is a clock controller which has PLLs, clocks and Power domains (GDSC), but the requirement from the SW driver is to use the GDSC power domain from the clock controller to recover the GPU firmware in case of any failure/hangs. The rest of the resources of the clock controller are being used by the firmware of GPU. This module exposes the GDSC power domains which helps the recovery of Graphics subsystem. Add bindings documentation for the Kaanapali Graphics Clock and Graphics power domain Controller for Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-7-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- .../clock/qcom,kaanapali-gxclkctl.yaml | 63 +++++++++++++++++++ .../bindings/clock/qcom,sm8450-gpucc.yaml | 2 + .../dt-bindings/clock/qcom,kaanapali-gpucc.h | 47 ++++++++++++++ .../clock/qcom,kaanapali-gxclkctl.h | 13 ++++ 4 files changed, 125 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml create mode 100644 include/dt-bindings/clock/qcom,kaanapali-gpucc.h create mode 100644 include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml new file mode 100644 index 0000000000000..5490a975f3db7 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,kaanapali-gxclkctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Graphics power domain Controller on Kaanapali + +maintainers: + - Taniya Das + +description: | + Qualcomm GX(graphics) is a clock controller which has PLLs, clocks and + Power domains (GDSC). This module provides the power domains control + of gxclkctl on Qualcomm SoCs which helps the recovery of Graphics subsystem. + + See also: + include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h + +properties: + compatible: + enum: + - qcom,kaanapali-gxclkctl + + power-domains: + description: + Power domains required for the clock controller to operate + items: + - description: GFX power domain + - description: GMXC power domain + - description: GPUCC(CX) power domain + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - power-domains + - '#power-domain-cells' + +unevaluatedProperties: false + +examples: + - | + #include + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@3d64000 { + compatible = "qcom,kaanapali-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc 0>; + #power-domain-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 44380f6f81368..6feaa32569f9a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -14,6 +14,7 @@ description: | domains on Qualcomm SoCs. See also:: + include/dt-bindings/clock/qcom,kaanapali-gpucc.h include/dt-bindings/clock/qcom,milos-gpucc.h include/dt-bindings/clock/qcom,sar2130p-gpucc.h include/dt-bindings/clock/qcom,sm4450-gpucc.h @@ -26,6 +27,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-gpucc - qcom,milos-gpucc - qcom,sar2130p-gpucc - qcom,sm4450-gpucc diff --git a/include/dt-bindings/clock/qcom,kaanapali-gpucc.h b/include/dt-bindings/clock/qcom,kaanapali-gpucc.h new file mode 100644 index 0000000000000..e8dc2009c71b7 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gpucc.h @@ -0,0 +1,47 @@ +/* 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_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_KAANAPALI_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_GMU_CLK 3 +#define GPU_CC_CXO_AON_CLK 4 +#define GPU_CC_CXO_CLK 5 +#define GPU_CC_DEMET_CLK 6 +#define GPU_CC_DPM_CLK 7 +#define GPU_CC_FF_CLK_SRC 8 +#define GPU_CC_FREQ_MEASURE_CLK 9 +#define GPU_CC_GMU_CLK_SRC 10 +#define GPU_CC_GPU_SMMU_VOTE_CLK 11 +#define GPU_CC_GX_ACCU_SHIFT_CLK 12 +#define GPU_CC_GX_GMU_CLK 13 +#define GPU_CC_HUB_AON_CLK 14 +#define GPU_CC_HUB_CLK_SRC 15 +#define GPU_CC_HUB_CX_INT_CLK 16 +#define GPU_CC_HUB_DIV_CLK_SRC 17 +#define GPU_CC_MEMNOC_GFX_CLK 18 +#define GPU_CC_PLL0 19 +#define GPU_CC_PLL0_OUT_EVEN 20 +#define GPU_CC_RSCC_HUB_AON_CLK 21 +#define GPU_CC_RSCC_XO_AON_CLK 22 +#define GPU_CC_SLEEP_CLK 23 + +/* 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 diff --git a/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h b/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h new file mode 100644 index 0000000000000..f32dade67cf2f --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h @@ -0,0 +1,13 @@ +/* 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_GX_CLKCTL_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GX_CLKCTL_KAANAPALI_H + +/* GX_CLKCTL power domains */ +#define GX_CLKCTL_GX_GDSC 0 +#define GX_CLKCTL_GX_SLICE_GDSC 1 + +#endif From f9bc454e4b77ae62244d8a182cde06ea79c2299c Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:11 +0530 Subject: [PATCH 322/659] FROMLIST: clk: qcom: dispcc: Add support for display clock controller Kaanapali Support the clock controller driver for Kaanapali to enable display SW to be able to control the clocks. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-8-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/dispcc-kaanapali.c | 1956 +++++++++++++++++++++++++++ 3 files changed, 1967 insertions(+) create mode 100644 drivers/clk/qcom/dispcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index f8b42e53bb1cc..157778785acd2 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,16 @@ 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_KAANAPALI_DISPCC + tristate "Kaanapali Display Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the display clock controller on Qualcomm Technologies, Inc + Kaanapali devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config CLK_KAANAPALI_GCC tristate "Kaanapali Global Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index b13497abe9d2c..49b21aa7579ff 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_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o diff --git a/drivers/clk/qcom/dispcc-kaanapali.c b/drivers/clk/qcom/dispcc-kaanapali.c new file mode 100644 index 0000000000000..baae2ec1f72aa --- /dev/null +++ b/drivers/clk/qcom/dispcc-kaanapali.c @@ -0,0 +1,1956 @@ +// 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 "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" + +#define DISP_CC_MISC_CMD 0xF000 + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_AHB_CLK, + DT_SLEEP_CLK, + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, +}; + +enum { + P_BI_TCXO, + P_DISP_CC_PLL0_OUT_MAIN, + P_DISP_CC_PLL1_OUT_EVEN, + P_DISP_CC_PLL1_OUT_MAIN, + P_DISP_CC_PLL2_OUT_MAIN, + P_DP0_PHY_PLL_LINK_CLK, + P_DP0_PHY_PLL_VCO_DIV_CLK, + P_DP1_PHY_PLL_LINK_CLK, + P_DP1_PHY_PLL_VCO_DIV_CLK, + P_DP2_PHY_PLL_LINK_CLK, + P_DP2_PHY_PLL_VCO_DIV_CLK, + P_DP3_PHY_PLL_LINK_CLK, + P_DP3_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, +}; + +static const struct pll_vco pongo_eko_t_vco[] = { + { 38400000, 153600000, 0 }, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 257.142858 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0xd, + .cal_l = 0x48, + .alpha = 0x6492, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .config = &disp_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 = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 300.0 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll1_config = { + .l = 0xf, + .cal_l = 0x48, + .alpha = 0xa000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll1 = { + .offset = 0x1000, + .config = &disp_cc_pll1_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 = "disp_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 38.4 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll2_config = { + .l = 0x493, + .cal_l = 0x493, + .alpha = 0x0, + .config_ctl_val = 0x60000f68, + .config_ctl_hi_val = 0x0001c808, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x040082f4, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x0080c496, + .test_ctl_hi1_val = 0x40100080, + .test_ctl_hi2_val = 0x001001bc, + .test_ctl_hi3_val = 0x002003d8, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00e50302, +}; + +static struct clk_alpha_pll disp_cc_pll2 = { + .offset = 0x2000, + .config = &disp_cc_pll2_config, + .vco_table = pongo_eko_t_vco, + .num_vco = ARRAY_SIZE(pongo_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_PONGO_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_SLEEP_CLK, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_pongo_eko_t_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DISP_CC_PLL2_OUT_MAIN, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .hw = &disp_cc_pll2.clkr.hw }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL2_OUT_MAIN, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_10[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll2.clkr.hw }, +}; + +static const struct freq_tbl ftbl_disp_cc_esync0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_esync0_clk_src = { + .cmd_rcgr = 0x80d4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_esync1_clk_src = { + .cmd_rcgr = 0x80ec, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(120000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(165000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(200000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(233333333, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(261666667, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(283333333, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x8378, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_7, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x8194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x81b0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8248, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { + .cmd_rcgr = 0x81fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_8, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk_src", + .parent_data = disp_cc_parent_data_8, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = { + .cmd_rcgr = 0x8218, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = { + .cmd_rcgr = 0x8230, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = { + .cmd_rcgr = 0x82ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x8290, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel0_clk_src = { + .cmd_rcgr = 0x8260, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = { + .cmd_rcgr = 0x8278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = { + .cmd_rcgr = 0x8310, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel0_clk_src = { + .cmd_rcgr = 0x82e0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = { + .cmd_rcgr = 0x82f8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = { + .cmd_rcgr = 0x835c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x8340, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_pixel0_clk_src = { + .cmd_rcgr = 0x8328, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x81cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x81e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(156000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(207000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(337000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(417000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(532000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(650000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x8164, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_9, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_9, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x811c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x8134, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x814c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x817c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_osc_clk_src[] = { + F(38400000, P_DISP_CC_PLL2_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_osc_clk_src = { + .cmd_rcgr = 0x8104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_10, + .freq_tbl = ftbl_disp_cc_osc_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk_src", + .parent_data = disp_cc_parent_data_10, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_ahb_swi_div_clk_src = { + .reg = 0x8374, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_swi_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x81ac, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { + .reg = 0x81c8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = { + .reg = 0x8214, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx1_link_div_clk_src = { + .reg = 0x82a8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx2_link_div_clk_src = { + .reg = 0x82dc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx3_link_div_clk_src = { + .reg = 0x8358, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch disp_cc_esync0_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_esync1_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_accu_shift_clk = { + .halt_reg = 0xe060, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xe060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb1_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x80c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_swi_clk = { + .halt_reg = 0x80c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_swi_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_swi_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_intf_clk = { + .halt_reg = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_aux_clk = { + .halt_reg = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_crypto_clk = { + .halt_reg = 0x8068, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = { + .halt_reg = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = { + .halt_reg = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = { + .halt_reg = 0x8060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_aux_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_crypto_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_clk = { + .halt_reg = 0x8080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_intf_clk = { + .halt_reg = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel0_clk = { + .halt_reg = 0x8078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel1_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_usb_router_link_intf_clk = { + .halt_reg = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_aux_clk = { + .halt_reg = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_crypto_clk = { + .halt_reg = 0x80a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_clk = { + .halt_reg = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_intf_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel0_clk = { + .halt_reg = 0x8094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel1_clk = { + .halt_reg = 0x8098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_aux_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_crypto_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_clk = { + .halt_reg = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_intf_clk = { + .halt_reg = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_pixel0_clk = { + .halt_reg = 0x80ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc1_clk = { + .halt_reg = 0x8058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp1_clk = { + .halt_reg = 0xa004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x8010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { + .halt_reg = 0xa014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x8020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_ss_ip_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_ss_ip_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk1_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk2_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_osc_clk = { + .halt_reg = 0x80c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_osc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc disp_cc_mdss_core_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct gdsc disp_cc_mdss_core_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct clk_regmap *disp_cc_kaanapali_clocks[] = { + [DISP_CC_ESYNC0_CLK] = &disp_cc_esync0_clk.clkr, + [DISP_CC_ESYNC0_CLK_SRC] = &disp_cc_esync0_clk_src.clkr, + [DISP_CC_ESYNC1_CLK] = &disp_cc_esync1_clk.clkr, + [DISP_CC_ESYNC1_CLK_SRC] = &disp_cc_esync1_clk_src.clkr, + [DISP_CC_MDSS_ACCU_SHIFT_CLK] = &disp_cc_mdss_accu_shift_clk.clkr, + [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_AHB_SWI_CLK] = &disp_cc_mdss_ahb_swi_clk.clkr, + [DISP_CC_MDSS_AHB_SWI_DIV_CLK_SRC] = &disp_cc_mdss_ahb_swi_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK] = &disp_cc_mdss_dptx1_aux_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &disp_cc_mdss_dptx1_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &disp_cc_mdss_dptx1_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK] = &disp_cc_mdss_dptx1_link_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &disp_cc_mdss_dptx1_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &disp_cc_mdss_dptx1_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &disp_cc_mdss_dptx1_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &disp_cc_mdss_dptx1_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK] = &disp_cc_mdss_dptx2_aux_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &disp_cc_mdss_dptx2_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_CRYPTO_CLK] = &disp_cc_mdss_dptx2_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK] = &disp_cc_mdss_dptx2_link_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &disp_cc_mdss_dptx2_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &disp_cc_mdss_dptx2_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &disp_cc_mdss_dptx2_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &disp_cc_mdss_dptx2_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK] = &disp_cc_mdss_dptx3_aux_clk.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &disp_cc_mdss_dptx3_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_CRYPTO_CLK] = &disp_cc_mdss_dptx3_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK] = &disp_cc_mdss_dptx3_link_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &disp_cc_mdss_dptx3_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &disp_cc_mdss_dptx3_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &disp_cc_mdss_dptx3_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, + [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, + [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_MDP_SS_IP_CLK] = &disp_cc_mdss_mdp_ss_ip_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, + [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, + [DISP_CC_MDSS_PCLK2_CLK] = &disp_cc_mdss_pclk2_clk.clkr, + [DISP_CC_MDSS_PCLK2_CLK_SRC] = &disp_cc_mdss_pclk2_clk_src.clkr, + [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_OSC_CLK] = &disp_cc_osc_clk.clkr, + [DISP_CC_OSC_CLK_SRC] = &disp_cc_osc_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_PLL1] = &disp_cc_pll1.clkr, + [DISP_CC_PLL2] = &disp_cc_pll2.clkr, +}; + +static struct gdsc *disp_cc_kaanapali_gdscs[] = { + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, + [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, +}; + +static const struct qcom_reset_map disp_cc_kaanapali_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct clk_alpha_pll *disp_cc_kaanapali_plls[] = { + &disp_cc_pll0, + &disp_cc_pll1, + &disp_cc_pll2, +}; + +static u32 disp_cc_kaanapali_critical_cbcrs[] = { + 0xe064, /* DISP_CC_SLEEP_CLK */ + 0xe05c, /* DISP_CC_XO_CLK */ + 0xc00c, /* DISP_CC_MDSS_RSCC_AHB_CLK */ + 0xc008, /* DISP_CC_MDSS_RSCC_VSYNC_CLK */ +}; + +static const struct regmap_config disp_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x12094, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Enable clock gating for MDP clocks */ + regmap_update_bits(regmap, DISP_CC_MISC_CMD, BIT(4), BIT(4)); +} + +static struct qcom_cc_driver_data disp_cc_kaanapali_driver_data = { + .alpha_plls = disp_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_kaanapali_plls), + .clk_cbcrs = disp_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc disp_cc_kaanapali_desc = { + .config = &disp_cc_kaanapali_regmap_config, + .clks = disp_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(disp_cc_kaanapali_clocks), + .resets = disp_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(disp_cc_kaanapali_resets), + .gdscs = disp_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &disp_cc_kaanapali_driver_data, +}; + +static const struct of_device_id disp_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_kaanapali_match_table); + +static int disp_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_kaanapali_desc); +} + +static struct platform_driver disp_cc_kaanapali_driver = { + .probe = disp_cc_kaanapali_probe, + .driver = { + .name = "dispcc-kaanapali", + .of_match_table = disp_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(disp_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI DISPCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From f36de3fc2b8f28ef528038916c3a657f59aca448 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:12 +0530 Subject: [PATCH 323/659] FROMLIST: clk: qcom: camcc: Add support for camera clock controller for Kaanapali Add support for the Camera Clock Controller (CAMCC) on the Kaanapali platform. The CAMCC block on Kaanapali includes both the primary camera clock controller and the Camera BIST clock controller, which provides the functional MCLK required for camera operations. Signed-off-by: Jingyi Wang Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-9-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/cambistmclkcc-kaanapali.c | 437 ++++ drivers/clk/qcom/camcc-kaanapali.c | 2661 ++++++++++++++++++++ 4 files changed, 3109 insertions(+) create mode 100644 drivers/clk/qcom/cambistmclkcc-kaanapali.c create mode 100644 drivers/clk/qcom/camcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 157778785acd2..1d1d657cbae53 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,16 @@ 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_KAANAPALI_CAMCC + tristate "Kaanapali Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the camera clock controller on Qualcomm Technologies, Inc + Kaanapali devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config CLK_KAANAPALI_DISPCC tristate "Kaanapali Display Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 49b21aa7579ff..8b214cb192dae 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_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o diff --git a/drivers/clk/qcom/cambistmclkcc-kaanapali.c b/drivers/clk/qcom/cambistmclkcc-kaanapali.c new file mode 100644 index 0000000000000..066c1087b0b65 --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-kaanapali.c @@ -0,0 +1,437 @@ +// 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 "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_AHB_CLK, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, + P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco rivian_eko_t_vco[] = { + { 883200000, 1171200000, 0 }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { + .l = 0x32, + .cal_l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_eko_t_vco, + .num_vco = ARRAY_SIZE(rivian_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_eko_t_ops, + }, + }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4), + F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = { + .cmd_rcgr = 0x401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = { + .cmd_rcgr = 0x4070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = { + .cmd_rcgr = 0x408c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = { + .cmd_rcgr = 0x40a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = { + .cmd_rcgr = 0x40c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk0_clk = { + .halt_reg = 0x4018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk1_clk = { + .halt_reg = 0x4034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk2_clk = { + .halt_reg = 0x4050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk3_clk = { + .halt_reg = 0x406c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x406c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk4_clk = { + .halt_reg = 0x4088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk5_clk = { + .halt_reg = 0x40a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk6_clk = { + .halt_reg = 0x40c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk7_clk = { + .halt_reg = 0x40dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *cam_bist_mclk_cc_kaanapali_clocks[] = { + [CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr, + [CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr, +}; + +static struct clk_alpha_pll *cam_bist_mclk_cc_kaanapali_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static u32 cam_bist_mclk_cc_kaanapali_critical_cbcrs[] = { + 0x40e0, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_bist_mclk_cc_kaanapali_driver_data = { + .alpha_plls = cam_bist_mclk_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_plls), + .clk_cbcrs = cam_bist_mclk_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_bist_mclk_cc_kaanapali_desc = { + .config = &cam_bist_mclk_cc_kaanapali_regmap_config, + .clks = cam_bist_mclk_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_kaanapali_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_kaanapali_match_table); + +static int cam_bist_mclk_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_kaanapali_desc); +} + +static struct platform_driver cam_bist_mclk_cc_kaanapali_driver = { + .probe = cam_bist_mclk_cc_kaanapali_probe, + .driver = { + .name = "cambistmclkcc-kaanapali", + .of_match_table = cam_bist_mclk_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-kaanapali.c b/drivers/clk/qcom/camcc-kaanapali.c new file mode 100644 index 0000000000000..82967993fcffe --- /dev/null +++ b/drivers/clk/qcom/camcc-kaanapali.c @@ -0,0 +1,2661 @@ +// 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 "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_AHB_CLK, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + 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_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL6_OUT_ODD, + P_CAM_CC_PLL7_OUT_EVEN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .cal_l = 0x48, + .alpha = 0x8000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_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 = "cam_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_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_TAYCAN_EKO_T], + .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_taycan_eko_t_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_TAYCAN_EKO_T], + .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_taycan_eko_t_ops, + }, +}; + +/* 665.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x22, + .cal_l = 0x48, + .alpha = 0xa2aa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_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 = "cam_cc_pll1", + .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_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_TAYCAN_EKO_T], + .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_taycan_eko_t_ops, + }, +}; + +/* 677.6 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x23, + .cal_l = 0x48, + .alpha = 0x4aaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_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 = "cam_cc_pll2", + .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_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_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 = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_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 = "cam_cc_pll3", + .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_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_TAYCAN_EKO_T], + .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_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_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 = "cam_cc_pll4", + .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_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_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 = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_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 = "cam_cc_pll5", + .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_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_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 = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_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 = "cam_cc_pll6", + .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_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_TAYCAN_EKO_T], + .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_taycan_eko_t_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_odd = { + .offset = 0x6000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll6_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 1000.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll7_config = { + .l = 0x34, + .cal_l = 0x48, + .alpha = 0x1555, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll7 = { + .offset = 0x7000, + .config = &cam_cc_pll7_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 = "cam_cc_pll7", + .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_cam_cc_pll7_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll7_out_even = { + .offset = 0x7000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll7_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll7_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 = "cam_cc_pll7_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll7.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_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_ODD, 4 }, + { 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_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_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .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_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { 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_PLL7_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .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_pll7_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_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_rt_axi_clk_src = { + .cmd_rcgr = 0x212cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_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_cci_0_clk_src[] = { + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x21250, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_cci_1_clk_src = { + .cmd_rcgr = 0x2126c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_cci_2_clk_src = { + .cmd_rcgr = 0x21288, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_2_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_cphy_rx_clk_src[] = { + F(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 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 = 0x21064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .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_cre_clk_src[] = { + F(137142857, P_CAM_CC_PLL6_OUT_EVEN, 3.5, 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_cre_clk_src = { + .cmd_rcgr = 0x211a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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_csi0phytimer_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x20000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .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 = 0x20024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .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 = 0x20044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .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 = 0x20064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .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 = 0x20084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .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 = 0x200a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .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 struct clk_rcg2 cam_cc_csid_clk_src = { + .cmd_rcgr = 0x212a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .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(213333333, P_CAM_CC_PLL6_OUT_ODD, 1.5, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 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 = 0x200dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_fast_ahb_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_icp_0_clk_src[] = { + F(500000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(740000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(875000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(1000000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x211f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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 struct clk_rcg2 cam_cc_icp_1_clk_src = { + .cmd_rcgr = 0x21220, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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 struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x21144, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .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 = 0x21170, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .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(332500000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x20188, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .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 struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x211c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_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_ofe_clk_src[] = { + F(338800000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(484000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(586000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(688000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(841000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ofe_clk_src = { + .cmd_rcgr = 0x2011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_qdss_debug_clk_src[] = { + F(40000000, P_CAM_CC_PLL6_OUT_ODD, 8, 0, 0), + F(60000000, P_CAM_CC_PLL6_OUT_EVEN, 8, 0, 0), + F(120000000, P_CAM_CC_PLL0_OUT_EVEN, 5, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x21314, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_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_slow_ahb_clk_src[] = { + F(56470588, P_CAM_CC_PLL6_OUT_EVEN, 8.5, 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 = 0x20100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_slow_ahb_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_tfe_0_clk_src[] = { + F(360280000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_0_clk_src = { + .cmd_rcgr = 0x21018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_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 const struct freq_tbl ftbl_cam_cc_tfe_1_clk_src[] = { + F(360280000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_1_clk_src = { + .cmd_rcgr = 0x21094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_2_clk_src[] = { + F(360280000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_2_clk_src = { + .cmd_rcgr = 0x210f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .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 = 0x2134c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_8, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x2137c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2137c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_cam_top_fast_ahb_clk = { + .halt_reg = 0x2136c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2136c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_nrt_axi_clk = { + .halt_reg = 0x212f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_cre_clk = { + .halt_reg = 0x211bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ipe_nps_clk = { + .halt_reg = 0x201b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_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_camnoc_nrt_ofe_main_clk = { + .halt_reg = 0x20144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x212e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_ife_lite_clk = { + .halt_reg = 0x2116c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2116c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_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_camnoc_rt_tfe_0_main_clk = { + .halt_reg = 0x21040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_main_clk = { + .halt_reg = 0x210bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_main_clk = { + .halt_reg = 0x21120, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_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 = 0x2130c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2130c, + .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 = 0x21268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21268, + .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 = 0x21284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21284, + .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_cci_2_clk = { + .halt_reg = 0x212a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_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 = 0x21348, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x21348, + .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_cre_ahb_clk = { + .halt_reg = 0x211c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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_cre_clk = { + .halt_reg = 0x211b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_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 = 0x20018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20018, + .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 = 0x2003c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2003c, + .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 = 0x2005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2005c, + .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 = 0x2007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2007c, + .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 = 0x2009c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2009c, + .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 = 0x200bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200bc, + .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 = 0x212bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212bc, + .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 = 0x20020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20020, + .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 = 0x2001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2001c, + .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 = 0x20040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20040, + .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 = 0x20060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20060, + .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 = 0x20080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20080, + .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 = 0x200a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200a0, + .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 = 0x200c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200c0, + .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_0_ahb_clk = { + .halt_reg = 0x21248, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21248, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_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_0_clk = { + .halt_reg = 0x21210, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21210, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x2124c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2124c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_1_clk = { + .halt_reg = 0x21238, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21238, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_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 = 0x2119c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2119c, + .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 = 0x2115c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2115c, + .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 = 0x21198, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21198, + .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 = 0x21188, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21188, + .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 = 0x201cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201cc, + .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 = 0x201a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201a0, + .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 = 0x201d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d0, + .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 = 0x201b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b4, + .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 = 0x201d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d4, + .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 = 0x211dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211dc, + .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_ofe_ahb_clk = { + .halt_reg = 0x20118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_ofe_anchor_clk = { + .halt_reg = 0x20148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_fast_ahb_clk = { + .halt_reg = 0x200f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_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_ofe_hdr_clk = { + .halt_reg = 0x20158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20158, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_fast_ahb_clk = { + .halt_reg = 0x200fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_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_ofe_main_clk = { + .halt_reg = 0x20134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_fast_ahb_clk = { + .halt_reg = 0x200f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_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_qdss_debug_clk = { + .halt_reg = 0x2132c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2132c, + .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 = 0x21330, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21330, + .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_tfe_0_bayer_clk = { + .halt_reg = 0x21044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_fast_ahb_clk = { + .halt_reg = 0x21060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_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_tfe_0_main_clk = { + .halt_reg = 0x21030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_fast_ahb_clk = { + .halt_reg = 0x2105c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2105c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_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_tfe_1_bayer_clk = { + .halt_reg = 0x210c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_fast_ahb_clk = { + .halt_reg = 0x210dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_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_tfe_1_main_clk = { + .halt_reg = 0x210ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_fast_ahb_clk = { + .halt_reg = 0x210d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_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_tfe_2_bayer_clk = { + .halt_reg = 0x21124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21124, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_fast_ahb_clk = { + .halt_reg = 0x21140, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21140, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_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_tfe_2_main_clk = { + .halt_reg = 0x21110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21110, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_fast_ahb_clk = { + .halt_reg = 0x2113c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2113c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_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_tracenoc_tpdm_1_cmb_clk = { + .halt_reg = 0x21394, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21394, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tracenoc_tpdm_1_cmb_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 = 0x21334, + .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_ipe_0_gdsc = { + .gdscr = 0x20174, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct gdsc cam_cc_ofe_gdsc = { + .gdscr = 0x200c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ofe_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_0_gdsc = { + .gdscr = 0x21004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_1_gdsc = { + .gdscr = 0x21080, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_2_gdsc = { + .gdscr = 0x210e4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct clk_regmap *cam_cc_kaanapali_clocks[] = { + [CAM_CC_CAM_TOP_AHB_CLK] = &cam_cc_cam_top_ahb_clk.clkr, + [CAM_CC_CAM_TOP_FAST_AHB_CLK] = &cam_cc_cam_top_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_NRT_CRE_CLK] = &cam_cc_camnoc_nrt_cre_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_NPS_CLK] = &cam_cc_camnoc_nrt_ipe_nps_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK] = &cam_cc_camnoc_nrt_ofe_main_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.clkr, + [CAM_CC_CAMNOC_RT_IFE_LITE_CLK] = &cam_cc_camnoc_rt_ife_lite_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_0_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_1_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_2_main_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_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_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_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.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_OFE_AHB_CLK] = &cam_cc_ofe_ahb_clk.clkr, + [CAM_CC_OFE_ANCHOR_CLK] = &cam_cc_ofe_anchor_clk.clkr, + [CAM_CC_OFE_ANCHOR_FAST_AHB_CLK] = &cam_cc_ofe_anchor_fast_ahb_clk.clkr, + [CAM_CC_OFE_CLK_SRC] = &cam_cc_ofe_clk_src.clkr, + [CAM_CC_OFE_HDR_CLK] = &cam_cc_ofe_hdr_clk.clkr, + [CAM_CC_OFE_HDR_FAST_AHB_CLK] = &cam_cc_ofe_hdr_fast_ahb_clk.clkr, + [CAM_CC_OFE_MAIN_CLK] = &cam_cc_ofe_main_clk.clkr, + [CAM_CC_OFE_MAIN_FAST_AHB_CLK] = &cam_cc_ofe_main_fast_ahb_clk.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_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_PLL5] = &cam_cc_pll5.clkr, + [CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr, + [CAM_CC_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL6_OUT_ODD] = &cam_cc_pll6_out_odd.clkr, + [CAM_CC_PLL7] = &cam_cc_pll7.clkr, + [CAM_CC_PLL7_OUT_EVEN] = &cam_cc_pll7_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_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_TFE_0_BAYER_CLK] = &cam_cc_tfe_0_bayer_clk.clkr, + [CAM_CC_TFE_0_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_0_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_CLK_SRC] = &cam_cc_tfe_0_clk_src.clkr, + [CAM_CC_TFE_0_MAIN_CLK] = &cam_cc_tfe_0_main_clk.clkr, + [CAM_CC_TFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_0_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_BAYER_CLK] = &cam_cc_tfe_1_bayer_clk.clkr, + [CAM_CC_TFE_1_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_1_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_CLK_SRC] = &cam_cc_tfe_1_clk_src.clkr, + [CAM_CC_TFE_1_MAIN_CLK] = &cam_cc_tfe_1_main_clk.clkr, + [CAM_CC_TFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_1_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_BAYER_CLK] = &cam_cc_tfe_2_bayer_clk.clkr, + [CAM_CC_TFE_2_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_2_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_CLK_SRC] = &cam_cc_tfe_2_clk_src.clkr, + [CAM_CC_TFE_2_MAIN_CLK] = &cam_cc_tfe_2_main_clk.clkr, + [CAM_CC_TFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_2_main_fast_ahb_clk.clkr, + [CAM_CC_TRACENOC_TPDM_1_CMB_CLK] = &cam_cc_tracenoc_tpdm_1_cmb_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_kaanapali_gdscs[] = { + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_OFE_GDSC] = &cam_cc_ofe_gdsc, + [CAM_CC_TFE_0_GDSC] = &cam_cc_tfe_0_gdsc, + [CAM_CC_TFE_1_GDSC] = &cam_cc_tfe_1_gdsc, + [CAM_CC_TFE_2_GDSC] = &cam_cc_tfe_2_gdsc, + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_kaanapali_resets[] = { + [CAM_CC_DRV_BCR] = { 0x2138c }, + [CAM_CC_ICP_BCR] = { 0x211f4 }, + [CAM_CC_IPE_0_BCR] = { 0x20170 }, + [CAM_CC_OFE_BCR] = { 0x200c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x21310 }, + [CAM_CC_TFE_0_BCR] = { 0x21000 }, + [CAM_CC_TFE_1_BCR] = { 0x2107c }, + [CAM_CC_TFE_2_BCR] = { 0x210e0 }, +}; + +static struct clk_alpha_pll *cam_cc_kaanapali_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, + &cam_cc_pll7, +}; + +static u32 cam_cc_kaanapali_critical_cbcrs[] = { + 0x21398, /* CAM_CC_DRV_AHB_CLK */ + 0x21390, /* CAM_CC_DRV_XO_CLK */ + 0x21364, /* CAM_CC_GDSC_CLK */ + 0x21368, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x2601c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_kaanapali_driver_data = { + .alpha_plls = cam_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_kaanapali_plls), + .clk_cbcrs = cam_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_kaanapali_desc = { + .config = &cam_cc_kaanapali_regmap_config, + .clks = cam_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(cam_cc_kaanapali_clocks), + .resets = cam_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(cam_cc_kaanapali_resets), + .gdscs = cam_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_kaanapali_driver_data, +}; + +static const struct of_device_id cam_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_kaanapali_match_table); + +static int cam_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_kaanapali_desc); +} + +static struct platform_driver cam_cc_kaanapali_driver = { + .probe = cam_cc_kaanapali_probe, + .driver = { + .name = "camcc-kaanapali", + .of_match_table = cam_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(cam_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI CAMCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From d8977ef377b4f2d3cfefcf30c85337e7c8b32575 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:13 +0530 Subject: [PATCH 324/659] FROMLIST: clk: qcom: Add support for VideoCC driver for Kaanapali Enable Kaanapali video clock driver for video SW to be able to control the clocks from the Video SW driver. Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-10-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-kaanapali.c | 821 +++++++++++++++++++++++++++ 3 files changed, 831 insertions(+) create mode 100644 drivers/clk/qcom/videocc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 1d1d657cbae53..8a81111ba1f3e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -83,6 +83,15 @@ config CLK_KAANAPALI_TCSRCC Support for the TCSR clock controller on Kaanapali devices. Say Y if you want to use peripheral devices such as PCIe, USB, UFS. +config CLK_KAANAPALI_VIDEOCC + tristate "Kaanapali Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the video clock controller on Kaanapali devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 8b214cb192dae..1a2e1c61f258b 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -28,6 +28,7 @@ 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 obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/videocc-kaanapali.c b/drivers/clk/qcom/videocc-kaanapali.c new file mode 100644 index 0000000000000..835a59536ba79 --- /dev/null +++ b/drivers/clk/qcom/videocc-kaanapali.c @@ -0,0 +1,821 @@ +// 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" + +#define ACCU_CFG_MASK GENMASK(25, 21) + +enum { + DT_BI_TCXO, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_VIDEO_CC_PLL0_OUT_MAIN, + P_VIDEO_CC_PLL1_OUT_MAIN, + P_VIDEO_CC_PLL2_OUT_MAIN, + P_VIDEO_CC_PLL3_OUT_MAIN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 360.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x12, + .cal_l = 0x48, + .alpha = 0xc000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .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, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll1_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll1 = { + .offset = 0x1000, + .config = &video_cc_pll1_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_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll2_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll2 = { + .offset = 0x2000, + .config = &video_cc_pll2_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_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll3_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll3 = { + .offset = 0x3000, + .config = &video_cc_pll3_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_pll3", + .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_PLL1_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll1.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL3_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll3.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL2_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll2.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +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 = 0x8060, + .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(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8030, + .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_mvs0a_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0a_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_mvs0a_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_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_mvs0b_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(850000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0b_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_3, + .freq_tbl = ftbl_video_cc_mvs0b_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk_src", + .parent_data = video_cc_parent_data_3, + .num_parents = ARRAY_SIZE(video_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = { + F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0c_clk_src = { + .cmd_rcgr = 0x8048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_4, + .freq_tbl = ftbl_video_cc_mvs0c_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk_src", + .parent_data = video_cc_parent_data_4, + .num_parents = ARRAY_SIZE(video_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x8194, + .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_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d0, + .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_mem_branch video_cc_mvs0_freerun_clk = { + .mem_enable_reg = 0x80e4, + .mem_ack_reg = 0x80e4, + .mem_enable_mask = BIT(3), + .mem_enable_ack_mask = GENMASK(11, 10), + .mem_enable_invert = true, + .branch = { + .halt_reg = 0x80e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80e0, + .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_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 = 0x81b4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b4, + .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_mvs0_vpp0_clk = { + .halt_reg = 0x8134, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8134, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_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_vpp0_freerun_clk = { + .halt_reg = 0x8144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_freerun_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_vpp1_clk = { + .halt_reg = 0x8108, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8108, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_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_vpp1_freerun_clk = { + .halt_reg = 0x8118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_freerun_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_mvs0a_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0a_freerun_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_freerun_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_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 = 0x8164, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8164, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8164, + .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_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 = 0x8174, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8174, + .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_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 = 0x81b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b8, + .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 gdsc video_cc_mvs0_vpp0_gdsc = { + .gdscr = 0x8120, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_vpp1_gdsc = { + .gdscr = 0x80f4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0a_gdsc = { + .gdscr = 0x807c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0a_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x814c, + .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 = 0x80a8, + .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 clk_regmap *video_cc_kaanapali_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_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr, + [VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr, + [VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr, + [VIDEO_CC_MVS0_VPP1_FREERUN_CLK] = &video_cc_mvs0_vpp1_freerun_clk.clkr, + [VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr, + [VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr, + [VIDEO_CC_MVS0A_FREERUN_CLK] = &video_cc_mvs0a_freerun_clk.clkr, + [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr, + [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr, + [VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_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_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_PLL2] = &video_cc_pll2.clkr, + [VIDEO_CC_PLL3] = &video_cc_pll3.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_kaanapali_gdscs[] = { + [VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc, + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc, + [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_kaanapali_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x8178 }, + [VIDEO_CC_MVS0_BCR] = { 0x80a4 }, + [VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c }, + [VIDEO_CC_MVS0_VPP1_BCR] = { 0x80f0 }, + [VIDEO_CC_MVS0A_BCR] = { 0x8078 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8148 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 }, +}; + +static struct clk_alpha_pll *video_cc_kaanapali_plls[] = { + &video_cc_pll0, + &video_cc_pll1, + &video_cc_pll2, + &video_cc_pll3, +}; + +static u32 video_cc_kaanapali_critical_cbcrs[] = { + 0x817c, /* VIDEO_CC_AHB_CLK */ + 0x81bc, /* VIDEO_CC_SLEEP_CLK */ + 0x81b0, /* VIDEO_CC_TS_XO_CLK */ + 0x81ac, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xa010, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* + * Enable clk_on sync for MVS0 and VPP clocks via VIDEO_CC_SPARE1 + * during core reset by default. + */ + regmap_set_bits(regmap, 0x9f24, BIT(0)); + + /* + * As per HW design recommendation + * Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for the below GDSCs + * MVS0A CFG3, MVS0 CFG3, MVS0 VPP1 CFG3, MVS0 VPP0 CFG3, MVS0C CFG3 + */ + regmap_set_bits(regmap, 0x8088, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8100, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK); +} + +static struct qcom_cc_driver_data video_cc_kaanapali_driver_data = { + .alpha_plls = video_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_kaanapali_plls), + .clk_cbcrs = video_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc video_cc_kaanapali_desc = { + .config = &video_cc_kaanapali_regmap_config, + .clks = video_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(video_cc_kaanapali_clocks), + .resets = video_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(video_cc_kaanapali_resets), + .gdscs = video_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &video_cc_kaanapali_driver_data, +}; + +static const struct of_device_id video_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_kaanapali_match_table); + +static int video_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_kaanapali_desc); +} + +static struct platform_driver video_cc_kaanapali_driver = { + .probe = video_cc_kaanapali_probe, + .driver = { + .name = "videocc-kaanapali", + .of_match_table = video_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(video_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From c0a33606267c768ff7c1e2a23751f1e13346c273 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:14 +0530 Subject: [PATCH 325/659] FROMLIST: clk: qcom: Add support for GPUCC and GXCLK for Kaanapali Support the graphics clock controller for Kaanapali 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. Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-11-8e10adc236a8@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-kaanapali.c | 482 ++++++++++++++++++++++++++ drivers/clk/qcom/gxclkctl-kaanapali.c | 76 ++++ 4 files changed, 568 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-kaanapali.c create mode 100644 drivers/clk/qcom/gxclkctl-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 8a81111ba1f3e..7e8e88dd0b4f3 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -75,6 +75,15 @@ config CLK_KAANAPALI_GCC Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. +config CLK_KAANAPALI_GPUCC + tristate "Kaanapali Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the graphics clock controller on Kaanapali devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_KAANAPALI_TCSRCC tristate "Kaanapali TCSR Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1a2e1c61f258b..6b0ad8832b55f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-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 +obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o diff --git a/drivers/clk/qcom/gpucc-kaanapali.c b/drivers/clk/qcom/gpucc-kaanapali.c new file mode 100644 index 0000000000000..52be48c15c672 --- /dev/null +++ b/drivers/clk/qcom/gpucc-kaanapali.c @@ -0,0 +1,482 @@ +// 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_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 }, +}; + +/* 950.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x31, + .cal_l = 0x48, + .alpha = 0x7aaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .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_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_0[] = { + { .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_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(475000000, P_GPU_CC_PLL0_OUT_EVEN, 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_0, + .hw_clk_ctrl = true, + .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_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_hub_clk_src[] = { + F(150000000, P_GPLL0_OUT_MAIN_DIV, 2, 0, 0), + 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_0, + .hw_clk_ctrl = true, + .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_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .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 = 0x9104, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9104, + .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_aon_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 = 0x9108, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9108, + .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_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_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 = 0x90ec, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90ec, + .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 = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_kaanapali_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_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_GMU_CLK] = &gpu_cc_gx_gmu_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_kaanapali_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_kaanapali_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_kaanapali_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_kaanapali_critical_cbcrs[] = { + 0x9008, /* GPU_CC_CXO_AON_CLK */ + 0x93e8, /* GPU_CC_RSCC_HUB_AON_CLK */ + 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ +}; + +static const struct regmap_config gpu_cc_kaanapali_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_kaanapali_driver_data = { + .alpha_plls = gpu_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_kaanapali_plls), + .clk_cbcrs = gpu_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_kaanapali_desc = { + .config = &gpu_cc_kaanapali_regmap_config, + .clks = gpu_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_kaanapali_clocks), + .resets = gpu_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(gpu_cc_kaanapali_resets), + .gdscs = gpu_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_kaanapali_driver_data, +}; + +static const struct of_device_id gpu_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_kaanapali_match_table); + +static int gpu_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_kaanapali_desc); +} + +static struct platform_driver gpu_cc_kaanapali_driver = { + .probe = gpu_cc_kaanapali_probe, + .driver = { + .name = "gpucc-kaanapali", + .of_match_table = gpu_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(gpu_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI GPUCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c new file mode 100644 index 0000000000000..c209ce5fe4f00 --- /dev/null +++ b/drivers/clk/qcom/gxclkctl-kaanapali.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, +}; + +static struct gdsc gx_clkctl_gx_gdsc = { + .gdscr = 0x4024, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gx_clkctl_gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc *gx_clkctl_gdscs[] = { + [GX_CLKCTL_GX_GDSC] = &gx_clkctl_gx_gdsc, +}; + +static const struct regmap_config gx_clkctl_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x4038, + .fast_io = true, +}; + +static const struct qcom_cc_desc gx_clkctl_kaanapali_desc = { + .config = &gx_clkctl_regmap_config, + .gdscs = gx_clkctl_gdscs, + .num_gdscs = ARRAY_SIZE(gx_clkctl_gdscs), + .use_rpm = true, +}; + +static const struct of_device_id gx_clkctl_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gxclkctl" }, + { } +}; +MODULE_DEVICE_TABLE(of, gx_clkctl_kaanapali_match_table); + +static int gx_clkctl_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gx_clkctl_kaanapali_desc); +} + +static struct platform_driver gx_clkctl_kaanapali_driver = { + .probe = gx_clkctl_kaanapali_probe, + .driver = { + .name = "gxclkctl-kaanapali", + .of_match_table = gx_clkctl_kaanapali_match_table, + }, +}; + +module_platform_driver(gx_clkctl_kaanapali_driver); + +MODULE_DESCRIPTION("QTI GXCLKCTL Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 777f5ec04572db7fab0b90f25128918fcb650313 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 24 Jan 2026 23:05:02 +0530 Subject: [PATCH 326/659] 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 dbb83bbb115ac39b5145b6fed5495c5b8d0321c5 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 24 Jan 2026 23:05:03 +0530 Subject: [PATCH 327/659] 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 7e8e88dd0b4f3..f8d2e1d5a27cd 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 deab819576d0e..66797eb2028dd 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 b7cb13d324453edc22a0283efb4ae807158386dc Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 30 Jan 2026 15:15:31 +0530 Subject: [PATCH 328/659] 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 d6d8c53bebe0f77a3f3c97f8711210db8d4002cb Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 30 Jan 2026 15:17:24 +0530 Subject: [PATCH 329/659] 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 f8d2e1d5a27cd..a893bff835925 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 249ee36eef0fb1f19bd397667e12bdfa0337b13f Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:32 +0530 Subject: [PATCH 330/659] 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 269d1ec573cbc72fec3aea411225623b3ab30915 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:33 +0530 Subject: [PATCH 331/659] 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 9dd21a44403d400c49f96520929dd6198bfff7d9 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:34 +0530 Subject: [PATCH 332/659] 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 a893bff835925..9f0062e42f165 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 e29690fc804820dc921b3ba72b6bf34cc9c88315 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:35 +0530 Subject: [PATCH 333/659] 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 c3fba17fbcfeba29c89adfb1784acf2b8e981a1f Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:36 +0530 Subject: [PATCH 334/659] 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 9f0062e42f165..6bd7edd1c1b53 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 5c3a5e0b6578b07c36f2171e01e53ea553de0c95 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 3 Jan 2026 11:27:05 +0530 Subject: [PATCH 335/659] FROMLIST: dt-bindings: clock: qcom,x1e80100-gcc: Add missing UFS mux clocks Add some of the UFS symbol rx/tx muxes were not initially described. Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20260103-ufs_symbol_clk-v2-1-51828cc76236@oss.qualcomm.com Signed-off-by: Taniya Das --- .../devicetree/bindings/clock/qcom,x1e80100-gcc.yaml | 8 +++++++- include/dt-bindings/clock/qcom,x1e80100-gcc.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml index 1b15b50709545..881a5dd8d06f9 100644 --- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml @@ -62,6 +62,9 @@ properties: - description: USB4_1 PHY max PIPE clock source - description: USB4_2 PHY PCIE PIPE clock source - description: USB4_2 PHY max PIPE clock source + - description: UFS PHY RX Symbol 0 clock source + - description: UFS PHY RX Symbol 1 clock source + - description: UFS PHY TX Symbol 0 clock source power-domains: description: @@ -121,7 +124,10 @@ examples: <&usb4_1_phy_pcie_pipe_clk>, <&usb4_1_phy_max_pipe_clk>, <&usb4_2_phy_pcie_pipe_clk>, - <&usb4_2_phy_max_pipe_clk>; + <&usb4_2_phy_max_pipe_clk>, + <&ufs_phy_rx_symbol_0>, + <&ufs_phy_rx_symbol_1>, + <&ufs_phy_tx_symbol_0>; power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/include/dt-bindings/clock/qcom,x1e80100-gcc.h b/include/dt-bindings/clock/qcom,x1e80100-gcc.h index 62aa124255927..d905804e64654 100644 --- a/include/dt-bindings/clock/qcom,x1e80100-gcc.h +++ b/include/dt-bindings/clock/qcom,x1e80100-gcc.h @@ -387,6 +387,9 @@ #define GCC_USB4_2_PHY_RX0_CLK_SRC 377 #define GCC_USB4_2_PHY_RX1_CLK_SRC 378 #define GCC_USB4_2_PHY_SYS_CLK_SRC 379 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC 380 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC 381 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC 382 /* GCC power domains */ #define GCC_PCIE_0_TUNNEL_GDSC 0 From 4a0d4ec7f50e2e2609856e3b72af981e45419792 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 3 Jan 2026 11:27:06 +0530 Subject: [PATCH 336/659] FROMLIST: clk: qcom: gcc-x1e80100: Add missing UFS symbol mux clocks The UFS symbol RX/TX mux clocks were not defined previously. Add these mux clocks so that clock rate propagation reaches the muxes correctly. Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") Reviewed-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260103-ufs_symbol_clk-v2-2-51828cc76236@oss.qualcomm.com Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-x1e80100.c | 72 +++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index b63c8abdd2fc2..ae9621aff8583 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -59,6 +59,9 @@ enum { DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, }; enum { @@ -103,6 +106,9 @@ enum { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, }; static struct clk_alpha_pll gcc_gpll0 = { @@ -482,6 +488,48 @@ static const struct clk_parent_data gcc_parent_data_33[] = { { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, }; +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77064, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_RX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770e0, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_RX_SYMBOL_1_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77054, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { .reg = 0x9f06c, .clkr = { @@ -5148,12 +5196,17 @@ static struct clk_branch gcc_ufs_phy_phy_aux_clk = { static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { .halt_reg = 0x7702c, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x7702c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5161,12 +5214,17 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { .halt_reg = 0x770cc, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x770cc, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5174,12 +5232,17 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { .halt_reg = 0x77028, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x77028, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -7180,6 +7243,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_2_TMU_CLK_SRC] = &gcc_usb4_2_tmu_clk_src.clkr, [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, }; static struct gdsc *gcc_x1e80100_gdscs[] = { From 58b254feb974382b36610c398edf91a072359ef2 Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Wed, 12 Nov 2025 20:18:12 +0530 Subject: [PATCH 337/659] 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 ee663e3b37f0b..a8c8e18ae599f 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -970,6 +970,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 22682792f03295accd4c867fcbc3c0e68d930663 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Fri, 17 Oct 2025 11:25:35 +0530 Subject: [PATCH 338/659] 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 8cabaa6c86085e742946d7c4f9efe9e2925516d8 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Fri, 10 Oct 2025 16:51:48 +0530 Subject: [PATCH 339/659] 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 | 25 + .../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, 3976 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 6f34d5ed331c4..71e7986ccca3a 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -37,6 +37,11 @@ lemans-evk-camera-dtbs := lemans-evk.dtb lemans-evk-camera.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera.dtb + +lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb + dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb @@ -141,7 +146,17 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb + +qcs9100-ride-camx-dtbs:= qcs9100-ride.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-camx.dtb + dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb + +qcs9100-ride-r3-camx-dtbs:= qcs9100-ride-r3.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3-camx.dtb + dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb @@ -155,7 +170,17 @@ dtb-$(CONFIG_ARCH_QCOM) += sa8155p-adp.dtb dtb-$(CONFIG_ARCH_QCOM) += sa8295p-adp.dtb dtb-$(CONFIG_ARCH_QCOM) += sa8540p-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride.dtb + +sa8775p-ride-camx-dtbs:= sa8775p-ride.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-camx.dtb + dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3.dtb + +sa8775p-ride-r3-camx-dtbs:= sa8775p-ride-r3.dtb sa8775p-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3-camx.dtb + sc7180-acer-aspire1-el2-dtbs := sc7180-acer-aspire1.dtb sc7180-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += sc7180-acer-aspire1.dtb sc7180-acer-aspire1-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-idp.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 217dde291a6a6143539dee6cdf2f1579d72ab647 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Fri, 17 Oct 2025 11:25:35 +0530 Subject: [PATCH 340/659] 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 | 6 + 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, 3052 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 71e7986ccca3a..4c3ab61e87647 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -143,6 +143,12 @@ qcs6490-rb3gen2-industrial-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2 dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.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 + dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.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 16fa6c001d7c427de24634464e15396f857303dd Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Sun, 19 Oct 2025 11:20:50 +0530 Subject: [PATCH 341/659] 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 | 10 + .../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, 3812 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 4c3ab61e87647..0ec2cd8fa3b1c 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -43,6 +43,11 @@ lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb + +monaco-evk-camx-dtbs := monaco-evk.dtb monaco-evk-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camx.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 @@ -150,6 +155,11 @@ qcs6490-rb3gen2-vision-mezzanine-camx-dtbs := qcs6490-rb3gen2-vision-mezzanine.d dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine-camx.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb + +qcs8300-ride-camx-dtbs:= qcs8300-ride.dtb qcs8300-ride-camx.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride-camx.dtb + dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.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 ab52136332bbdb99000e28352f67cf453faf5a4f Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Thu, 30 Oct 2025 00:58:58 +0530 Subject: [PATCH 342/659] 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 816fa2af8a9a6..29326f95c99d7 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -768,7 +768,7 @@ }; camera_mem: camera-region@95200000 { - reg = <0x0 0x95200000 0x0 0x500000>; + reg = <0x0 0x95200000 0x0 0x700000>; no-map; }; From e923cabfa549f822f4a6c98c4a350cd7cfea351a Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 27 Oct 2025 23:48:22 +0530 Subject: [PATCH 343/659] 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 7e1a94e9ae4093521df613197516beb178924dc6 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 27 Oct 2025 23:42:23 +0530 Subject: [PATCH 344/659] 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 ee8d042367b7e2329fe4e63ae2f3a8d8b0e28fbf Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 27 Oct 2025 23:36:51 +0530 Subject: [PATCH 345/659] 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 b0180e38339f4a2166e970685e2b7cfa4a09995c Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Wed, 24 Dec 2025 14:00:56 +0800 Subject: [PATCH 346/659] 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 95d26e3136229..3559500b84625 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -647,6 +647,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 7232c62293e519bdb0b27641636d16766131e32a Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 24 Dec 2025 16:16:57 +0530 Subject: [PATCH 347/659] 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 0ec2cd8fa3b1c..cfd7a0e6217ec 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -140,6 +140,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-camx-dtbs := qcs615-ride.dtb qcs615-ride-camx.dtbo +dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride-camx.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/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 29aad9556145cac69d5651528c558f86f46f6729 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:23:37 +0530 Subject: [PATCH 348/659] 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 41265db44f3e2a092cf1a212627de49796d2e6d1 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:33:18 +0530 Subject: [PATCH 349/659] 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 73252e4e73ce7e01c7f48a03ec58d6133cfa771e Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:32:20 +0530 Subject: [PATCH 350/659] 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 1f68ee16f4b78fef4ae06fc3652e5eaac289b0b7 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Wed, 7 Jan 2026 19:30:22 +0530 Subject: [PATCH 351/659] 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 e8349f97b56e436eb4c7e8d4bc59f120d435d3a3 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Fri, 9 Jan 2026 00:54:23 +0530 Subject: [PATCH 352/659] 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 353/659] 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 b85467e8227775774b42430aa9b057f7c0d6406c Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Mon, 2 Feb 2026 17:03:05 +0800 Subject: [PATCH 354/659] 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 f9eeec0aed57d..71164960ede79 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3356,7 +3356,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 dae2a32733a23ac7ed5dd79418ff8b49781b7b8a Mon Sep 17 00:00:00 2001 From: Nihal Kumar Gupta Date: Thu, 29 Jan 2026 18:26:31 +0530 Subject: [PATCH 355/659] 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 f48e382094b1154435475fa847aff6829912fbda Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Mon, 2 Feb 2026 15:44:15 +0530 Subject: [PATCH 356/659] QCLINUX: arm64: dts: qcom: Move camx overlay Move all camx overlay to end of file to avoid conflicts. Signed-off-by: Vikram Sharma --- arch/arm64/boot/dts/qcom/Makefile | 75 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index cfd7a0e6217ec..e88e7c7693395 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -38,16 +38,8 @@ lemans-evk-camera-dtbs := lemans-evk.dtb lemans-evk-camera.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera.dtb -lemans-evk-camx-dtbs := lemans-evk.dtb lemans-evk-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camx.dtb - dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb -monaco-evk-camx-dtbs := monaco-evk.dtb monaco-evk-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-camx.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 @@ -141,9 +133,6 @@ 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-camx-dtbs := qcs615-ride.dtb qcs615-ride-camx.dtbo -dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride-camx.dtb - dtb-$(CONFIG_ARCH_QCOM) += qcs6490-radxa-dragon-q6a.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2.dtb @@ -153,30 +142,10 @@ qcs6490-rb3gen2-industrial-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2 dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.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 - dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb - -qcs8300-ride-camx-dtbs:= qcs8300-ride.dtb qcs8300-ride-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride-camx.dtb - dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb - -qcs9100-ride-camx-dtbs:= qcs9100-ride.dtb sa8775p-ride-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-camx.dtb - dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb - -qcs9100-ride-r3-camx-dtbs:= qcs9100-ride-r3.dtb sa8775p-ride-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3-camx.dtb - dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb @@ -191,16 +160,8 @@ dtb-$(CONFIG_ARCH_QCOM) += sa8295p-adp.dtb dtb-$(CONFIG_ARCH_QCOM) += sa8540p-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride.dtb -sa8775p-ride-camx-dtbs:= sa8775p-ride.dtb sa8775p-ride-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-camx.dtb - dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3.dtb -sa8775p-ride-r3-camx-dtbs:= sa8775p-ride-r3.dtb sa8775p-ride-camx.dtbo - -dtb-$(CONFIG_ARCH_QCOM) += sa8775p-ride-r3-camx.dtb - sc7180-acer-aspire1-el2-dtbs := sc7180-acer-aspire1.dtb sc7180-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += sc7180-acer-aspire1.dtb sc7180-acer-aspire1-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-idp.dtb @@ -407,3 +368,39 @@ x1p42100-hp-omnibook-x14-el2-dtbs := x1p42100-hp-omnibook-x14.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1p42100-hp-omnibook-x14.dtb x1p42100-hp-omnibook-x14-el2.dtb x1p42100-lenovo-thinkbook-16-el2-dtbs := x1p42100-lenovo-thinkbook-16.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1p42100-lenovo-thinkbook-16.dtb x1p42100-lenovo-thinkbook-16-el2.dtb + +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 + +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 +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 + +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 From 7046a709c092f44371aac64e0efeccb7e9fd9851 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Mon, 2 Feb 2026 15:46:31 +0530 Subject: [PATCH 357/659] 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 e88e7c7693395..4093376e923fe 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -404,3 +404,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 8832d0f972ff24d6584249f4ad9ecc03ace76d66 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 2 Feb 2026 18:16:25 +0800 Subject: [PATCH 358/659] 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 524d34a0e9219..c1742eb63ddde 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 @@ -331,6 +332,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 e2e878598fd2f5ac7bcb564f35853d849aa5b9c4 Mon Sep 17 00:00:00 2001 From: Le Qi Date: Fri, 30 Jan 2026 16:24:44 +0800 Subject: [PATCH 359/659] 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/ Signed-off-by: Le Qi --- 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 82a923d419149..26ed1c9985c8b 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -401,6 +401,16 @@ static const struct qcom_pdm_domain_data *qcs404_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 *sa8775p_domains[] = { &adsp_audio_pd, &adsp_root_pd, @@ -580,6 +590,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 = sa8775p_domains, }, { .compatible = "qcom,sa8775p", .data = sa8775p_domains, }, { .compatible = "qcom,sc7180", .data = sc7180_domains, }, From 1d8a94974cf44cfc95685bc90885ea46077c04f1 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 14 Jan 2026 22:49:12 -0800 Subject: [PATCH 360/659] 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 platform. Signed-off-by: Taniya Das Signed-off-by: Jingyi Wang Reviewed-by: Abel Vesa Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20260127-knp-dts-misc-v4-10-02723207a450@oss.qualcomm.com/ --- arch/arm64/configs/defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index a8c8e18ae599f..c37377fe7ad90 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1405,8 +1405,12 @@ CONFIG_COMMON_CLK_QCOM=y CONFIG_CLK_GLYMUR_DISPCC=y CONFIG_CLK_GLYMUR_GCC=y CONFIG_CLK_GLYMUR_TCSRCC=y +CONFIG_CLK_KAANAPALI_CAMCC=m CONFIG_CLK_KAANAPALI_GCC=y +CONFIG_CLK_KAANAPALI_DISPCC=m +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 e129e23bba0d0f50d257a16e545367bf33b6da10 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 2 Feb 2026 22:21:36 +0530 Subject: [PATCH 361/659] 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 ba99ff10a2448f95028e534842ceb4b1ae57067d Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 2 Feb 2026 22:38:12 +0530 Subject: [PATCH 362/659] 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 249054f60a90eac6070b637ca4402ecde5e284af Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 2 Feb 2026 16:06:40 +0530 Subject: [PATCH 363/659] 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 c6c4df7b49310ee2948d4e32b1c73a71e2e8df02 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 2 Feb 2026 16:06:41 +0530 Subject: [PATCH 364/659] 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 6500f863aae5c..941612b1bd2e6 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 740d6b63a21f7b69fffefbda744312c57793af08 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 3 Nov 2025 15:06:21 +0800 Subject: [PATCH 365/659] FROMLIST: dt-bindings: arm: add CTCU device for monaco The CTCU device for monaco shares the same configurations as SA8775p. Add a fallback to enable the CTCU for monaco to utilize the compitable of the SA8775p. Link: https://lore.kernel.org/all/20251103-enable-ctcu-for-monaco-v4-1-92ff83201584@oss.qualcomm.com/ Reviewed-by: Krzysztof Kozlowski Acked-by: Suzuki K Poulose Reviewed-by: Bjorn Andersson Signed-off-by: Jie Gan --- .../devicetree/bindings/arm/qcom,coresight-ctcu.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index 3ce8662e43ff7..0363eea51d13a 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml @@ -26,8 +26,13 @@ description: | properties: compatible: - enum: - - qcom,sa8775p-ctcu + oneOf: + - items: + - enum: + - qcom,qcs8300-ctcu + - const: qcom,sa8775p-ctcu + - enum: + - qcom,sa8775p-ctcu reg: maxItems: 1 From ca9a1762361f8aefa943924a351d0959ff4b030b Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Tue, 3 Feb 2026 14:39:38 +0800 Subject: [PATCH 366/659] 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 0363eea51d13a..69f1e7c9d70e7 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 5c20c018f8437cb635577c9eeb98425f7ee57233 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:27 +0530 Subject: [PATCH 367/659] wifi: ath12k: Restructure PCI code to common and Wi-Fi 7 specific logic Refactor pci.c to split common and hardware family specific components. Retain shared logic such as probe and initialization sequences in common pci.c to support reuse across device families and move Wi-Fi 7 specific initialization and configuration to a new pci_wifi7.c file. Register device specific routines via callbacks to keep the common PCI code generic and extensible for future hardware families. This improves maintainability and prepare the codebase for additional device family support. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-1-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/core.c | 5 +- drivers/net/wireless/ath/ath12k/core.h | 6 + drivers/net/wireless/ath/ath12k/pci.c | 200 +++++++------------- drivers/net/wireless/ath/ath12k/pci.h | 21 +- drivers/net/wireless/ath/ath12k/pci_wifi7.c | 173 +++++++++++++++++ drivers/net/wireless/ath/ath12k/pci_wifi7.h | 12 ++ 7 files changed, 278 insertions(+), 140 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/pci_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/pci_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index d95ee525a6cd0..1a26e00627b0a 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -19,6 +19,7 @@ ath12k-y += core.o \ hw.o \ mhi.o \ pci.o \ + pci_wifi7.o \ dp_mon.o \ fw.o \ p2p.o diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index cc352eef19399..7b02e0c8b1919 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -21,6 +21,7 @@ #include "hif.h" #include "pci.h" #include "wow.h" +#include "pci_wifi7.h" static int ahb_err, pci_err; unsigned int ath12k_debug_mask; @@ -2297,7 +2298,7 @@ static int ath12k_init(void) if (ahb_err) pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err); - pci_err = ath12k_pci_init(); + pci_err = ath12k_wifi7_pci_init(); if (pci_err) pr_warn("Failed to initialize ath12k PCI device: %d\n", pci_err); @@ -2308,7 +2309,7 @@ static int ath12k_init(void) static void ath12k_exit(void) { if (!pci_err) - ath12k_pci_exit(); + ath12k_wifi7_pci_exit(); if (!ahb_err) ath12k_ahb_exit(); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 3c1e0069be1e7..60c2237cb055e 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1035,6 +1035,12 @@ struct ath12k_mem_profile_based_param { struct ath12k_dp_profile_params dp_params; }; +enum ath12k_device_family { + ATH12K_DEVICE_FAMILY_START, + ATH12K_DEVICE_FAMILY_WIFI7 = ATH12K_DEVICE_FAMILY_START, + ATH12K_DEVICE_FAMILY_MAX, +}; + /* Master structure to hold the hw data which may be used in core module */ struct ath12k_base { enum ath12k_hw_rev hw_rev; diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index a12c8379cb466..3e119cc329de2 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -28,44 +28,17 @@ #define WINDOW_RANGE_MASK GENMASK(18, 0) #define WINDOW_STATIC_MASK GENMASK(31, 6) -#define TCSR_SOC_HW_VERSION 0x1B00000 -#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) -#define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) - /* BAR0 + 4k is always accessible, and no * need to force wakeup. * 4K - 32 = 0xFE0 */ #define ACCESS_ALWAYS_OFF 0xFE0 -#define QCN9274_DEVICE_ID 0x1109 -#define WCN7850_DEVICE_ID 0x1107 - #define PCIE_LOCAL_REG_QRTR_NODE_ID 0x1E03164 #define DOMAIN_NUMBER_MASK GENMASK(7, 4) #define BUS_NUMBER_MASK GENMASK(3, 0) -static const struct pci_device_id ath12k_pci_id_table[] = { - { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, - { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, - {} -}; - -MODULE_DEVICE_TABLE(pci, ath12k_pci_id_table); - -/* TODO: revisit IRQ mapping for new SRNG's */ -static const struct ath12k_msi_config ath12k_msi_config[] = { - { - .total_vectors = 16, - .total_users = 3, - .users = (struct ath12k_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 5, .base_vector = 3 }, - { .name = "DP", .num_vectors = 8, .base_vector = 8 }, - }, - }, -}; - +static struct ath12k_pci_driver *ath12k_pci_family_drivers[ATH12K_DEVICE_FAMILY_MAX]; static const struct ath12k_msi_config msi_config_one_msi = { .total_vectors = 1, .total_users = 4, @@ -136,30 +109,6 @@ static const char *irq_name[ATH12K_IRQ_NUM_MAX] = { "tcl2host-status-ring", }; -static int ath12k_pci_bus_wake_up(struct ath12k_base *ab) -{ - struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); - - return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); -} - -static void ath12k_pci_bus_release(struct ath12k_base *ab) -{ - struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); - - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); -} - -static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = { - .wakeup = NULL, - .release = NULL, -}; - -static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = { - .wakeup = ath12k_pci_bus_wake_up, - .release = ath12k_pci_bus_release, -}; - static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset) { struct ath12k_base *ab = ab_pci->ab; @@ -1549,28 +1498,34 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = { #endif }; -static -void ath12k_pci_read_hw_version(struct ath12k_base *ab, u32 *major, u32 *minor) +static enum ath12k_device_family +ath12k_get_device_family(const struct pci_device_id *pci_dev) { - u32 soc_hw_version; + enum ath12k_device_family device_family_id; + const struct pci_device_id *id; - soc_hw_version = ath12k_pci_read32(ab, TCSR_SOC_HW_VERSION); - *major = FIELD_GET(TCSR_SOC_HW_VERSION_MAJOR_MASK, - soc_hw_version); - *minor = FIELD_GET(TCSR_SOC_HW_VERSION_MINOR_MASK, - soc_hw_version); + for (device_family_id = ATH12K_DEVICE_FAMILY_START; + device_family_id < ATH12K_DEVICE_FAMILY_MAX; device_family_id++) { + if (!ath12k_pci_family_drivers[device_family_id]) + continue; + + id = ath12k_pci_family_drivers[device_family_id]->id_table; + while (id->device) { + if (id->device == pci_dev->device) + return device_family_id; + id += 1; + } + } - ath12k_dbg(ab, ATH12K_DBG_PCI, - "pci tcsr_soc_hw_version major %d minor %d\n", - *major, *minor); + return ATH12K_DEVICE_FAMILY_MAX; } static int ath12k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_dev) { - struct ath12k_base *ab; + enum ath12k_device_family device_id; struct ath12k_pci *ab_pci; - u32 soc_hw_version_major, soc_hw_version_minor; + struct ath12k_base *ab; int ret; ab = ath12k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH12K_BUS_PCI); @@ -1605,56 +1560,24 @@ static int ath12k_pci_probe(struct pci_dev *pdev, ab->id.subsystem_vendor = pdev->subsystem_vendor; ab->id.subsystem_device = pdev->subsystem_device; - switch (pci_dev->device) { - case QCN9274_DEVICE_ID: - ab_pci->msi_config = &ath12k_msi_config[0]; - ab->static_window_map = true; - ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; - ab->hal_rx_ops = &hal_rx_qcn9274_ops; - ath12k_pci_read_hw_version(ab, &soc_hw_version_major, - &soc_hw_version_minor); - ab->target_mem_mode = ath12k_core_get_memory_mode(ab); - switch (soc_hw_version_major) { - case ATH12K_PCI_SOC_HW_VERSION_2: - ab->hw_rev = ATH12K_HW_QCN9274_HW20; - break; - case ATH12K_PCI_SOC_HW_VERSION_1: - ab->hw_rev = ATH12K_HW_QCN9274_HW10; - break; - default: - dev_err(&pdev->dev, - "Unknown hardware version found for QCN9274: 0x%x\n", - soc_hw_version_major); - ret = -EOPNOTSUPP; - goto err_pci_free_region; - } - break; - case WCN7850_DEVICE_ID: - ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; - ab_pci->msi_config = &ath12k_msi_config[0]; - ab->static_window_map = false; - ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; - ab->hal_rx_ops = &hal_rx_wcn7850_ops; - ath12k_pci_read_hw_version(ab, &soc_hw_version_major, - &soc_hw_version_minor); - ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; - switch (soc_hw_version_major) { - case ATH12K_PCI_SOC_HW_VERSION_2: - ab->hw_rev = ATH12K_HW_WCN7850_HW20; - break; - default: - dev_err(&pdev->dev, - "Unknown hardware version found for WCN7850: 0x%x\n", - soc_hw_version_major); - ret = -EOPNOTSUPP; - goto err_pci_free_region; - } - break; + device_id = ath12k_get_device_family(pci_dev); + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) { + ath12k_err(ab, "failed to get device family id\n"); + ret = -EINVAL; + goto err_pci_free_region; + } + + ath12k_dbg(ab, ATH12K_DBG_PCI, "PCI device family id: %d\n", device_id); + + ab_pci->device_family_ops = &ath12k_pci_family_drivers[device_id]->ops; - default: - dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", - pci_dev->device); - ret = -EOPNOTSUPP; + /* Call device specific probe. This is the callback that can + * be used to override any ops in future + * probe is validated for NULL during registration. + */ + ret = ab_pci->device_family_ops->probe(pdev, pci_dev); + if (ret) { + ath12k_err(ab, "failed to probe device: %d\n", ret); goto err_pci_free_region; } @@ -1862,32 +1785,43 @@ static const struct dev_pm_ops __maybe_unused ath12k_pci_pm_ops = { ath12k_pci_pm_resume_early) }; -static struct pci_driver ath12k_pci_driver = { - .name = "ath12k_pci", - .id_table = ath12k_pci_id_table, - .probe = ath12k_pci_probe, - .remove = ath12k_pci_remove, - .shutdown = ath12k_pci_shutdown, - .driver.pm = &ath12k_pci_pm_ops, -}; - -int ath12k_pci_init(void) +int ath12k_pci_register_driver(const enum ath12k_device_family device_id, + struct ath12k_pci_driver *driver) { - int ret; + struct pci_driver *pci_driver; - ret = pci_register_driver(&ath12k_pci_driver); - if (ret) { - pr_err("failed to register ath12k pci driver: %d\n", - ret); - return ret; + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) + return -EINVAL; + + if (!driver || !driver->ops.probe) + return -EINVAL; + + if (ath12k_pci_family_drivers[device_id]) { + pr_err("Driver already registered for %d\n", device_id); + return -EALREADY; } - return 0; + ath12k_pci_family_drivers[device_id] = driver; + + pci_driver = &ath12k_pci_family_drivers[device_id]->driver; + pci_driver->name = driver->name; + pci_driver->id_table = driver->id_table; + pci_driver->probe = ath12k_pci_probe; + pci_driver->remove = ath12k_pci_remove; + pci_driver->shutdown = ath12k_pci_shutdown; + pci_driver->driver.pm = &ath12k_pci_pm_ops; + + return pci_register_driver(pci_driver); } -void ath12k_pci_exit(void) +void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) { - pci_unregister_driver(&ath12k_pci_driver); + if (device_id >= ATH12K_DEVICE_FAMILY_MAX || + !ath12k_pci_family_drivers[device_id]) + return; + + pci_unregister_driver(&ath12k_pci_family_drivers[device_id]->driver); + ath12k_pci_family_drivers[device_id] = NULL; } /* firmware files */ diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index d1ec8aad7f6c3..1b7ecc329a017 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -7,6 +7,7 @@ #define ATH12K_PCI_H #include +#include #include "core.h" @@ -70,9 +71,6 @@ #define QRTR_PCI_DOMAIN_NR_MASK GENMASK(7, 4) #define QRTR_PCI_BUS_NUMBER_MASK GENMASK(3, 0) -#define ATH12K_PCI_SOC_HW_VERSION_1 1 -#define ATH12K_PCI_SOC_HW_VERSION_2 2 - struct ath12k_msi_user { const char *name; int num_vectors; @@ -97,6 +95,10 @@ struct ath12k_pci_ops { void (*release)(struct ath12k_base *ab); }; +struct ath12k_pci_device_family_ops { + int (*probe)(struct pci_dev *pdev, const struct pci_device_id *pci_dev); +}; + struct ath12k_pci { struct pci_dev *pdev; struct ath12k_base *ab; @@ -119,6 +121,14 @@ struct ath12k_pci { const struct ath12k_pci_ops *pci_ops; u32 qmi_instance; u64 dma_mask; + const struct ath12k_pci_device_family_ops *device_family_ops; +}; + +struct ath12k_pci_driver { + const char *name; + const struct pci_device_id *id_table; + struct ath12k_pci_device_family_ops ops; + struct pci_driver driver; }; static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab) @@ -148,6 +158,7 @@ void ath12k_pci_stop(struct ath12k_base *ab); int ath12k_pci_start(struct ath12k_base *ab); int ath12k_pci_power_up(struct ath12k_base *ab); void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend); -int ath12k_pci_init(void); -void ath12k_pci_exit(void); +int ath12k_pci_register_driver(const enum ath12k_device_family device_id, + struct ath12k_pci_driver *driver); +void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id); #endif /* ATH12K_PCI_H */ diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.c b/drivers/net/wireless/ath/ath12k/pci_wifi7.c new file mode 100644 index 0000000000000..8c7718153534c --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/pci_wifi7.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +#include "pci.h" +#include "pci_wifi7.h" +#include "core.h" +#include "hif.h" +#include "mhi.h" + +#define QCN9274_DEVICE_ID 0x1109 +#define WCN7850_DEVICE_ID 0x1107 + +#define ATH12K_PCI_W7_SOC_HW_VERSION_1 1 +#define ATH12K_PCI_W7_SOC_HW_VERSION_2 2 + +#define TCSR_SOC_HW_VERSION 0x1B00000 +#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) +#define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) + +static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { + { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, + { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, + {} +}; + +MODULE_DEVICE_TABLE(pci, ath12k_wifi7_pci_id_table); + +/* TODO: revisit IRQ mapping for new SRNG's */ +static const struct ath12k_msi_config ath12k_wifi7_msi_config[] = { + { + .total_vectors = 16, + .total_users = 3, + .users = (struct ath12k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 5, .base_vector = 3 }, + { .name = "DP", .num_vectors = 8, .base_vector = 8 }, + }, + }, +}; + +static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = { + .wakeup = NULL, + .release = NULL, +}; + +static int ath12k_wifi7_pci_bus_wake_up(struct ath12k_base *ab) +{ + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); + + return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); +} + +static void ath12k_wifi7_pci_bus_release(struct ath12k_base *ab) +{ + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); + + mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); +} + +static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = { + .wakeup = ath12k_wifi7_pci_bus_wake_up, + .release = ath12k_wifi7_pci_bus_release, +}; + +static +void ath12k_wifi7_pci_read_hw_version(struct ath12k_base *ab, + u32 *major, u32 *minor) +{ + u32 soc_hw_version; + + soc_hw_version = ath12k_pci_read32(ab, TCSR_SOC_HW_VERSION); + *major = u32_get_bits(soc_hw_version, TCSR_SOC_HW_VERSION_MAJOR_MASK); + *minor = u32_get_bits(soc_hw_version, TCSR_SOC_HW_VERSION_MINOR_MASK); +} + +static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_dev) +{ + u32 soc_hw_version_major, soc_hw_version_minor; + struct ath12k_pci *ab_pci; + struct ath12k_base *ab; + + ab = pci_get_drvdata(pdev); + if (!ab) + return -EINVAL; + + ab_pci = ath12k_pci_priv(ab); + if (!ab_pci) + return -EINVAL; + + switch (pci_dev->device) { + case QCN9274_DEVICE_ID: + ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->static_window_map = true; + ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; + ab->hal_rx_ops = &hal_rx_qcn9274_ops; + ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); + ab->target_mem_mode = ath12k_core_get_memory_mode(ab); + switch (soc_hw_version_major) { + case ATH12K_PCI_W7_SOC_HW_VERSION_2: + ab->hw_rev = ATH12K_HW_QCN9274_HW20; + break; + case ATH12K_PCI_W7_SOC_HW_VERSION_1: + ab->hw_rev = ATH12K_HW_QCN9274_HW10; + break; + default: + dev_err(&pdev->dev, + "Unknown hardware version found for QCN9274: 0x%x\n", + soc_hw_version_major); + return -EOPNOTSUPP; + } + break; + case WCN7850_DEVICE_ID: + ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; + ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->static_window_map = false; + ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; + ab->hal_rx_ops = &hal_rx_wcn7850_ops; + ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); + ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; + switch (soc_hw_version_major) { + case ATH12K_PCI_W7_SOC_HW_VERSION_2: + ab->hw_rev = ATH12K_HW_WCN7850_HW20; + break; + default: + dev_err(&pdev->dev, + "Unknown hardware version found for WCN7850: 0x%x\n", + soc_hw_version_major); + return -EOPNOTSUPP; + } + break; + + default: + dev_err(&pdev->dev, "Unknown Wi-Fi 7 PCI device found: 0x%x\n", + pci_dev->device); + return -EOPNOTSUPP; + } + + return 0; +} + +static struct ath12k_pci_driver ath12k_pci_wifi7_driver = { + .name = "ath12k_wifi7_pci", + .id_table = ath12k_wifi7_pci_id_table, + .ops.probe = ath12k_wifi7_pci_probe, +}; + +int ath12k_wifi7_pci_init(void) +{ + int ret; + + ret = ath12k_pci_register_driver(ATH12K_DEVICE_FAMILY_WIFI7, + &ath12k_pci_wifi7_driver); + if (ret) { + pr_err("Failed to register ath12k Wi-Fi 7 driver: %d\n", + ret); + return ret; + } + + return 0; +} + +void ath12k_wifi7_pci_exit(void) +{ + ath12k_pci_unregister_driver(ATH12K_DEVICE_FAMILY_WIFI7); +} diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.h b/drivers/net/wireless/ath/ath12k/pci_wifi7.h new file mode 100644 index 0000000000000..662a8bab0ce7f --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/pci_wifi7.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_PCI_WIFI7_H +#define ATH12K_PCI_WIFI7_H + +int ath12k_wifi7_pci_init(void); +void ath12k_wifi7_pci_exit(void); + +#endif /* ATH12K_PCI_WIFI7_H */ From 39a773540271c3c4089a40561a54edb8602c8784 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:28 +0530 Subject: [PATCH 368/659] wifi: ath12k: Move Copy Engine configuration to Wi-Fi 7 specific file Relocate Copy Engine (CE) assignment logic from ce.c to a new ce_wifi7.c file to consolidate Wi-Fi 7 specific CE configuration in one place. Move CE service map and target configuration from hw.c to ce_wifi7.c. This reorganization improves code clarity and modularity by isolating device-specific logic. It is part of a broader effort to separate common and hardware-specific code into distinct modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-2-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/ce.c | 301 ------- drivers/net/wireless/ath/ath12k/ce.h | 4 - drivers/net/wireless/ath/ath12k/ce_wifi7.c | 970 +++++++++++++++++++++ drivers/net/wireless/ath/ath12k/ce_wifi7.h | 22 + drivers/net/wireless/ath/ath12k/hw.c | 629 +------------ 6 files changed, 994 insertions(+), 933 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/ce_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/ce_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 1a26e00627b0a..e4776887c939a 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -14,6 +14,7 @@ ath12k-y += core.o \ dp_rx.o \ debug.o \ ce.o \ + ce_wifi7.o \ peer.o \ dbring.o \ hw.o \ diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index 4aea584468381..8fcf2f91b9a46 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -8,307 +8,6 @@ #include "debug.h" #include "hif.h" -const struct ce_attr ath12k_host_ce_config_qcn9274[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 128, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE3: host->target WMI (mac0) */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 2048, - .src_sz_max = 256, - .dest_nentries = 0, - }, - - /* CE5: target->host pktlog */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, - }, - - /* CE6: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE7: host->target WMI (mac1) */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE8: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE9: MHI */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE10: MHI */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE11: MHI */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE12: CV Prefetch */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE13: CV Prefetch */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE14: target->host dbg log */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE15: reserved for future use */ - { - .flags = (CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, -}; - -const struct ce_attr ath12k_host_ce_config_wcn7850[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 64, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE3: host->target WMI (mac0) */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 2048, - .src_sz_max = 256, - .dest_nentries = 0, - }, - - /* CE5: target->host pktlog */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE6: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE7: host->target WMI (mac1) */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE8: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - -}; - -const struct ce_attr ath12k_host_ce_config_ipq5332[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 128, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - /* CE3: host->target WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 2048, - .src_sz_max = 256, - .dest_nentries = 0, - }, - /* CE5: target -> host PKTLOG */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, - }, - /* CE6: Target autonomous HIF_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE7: CV Prefetch */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE8: Target HIF memcpy (Generic HIF memcypy) */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE9: WMI logging/CFR/Spectral/Radar */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 128, - }, - /* CE10: Unused */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE11: Unused */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, -}; - static int ath12k_ce_rx_buf_enqueue_pipe(struct ath12k_ce_pipe *pipe, struct sk_buff *skb, dma_addr_t paddr) { diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index 57f75899ee03d..f44ce2244bcfd 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -173,10 +173,6 @@ struct ath12k_ce { struct ath12k_hp_update_timer hp_timer[CE_COUNT_MAX]; }; -extern const struct ce_attr ath12k_host_ce_config_qcn9274[]; -extern const struct ce_attr ath12k_host_ce_config_wcn7850[]; -extern const struct ce_attr ath12k_host_ce_config_ipq5332[]; - void ath12k_ce_cleanup_pipes(struct ath12k_base *ab); void ath12k_ce_rx_replenish_retry(struct timer_list *t); void ath12k_ce_per_engine_service(struct ath12k_base *ab, u16 ce_id); diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.c b/drivers/net/wireless/ath/ath12k/ce_wifi7.c new file mode 100644 index 0000000000000..cf27259d15a0e --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ce_wifi7.c @@ -0,0 +1,970 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include + +#include "core.h" +#include "ce.h" +#include "ce_wifi7.h" +#include "dp_rx.h" + +/* Copy Engine (CE) configs for QCN9274 */ +/* Target firmware's Copy Engine configuration. */ +const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { + /* CE0: host->target HTC control and raw streams */ + { + .pipenum = __cpu_to_le32(0), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE1: target->host HTT + HTC control */ + { + .pipenum = __cpu_to_le32(1), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE2: target->host WMI */ + { + .pipenum = __cpu_to_le32(2), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE3: host->target WMI (mac0) */ + { + .pipenum = __cpu_to_le32(3), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE4: host->target HTT */ + { + .pipenum = __cpu_to_le32(4), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(256), + .nbytes_max = __cpu_to_le32(256), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE5: target->host Pktlog */ + { + .pipenum = __cpu_to_le32(5), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE6: Reserved for target autonomous hif_memcpy */ + { + .pipenum = __cpu_to_le32(6), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE7: host->target WMI (mac1) */ + { + .pipenum = __cpu_to_le32(7), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE8: Reserved for target autonomous hif_memcpy */ + { + .pipenum = __cpu_to_le32(8), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE9, 10 and 11: Reserved for MHI */ + + /* CE12: Target CV prefetch */ + { + .pipenum = __cpu_to_le32(12), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE13: Target CV prefetch */ + { + .pipenum = __cpu_to_le32(13), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE14: WMI logging/CFR/Spectral/Radar */ + { + .pipenum = __cpu_to_le32(14), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE15: Reserved */ +}; + +/* Map from service/endpoint to Copy Engine. + * This table is derived from the CE_PCI TABLE, above. + * It is passed to the Target at startup for use by firmware. + * Pipe direction: + * PIPEDIR_OUT = UL = host -> target + * PIPEDIR_IN = DL = target -> host + */ +const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(4), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(7), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(5), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(14), + }, + + /* (Additions here) */ + + { /* must be last */ + __cpu_to_le32(0), + __cpu_to_le32(0), + __cpu_to_le32(0), + }, +}; + +const struct ce_attr ath12k_host_ce_config_qcn9274[] = { + /* CE0: host->target HTC control and raw streams */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE1: target->host HTT + HTC control */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE2: target->host WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 128, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI (mac0) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target->host pktlog */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, + }, + + /* CE6: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: host->target WMI (mac1) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE8: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE9: MHI */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE10: MHI */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE11: MHI */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE12: CV Prefetch */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE13: CV Prefetch */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE14: target->host dbg log */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE15: reserved for future use */ + { + .flags = (CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, +}; + +/* Copy Engine (CE) configs for WCN7850 */ +/* Target firmware's Copy Engine configuration. */ +const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { + /* CE0: host->target HTC control and raw streams */ + { + .pipenum = __cpu_to_le32(0), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE1: target->host HTT + HTC control */ + { + .pipenum = __cpu_to_le32(1), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE2: target->host WMI */ + { + .pipenum = __cpu_to_le32(2), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE3: host->target WMI */ + { + .pipenum = __cpu_to_le32(3), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE4: host->target HTT */ + { + .pipenum = __cpu_to_le32(4), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(256), + .nbytes_max = __cpu_to_le32(256), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE5: target->host Pktlog */ + { + .pipenum = __cpu_to_le32(5), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE6: Reserved for target autonomous hif_memcpy */ + { + .pipenum = __cpu_to_le32(6), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE7 used only by Host */ + { + .pipenum = __cpu_to_le32(7), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H), + .nentries = __cpu_to_le32(0), + .nbytes_max = __cpu_to_le32(0), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE8 target->host used only by IPA */ + { + .pipenum = __cpu_to_le32(8), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + /* CE 9, 10, 11 are used by MHI driver */ +}; + +const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(4), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + + /* (Additions here) */ + + { /* must be last */ + __cpu_to_le32(0), + __cpu_to_le32(0), + __cpu_to_le32(0), + }, +}; + +const struct ce_attr ath12k_host_ce_config_wcn7850[] = { + /* CE0: host->target HTC control and raw streams */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE1: target->host HTT + HTC control */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE2: target->host WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 64, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI (mac0) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target->host pktlog */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE6: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: host->target WMI (mac1) */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE8: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, +}; + +/* Copy Engine (CE) configs for IPQ5332 */ +/* Target firmware's Copy Engine configuration. */ +const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { + /* CE0: host->target HTC control and raw streams */ + { + .pipenum = __cpu_to_le32(0), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE1: target->host HTT */ + { + .pipenum = __cpu_to_le32(1), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE2: target->host WMI + HTC control */ + { + .pipenum = __cpu_to_le32(2), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE3: host->target WMI */ + { + .pipenum = __cpu_to_le32(3), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE4: host->target HTT */ + { + .pipenum = __cpu_to_le32(4), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(256), + .nbytes_max = __cpu_to_le32(256), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE5: Target -> host PKTLOG */ + { + .pipenum = __cpu_to_le32(5), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE6: Reserved for target autonomous HIF_memcpy */ + { + .pipenum = __cpu_to_le32(6), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE7: Reserved for CV Prefetch */ + { + .pipenum = __cpu_to_le32(7), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE8: Reserved for target generic HIF memcpy */ + { + .pipenum = __cpu_to_le32(8), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE9: WMI logging/CFR/Spectral/Radar/ */ + { + .pipenum = __cpu_to_le32(9), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE10: Unused TBD */ + { + .pipenum = __cpu_to_le32(10), + .pipedir = __cpu_to_le32(PIPEDIR_NONE), + .nentries = __cpu_to_le32(0), + .nbytes_max = __cpu_to_le32(0), + .flags = __cpu_to_le32(0), + .reserved = __cpu_to_le32(0), + }, + /* CE11: Unused TBD */ + { + .pipenum = __cpu_to_le32(11), + .pipedir = __cpu_to_le32(PIPEDIR_NONE), + .nentries = __cpu_to_le32(0), + .nbytes_max = __cpu_to_le32(0), + .flags = __cpu_to_le32(0), + .reserved = __cpu_to_le32(0), + }, +}; + +const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(4), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(5), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(9), + }, + /* (Additions here) */ + + { /* must be last */ + __cpu_to_le32(0), + __cpu_to_le32(0), + __cpu_to_le32(0), + }, +}; + +const struct ce_attr ath12k_host_ce_config_ipq5332[] = { + /* CE0: host->target HTC control and raw streams */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE1: target->host HTT + HTC control */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE2: target->host WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 128, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target -> host PKTLOG */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, + }, + + /* CE6: Target autonomous HIF_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: CV Prefetch */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE8: Target HIF memcpy (Generic HIF memcypy) */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE9: WMI logging/CFR/Spectral/Radar */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 128, + }, + + /* CE10: Unused */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE11: Unused */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, +}; diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.h b/drivers/net/wireless/ath/ath12k/ce_wifi7.h new file mode 100644 index 0000000000000..1e211e8c24672 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ce_wifi7.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_WIFI7_CE_H +#define ATH12K_WIFI7_CE_H + +extern const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[]; +extern const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[]; +extern const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[]; + +extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[]; +extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[]; +extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[]; + +extern const struct ce_attr ath12k_host_ce_config_qcn9274[]; +extern const struct ce_attr ath12k_host_ce_config_wcn7850[]; +extern const struct ce_attr ath12k_host_ce_config_ipq5332[]; + +#endif /* ATH12K_WIFI7_CE_H */ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index 6791ae1d64e50..dd60e27cc4996 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -11,6 +11,7 @@ #include "debug.h" #include "core.h" #include "ce.h" +#include "ce_wifi7.h" #include "hw.h" #include "mhi.h" #include "dp_rx.h" @@ -177,634 +178,6 @@ static const struct ath12k_hw_ops wcn7850_ops = { #define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2 #define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4 -/* Target firmware's Copy Engine configuration. */ -static const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { - /* CE0: host->target HTC control and raw streams */ - { - .pipenum = __cpu_to_le32(0), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE1: target->host HTT + HTC control */ - { - .pipenum = __cpu_to_le32(1), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE2: target->host WMI */ - { - .pipenum = __cpu_to_le32(2), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE3: host->target WMI (mac0) */ - { - .pipenum = __cpu_to_le32(3), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE4: host->target HTT */ - { - .pipenum = __cpu_to_le32(4), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(256), - .nbytes_max = __cpu_to_le32(256), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - - /* CE5: target->host Pktlog */ - { - .pipenum = __cpu_to_le32(5), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE6: Reserved for target autonomous hif_memcpy */ - { - .pipenum = __cpu_to_le32(6), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE7: host->target WMI (mac1) */ - { - .pipenum = __cpu_to_le32(7), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE8: Reserved for target autonomous hif_memcpy */ - { - .pipenum = __cpu_to_le32(8), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE9, 10 and 11: Reserved for MHI */ - - /* CE12: Target CV prefetch */ - { - .pipenum = __cpu_to_le32(12), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE13: Target CV prefetch */ - { - .pipenum = __cpu_to_le32(13), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE14: WMI logging/CFR/Spectral/Radar */ - { - .pipenum = __cpu_to_le32(14), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE15: Reserved */ -}; - -/* Target firmware's Copy Engine configuration. */ -static const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { - /* CE0: host->target HTC control and raw streams */ - { - .pipenum = __cpu_to_le32(0), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE1: target->host HTT + HTC control */ - { - .pipenum = __cpu_to_le32(1), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE2: target->host WMI */ - { - .pipenum = __cpu_to_le32(2), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE3: host->target WMI */ - { - .pipenum = __cpu_to_le32(3), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE4: host->target HTT */ - { - .pipenum = __cpu_to_le32(4), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(256), - .nbytes_max = __cpu_to_le32(256), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - - /* CE5: target->host Pktlog */ - { - .pipenum = __cpu_to_le32(5), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE6: Reserved for target autonomous hif_memcpy */ - { - .pipenum = __cpu_to_le32(6), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE7 used only by Host */ - { - .pipenum = __cpu_to_le32(7), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H), - .nentries = __cpu_to_le32(0), - .nbytes_max = __cpu_to_le32(0), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - - /* CE8 target->host used only by IPA */ - { - .pipenum = __cpu_to_le32(8), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE 9, 10, 11 are used by MHI driver */ -}; - -/* Map from service/endpoint to Copy Engine. - * This table is derived from the CE_PCI TABLE, above. - * It is passed to the Target at startup for use by firmware. - */ -static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(4), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(7), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(5), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(14), - }, - - /* (Additions here) */ - - { /* must be last */ - __cpu_to_le32(0), - __cpu_to_le32(0), - __cpu_to_le32(0), - }, -}; - -static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(4), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - - /* (Additions here) */ - - { /* must be last */ - __cpu_to_le32(0), - __cpu_to_le32(0), - __cpu_to_le32(0), - }, -}; - -static const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { - /* host->target HTC control and raw streams */ - { - .pipenum = __cpu_to_le32(0), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* target->host HTT */ - { - .pipenum = __cpu_to_le32(1), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* target->host WMI + HTC control */ - { - .pipenum = __cpu_to_le32(2), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* host->target WMI */ - { - .pipenum = __cpu_to_le32(3), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* host->target HTT */ - { - .pipenum = __cpu_to_le32(4), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(256), - .nbytes_max = __cpu_to_le32(256), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - /* Target -> host PKTLOG */ - { - .pipenum = __cpu_to_le32(5), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* Reserved for target autonomous HIF_memcpy */ - { - .pipenum = __cpu_to_le32(6), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE7 Reserved for CV Prefetch */ - { - .pipenum = __cpu_to_le32(7), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE8 Reserved for target generic HIF memcpy */ - { - .pipenum = __cpu_to_le32(8), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE9 WMI logging/CFR/Spectral/Radar/ */ - { - .pipenum = __cpu_to_le32(9), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* Unused TBD */ - { - .pipenum = __cpu_to_le32(10), - .pipedir = __cpu_to_le32(PIPEDIR_NONE), - .nentries = __cpu_to_le32(0), - .nbytes_max = __cpu_to_le32(0), - .flags = __cpu_to_le32(0), - .reserved = __cpu_to_le32(0), - }, - /* Unused TBD */ - { - .pipenum = __cpu_to_le32(11), - .pipedir = __cpu_to_le32(PIPEDIR_NONE), - .nentries = __cpu_to_le32(0), - .nbytes_max = __cpu_to_le32(0), - .flags = __cpu_to_le32(0), - .reserved = __cpu_to_le32(0), - }, -}; - -static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(4), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(5), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(9), - }, - /* (Additions here) */ - - { /* must be last */ - __cpu_to_le32(0), - __cpu_to_le32(0), - __cpu_to_le32(0), - }, -}; - static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { .tx = { ATH12K_TX_RING_MASK_0, From d4505ac87ca5a41492458b17805ed201faca2085 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:29 +0530 Subject: [PATCH 369/659] wifi: ath12k: Move Wi-Fi 7 WMI configuration to dedicated file Relocate Wi-Fi 7 specific WMI configuration from shared codebase to a new target-specific file. Isolate WMI settings per target to improve modularity and maintainability. This change is part of a broader effort to separate hardware-dependent logic into standalone modules, paving the way for cleaner support of multiple hardware families Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-3-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/hw.c | 1 + drivers/net/wireless/ath/ath12k/wmi.c | 97 ------------------ drivers/net/wireless/ath/ath12k/wmi.h | 4 - drivers/net/wireless/ath/ath12k/wmi_wifi7.c | 105 ++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wmi_wifi7.h | 15 +++ 6 files changed, 122 insertions(+), 101 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wmi_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/wmi_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index e4776887c939a..ee075ee68bb83 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -5,6 +5,7 @@ ath12k-y += core.o \ hal_tx.o \ hal_rx.o \ wmi.o \ + wmi_wifi7.o \ mac.o \ reg.o \ htc.o \ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index dd60e27cc4996..df1b4439adc79 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -16,6 +16,7 @@ #include "mhi.h" #include "dp_rx.h" #include "peer.h" +#include "wmi_wifi7.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 3ce5fcb0e4600..8f0171c7aa4d1 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -206,103 +206,6 @@ static __le32 ath12k_wmi_tlv_cmd_hdr(u32 cmd, u32 len) return ath12k_wmi_tlv_hdr(cmd, len - TLV_HDR_SIZE); } -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) -{ - config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS(ab); - config->num_peers = ab->num_radios * - ath12k_core_get_max_peers_per_radio(ab); - config->num_offload_peers = TARGET_NUM_OFFLD_PEERS; - config->num_offload_reorder_buffs = TARGET_NUM_OFFLD_REORDER_BUFFS; - config->num_peer_keys = TARGET_NUM_PEER_KEYS; - config->ast_skid_limit = TARGET_AST_SKID_LIMIT; - config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; - - if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) - config->rx_decap_mode = TARGET_DECAP_MODE_RAW; - else - config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; - - config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; - config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; - config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; - config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; - config->num_mcast_groups = TARGET_NUM_MCAST_GROUPS; - config->num_mcast_table_elems = TARGET_NUM_MCAST_TABLE_ELEMS; - config->mcast2ucast_mode = TARGET_MCAST2UCAST_MODE; - config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; - config->num_wds_entries = TARGET_NUM_WDS_ENTRIES; - config->dma_burst_size = TARGET_DMA_BURST_SIZE; - config->rx_skip_defrag_timeout_dup_detection_check = - TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; - config->vow_config = TARGET_VOW_CONFIG; - config->gtk_offload_max_vdev = TARGET_GTK_OFFLOAD_MAX_VDEV; - config->num_msdu_desc = TARGET_NUM_MSDU_DESC; - config->beacon_tx_offload_max_vdev = ab->num_radios * TARGET_MAX_BCN_OFFLD; - config->rx_batchmode = TARGET_RX_BATCHMODE; - /* Indicates host supports peer map v3 and unmap v2 support */ - config->peer_map_unmap_version = 0x32; - config->twt_ap_pdev_count = ab->num_radios; - config->twt_ap_sta_count = 1000; - config->ema_max_vap_cnt = ab->num_radios; - config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; - config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; - - if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) - config->peer_metadata_ver = ATH12K_PEER_METADATA_V1B; -} - -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) -{ - config->num_vdevs = 4; - config->num_peers = 16; - config->num_tids = 32; - - config->num_offload_peers = 3; - config->num_offload_reorder_buffs = 3; - config->num_peer_keys = TARGET_NUM_PEER_KEYS; - config->ast_skid_limit = TARGET_AST_SKID_LIMIT; - config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; - config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; - config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; - config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; - config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; - config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; - config->num_mcast_groups = 0; - config->num_mcast_table_elems = 0; - config->mcast2ucast_mode = 0; - config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; - config->num_wds_entries = 0; - config->dma_burst_size = 0; - config->rx_skip_defrag_timeout_dup_detection_check = 0; - config->vow_config = TARGET_VOW_CONFIG; - config->gtk_offload_max_vdev = 2; - config->num_msdu_desc = 0x400; - config->beacon_tx_offload_max_vdev = 2; - config->rx_batchmode = TARGET_RX_BATCHMODE; - - config->peer_map_unmap_version = 0x1; - config->use_pdev_id = 1; - config->max_frag_entries = 0xa; - config->num_tdls_vdevs = 0x1; - config->num_tdls_conn_table_entries = 8; - config->beacon_tx_offload_max_vdev = 0x2; - config->num_multicast_filter_entries = 0x20; - config->num_wow_filters = 0x16; - config->num_keep_alive_pattern = 0; -} - #define PRIMAP(_hw_mode_) \ [_hw_mode_] = _hw_mode_##_PRI diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index f99fced1610e6..b1ba1f8b6bb2d 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -6323,10 +6323,6 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg { s8 min_nf_dbm; }; -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.c b/drivers/net/wireless/ath/ath12k/wmi_wifi7.c new file mode 100644 index 0000000000000..f27fa56210e83 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wmi_wifi7.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "core.h" +#include "wmi_wifi7.h" + +void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) +{ + config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS(ab); + config->num_peers = ab->num_radios * + ath12k_core_get_max_peers_per_radio(ab); + config->num_offload_peers = TARGET_NUM_OFFLD_PEERS; + config->num_offload_reorder_buffs = TARGET_NUM_OFFLD_REORDER_BUFFS; + config->num_peer_keys = TARGET_NUM_PEER_KEYS; + config->ast_skid_limit = TARGET_AST_SKID_LIMIT; + config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; + + if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) + config->rx_decap_mode = TARGET_DECAP_MODE_RAW; + else + config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; + + config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; + config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; + config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; + config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; + config->num_mcast_groups = TARGET_NUM_MCAST_GROUPS; + config->num_mcast_table_elems = TARGET_NUM_MCAST_TABLE_ELEMS; + config->mcast2ucast_mode = TARGET_MCAST2UCAST_MODE; + config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; + config->num_wds_entries = TARGET_NUM_WDS_ENTRIES; + config->dma_burst_size = TARGET_DMA_BURST_SIZE; + config->rx_skip_defrag_timeout_dup_detection_check = + TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; + config->vow_config = TARGET_VOW_CONFIG; + config->gtk_offload_max_vdev = TARGET_GTK_OFFLOAD_MAX_VDEV; + config->num_msdu_desc = TARGET_NUM_MSDU_DESC; + config->beacon_tx_offload_max_vdev = ab->num_radios * TARGET_MAX_BCN_OFFLD; + config->rx_batchmode = TARGET_RX_BATCHMODE; + /* Indicates host supports peer map v3 and unmap v2 support */ + config->peer_map_unmap_version = 0x32; + config->twt_ap_pdev_count = ab->num_radios; + config->twt_ap_sta_count = 1000; + config->ema_max_vap_cnt = ab->num_radios; + config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; + config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; + + if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) + config->peer_metadata_ver = ATH12K_PEER_METADATA_V1B; +} + +void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) +{ + config->num_vdevs = 4; + config->num_peers = 16; + config->num_tids = 32; + + config->num_offload_peers = 3; + config->num_offload_reorder_buffs = 3; + config->num_peer_keys = TARGET_NUM_PEER_KEYS; + config->ast_skid_limit = TARGET_AST_SKID_LIMIT; + config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; + config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; + config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; + config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; + config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; + config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; + config->num_mcast_groups = 0; + config->num_mcast_table_elems = 0; + config->mcast2ucast_mode = 0; + config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; + config->num_wds_entries = 0; + config->dma_burst_size = 0; + config->rx_skip_defrag_timeout_dup_detection_check = 0; + config->vow_config = TARGET_VOW_CONFIG; + config->gtk_offload_max_vdev = 2; + config->num_msdu_desc = 0x400; + config->beacon_tx_offload_max_vdev = 2; + config->rx_batchmode = TARGET_RX_BATCHMODE; + + config->peer_map_unmap_version = 0x1; + config->use_pdev_id = 1; + config->max_frag_entries = 0xa; + config->num_tdls_vdevs = 0x1; + config->num_tdls_conn_table_entries = 8; + config->beacon_tx_offload_max_vdev = 0x2; + config->num_multicast_filter_entries = 0x20; + config->num_wow_filters = 0x16; + config->num_keep_alive_pattern = 0; +} diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.h b/drivers/net/wireless/ath/ath12k/wmi_wifi7.h new file mode 100644 index 0000000000000..1514e3e8d4cb6 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wmi_wifi7.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_WMI_WIFI7_H +#define ATH12K_WMI_WIFI7_H + +void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); +void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); + +#endif From c0a6775b6febceabc5d83ba1539a9821eef77f14 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:30 +0530 Subject: [PATCH 370/659] wifi: ath12k: Move Wi-Fi 7 MHI configuration to dedicated file Relocate target-specific MHI configuration to a new mhi_wifi7.c file to isolate Wi-Fi 7 related logic from the common codebase. Improve modularity by separating hardware-dependent code from shared components. Enhance maintainability and prepare the driver for clean integration of additional device families. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-4-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/hw.c | 1 + drivers/net/wireless/ath/ath12k/mhi.c | 130 ------------------ drivers/net/wireless/ath/ath12k/mhi.h | 4 +- drivers/net/wireless/ath/ath12k/mhi_wifi7.c | 138 ++++++++++++++++++++ drivers/net/wireless/ath/ath12k/mhi_wifi7.h | 11 ++ 6 files changed, 152 insertions(+), 133 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/mhi_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/mhi_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index ee075ee68bb83..fb968884f6560 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -20,6 +20,7 @@ ath12k-y += core.o \ dbring.o \ hw.o \ mhi.o \ + mhi_wifi7.o \ pci.o \ pci_wifi7.o \ dp_mon.o \ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index df1b4439adc79..ad372feaef28b 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -17,6 +17,7 @@ #include "dp_rx.h" #include "peer.h" #include "wmi_wifi7.h" +#include "mhi_wifi7.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c index 08f44baf182a5..1f680f6e65d30 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.c +++ b/drivers/net/wireless/ath/ath12k/mhi.c @@ -18,136 +18,6 @@ #define OTP_VALID_DUALMAC_BOARD_ID_MASK 0x1000 #define MHI_CB_INVALID 0xff -static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { - { - .num = 20, - .name = "IPCR", - .num_elements = 32, - .event_ring = 1, - .dir = DMA_TO_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = false, - }, - { - .num = 21, - .name = "IPCR", - .num_elements = 32, - .event_ring = 1, - .dir = DMA_FROM_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = true, - }, -}; - -static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { - { - .num_elements = 32, - .irq_moderation_ms = 0, - .irq = 1, - .data_type = MHI_ER_CTRL, - .mode = MHI_DB_BRST_DISABLE, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, - { - .num_elements = 256, - .irq_moderation_ms = 1, - .irq = 2, - .mode = MHI_DB_BRST_DISABLE, - .priority = 1, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, -}; - -const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { - .max_channels = 30, - .timeout_ms = 10000, - .use_bounce_buf = false, - .buf_len = 0, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), - .ch_cfg = ath12k_mhi_channels_qcn9274, - .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), - .event_cfg = ath12k_mhi_events_qcn9274, -}; - -static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { - { - .num = 20, - .name = "IPCR", - .num_elements = 64, - .event_ring = 1, - .dir = DMA_TO_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = false, - }, - { - .num = 21, - .name = "IPCR", - .num_elements = 64, - .event_ring = 1, - .dir = DMA_FROM_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = true, - }, -}; - -static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { - { - .num_elements = 32, - .irq_moderation_ms = 0, - .irq = 1, - .mode = MHI_DB_BRST_DISABLE, - .data_type = MHI_ER_CTRL, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, - { - .num_elements = 256, - .irq_moderation_ms = 1, - .irq = 2, - .mode = MHI_DB_BRST_DISABLE, - .priority = 1, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, -}; - -const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { - .max_channels = 128, - .timeout_ms = 2000, - .use_bounce_buf = false, - .buf_len = 8192, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), - .ch_cfg = ath12k_mhi_channels_wcn7850, - .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), - .event_cfg = ath12k_mhi_events_wcn7850, -}; - void ath12k_mhi_set_mhictrl_reset(struct ath12k_base *ab) { u32 val; diff --git a/drivers/net/wireless/ath/ath12k/mhi.h b/drivers/net/wireless/ath/ath12k/mhi.h index 7358b8477536a..5e1363650a9a7 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.h +++ b/drivers/net/wireless/ath/ath12k/mhi.h @@ -2,6 +2,7 @@ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef _ATH12K_MHI_H #define _ATH12K_MHI_H @@ -31,9 +32,6 @@ enum ath12k_mhi_state { ATH12K_MHI_RDDM_DONE, }; -extern const struct mhi_controller_config ath12k_mhi_config_qcn9274; -extern const struct mhi_controller_config ath12k_mhi_config_wcn7850; - int ath12k_mhi_start(struct ath12k_pci *ar_pci); void ath12k_mhi_stop(struct ath12k_pci *ar_pci, bool is_suspend); int ath12k_mhi_register(struct ath12k_pci *ar_pci); diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.c b/drivers/net/wireless/ath/ath12k/mhi_wifi7.c new file mode 100644 index 0000000000000..be74df152f6f8 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/mhi_wifi7.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "mhi.h" +#include "mhi_wifi7.h" + +static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { + { + .num = 20, + .name = "IPCR", + .num_elements = 32, + .event_ring = 1, + .dir = DMA_TO_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + }, + { + .num = 21, + .name = "IPCR", + .num_elements = 32, + .event_ring = 1, + .dir = DMA_FROM_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = true, + }, +}; + +static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { + { + .num_elements = 32, + .irq_moderation_ms = 0, + .irq = 1, + .data_type = MHI_ER_CTRL, + .mode = MHI_DB_BRST_DISABLE, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, + { + .num_elements = 256, + .irq_moderation_ms = 1, + .irq = 2, + .mode = MHI_DB_BRST_DISABLE, + .priority = 1, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, +}; + +const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { + .max_channels = 30, + .timeout_ms = 10000, + .use_bounce_buf = false, + .buf_len = 0, + .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), + .ch_cfg = ath12k_mhi_channels_qcn9274, + .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), + .event_cfg = ath12k_mhi_events_qcn9274, +}; + +static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { + { + .num = 20, + .name = "IPCR", + .num_elements = 64, + .event_ring = 1, + .dir = DMA_TO_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + }, + { + .num = 21, + .name = "IPCR", + .num_elements = 64, + .event_ring = 1, + .dir = DMA_FROM_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = true, + }, +}; + +static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { + { + .num_elements = 32, + .irq_moderation_ms = 0, + .irq = 1, + .mode = MHI_DB_BRST_DISABLE, + .data_type = MHI_ER_CTRL, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, + { + .num_elements = 256, + .irq_moderation_ms = 1, + .irq = 2, + .mode = MHI_DB_BRST_DISABLE, + .priority = 1, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, +}; + +const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { + .max_channels = 128, + .timeout_ms = 2000, + .use_bounce_buf = false, + .buf_len = 8192, + .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), + .ch_cfg = ath12k_mhi_channels_wcn7850, + .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), + .event_cfg = ath12k_mhi_events_wcn7850, +}; diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.h b/drivers/net/wireless/ath/ath12k/mhi_wifi7.h new file mode 100644 index 0000000000000..8417a2bde0877 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/mhi_wifi7.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _ATH12K_WIFI7_MHI_H +#define _ATH12K_WIFI7_MHI_H +extern const struct mhi_controller_config ath12k_mhi_config_qcn9274; +extern const struct mhi_controller_config ath12k_mhi_config_wcn7850; +#endif /* _ATH12K_WIFI7_MHI_H */ From 4b071237b2956ac9b9199a0423e268c44faf5373 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:31 +0530 Subject: [PATCH 371/659] wifi: ath12k: Rename hw.c to Wi-Fi 7 specific implementation file Rename hw.c to hw_wifi7.c to reflect its focus on Wi-Fi 7 chipset specific configurations. Clarify the files role in containing hardware dependent logic tailored to the Wi-Fi 7 family. This change is part of a broader effort to modularize the codebase by separating common and target specific components into distinct modules for improved clarity and maintainability. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-5-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 2 +- drivers/net/wireless/ath/ath12k/{hw.c => hw_wifi7.c} | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename drivers/net/wireless/ath/ath12k/{hw.c => hw_wifi7.c} (99%) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index fb968884f6560..f1105d7adafff 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -18,7 +18,7 @@ ath12k-y += core.o \ ce_wifi7.o \ peer.o \ dbring.o \ - hw.o \ + hw_wifi7.o \ mhi.o \ mhi_wifi7.o \ pci.o \ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw_wifi7.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/hw.c rename to drivers/net/wireless/ath/ath12k/hw_wifi7.c index ad372feaef28b..f6177f8e032d9 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw_wifi7.c @@ -1043,13 +1043,14 @@ int ath12k_hw_init(struct ath12k_base *ab) } if (i == ARRAY_SIZE(ath12k_hw_params)) { - ath12k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev); + ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n", + ab->hw_rev); return -EINVAL; } ab->hw_params = hw_params; - ath12k_info(ab, "Hardware name: %s\n", ab->hw_params->name); + ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name); return 0; } From c38df1ebc0ebcc64480613d1fb0547bed3b687f2 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:32 +0530 Subject: [PATCH 372/659] wifi: ath12k: Rename ahb_hif_ops to reflect generic usage Rename ahb_hif_ops structure to remove the IPQ5322 qualifier and reflect its generic applicability across multiple targets. Clarify its role as a container for common HIF callbacks. This renaming is part of a broader effort to modularize the codebase by separating common logic from device-specific implementations. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-6-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index b30527c402f6c..d3f7cc6417cca 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -698,7 +698,7 @@ static int ath12k_ahb_map_service_to_pipe(struct ath12k_base *ab, u16 service_id return 0; } -static const struct ath12k_hif_ops ath12k_ahb_hif_ops_ipq5332 = { +static const struct ath12k_hif_ops ath12k_ahb_hif_ops = { .start = ath12k_ahb_start, .stop = ath12k_ahb_stop, .read32 = ath12k_ahb_read32, @@ -1011,7 +1011,7 @@ static int ath12k_ahb_probe(struct platform_device *pdev) hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); switch (hw_rev) { case ATH12K_HW_IPQ5332_HW10: - hif_ops = &ath12k_ahb_hif_ops_ipq5332; + hif_ops = &ath12k_ahb_hif_ops; userpd_id = ATH12K_IPQ5332_USERPD_ID; break; default: From 86fc60c4b9d3cef607c4c2909553d12b2fa1c1f1 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:33 +0530 Subject: [PATCH 373/659] wifi: ath12k: Restructure ahb.c into common and Wi-Fi 7 specific modules Split ahb.c into a common module (ahb.c) and a Wi-Fi 7 specific module (ahb_wifi7.c). Retain shared logic-such as probe and initialization sequences-in ahb.c to support reuse across hardware families. Move Wi-Fi 7 specific initialization and configuration routines to ahb_wifi7.c and register them via callbacks. This modular approach improves code organization and prepares the driver for scalable support of additional hardware families. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-7-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 2 +- drivers/net/wireless/ath/ath12k/ahb.c | 128 +++++++++++++------- drivers/net/wireless/ath/ath12k/ahb.h | 27 +++-- drivers/net/wireless/ath/ath12k/ahb_wifi7.c | 63 ++++++++++ drivers/net/wireless/ath/ath12k/ahb_wifi7.h | 20 +++ drivers/net/wireless/ath/ath12k/core.c | 5 +- 6 files changed, 190 insertions(+), 55 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/ahb_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/ahb_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index f1105d7adafff..5c044e3963305 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -27,7 +27,7 @@ ath12k-y += core.o \ fw.o \ p2p.o -ath12k-$(CONFIG_ATH12K_AHB) += ahb.o +ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ahb_wifi7.o ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ath12k-$(CONFIG_ACPI) += acpi.o ath12k-$(CONFIG_ATH12K_TRACING) += trace.o diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index d3f7cc6417cca..777edaf0e58e5 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -16,18 +16,11 @@ #include "debug.h" #include "hif.h" -static const struct of_device_id ath12k_ahb_of_match[] = { - { .compatible = "qcom,ipq5332-wifi", - .data = (void *)ATH12K_HW_IPQ5332_HW10, - }, - { } -}; - -MODULE_DEVICE_TABLE(of, ath12k_ahb_of_match); - #define ATH12K_IRQ_CE0_OFFSET 4 #define ATH12K_MAX_UPDS 1 #define ATH12K_UPD_IRQ_WRD_LEN 18 + +static struct ath12k_ahb_driver *ath12k_ahb_family_drivers[ATH12K_DEVICE_FAMILY_MAX]; static const char ath12k_userpd_irq[][9] = {"spawn", "ready", "stop-ack"}; @@ -988,13 +981,34 @@ static void ath12k_ahb_resource_deinit(struct ath12k_base *ab) ab_ahb->xo_clk = NULL; } +static enum ath12k_device_family +ath12k_ahb_get_device_family(const struct platform_device *pdev) +{ + enum ath12k_device_family device_family_id; + struct ath12k_ahb_driver *driver; + const struct of_device_id *of_id; + + for (device_family_id = ATH12K_DEVICE_FAMILY_START; + device_family_id < ATH12K_DEVICE_FAMILY_MAX; device_family_id++) { + driver = ath12k_ahb_family_drivers[device_family_id]; + if (driver) { + of_id = of_match_device(driver->id_table, &pdev->dev); + if (of_id) { + /* Found the driver */ + return device_family_id; + } + } + } + + return ATH12K_DEVICE_FAMILY_MAX; +} + static int ath12k_ahb_probe(struct platform_device *pdev) { - struct ath12k_base *ab; - const struct ath12k_hif_ops *hif_ops; + enum ath12k_device_family device_id; struct ath12k_ahb *ab_ahb; - enum ath12k_hw_rev hw_rev; - u32 addr, userpd_id; + struct ath12k_base *ab; + u32 addr; int ret; ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); @@ -1008,25 +1022,32 @@ static int ath12k_ahb_probe(struct platform_device *pdev) if (!ab) return -ENOMEM; - hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); - switch (hw_rev) { - case ATH12K_HW_IPQ5332_HW10: - hif_ops = &ath12k_ahb_hif_ops; - userpd_id = ATH12K_IPQ5332_USERPD_ID; - break; - default: - ret = -EOPNOTSUPP; + ab_ahb = ath12k_ab_to_ahb(ab); + ab_ahb->ab = ab; + ab->hif.ops = &ath12k_ahb_hif_ops; + ab->pdev = pdev; + platform_set_drvdata(pdev, ab); + + device_id = ath12k_ahb_get_device_family(pdev); + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) { + ath12k_err(ab, "failed to get device family: %d\n", device_id); + ret = -EINVAL; goto err_core_free; } - ab->hif.ops = hif_ops; - ab->pdev = pdev; - ab->hw_rev = hw_rev; - ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; - platform_set_drvdata(pdev, ab); - ab_ahb = ath12k_ab_to_ahb(ab); - ab_ahb->ab = ab; - ab_ahb->userpd_id = userpd_id; + ath12k_dbg(ab, ATH12K_DBG_AHB, "AHB device family id: %d\n", device_id); + + ab_ahb->device_family_ops = &ath12k_ahb_family_drivers[device_id]->ops; + + /* Call device specific probe. This is the callback that can + * be used to override any ops in future + * probe is validated for NULL during registration. + */ + ret = ab_ahb->device_family_ops->probe(pdev); + if (ret) { + ath12k_err(ab, "failed to probe device: %d\n", ret); + goto err_core_free; + } /* Set fixed_mem_region to true for platforms that support fixed memory * reservation from DT. If memory is reserved from DT for FW, ath12k driver @@ -1136,21 +1157,44 @@ static void ath12k_ahb_remove(struct platform_device *pdev) ath12k_ahb_free_resources(ab); } -static struct platform_driver ath12k_ahb_driver = { - .driver = { - .name = "ath12k_ahb", - .of_match_table = ath12k_ahb_of_match, - }, - .probe = ath12k_ahb_probe, - .remove = ath12k_ahb_remove, -}; - -int ath12k_ahb_init(void) +int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, + struct ath12k_ahb_driver *driver) { - return platform_driver_register(&ath12k_ahb_driver); + struct platform_driver *ahb_driver; + + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) + return -EINVAL; + + if (!driver || !driver->ops.probe) + return -EINVAL; + + if (ath12k_ahb_family_drivers[device_id]) { + pr_err("Driver already registered for id %d\n", device_id); + return -EALREADY; + } + + ath12k_ahb_family_drivers[device_id] = driver; + + ahb_driver = &ath12k_ahb_family_drivers[device_id]->driver; + ahb_driver->driver.name = driver->name; + ahb_driver->driver.of_match_table = driver->id_table; + ahb_driver->probe = ath12k_ahb_probe; + ahb_driver->remove = ath12k_ahb_remove; + + return platform_driver_register(ahb_driver); } -void ath12k_ahb_exit(void) +void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id) { - platform_driver_unregister(&ath12k_ahb_driver); + struct platform_driver *ahb_driver; + + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) + return; + + if (!ath12k_ahb_family_drivers[device_id]) + return; + + ahb_driver = &ath12k_ahb_family_drivers[device_id]->driver; + platform_driver_unregister(ahb_driver); + ath12k_ahb_family_drivers[device_id] = NULL; } diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h index d56244b20a6a6..fce02e3af5fb4 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.h +++ b/drivers/net/wireless/ath/ath12k/ahb.h @@ -8,6 +8,7 @@ #include #include +#include #include "core.h" #define ATH12K_AHB_RECOVERY_TIMEOUT (3 * HZ) @@ -43,6 +44,10 @@ enum ath12k_ahb_userpd_irq { struct ath12k_base; +struct ath12k_ahb_device_family_ops { + int (*probe)(struct platform_device *pdev); +}; + struct ath12k_ahb { struct ath12k_base *ab; struct rproc *tgt_rproc; @@ -59,6 +64,15 @@ struct ath12k_ahb { u32 spawn_bit; u32 stop_bit; int userpd_irq_num[ATH12K_USERPD_MAX_IRQ]; + const struct ath12k_ahb_ops *ahb_ops; + const struct ath12k_ahb_device_family_ops *device_family_ops; +}; + +struct ath12k_ahb_driver { + const char *name; + const struct of_device_id *id_table; + struct ath12k_ahb_device_family_ops ops; + struct platform_driver driver; }; static inline struct ath12k_ahb *ath12k_ab_to_ahb(struct ath12k_base *ab) @@ -66,15 +80,8 @@ static inline struct ath12k_ahb *ath12k_ab_to_ahb(struct ath12k_base *ab) return (struct ath12k_ahb *)ab->drv_priv; } -#ifdef CONFIG_ATH12K_AHB -int ath12k_ahb_init(void); -void ath12k_ahb_exit(void); -#else -static inline int ath12k_ahb_init(void) -{ - return 0; -} +int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, + struct ath12k_ahb_driver *driver); +void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id); -static inline void ath12k_ahb_exit(void) {}; -#endif #endif diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c new file mode 100644 index 0000000000000..7a869722b77e6 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include "ahb.h" +#include "ahb_wifi7.h" +#include "debug.h" +#include "hif.h" + +static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { + { .compatible = "qcom,ipq5332-wifi", + .data = (void *)ATH12K_HW_IPQ5332_HW10, + }, + { } +}; + +MODULE_DEVICE_TABLE(of, ath12k_wifi7_ahb_of_match); + +static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) +{ + struct ath12k_ahb *ab_ahb; + enum ath12k_hw_rev hw_rev; + struct ath12k_base *ab; + + ab = platform_get_drvdata(pdev); + ab_ahb = ath12k_ab_to_ahb(ab); + + hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); + switch (hw_rev) { + case ATH12K_HW_IPQ5332_HW10: + ab_ahb->userpd_id = ATH12K_IPQ5332_USERPD_ID; + break; + default: + return -EOPNOTSUPP; + } + + ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; + ab->hw_rev = hw_rev; + + return 0; +} + +static struct ath12k_ahb_driver ath12k_wifi7_ahb_driver = { + .name = "ath12k_wifi7_ahb", + .id_table = ath12k_wifi7_ahb_of_match, + .ops.probe = ath12k_wifi7_ahb_probe, +}; + +int ath12k_wifi7_ahb_init(void) +{ + return ath12k_ahb_register_driver(ATH12K_DEVICE_FAMILY_WIFI7, + &ath12k_wifi7_ahb_driver); +} + +void ath12k_wifi7_ahb_exit(void) +{ + ath12k_ahb_unregister_driver(ATH12K_DEVICE_FAMILY_WIFI7); +} diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.h b/drivers/net/wireless/ath/ath12k/ahb_wifi7.h new file mode 100644 index 0000000000000..5974c7cad69ae --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ahb_wifi7.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_AHB_WIFI7_H +#define ATH12K_AHB_WIFI7_H + +#ifdef CONFIG_ATH12K_AHB +int ath12k_wifi7_ahb_init(void); +void ath12k_wifi7_ahb_exit(void); +#else +static inline int ath12k_wifi7_ahb_init(void) +{ + return 0; +} + +static inline void ath12k_wifi7_ahb_exit(void) {} +#endif +#endif /* ATH12K_AHB_WIFI7_H */ diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 7b02e0c8b1919..1842777b362e6 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -22,6 +22,7 @@ #include "pci.h" #include "wow.h" #include "pci_wifi7.h" +#include "ahb_wifi7.h" static int ahb_err, pci_err; unsigned int ath12k_debug_mask; @@ -2294,7 +2295,7 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, static int ath12k_init(void) { - ahb_err = ath12k_ahb_init(); + ahb_err = ath12k_wifi7_ahb_init(); if (ahb_err) pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err); @@ -2312,7 +2313,7 @@ static void ath12k_exit(void) ath12k_wifi7_pci_exit(); if (!ahb_err) - ath12k_ahb_exit(); + ath12k_wifi7_ahb_exit(); } module_init(ath12k_init); From 14af52040c95f79d48e04e5554687ef25e57a436 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:34 +0530 Subject: [PATCH 374/659] wifi: ath12k: Move Wi-Fi 7 specific init routines to dedicated file Move Wi-Fi 7 specific module initialization and exit routines from core.c to a new core_wifi7.c file. Decouple these routines from common module entry points to improve modularity. This restructuring is part of a broader effort to modularize the ATH12K driver by separating common logic from hardware family-specific implementations, improving maintainability and scalability. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-8-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/core.c | 32 -------------- drivers/net/wireless/ath/ath12k/core_wifi7.c | 44 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/core_wifi7.c diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 5c044e3963305..9c7a32930ed60 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause-Clear obj-$(CONFIG_ATH12K) += ath12k.o ath12k-y += core.o \ + core_wifi7.o \ hal.o \ hal_tx.o \ hal_rx.o \ diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 1842777b362e6..ce080071473c7 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -21,10 +21,7 @@ #include "hif.h" #include "pci.h" #include "wow.h" -#include "pci_wifi7.h" -#include "ahb_wifi7.h" -static int ahb_err, pci_err; unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); MODULE_PARM_DESC(debug_mask, "Debugging mask"); @@ -2292,32 +2289,3 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, kfree(ab); return NULL; } - -static int ath12k_init(void) -{ - ahb_err = ath12k_wifi7_ahb_init(); - if (ahb_err) - pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err); - - pci_err = ath12k_wifi7_pci_init(); - if (pci_err) - pr_warn("Failed to initialize ath12k PCI device: %d\n", pci_err); - - /* If both failed, return one of the failures (arbitrary) */ - return ahb_err && pci_err ? ahb_err : 0; -} - -static void ath12k_exit(void) -{ - if (!pci_err) - ath12k_wifi7_pci_exit(); - - if (!ahb_err) - ath12k_wifi7_ahb_exit(); -} - -module_init(ath12k_init); -module_exit(ath12k_exit); - -MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11be WLAN devices"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath12k/core_wifi7.c b/drivers/net/wireless/ath/ath12k/core_wifi7.c new file mode 100644 index 0000000000000..85ea8904672cb --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/core_wifi7.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include "ahb.h" +#include "pci.h" +#include "pci_wifi7.h" +#include "ahb_wifi7.h" + +static int ahb_err, pci_err; + +static int ath12k_wifi7_init(void) +{ + ahb_err = ath12k_wifi7_ahb_init(); + if (ahb_err) + pr_warn("Failed to initialize ath12k Wi-Fi 7 AHB device: %d\n", + ahb_err); + + pci_err = ath12k_wifi7_pci_init(); + if (pci_err) + pr_warn("Failed to initialize ath12k Wi-Fi 7 PCI device: %d\n", + pci_err); + + /* If both failed, return one of the failures (arbitrary) */ + return ahb_err && pci_err ? ahb_err : 0; +} + +static void ath12k_wifi7_exit(void) +{ + if (!pci_err) + ath12k_wifi7_pci_exit(); + + if (!ahb_err) + ath12k_wifi7_ahb_exit(); +} + +module_init(ath12k_wifi7_init); +module_exit(ath12k_wifi7_exit); + +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11be WLAN devices"); +MODULE_LICENSE("Dual BSD/GPL"); From c1dab401113a6323fddcdcc61388495e112a0578 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:35 +0530 Subject: [PATCH 375/659] wifi: ath12k: Move hw_init invocation to target-specific probe Relocate hw_init call from the shared probe path to target-specific probe implementations. Handle Wi-Fi 7 initialization entirely within its corresponding target-specific file. Improve modularity by decoupling hardware-dependent initialization from common probe logic. Support broader effort to separate shared and target-specific code paths. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-9-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb_wifi7.c | 8 ++++++++ drivers/net/wireless/ath/ath12k/core.c | 7 ------- drivers/net/wireless/ath/ath12k/hw.h | 2 -- drivers/net/wireless/ath/ath12k/hw_wifi7.c | 3 ++- drivers/net/wireless/ath/ath12k/hw_wifi7.h | 13 +++++++++++++ drivers/net/wireless/ath/ath12k/pci_wifi7.c | 8 ++++++++ 6 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/hw_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c index 7a869722b77e6..ff4f041bafbc4 100644 --- a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c @@ -11,6 +11,7 @@ #include "ahb_wifi7.h" #include "debug.h" #include "hif.h" +#include "hw_wifi7.h" static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", @@ -26,6 +27,7 @@ static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) struct ath12k_ahb *ab_ahb; enum ath12k_hw_rev hw_rev; struct ath12k_base *ab; + int ret; ab = platform_get_drvdata(pdev); ab_ahb = ath12k_ab_to_ahb(ab); @@ -42,6 +44,12 @@ static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; ab->hw_rev = hw_rev; + ret = ath12k_wifi7_hw_init(ab); + if (ret) { + ath12k_err(ab, "WiFi-7 hw_init for AHB failed: %d\n", ret); + return ret; + } + return 0; } diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index ce080071473c7..b4a8923d6d48d 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1742,13 +1742,6 @@ enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab) int ath12k_core_pre_init(struct ath12k_base *ab) { const struct ath12k_mem_profile_based_param *param; - int ret; - - ret = ath12k_hw_init(ab); - if (ret) { - ath12k_err(ab, "failed to init hw params: %d\n", ret); - return ret; - } param = &ath12k_mem_profile_based_param[ab->target_mem_mode]; ab->profile_param = param; diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 8ce11c3e6d5c2..35d6900720fee 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -377,6 +377,4 @@ static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type) return "unknown"; } -int ath12k_hw_init(struct ath12k_base *ab); - #endif diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.c b/drivers/net/wireless/ath/ath12k/hw_wifi7.c index f6177f8e032d9..5f5d3c57b288c 100644 --- a/drivers/net/wireless/ath/ath12k/hw_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/hw_wifi7.c @@ -13,6 +13,7 @@ #include "ce.h" #include "ce_wifi7.h" #include "hw.h" +#include "hw_wifi7.h" #include "mhi.h" #include "dp_rx.h" #include "peer.h" @@ -1030,7 +1031,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { }, }; -int ath12k_hw_init(struct ath12k_base *ab) +int ath12k_wifi7_hw_init(struct ath12k_base *ab) { const struct ath12k_hw_params *hw_params = NULL; int i; diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.h b/drivers/net/wireless/ath/ath12k/hw_wifi7.h new file mode 100644 index 0000000000000..643b6fdfdb66f --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/hw_wifi7.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_WIFI7_HW_H +#define ATH12K_WIFI7_HW_H + +struct ath12k_base; +int ath12k_wifi7_hw_init(struct ath12k_base *ab); + +#endif /* ATH12K_WIFI7_HW_H */ diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.c b/drivers/net/wireless/ath/ath12k/pci_wifi7.c index 8c7718153534c..a680cd9a04e33 100644 --- a/drivers/net/wireless/ath/ath12k/pci_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/pci_wifi7.c @@ -11,6 +11,7 @@ #include "core.h" #include "hif.h" #include "mhi.h" +#include "hw_wifi7.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 @@ -84,6 +85,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, u32 soc_hw_version_major, soc_hw_version_minor; struct ath12k_pci *ab_pci; struct ath12k_base *ab; + int ret; ab = pci_get_drvdata(pdev); if (!ab) @@ -143,6 +145,12 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return -EOPNOTSUPP; } + ret = ath12k_wifi7_hw_init(ab); + if (ret) { + dev_err(&pdev->dev, "WiFi-7 hw_init for PCI failed: %d\n", ret); + return ret; + } + return 0; } From e991219c12a4c98787146f3b95e86582e025184e Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:36 +0530 Subject: [PATCH 376/659] wifi: ath12k: Modularize driver into common and Wi-Fi 7 specific components Split the ath12k driver into two kernel modules: - ath12k.ko for shared logic across multiple targets - ath12k_wifi7.ko for Wi-Fi 7 specific configuration and routines The common module (ath12k.ko) must be loaded prior to any device-specific module, as the latter depends on exported symbols from the former. As part of this restructuring, Wi-Fi 7 specific files are moved into a dedicated `wifi7/` directory and built as a separate module. Common symbols are exported accordingly, with further adjustments planned in upcoming patches to support architecture-dependent separation. This modularization improves maintainability and scalability by enabling clean separation of hardware-specific logic from the shared driver core. +-----------------+ | | | ath12k.ko | | (common) | +---------------+ | | | | +-----------------+ | ath12k.ko | ===========> | | +------------------+ +---------------+ | | | ath12k_wifi7.ko | | (wifi7 family) | | | +------------------+ Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-10-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 11 ++++------- drivers/net/wireless/ath/ath12k/ahb.c | 2 ++ drivers/net/wireless/ath/ath12k/core.c | 5 +++++ drivers/net/wireless/ath/ath12k/debug.c | 4 ++++ drivers/net/wireless/ath/ath12k/dp_rx.c | 3 +++ drivers/net/wireless/ath/ath12k/hal.c | 4 ++++ drivers/net/wireless/ath/ath12k/htc.c | 2 ++ drivers/net/wireless/ath/ath12k/pci.c | 3 +++ drivers/net/wireless/ath/ath12k/peer.c | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/Makefile | 10 ++++++++++ .../ath/ath12k/{ahb_wifi7.c => wifi7/ahb.c} | 8 ++++---- .../ath/ath12k/{ahb_wifi7.h => wifi7/ahb.h} | 0 .../ath/ath12k/{ce_wifi7.c => wifi7/ce.c} | 6 +++--- .../ath/ath12k/{ce_wifi7.h => wifi7/ce.h} | 0 .../ath/ath12k/{core_wifi7.c => wifi7/core.c} | 6 +++--- .../ath/ath12k/{hw_wifi7.c => wifi7/hw.c} | 16 ++++++++-------- .../ath/ath12k/{hw_wifi7.h => wifi7/hw.h} | 0 .../ath/ath12k/{mhi_wifi7.c => wifi7/mhi.c} | 2 +- .../ath/ath12k/{mhi_wifi7.h => wifi7/mhi.h} | 0 .../ath/ath12k/{pci_wifi7.c => wifi7/pci.c} | 10 +++++----- .../ath/ath12k/{pci_wifi7.h => wifi7/pci.h} | 0 .../ath/ath12k/{wmi_wifi7.c => wifi7/wmi.c} | 4 ++-- .../ath/ath12k/{wmi_wifi7.h => wifi7/wmi.h} | 0 23 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/Makefile rename drivers/net/wireless/ath/ath12k/{ahb_wifi7.c => wifi7/ahb.c} (95%) rename drivers/net/wireless/ath/ath12k/{ahb_wifi7.h => wifi7/ahb.h} (100%) rename drivers/net/wireless/ath/ath12k/{ce_wifi7.c => wifi7/ce.c} (99%) rename drivers/net/wireless/ath/ath12k/{ce_wifi7.h => wifi7/ce.h} (100%) rename drivers/net/wireless/ath/ath12k/{core_wifi7.c => wifi7/core.c} (95%) rename drivers/net/wireless/ath/ath12k/{hw_wifi7.c => wifi7/hw.c} (99%) rename drivers/net/wireless/ath/ath12k/{hw_wifi7.h => wifi7/hw.h} (100%) rename drivers/net/wireless/ath/ath12k/{mhi_wifi7.c => wifi7/mhi.c} (99%) rename drivers/net/wireless/ath/ath12k/{mhi_wifi7.h => wifi7/mhi.h} (100%) rename drivers/net/wireless/ath/ath12k/{pci_wifi7.c => wifi7/pci.c} (97%) rename drivers/net/wireless/ath/ath12k/{pci_wifi7.h => wifi7/pci.h} (100%) rename drivers/net/wireless/ath/ath12k/{wmi_wifi7.c => wifi7/wmi.c} (99%) rename drivers/net/wireless/ath/ath12k/{wmi_wifi7.h => wifi7/wmi.h} (100%) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 9c7a32930ed60..8dd77729f52f5 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -1,12 +1,10 @@ # SPDX-License-Identifier: BSD-3-Clause-Clear obj-$(CONFIG_ATH12K) += ath12k.o ath12k-y += core.o \ - core_wifi7.o \ hal.o \ hal_tx.o \ hal_rx.o \ wmi.o \ - wmi_wifi7.o \ mac.o \ reg.o \ htc.o \ @@ -16,19 +14,18 @@ ath12k-y += core.o \ dp_rx.o \ debug.o \ ce.o \ - ce_wifi7.o \ peer.o \ dbring.o \ - hw_wifi7.o \ mhi.o \ - mhi_wifi7.o \ pci.o \ - pci_wifi7.o \ dp_mon.o \ fw.o \ p2p.o -ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ahb_wifi7.o +ath12k-$(CONFIG_ATH12K_AHB) += ahb.o + +obj-$(CONFIG_ATH12K) += wifi7/ + ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ath12k-$(CONFIG_ACPI) += acpi.o ath12k-$(CONFIG_ATH12K_TRACING) += trace.o diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 777edaf0e58e5..5fe2b5b7db499 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -1183,6 +1183,7 @@ int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, return platform_driver_register(ahb_driver); } +EXPORT_SYMBOL(ath12k_ahb_register_driver); void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id) { @@ -1198,3 +1199,4 @@ void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id) platform_driver_unregister(ahb_driver); ath12k_ahb_family_drivers[device_id] = NULL; } +EXPORT_SYMBOL(ath12k_ahb_unregister_driver); diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index b4a8923d6d48d..301d1337ab8bd 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -631,6 +631,7 @@ u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab) { return ath12k_core_get_max_station_per_radio(ab) + TARGET_NUM_VDEVS(ab); } +EXPORT_SYMBOL(ath12k_core_get_max_peers_per_radio); struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab, int index) @@ -1738,6 +1739,7 @@ enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab) return ATH12K_QMI_MEMORY_MODE_DEFAULT; } +EXPORT_SYMBOL(ath12k_core_get_memory_mode); int ath12k_core_pre_init(struct ath12k_base *ab) { @@ -2282,3 +2284,6 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, kfree(ab); return NULL; } + +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies WLAN devices"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c index 5ce100cd9a9d1..9910c60f30ced 100644 --- a/drivers/net/wireless/ath/ath12k/debug.c +++ b/drivers/net/wireless/ath/ath12k/debug.c @@ -21,6 +21,7 @@ void ath12k_info(struct ath12k_base *ab, const char *fmt, ...) /* TODO: Trace the log */ va_end(args); } +EXPORT_SYMBOL(ath12k_info); void ath12k_err(struct ath12k_base *ab, const char *fmt, ...) { @@ -35,6 +36,7 @@ void ath12k_err(struct ath12k_base *ab, const char *fmt, ...) /* TODO: Trace the log */ va_end(args); } +EXPORT_SYMBOL(ath12k_err); void __ath12k_warn(struct device *dev, const char *fmt, ...) { @@ -49,6 +51,7 @@ void __ath12k_warn(struct device *dev, const char *fmt, ...) /* TODO: Trace the log */ va_end(args); } +EXPORT_SYMBOL(__ath12k_warn); #ifdef CONFIG_ATH12K_DEBUG @@ -72,6 +75,7 @@ void __ath12k_dbg(struct ath12k_base *ab, enum ath12k_debug_mask mask, va_end(args); } +EXPORT_SYMBOL(__ath12k_dbg); void ath12k_dbg_dump(struct ath12k_base *ab, enum ath12k_debug_mask mask, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index d28d8ffec0f83..cd07bb5b8e9a4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -2007,6 +2007,7 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, dev_kfree_skb_any(skb); } +EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, struct sk_buff_head *msdu_list, @@ -4563,6 +4564,7 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) return ret; } +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) { @@ -4605,6 +4607,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 6406fcf5d69fd..022eea9515efd 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -746,6 +746,7 @@ const struct hal_rx_ops hal_rx_qcn9274_ops = { .rx_desc_get_desc_size = ath12k_hw_qcn9274_get_rx_desc_size, .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_rx_desc_get_msdu_src_link, }; +EXPORT_SYMBOL(hal_rx_qcn9274_ops); static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { @@ -1093,6 +1094,7 @@ const struct hal_ops hal_qcn9274_ops = { .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, .get_hal_rx_compact_ops = ath12k_hal_qcn9274_get_hal_rx_compact_ops, }; +EXPORT_SYMBOL(hal_qcn9274_ops); static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { @@ -1552,6 +1554,7 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_desc_size = ath12k_hw_wcn7850_get_rx_desc_size, .rx_desc_get_msdu_src_link_id = ath12k_hw_wcn7850_rx_desc_get_msdu_src_link, }; +EXPORT_SYMBOL(hal_rx_wcn7850_ops); const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, @@ -1560,6 +1563,7 @@ const struct hal_ops hal_wcn7850_ops = { .rxdma_ring_wmask_rx_msdu_end = NULL, .get_hal_rx_compact_ops = NULL, }; +EXPORT_SYMBOL(hal_wcn7850_ops); static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/htc.c b/drivers/net/wireless/ath/ath12k/htc.c index d13616bf07f43..fe8218a56125b 100644 --- a/drivers/net/wireless/ath/ath12k/htc.c +++ b/drivers/net/wireless/ath/ath12k/htc.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include #include @@ -376,6 +377,7 @@ void ath12k_htc_rx_completion_handler(struct ath12k_base *ab, out: kfree_skb(skb); } +EXPORT_SYMBOL(ath12k_htc_rx_completion_handler); static void ath12k_htc_control_rx_complete(struct ath12k_base *ab, struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 3e119cc329de2..7b9853f5c7b08 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1193,6 +1193,7 @@ u32 ath12k_pci_read32(struct ath12k_base *ab, u32 offset) ab_pci->pci_ops->release(ab); return val; } +EXPORT_SYMBOL(ath12k_pci_read32); void ath12k_pci_write32(struct ath12k_base *ab, u32 offset, u32 value) { @@ -1813,6 +1814,7 @@ int ath12k_pci_register_driver(const enum ath12k_device_family device_id, return pci_register_driver(pci_driver); } +EXPORT_SYMBOL(ath12k_pci_register_driver); void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) { @@ -1823,6 +1825,7 @@ void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) pci_unregister_driver(&ath12k_pci_family_drivers[device_id]->driver); ath12k_pci_family_drivers[device_id] = NULL; } +EXPORT_SYMBOL(ath12k_pci_unregister_driver); /* firmware files */ MODULE_FIRMWARE(ATH12K_FW_DIR "/QCN9274/hw2.0/*"); diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index f1ae9e5b5af72..af95324f27086 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -23,6 +23,7 @@ struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) return NULL; } +EXPORT_SYMBOL(ath12k_peer_ml_find); struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, const u8 *addr) @@ -78,6 +79,7 @@ struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, return NULL; } +EXPORT_SYMBOL(ath12k_peer_find_by_addr); static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile new file mode 100644 index 0000000000000..872ca620a5c50 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause-Clear +obj-$(CONFIG_ATH12K) += ath12k_wifi7.o +ath12k_wifi7-y += core.o \ + pci.o \ + wmi.o \ + mhi.o \ + ce.o \ + hw.o + +ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c similarity index 95% rename from drivers/net/wireless/ath/ath12k/ahb_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/ahb.c index ff4f041bafbc4..803e13207bc06 100644 --- a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c @@ -7,11 +7,11 @@ #include #include #include +#include "../ahb.h" #include "ahb.h" -#include "ahb_wifi7.h" -#include "debug.h" -#include "hif.h" -#include "hw_wifi7.h" +#include "../debug.h" +#include "../hif.h" +#include "hw.h" static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/ahb.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/ahb_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/ahb.h diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/ce.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/ce_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/ce.c index cf27259d15a0e..b4bd1136c2565 100644 --- a/drivers/net/wireless/ath/ath12k/ce_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ce.c @@ -8,10 +8,10 @@ #include #include -#include "core.h" +#include "../core.h" +#include "../ce.h" #include "ce.h" -#include "ce_wifi7.h" -#include "dp_rx.h" +#include "../dp_rx.h" /* Copy Engine (CE) configs for QCN9274 */ /* Target firmware's Copy Engine configuration. */ diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/ce.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/ce_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/ce.h diff --git a/drivers/net/wireless/ath/ath12k/core_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/core.c similarity index 95% rename from drivers/net/wireless/ath/ath12k/core_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/core.c index 85ea8904672cb..eb882e56e5ec2 100644 --- a/drivers/net/wireless/ath/ath12k/core_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/core.c @@ -5,10 +5,10 @@ */ #include -#include "ahb.h" +#include "../ahb.h" +#include "../pci.h" #include "pci.h" -#include "pci_wifi7.h" -#include "ahb_wifi7.h" +#include "ahb.h" static int ahb_err, pci_err; diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/hw_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/hw.c index 5f5d3c57b288c..93f558847baed 100644 --- a/drivers/net/wireless/ath/ath12k/hw_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -8,17 +8,17 @@ #include #include -#include "debug.h" -#include "core.h" +#include "../debug.h" +#include "../core.h" +#include "../ce.h" #include "ce.h" -#include "ce_wifi7.h" +#include "../hw.h" #include "hw.h" -#include "hw_wifi7.h" +#include "../mhi.h" #include "mhi.h" -#include "dp_rx.h" -#include "peer.h" -#include "wmi_wifi7.h" -#include "mhi_wifi7.h" +#include "../dp_rx.h" +#include "../peer.h" +#include "wmi.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/hw.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/hw_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/hw.h diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/mhi_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/mhi.c index be74df152f6f8..74d5f09645311 100644 --- a/drivers/net/wireless/ath/ath12k/mhi_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c @@ -4,8 +4,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ +#include "../mhi.h" #include "mhi.h" -#include "mhi_wifi7.h" static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { { diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/mhi.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/mhi_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/mhi.h diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c similarity index 97% rename from drivers/net/wireless/ath/ath12k/pci_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/pci.c index a680cd9a04e33..01a0b42f0e808 100644 --- a/drivers/net/wireless/ath/ath12k/pci_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -6,12 +6,12 @@ #include +#include "../pci.h" #include "pci.h" -#include "pci_wifi7.h" -#include "core.h" -#include "hif.h" -#include "mhi.h" -#include "hw_wifi7.h" +#include "../core.h" +#include "../hif.h" +#include "../mhi.h" +#include "hw.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/pci.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/pci_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/pci.h diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/wmi_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/wmi.c index f27fa56210e83..652c353f9fc58 100644 --- a/drivers/net/wireless/ath/ath12k/wmi_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c @@ -4,8 +4,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "core.h" -#include "wmi_wifi7.h" +#include "../core.h" +#include "wmi.h" void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, struct ath12k_wmi_resource_config_arg *config) diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/wmi.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/wmi_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/wmi.h From 6b70a470a6f3c318553e3a099894ae1cb405fb52 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:37 +0530 Subject: [PATCH 377/659] wifi: ath12k: Rename ath12k_* symbols to ath12k_wifi7_* for clarity Rename functions and global definitions from ath12k_* to ath12k_wifi7_* to reflect their association with the Wi-Fi 7 specific module. Align symbol naming with recent relocation of components into the ath12k/wifi7 directory. This change improves code clarity and supports the modularization effort that separates common and hardware-specific logic into distinct modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-11-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/ce.c | 21 +-- drivers/net/wireless/ath/ath12k/wifi7/ce.h | 18 +-- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 150 +++++++++++--------- drivers/net/wireless/ath/ath12k/wifi7/mhi.c | 28 ++-- drivers/net/wireless/ath/ath12k/wifi7/mhi.h | 4 +- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 13 +- drivers/net/wireless/ath/ath12k/wifi7/wmi.c | 8 +- drivers/net/wireless/ath/ath12k/wifi7/wmi.h | 8 +- 8 files changed, 132 insertions(+), 118 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ce.c b/drivers/net/wireless/ath/ath12k/wifi7/ce.c index b4bd1136c2565..952d6c39c3334 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ce.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ce.c @@ -15,7 +15,7 @@ /* Copy Engine (CE) configs for QCN9274 */ /* Target firmware's Copy Engine configuration. */ -const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { +const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_qcn9274[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), @@ -148,7 +148,8 @@ const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { * PIPEDIR_OUT = UL = host -> target * PIPEDIR_IN = DL = target -> host */ -const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { +const struct service_to_pipe +ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), @@ -259,7 +260,7 @@ const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { }, }; -const struct ce_attr ath12k_host_ce_config_qcn9274[] = { +const struct ce_attr ath12k_wifi7_host_ce_config_qcn9274[] = { /* CE0: host->target HTC control and raw streams */ { .flags = CE_ATTR_FLAGS, @@ -395,7 +396,7 @@ const struct ce_attr ath12k_host_ce_config_qcn9274[] = { /* Copy Engine (CE) configs for WCN7850 */ /* Target firmware's Copy Engine configuration. */ -const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { +const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_wcn7850[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), @@ -488,7 +489,8 @@ const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { /* CE 9, 10, 11 are used by MHI driver */ }; -const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { +const struct service_to_pipe +ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), @@ -569,7 +571,7 @@ const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { }, }; -const struct ce_attr ath12k_host_ce_config_wcn7850[] = { +const struct ce_attr ath12k_wifi7_host_ce_config_wcn7850[] = { /* CE0: host->target HTC control and raw streams */ { .flags = CE_ATTR_FLAGS, @@ -647,7 +649,7 @@ const struct ce_attr ath12k_host_ce_config_wcn7850[] = { /* Copy Engine (CE) configs for IPQ5332 */ /* Target firmware's Copy Engine configuration. */ -const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { +const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_ipq5332[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), @@ -768,7 +770,8 @@ const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { }, }; -const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { +const struct service_to_pipe +ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), @@ -868,7 +871,7 @@ const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { }, }; -const struct ce_attr ath12k_host_ce_config_ipq5332[] = { +const struct ce_attr ath12k_wifi7_host_ce_config_ipq5332[] = { /* CE0: host->target HTC control and raw streams */ { .flags = CE_ATTR_FLAGS, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ce.h b/drivers/net/wireless/ath/ath12k/wifi7/ce.h index 1e211e8c24672..369a14472913b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ce.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/ce.h @@ -7,16 +7,16 @@ #ifndef ATH12K_WIFI7_CE_H #define ATH12K_WIFI7_CE_H -extern const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[]; -extern const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[]; -extern const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[]; +extern const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_qcn9274[]; +extern const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_wcn7850[]; +extern const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_ipq5332[]; -extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[]; -extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[]; -extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[]; +extern const struct service_to_pipe ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274[]; +extern const struct service_to_pipe ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850[]; +extern const struct service_to_pipe ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332[]; -extern const struct ce_attr ath12k_host_ce_config_qcn9274[]; -extern const struct ce_attr ath12k_host_ce_config_wcn7850[]; -extern const struct ce_attr ath12k_host_ce_config_ipq5332[]; +extern const struct ce_attr ath12k_wifi7_host_ce_config_qcn9274[]; +extern const struct ce_attr ath12k_wifi7_host_ce_config_wcn7850[]; +extern const struct ce_attr ath12k_wifi7_host_ce_config_ipq5332[]; #endif /* ATH12K_WIFI7_CE_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 93f558847baed..9995eccd32d39 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -24,29 +24,31 @@ static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, 0xac, 0x12, 0x00, 0x03); -static u8 ath12k_hw_qcn9274_mac_from_pdev_id(int pdev_idx) +static u8 ath12k_wifi7_hw_qcn9274_mac_from_pdev_id(int pdev_idx) { return pdev_idx; } -static int ath12k_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params *hw, + int mac_id) { return mac_id; } -static int ath12k_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw, + int mac_id) { return 0; } -static u8 ath12k_hw_get_ring_selector_qcn9274(struct sk_buff *skb) +static u8 ath12k_wifi7_hw_get_ring_selector_qcn9274(struct sk_buff *skb) { return smp_processor_id(); } -static bool ath12k_dp_srng_is_comp_ring_qcn9274(int ring_num) +static bool ath12k_wifi7_dp_srng_is_comp_ring_qcn9274(int ring_num) { if (ring_num < 3 || ring_num == 4) return true; @@ -54,30 +56,33 @@ static bool ath12k_dp_srng_is_comp_ring_qcn9274(int ring_num) return false; } -static bool ath12k_is_frame_link_agnostic_qcn9274(struct ath12k_link_vif *arvif, - struct ieee80211_mgmt *mgmt) +static bool +ath12k_wifi7_is_frame_link_agnostic_qcn9274(struct ath12k_link_vif *arvif, + struct ieee80211_mgmt *mgmt) { return ieee80211_is_action(mgmt->frame_control); } -static int ath12k_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw, + int mac_id) { return 0; } -static int ath12k_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params *hw, + int mac_id) { return mac_id; } -static u8 ath12k_hw_get_ring_selector_wcn7850(struct sk_buff *skb) +static u8 ath12k_wifi7_hw_get_ring_selector_wcn7850(struct sk_buff *skb) { return skb_get_queue_mapping(skb); } -static bool ath12k_dp_srng_is_comp_ring_wcn7850(int ring_num) +static bool ath12k_wifi7_dp_srng_is_comp_ring_wcn7850(int ring_num) { if (ring_num == 0 || ring_num == 2 || ring_num == 4) return true; @@ -99,8 +104,9 @@ static bool ath12k_is_addba_resp_action_code(struct ieee80211_mgmt *mgmt) return true; } -static bool ath12k_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, - struct ieee80211_mgmt *mgmt) +static bool +ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, + struct ieee80211_mgmt *mgmt) { struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar); @@ -132,23 +138,23 @@ static bool ath12k_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, } static const struct ath12k_hw_ops qcn9274_ops = { - .get_hw_mac_from_pdev_id = ath12k_hw_qcn9274_mac_from_pdev_id, - .mac_id_to_pdev_id = ath12k_hw_mac_id_to_pdev_id_qcn9274, - .mac_id_to_srng_id = ath12k_hw_mac_id_to_srng_id_qcn9274, + .get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id, + .mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274, + .mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274, .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcn9274, - .get_ring_selector = ath12k_hw_get_ring_selector_qcn9274, - .dp_srng_is_tx_comp_ring = ath12k_dp_srng_is_comp_ring_qcn9274, - .is_frame_link_agnostic = ath12k_is_frame_link_agnostic_qcn9274, + .get_ring_selector = ath12k_wifi7_hw_get_ring_selector_qcn9274, + .dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_qcn9274, + .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_qcn9274, }; static const struct ath12k_hw_ops wcn7850_ops = { - .get_hw_mac_from_pdev_id = ath12k_hw_qcn9274_mac_from_pdev_id, - .mac_id_to_pdev_id = ath12k_hw_mac_id_to_pdev_id_wcn7850, - .mac_id_to_srng_id = ath12k_hw_mac_id_to_srng_id_wcn7850, + .get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id, + .mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850, + .mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850, .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_wcn7850, - .get_ring_selector = ath12k_hw_get_ring_selector_wcn7850, - .dp_srng_is_tx_comp_ring = ath12k_dp_srng_is_comp_ring_wcn7850, - .is_frame_link_agnostic = ath12k_is_frame_link_agnostic_wcn7850, + .get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850, + .dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850, + .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850, }; #define ATH12K_TX_RING_MASK_0 0x1 @@ -181,7 +187,7 @@ static const struct ath12k_hw_ops wcn7850_ops = { #define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2 #define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4 -static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { +static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_qcn9274 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, @@ -223,7 +229,7 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { }, }; -static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq5332 = { +static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_ipq5332 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, @@ -263,7 +269,7 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq5332 = { }, }; -static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = { +static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, @@ -654,7 +660,7 @@ static const struct ath12k_hw_regs wcn7850_regs = { .gcc_gcc_pcie_hot_rst = 0x1e40304, }; -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { +static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_qcn9274 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | @@ -663,7 +669,7 @@ static const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { +static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_wcn7850 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | @@ -671,7 +677,7 @@ static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { +static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_ipq5332 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | @@ -680,18 +686,18 @@ static const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static const struct ce_ie_addr ath12k_ce_ie_addr_ipq5332 = { +static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = { .ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, .ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, .ie3_reg_addr = CE_HOST_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, }; -static const struct ce_remap ath12k_ce_remap_ipq5332 = { +static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = { .base = HAL_IPQ5332_CE_WFSS_REG_BASE, .size = HAL_IPQ5332_CE_SIZE, }; -static const struct ath12k_hw_params ath12k_hw_params[] = { +static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { { .name = "qcn9274 hw1.0", .hw_rev = ATH12K_HW_QCN9274_HW10, @@ -707,17 +713,18 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, - .ring_mask = &ath12k_hw_ring_mask_qcn9274, + .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, .regs = &qcn9274_v1_regs, - .host_ce_config = ath12k_host_ce_config_qcn9274, + .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, - .target_ce_config = ath12k_target_ce_config_wlan_qcn9274, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274, .target_ce_count = 12, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9274, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_hw_hal_params_qcn9274, + .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, .rxdma1_enable = false, .num_rxdma_per_pdev = 1, @@ -741,9 +748,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 48, .max_tx_ring = 4, - .mhi_config = &ath12k_mhi_config_qcn9274, + .mhi_config = &ath12k_wifi7_mhi_config_qcn9274, - .wmi_init = ath12k_wmi_init_qcn9274, + .wmi_init = ath12k_wifi7_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, @@ -794,17 +801,18 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .internal_sleep_clock = true, .hw_ops = &wcn7850_ops, - .ring_mask = &ath12k_hw_ring_mask_wcn7850, + .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, .regs = &wcn7850_regs, - .host_ce_config = ath12k_host_ce_config_wcn7850, + .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, .ce_count = 9, - .target_ce_config = ath12k_target_ce_config_wlan_wcn7850, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850, .target_ce_count = 9, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_wcn7850, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850, .svc_to_ce_map_len = 14, - .hal_params = &ath12k_hw_hal_params_wcn7850, + .hal_params = &ath12k_wifi7_hw_hal_params_wcn7850, .rxdma1_enable = false, .num_rxdma_per_pdev = 2, @@ -829,9 +837,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 7, .max_tx_ring = 3, - .mhi_config = &ath12k_mhi_config_wcn7850, + .mhi_config = &ath12k_wifi7_mhi_config_wcn7850, - .wmi_init = ath12k_wmi_init_wcn7850, + .wmi_init = ath12k_wifi7_wmi_init_wcn7850, .hal_ops = &hal_wcn7850_ops, @@ -881,17 +889,18 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, - .ring_mask = &ath12k_hw_ring_mask_qcn9274, + .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, .regs = &qcn9274_v2_regs, - .host_ce_config = ath12k_host_ce_config_qcn9274, + .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, - .target_ce_config = ath12k_target_ce_config_wlan_qcn9274, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274, .target_ce_count = 12, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9274, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_hw_hal_params_qcn9274, + .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, .rxdma1_enable = true, .num_rxdma_per_pdev = 1, @@ -915,9 +924,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 48, .max_tx_ring = 4, - .mhi_config = &ath12k_mhi_config_qcn9274, + .mhi_config = &ath12k_wifi7_mhi_config_qcn9274, - .wmi_init = ath12k_wmi_init_qcn9274, + .wmi_init = ath12k_wifi7_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, @@ -967,16 +976,17 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .hw_ops = &qcn9274_ops, .regs = &ipq5332_regs, - .ring_mask = &ath12k_hw_ring_mask_ipq5332, + .ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332, - .host_ce_config = ath12k_host_ce_config_ipq5332, + .host_ce_config = ath12k_wifi7_host_ce_config_ipq5332, .ce_count = 12, - .target_ce_config = ath12k_target_ce_config_wlan_ipq5332, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332, .target_ce_count = 12, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_ipq5332, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_hw_hal_params_ipq5332, + .hal_params = &ath12k_wifi7_hw_hal_params_ipq5332, .rxdma1_enable = false, .num_rxdma_per_pdev = 1, @@ -999,7 +1009,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 48, .max_tx_ring = 4, - .wmi_init = &ath12k_wmi_init_qcn9274, + .wmi_init = &ath12k_wifi7_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, @@ -1023,8 +1033,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .iova_mask = 0, .supports_aspm = false, - .ce_ie_addr = &ath12k_ce_ie_addr_ipq5332, - .ce_remap = &ath12k_ce_remap_ipq5332, + .ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5332, + .ce_remap = &ath12k_wifi7_ce_remap_ipq5332, .bdf_addr_offset = 0xC00000, .dp_primary_link_only = true, @@ -1036,14 +1046,14 @@ int ath12k_wifi7_hw_init(struct ath12k_base *ab) const struct ath12k_hw_params *hw_params = NULL; int i; - for (i = 0; i < ARRAY_SIZE(ath12k_hw_params); i++) { - hw_params = &ath12k_hw_params[i]; + for (i = 0; i < ARRAY_SIZE(ath12k_wifi7_hw_params); i++) { + hw_params = &ath12k_wifi7_hw_params[i]; if (hw_params->hw_rev == ab->hw_rev) break; } - if (i == ARRAY_SIZE(ath12k_hw_params)) { + if (i == ARRAY_SIZE(ath12k_wifi7_hw_params)) { ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n", ab->hw_rev); return -EINVAL; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/mhi.c b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c index 74d5f09645311..b8d972659314b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/mhi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c @@ -7,7 +7,7 @@ #include "../mhi.h" #include "mhi.h" -static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { +static const struct mhi_channel_config ath12k_wifi7_mhi_channels_qcn9274[] = { { .num = 20, .name = "IPCR", @@ -38,7 +38,7 @@ static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { }, }; -static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { +static struct mhi_event_config ath12k_wifi7_mhi_events_qcn9274[] = { { .num_elements = 32, .irq_moderation_ms = 0, @@ -61,18 +61,18 @@ static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { }, }; -const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { +const struct mhi_controller_config ath12k_wifi7_mhi_config_qcn9274 = { .max_channels = 30, .timeout_ms = 10000, .use_bounce_buf = false, .buf_len = 0, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), - .ch_cfg = ath12k_mhi_channels_qcn9274, - .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), - .event_cfg = ath12k_mhi_events_qcn9274, + .num_channels = ARRAY_SIZE(ath12k_wifi7_mhi_channels_qcn9274), + .ch_cfg = ath12k_wifi7_mhi_channels_qcn9274, + .num_events = ARRAY_SIZE(ath12k_wifi7_mhi_events_qcn9274), + .event_cfg = ath12k_wifi7_mhi_events_qcn9274, }; -static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { +static const struct mhi_channel_config ath12k_wifi7_mhi_channels_wcn7850[] = { { .num = 20, .name = "IPCR", @@ -103,7 +103,7 @@ static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { }, }; -static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { +static struct mhi_event_config ath12k_wifi7_mhi_events_wcn7850[] = { { .num_elements = 32, .irq_moderation_ms = 0, @@ -126,13 +126,13 @@ static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { }, }; -const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { +const struct mhi_controller_config ath12k_wifi7_mhi_config_wcn7850 = { .max_channels = 128, .timeout_ms = 2000, .use_bounce_buf = false, .buf_len = 8192, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), - .ch_cfg = ath12k_mhi_channels_wcn7850, - .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), - .event_cfg = ath12k_mhi_events_wcn7850, + .num_channels = ARRAY_SIZE(ath12k_wifi7_mhi_channels_wcn7850), + .ch_cfg = ath12k_wifi7_mhi_channels_wcn7850, + .num_events = ARRAY_SIZE(ath12k_wifi7_mhi_events_wcn7850), + .event_cfg = ath12k_wifi7_mhi_events_wcn7850, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/mhi.h b/drivers/net/wireless/ath/ath12k/wifi7/mhi.h index 8417a2bde0877..2e2dd3503d830 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/mhi.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.h @@ -6,6 +6,6 @@ #ifndef _ATH12K_WIFI7_MHI_H #define _ATH12K_WIFI7_MHI_H -extern const struct mhi_controller_config ath12k_mhi_config_qcn9274; -extern const struct mhi_controller_config ath12k_mhi_config_wcn7850; +extern const struct mhi_controller_config ath12k_wifi7_mhi_config_qcn9274; +extern const struct mhi_controller_config ath12k_wifi7_mhi_config_wcn7850; #endif /* _ATH12K_WIFI7_MHI_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 01a0b42f0e808..608669a83ea75 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -12,6 +12,7 @@ #include "../hif.h" #include "../mhi.h" #include "hw.h" +#include "../hal.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 @@ -44,7 +45,7 @@ static const struct ath12k_msi_config ath12k_wifi7_msi_config[] = { }, }; -static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = { +static const struct ath12k_pci_ops ath12k_wifi7_pci_ops_qcn9274 = { .wakeup = NULL, .release = NULL, }; @@ -63,7 +64,7 @@ static void ath12k_wifi7_pci_bus_release(struct ath12k_base *ab) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); } -static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = { +static const struct ath12k_pci_ops ath12k_wifi7_pci_ops_wcn7850 = { .wakeup = ath12k_wifi7_pci_bus_wake_up, .release = ath12k_wifi7_pci_bus_release, }; @@ -99,7 +100,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, case QCN9274_DEVICE_ID: ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; - ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; + ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; ab->hal_rx_ops = &hal_rx_qcn9274_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); @@ -122,7 +123,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = false; - ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; + ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; ab->hal_rx_ops = &hal_rx_wcn7850_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); @@ -154,7 +155,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return 0; } -static struct ath12k_pci_driver ath12k_pci_wifi7_driver = { +static struct ath12k_pci_driver ath12k_wifi7_pci_driver = { .name = "ath12k_wifi7_pci", .id_table = ath12k_wifi7_pci_id_table, .ops.probe = ath12k_wifi7_pci_probe, @@ -165,7 +166,7 @@ int ath12k_wifi7_pci_init(void) int ret; ret = ath12k_pci_register_driver(ATH12K_DEVICE_FAMILY_WIFI7, - &ath12k_pci_wifi7_driver); + &ath12k_wifi7_pci_driver); if (ret) { pr_err("Failed to register ath12k Wi-Fi 7 driver: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c index 652c353f9fc58..c575b44a33f3b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c @@ -7,8 +7,8 @@ #include "../core.h" #include "wmi.h" -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) +void ath12k_wifi7_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) { config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS(ab); config->num_peers = ab->num_radios * @@ -58,8 +58,8 @@ void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, config->peer_metadata_ver = ATH12K_PEER_METADATA_V1B; } -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) +void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) { config->num_vdevs = 4; config->num_peers = 16; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/wmi.h b/drivers/net/wireless/ath/ath12k/wifi7/wmi.h index 1514e3e8d4cb6..ae74e176fa2d3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.h @@ -7,9 +7,9 @@ #ifndef ATH12K_WMI_WIFI7_H #define ATH12K_WMI_WIFI7_H -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); +void ath12k_wifi7_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); +void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); #endif From 18a788869ce02ad6e82d1cd27834986a05df6636 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:38 +0530 Subject: [PATCH 378/659] wifi: ath12k: Remove HAL defines from shared PCI code Eliminate use of HAL-specific defines in the shared PCI implementation. Pass required register offsets during PCI registration and store them in the PCI context structure. Access offsets directly from the context to improve modularity and remove hardware-specific dependencies in the common code path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-12-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 12 ++++++++---- drivers/net/wireless/ath/ath12k/pci.h | 7 +++++++ drivers/net/wireless/ath/ath12k/wifi7/pci.c | 6 ++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 7b9853f5c7b08..de88ba70bf23b 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -132,10 +132,12 @@ static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset) static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci) { - u32 umac_window = u32_get_bits(HAL_SEQ_WCSS_UMAC_OFFSET, WINDOW_VALUE_MASK); - u32 ce_window = u32_get_bits(HAL_CE_WFSS_CE_REG_BASE, WINDOW_VALUE_MASK); + u32 umac_window; + u32 ce_window; u32 window; + umac_window = u32_get_bits(ab_pci->reg_base->umac_base, WINDOW_VALUE_MASK); + ce_window = u32_get_bits(ab_pci->reg_base->ce_reg_base, WINDOW_VALUE_MASK); window = (umac_window << 12) | (ce_window << 6); spin_lock_bh(&ab_pci->window_lock); @@ -148,13 +150,14 @@ static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci) static u32 ath12k_pci_get_window_start(struct ath12k_base *ab, u32 offset) { + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); u32 window_start; /* If offset lies within DP register range, use 3rd window */ - if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK) + if ((offset ^ ab_pci->reg_base->umac_base) < WINDOW_RANGE_MASK) window_start = 3 * WINDOW_START; /* If offset lies within CE register range, use 2nd window */ - else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) + else if ((offset ^ ab_pci->reg_base->ce_reg_base) < WINDOW_RANGE_MASK) window_start = 2 * WINDOW_START; else window_start = WINDOW_START; @@ -1571,6 +1574,7 @@ static int ath12k_pci_probe(struct pci_dev *pdev, ath12k_dbg(ab, ATH12K_DBG_PCI, "PCI device family id: %d\n", device_id); ab_pci->device_family_ops = &ath12k_pci_family_drivers[device_id]->ops; + ab_pci->reg_base = ath12k_pci_family_drivers[device_id]->reg_base; /* Call device specific probe. This is the callback that can * be used to override any ops in future diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 1b7ecc329a017..5af33e5deacfd 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -99,6 +99,11 @@ struct ath12k_pci_device_family_ops { int (*probe)(struct pci_dev *pdev, const struct pci_device_id *pci_dev); }; +struct ath12k_pci_reg_base { + u32 umac_base; + u32 ce_reg_base; +}; + struct ath12k_pci { struct pci_dev *pdev; struct ath12k_base *ab; @@ -122,6 +127,7 @@ struct ath12k_pci { u32 qmi_instance; u64 dma_mask; const struct ath12k_pci_device_family_ops *device_family_ops; + const struct ath12k_pci_reg_base *reg_base; }; struct ath12k_pci_driver { @@ -129,6 +135,7 @@ struct ath12k_pci_driver { const struct pci_device_id *id_table; struct ath12k_pci_device_family_ops ops; struct pci_driver driver; + const struct ath12k_pci_reg_base *reg_base; }; static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 608669a83ea75..9b1acf6c7aa31 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -155,10 +155,16 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return 0; } +static const struct ath12k_pci_reg_base ath12k_wifi7_reg_base = { + .umac_base = HAL_SEQ_WCSS_UMAC_OFFSET, + .ce_reg_base = HAL_CE_WFSS_CE_REG_BASE, +}; + static struct ath12k_pci_driver ath12k_wifi7_pci_driver = { .name = "ath12k_wifi7_pci", .id_table = ath12k_wifi7_pci_id_table, .ops.probe = ath12k_wifi7_pci_probe, + .reg_base = &ath12k_wifi7_reg_base, }; int ath12k_wifi7_pci_init(void) From 6ad056144fd64fa0b48902f060fdc8536d51eef2 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:39 +0530 Subject: [PATCH 379/659] wifi: ath12k: Remove HAL define dependencies from shared AHB code Eliminate HAL-specific defines from the shared AHB implementation. Store the WFSS register base-already available in hw_params via the ce_remap structure-in the AHB context and access it directly. Add the CMEM offset to the ce_remap structure and use it consistently in shared code. Improve modularity by removing hardware abstraction layer dependencies from common code paths and enable cleaner separation of target-specific logic Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-13-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 7 ++++--- drivers/net/wireless/ath/ath12k/ce.h | 1 + drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 5fe2b5b7db499..9348b5aa08c67 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -123,7 +123,7 @@ enum ext_irq_num { static u32 ath12k_ahb_read32(struct ath12k_base *ab, u32 offset) { - if (ab->ce_remap && offset < HAL_SEQ_WCSS_CMEM_OFFSET) + if (ab->ce_remap && offset < ab->cmem_offset) return ioread32(ab->mem_ce + offset); return ioread32(ab->mem + offset); } @@ -131,7 +131,7 @@ static u32 ath12k_ahb_read32(struct ath12k_base *ab, u32 offset) static void ath12k_ahb_write32(struct ath12k_base *ab, u32 offset, u32 value) { - if (ab->ce_remap && offset < HAL_SEQ_WCSS_CMEM_OFFSET) + if (ab->ce_remap && offset < ab->cmem_offset) iowrite32(value, ab->mem_ce + offset); else iowrite32(value, ab->mem + offset); @@ -928,7 +928,8 @@ static int ath12k_ahb_resource_init(struct ath12k_base *ab) goto err_mem_unmap; } ab->ce_remap = true; - ab->ce_remap_base_addr = HAL_IPQ5332_CE_WFSS_REG_BASE; + ab->cmem_offset = ce_remap->cmem_offset; + ab->ce_remap_base_addr = ce_remap->base; } ab_ahb->xo_clk = devm_clk_get(ab->dev, "xo"); diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index f44ce2244bcfd..38f986ea1cd2b 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -85,6 +85,7 @@ struct ce_ie_addr { struct ce_remap { u32 base; u32 size; + u32 cmem_offset; }; struct ce_attr { diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 60c2237cb055e..e1700c63b1bee 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1067,6 +1067,7 @@ struct ath12k_base { void __iomem *mem_ce; u32 ce_remap_base_addr; + u32 cmem_offset; bool ce_remap; struct { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 9995eccd32d39..82b4f5b9f5700 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -695,6 +695,7 @@ static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = { static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = { .base = HAL_IPQ5332_CE_WFSS_REG_BASE, .size = HAL_IPQ5332_CE_SIZE, + .cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET, }; static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { From 81f7cbedf5ab11f302e3873221504bbe863cb907 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:34 +0530 Subject: [PATCH 380/659] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory Move architecture-specific files hal_rx.c and hal_tx.c into the wifi7 directory as part of a broader effort to separate common and hardware -specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. The relocated files remain part of ath12k.ko temporarily, until the corresponding infra for movement to the ath12k_wifi7.ko arrives in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 5 +++-- drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c | 12 ++++++------ drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c | 10 +++++----- 3 files changed, 14 insertions(+), 13 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c (99%) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c (96%) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 8dd77729f52f5..b34cf83a24eb1 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -2,8 +2,6 @@ obj-$(CONFIG_ATH12K) += ath12k.o ath12k-y += core.o \ hal.o \ - hal_tx.o \ - hal_rx.o \ wmi.o \ mac.o \ reg.o \ @@ -24,6 +22,9 @@ ath12k-y += core.o \ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o +ath12k-y += wifi7/hal_tx.o \ + wifi7/hal_rx.o \ + obj-$(CONFIG_ATH12K) += wifi7/ ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/hal_rx.c rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index c4443ca05cd65..d5f149bf29f4c 100644 --- a/drivers/net/wireless/ath/ath12k/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -4,12 +4,12 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "debug.h" -#include "hal.h" -#include "hal_tx.h" -#include "hal_rx.h" -#include "hal_desc.h" -#include "hif.h" +#include "../debug.h" +#include "../hal.h" +#include "../hif.h" +#include "../hal_tx.h" +#include "../hal_rx.h" +#include "../hal_desc.h" static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, u8 owner, u8 buffer_type, u32 magic) diff --git a/drivers/net/wireless/ath/ath12k/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c similarity index 96% rename from drivers/net/wireless/ath/ath12k/hal_tx.c rename to drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 869e07e406fef..f58da63a1b021 100644 --- a/drivers/net/wireless/ath/ath12k/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "hal_desc.h" -#include "hal.h" -#include "hal_tx.h" -#include "hif.h" +#include "../hal_desc.h" +#include "../hal.h" +#include "../hal_tx.h" +#include "../hif.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 From ec868780f4e63af8b7237583105f6c0dca6c1aa2 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:35 +0530 Subject: [PATCH 381/659] wifi: ath12k: Move hal_tx.h file to wifi7 directory Move wifi7 architecture specific file hal_tx.h to wifi7 directory, and move the common part from it to hal.h file which is in the common directory. It is as part of a broader effort to separate common and hardware-specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 4 ++-- drivers/net/wireless/ath/ath12k/dp_tx.h | 4 ++-- drivers/net/wireless/ath/ath12k/hal.c | 4 ++-- drivers/net/wireless/ath/ath12k/hal.h | 9 ++++++++- drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +- .../net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h | 13 +++---------- 7 files changed, 19 insertions(+), 19 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h (95%) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4a54b8c353111..ec6300eb38921 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include #include "core.h" #include "dp_tx.h" -#include "hal_tx.h" +#include "wifi7/hal_tx.h" #include "hif.h" #include "debug.h" #include "dp_rx.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 10acdcf1fa8f7..aa2f6397bc83d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -1,14 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_DP_TX_H #define ATH12K_DP_TX_H #include "core.h" -#include "hal_tx.h" +#include "wifi7/hal_tx.h" struct ath12k_dp_htt_wbm_tx_status { bool acked; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 022eea9515efd..dbbdb6f3f8cfd 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include -#include "hal_tx.h" +#include "wifi7/hal_tx.h" #include "hal_rx.h" #include "debug.h" #include "hal_desc.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index efe00e1679986..e908e9f009657 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_HAL_H @@ -11,6 +11,13 @@ #include "rx_desc.h" struct ath12k_base; + +#define HAL_TX_ADDRX_EN 1 +#define HAL_TX_ADDRY_EN 2 + +#define HAL_TX_ADDR_SEARCH_DEFAULT 0 +#define HAL_TX_ADDR_SEARCH_INDEX 1 + #define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr) #define HAL_LINK_DESC_SIZE (32 << 2) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index d5f149bf29f4c..2be03db483a00 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -7,7 +7,7 @@ #include "../debug.h" #include "../hal.h" #include "../hif.h" -#include "../hal_tx.h" +#include "hal_tx.h" #include "../hal_rx.h" #include "../hal_desc.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index f58da63a1b021..87c1312c4f46d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -6,7 +6,7 @@ #include "../hal_desc.h" #include "../hal.h" -#include "../hal_tx.h" +#include "hal_tx.h" #include "../hif.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 diff --git a/drivers/net/wireless/ath/ath12k/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h similarity index 95% rename from drivers/net/wireless/ath/ath12k/hal_tx.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index eb065a79f6c64..b179320569ff7 100644 --- a/drivers/net/wireless/ath/ath12k/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -1,21 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. - * All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_HAL_TX_H #define ATH12K_HAL_TX_H -#include "hal_desc.h" -#include "core.h" - -#define HAL_TX_ADDRX_EN 1 -#define HAL_TX_ADDRY_EN 2 - -#define HAL_TX_ADDR_SEARCH_DEFAULT 0 -#define HAL_TX_ADDR_SEARCH_INDEX 1 +#include "../hal_desc.h" +#include "../core.h" /* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */ struct hal_tx_info { From cf48764a214d4fb84c535d2b4e3c23df2020c64c Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:36 +0530 Subject: [PATCH 382/659] wifi: ath12k: Move hal_rx.h file to wifi7 directory Move wifi7 architecture specific file hal_rx.h to wifi7 directory, and move the common part from it to hal.h file which is in the common directory. It is as part of a broader effort to separate common and hardware-specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 +- drivers/net/wireless/ath/ath12k/dp.h | 4 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/hal.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 295 +++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- .../wireless/ath/ath12k/{ => wifi7}/hal_rx.h | 299 +----------------- 7 files changed, 302 insertions(+), 304 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.h (83%) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index e1700c63b1bee..7eaf098ccc8f5 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -26,7 +26,7 @@ #include "ce.h" #include "mac.h" #include "hw.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "reg.h" #include "dbring.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 4ffec6ad7d8d9..dc33a0f85f2af 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -1,14 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_DP_H #define ATH12K_DP_H #include "hal_desc.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "hw.h" #define MAX_RXDMA_PER_PDEV 2 diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index cd07bb5b8e9a4..80fb1cc9ed599 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -13,7 +13,7 @@ #include "hal_desc.h" #include "hw.h" #include "dp_rx.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "dp_tx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index dbbdb6f3f8cfd..f9ce60d22cc1a 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -5,7 +5,7 @@ */ #include #include "wifi7/hal_tx.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "debug.h" #include "hal_desc.h" #include "hif.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index e908e9f009657..322ebfed9b011 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -12,12 +12,22 @@ struct ath12k_base; +#define HAL_INVALID_PEERID 0x3fff +#define VHT_SIG_SU_NSS_MASK 0x7 + #define HAL_TX_ADDRX_EN 1 #define HAL_TX_ADDRY_EN 2 #define HAL_TX_ADDR_SEARCH_DEFAULT 0 #define HAL_TX_ADDR_SEARCH_INDEX 1 +#define HAL_RX_MAX_MPDU 256 +#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) + +#define EHT_MAX_USER_INFO 4 +#define HAL_RX_MON_MAX_AGGR_SIZE 128 +#define HAL_MAX_UL_MU_USERS 37 + #define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr) #define HAL_LINK_DESC_SIZE (32 << 2) @@ -532,6 +542,64 @@ enum hal_srng_ring_id { #define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_DMAC_CMN_ID_END + \ HAL_SRNG_NUM_PMAC_RINGS) +enum hal_rx_su_mu_coding { + HAL_RX_SU_MU_CODING_BCC, + HAL_RX_SU_MU_CODING_LDPC, + HAL_RX_SU_MU_CODING_MAX, +}; + +enum hal_rx_gi { + HAL_RX_GI_0_8_US, + HAL_RX_GI_0_4_US, + HAL_RX_GI_1_6_US, + HAL_RX_GI_3_2_US, + HAL_RX_GI_MAX, +}; + +enum hal_rx_bw { + HAL_RX_BW_20MHZ, + HAL_RX_BW_40MHZ, + HAL_RX_BW_80MHZ, + HAL_RX_BW_160MHZ, + HAL_RX_BW_320MHZ, + HAL_RX_BW_MAX, +}; + +enum hal_rx_preamble { + HAL_RX_PREAMBLE_11A, + HAL_RX_PREAMBLE_11B, + HAL_RX_PREAMBLE_11N, + HAL_RX_PREAMBLE_11AC, + HAL_RX_PREAMBLE_11AX, + HAL_RX_PREAMBLE_11BA, + HAL_RX_PREAMBLE_11BE, + HAL_RX_PREAMBLE_MAX, +}; + +enum hal_rx_reception_type { + HAL_RX_RECEPTION_TYPE_SU, + HAL_RX_RECEPTION_TYPE_MU_MIMO, + HAL_RX_RECEPTION_TYPE_MU_OFDMA, + HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO, + HAL_RX_RECEPTION_TYPE_MAX, +}; + +enum hal_rx_legacy_rate { + HAL_RX_LEGACY_RATE_1_MBPS, + HAL_RX_LEGACY_RATE_2_MBPS, + HAL_RX_LEGACY_RATE_5_5_MBPS, + HAL_RX_LEGACY_RATE_6_MBPS, + HAL_RX_LEGACY_RATE_9_MBPS, + HAL_RX_LEGACY_RATE_11_MBPS, + HAL_RX_LEGACY_RATE_12_MBPS, + HAL_RX_LEGACY_RATE_18_MBPS, + HAL_RX_LEGACY_RATE_24_MBPS, + HAL_RX_LEGACY_RATE_36_MBPS, + HAL_RX_LEGACY_RATE_48_MBPS, + HAL_RX_LEGACY_RATE_54_MBPS, + HAL_RX_LEGACY_RATE_INVALID, +}; + enum hal_ring_type { HAL_REO_DST, HAL_REO_EXCEPTION, @@ -632,6 +700,158 @@ enum hal_srng_dir { HAL_SRNG_DIR_DST }; +struct hal_rx_user_status { + u32 mcs:4, + nss:3, + ofdma_info_valid:1, + ul_ofdma_ru_start_index:7, + ul_ofdma_ru_width:7, + ul_ofdma_ru_size:8; + u32 ul_ofdma_user_v0_word0; + u32 ul_ofdma_user_v0_word1; + u32 ast_index; + u32 tid; + u16 tcp_msdu_count; + u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 frame_control; + u8 frame_control_info_valid; + u8 data_sequence_control_info_valid; + u16 first_data_seq_ctrl; + u32 preamble_type; + u16 ht_flags; + u16 vht_flags; + u16 he_flags; + u8 rs_flags; + u8 ldpc; + u32 mpdu_cnt_fcs_ok; + u32 mpdu_cnt_fcs_err; + u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u32 mpdu_ok_byte_count; + u32 mpdu_err_byte_count; + bool ampdu_present; + u16 ampdu_id; +}; + +struct hal_rx_u_sig_info { + bool ul_dl; + u8 bw; + u8 ppdu_type_comp_mode; + u8 eht_sig_mcs; + u8 num_eht_sig_sym; + struct ieee80211_radiotap_eht_usig usig; +}; + +struct hal_rx_tlv_aggr_info { + bool in_progress; + u16 cur_len; + u16 tlv_tag; + u8 buf[HAL_RX_MON_MAX_AGGR_SIZE]; +}; + +struct hal_rx_radiotap_eht { + __le32 known; + __le32 data[9]; +}; + +struct hal_rx_eht_info { + u8 num_user_info; + struct hal_rx_radiotap_eht eht; + u32 user_info[EHT_MAX_USER_INFO]; +}; + +struct hal_rx_mon_ppdu_info { + u32 ppdu_id; + u32 last_ppdu_id; + u64 ppdu_ts; + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; + u32 preamble_type; + u32 mpdu_len; + u16 chan_num; + u16 freq; + u16 tcp_msdu_count; + u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 peer_id; + u8 rate; + u8 mcs; + u8 nss; + u8 bw; + u8 vht_flag_values1; + u8 vht_flag_values2; + u8 vht_flag_values3[4]; + u8 vht_flag_values4; + u8 vht_flag_values5; + u16 vht_flag_values6; + u8 is_stbc; + u8 gi; + u8 sgi; + u8 ldpc; + u8 beamformed; + u8 rssi_comb; + u16 tid; + u8 fc_valid; + u16 ht_flags; + u16 vht_flags; + u16 he_flags; + u16 he_mu_flags; + u8 dcm; + u8 ru_alloc; + u8 reception_type; + u64 tsft; + u64 rx_duration; + u16 frame_control; + u32 ast_index; + u8 rs_fcs_err; + u8 rs_flags; + u8 cck_flag; + u8 ofdm_flag; + u8 ulofdma_flag; + u8 frame_control_info_valid; + u16 he_per_user_1; + u16 he_per_user_2; + u8 he_per_user_position; + u8 he_per_user_known; + u16 he_flags1; + u16 he_flags2; + u8 he_RU[4]; + u16 he_data1; + u16 he_data2; + u16 he_data3; + u16 he_data4; + u16 he_data5; + u16 he_data6; + u32 ppdu_len; + u32 prev_ppdu_id; + u32 device_id; + u16 first_data_seq_ctrl; + u8 monitor_direct_used; + u8 data_sequence_control_info_valid; + u8 ltf_size; + u8 rxpcu_filter_pass; + s8 rssi_chain[8][8]; + u32 num_users; + u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u8 addr4[ETH_ALEN]; + struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS]; + u8 userid; + bool first_msdu_in_mpdu; + bool is_ampdu; + u8 medium_prot_type; + bool ppdu_continuation; + bool eht_usig; + struct hal_rx_u_sig_info u_sig_info; + bool is_eht; + struct hal_rx_eht_info eht_info; + struct hal_rx_tlv_aggr_info tlv_aggr; +}; + /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 #define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010 @@ -1061,6 +1281,81 @@ struct ath12k_hal_tcl_to_wbm_rbm_map { u8 rbm_id; }; +#define RU_INVALID 0 +#define RU_26 1 +#define RU_52 2 +#define RU_106 4 +#define RU_242 9 +#define RU_484 18 +#define RU_996 37 +#define RU_2X996 74 +#define RU_3X996 111 +#define RU_4X996 148 +#define RU_52_26 (RU_52 + RU_26) +#define RU_106_26 (RU_106 + RU_26) +#define RU_484_242 (RU_484 + RU_242) +#define RU_996_484 (RU_996 + RU_484) +#define RU_996_484_242 (RU_996 + RU_484_242) +#define RU_2X996_484 (RU_2X996 + RU_484) +#define RU_3X996_484 (RU_3X996 + RU_484) + +enum ath12k_eht_ru_size { + ATH12K_EHT_RU_26, + ATH12K_EHT_RU_52, + ATH12K_EHT_RU_106, + ATH12K_EHT_RU_242, + ATH12K_EHT_RU_484, + ATH12K_EHT_RU_996, + ATH12K_EHT_RU_996x2, + ATH12K_EHT_RU_996x4, + ATH12K_EHT_RU_52_26, + ATH12K_EHT_RU_106_26, + ATH12K_EHT_RU_484_242, + ATH12K_EHT_RU_996_484, + ATH12K_EHT_RU_996_484_242, + ATH12K_EHT_RU_996x2_484, + ATH12K_EHT_RU_996x3, + ATH12K_EHT_RU_996x3_484, + + /* Keep last */ + ATH12K_EHT_RU_INVALID, +}; + +#define HAL_RX_RU_ALLOC_TYPE_MAX ATH12K_EHT_RU_INVALID + +static inline +enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) +{ + enum nl80211_he_ru_alloc ret; + + switch (ru_tones) { + case RU_52: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_52; + break; + case RU_106: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_106; + break; + case RU_242: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_242; + break; + case RU_484: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_484; + break; + case RU_996: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_996; + break; + case RU_2X996: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; + break; + case RU_26: + fallthrough; + default: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_26; + break; + } + return ret; +} + struct hal_rx_ops { bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 2be03db483a00..e8379e660d3a5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -8,7 +8,7 @@ #include "../hal.h" #include "../hif.h" #include "hal_tx.h" -#include "../hal_rx.h" +#include "hal_rx.h" #include "../hal_desc.h" static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h similarity index 83% rename from drivers/net/wireless/ath/ath12k/hal_rx.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index d1ad7747b82c4..d8d9d469c6704 100644 --- a/drivers/net/wireless/ath/ath12k/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_HAL_RX_H @@ -19,9 +19,6 @@ struct hal_rx_wbm_rel_info { bool hw_cc_done; }; -#define HAL_INVALID_PEERID 0x3fff -#define VHT_SIG_SU_NSS_MASK 0x7 - #define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ le32_get_bits((__val), GENMASK(7, 0)) @@ -39,64 +36,6 @@ struct hal_rx_mon_status_tlv_hdr { u8 value[]; }; -enum hal_rx_su_mu_coding { - HAL_RX_SU_MU_CODING_BCC, - HAL_RX_SU_MU_CODING_LDPC, - HAL_RX_SU_MU_CODING_MAX, -}; - -enum hal_rx_gi { - HAL_RX_GI_0_8_US, - HAL_RX_GI_0_4_US, - HAL_RX_GI_1_6_US, - HAL_RX_GI_3_2_US, - HAL_RX_GI_MAX, -}; - -enum hal_rx_bw { - HAL_RX_BW_20MHZ, - HAL_RX_BW_40MHZ, - HAL_RX_BW_80MHZ, - HAL_RX_BW_160MHZ, - HAL_RX_BW_320MHZ, - HAL_RX_BW_MAX, -}; - -enum hal_rx_preamble { - HAL_RX_PREAMBLE_11A, - HAL_RX_PREAMBLE_11B, - HAL_RX_PREAMBLE_11N, - HAL_RX_PREAMBLE_11AC, - HAL_RX_PREAMBLE_11AX, - HAL_RX_PREAMBLE_11BA, - HAL_RX_PREAMBLE_11BE, - HAL_RX_PREAMBLE_MAX, -}; - -enum hal_rx_reception_type { - HAL_RX_RECEPTION_TYPE_SU, - HAL_RX_RECEPTION_TYPE_MU_MIMO, - HAL_RX_RECEPTION_TYPE_MU_OFDMA, - HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO, - HAL_RX_RECEPTION_TYPE_MAX, -}; - -enum hal_rx_legacy_rate { - HAL_RX_LEGACY_RATE_1_MBPS, - HAL_RX_LEGACY_RATE_2_MBPS, - HAL_RX_LEGACY_RATE_5_5_MBPS, - HAL_RX_LEGACY_RATE_6_MBPS, - HAL_RX_LEGACY_RATE_9_MBPS, - HAL_RX_LEGACY_RATE_11_MBPS, - HAL_RX_LEGACY_RATE_12_MBPS, - HAL_RX_LEGACY_RATE_18_MBPS, - HAL_RX_LEGACY_RATE_24_MBPS, - HAL_RX_LEGACY_RATE_36_MBPS, - HAL_RX_LEGACY_RATE_48_MBPS, - HAL_RX_LEGACY_RATE_54_MBPS, - HAL_RX_LEGACY_RATE_INVALID, -}; - #define HAL_TLV_STATUS_PPDU_NOT_DONE 0 #define HAL_TLV_STATUS_PPDU_DONE 1 #define HAL_TLV_STATUS_BUF_DONE 2 @@ -113,167 +52,6 @@ enum hal_rx_mon_status { HAL_RX_MON_STATUS_MSDU_END, }; -#define HAL_RX_MAX_MPDU 1024 -#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) - -struct hal_rx_user_status { - u32 mcs:4, - nss:3, - ofdma_info_valid:1, - ul_ofdma_ru_start_index:7, - ul_ofdma_ru_width:7, - ul_ofdma_ru_size:8; - u32 ul_ofdma_user_v0_word0; - u32 ul_ofdma_user_v0_word1; - u32 ast_index; - u32 tid; - u16 tcp_msdu_count; - u16 tcp_ack_msdu_count; - u16 udp_msdu_count; - u16 other_msdu_count; - u16 frame_control; - u8 frame_control_info_valid; - u8 data_sequence_control_info_valid; - u16 first_data_seq_ctrl; - u32 preamble_type; - u16 ht_flags; - u16 vht_flags; - u16 he_flags; - u8 rs_flags; - u8 ldpc; - u32 mpdu_cnt_fcs_ok; - u32 mpdu_cnt_fcs_err; - u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; - u32 mpdu_ok_byte_count; - u32 mpdu_err_byte_count; - bool ampdu_present; - u16 ampdu_id; -}; - -#define HAL_MAX_UL_MU_USERS 37 - -struct hal_rx_u_sig_info { - bool ul_dl; - u8 bw; - u8 ppdu_type_comp_mode; - u8 eht_sig_mcs; - u8 num_eht_sig_sym; - struct ieee80211_radiotap_eht_usig usig; -}; - -#define HAL_RX_MON_MAX_AGGR_SIZE 128 - -struct hal_rx_tlv_aggr_info { - bool in_progress; - u16 cur_len; - u16 tlv_tag; - u8 buf[HAL_RX_MON_MAX_AGGR_SIZE]; -}; - -struct hal_rx_radiotap_eht { - __le32 known; - __le32 data[9]; -}; - -#define EHT_MAX_USER_INFO 4 - -struct hal_rx_eht_info { - u8 num_user_info; - struct hal_rx_radiotap_eht eht; - u32 user_info[EHT_MAX_USER_INFO]; -}; - -struct hal_rx_mon_ppdu_info { - u32 ppdu_id; - u32 last_ppdu_id; - u64 ppdu_ts; - u32 num_mpdu_fcs_ok; - u32 num_mpdu_fcs_err; - u32 preamble_type; - u32 mpdu_len; - u16 chan_num; - u16 freq; - u16 tcp_msdu_count; - u16 tcp_ack_msdu_count; - u16 udp_msdu_count; - u16 other_msdu_count; - u16 peer_id; - u8 rate; - u8 mcs; - u8 nss; - u8 bw; - u8 vht_flag_values1; - u8 vht_flag_values2; - u8 vht_flag_values3[4]; - u8 vht_flag_values4; - u8 vht_flag_values5; - u16 vht_flag_values6; - u8 is_stbc; - u8 gi; - u8 sgi; - u8 ldpc; - u8 beamformed; - u8 rssi_comb; - u16 tid; - u8 fc_valid; - u16 ht_flags; - u16 vht_flags; - u16 he_flags; - u16 he_mu_flags; - u8 dcm; - u8 ru_alloc; - u8 reception_type; - u64 tsft; - u64 rx_duration; - u16 frame_control; - u32 ast_index; - u8 rs_fcs_err; - u8 rs_flags; - u8 cck_flag; - u8 ofdm_flag; - u8 ulofdma_flag; - u8 frame_control_info_valid; - u16 he_per_user_1; - u16 he_per_user_2; - u8 he_per_user_position; - u8 he_per_user_known; - u16 he_flags1; - u16 he_flags2; - u8 he_RU[4]; - u16 he_data1; - u16 he_data2; - u16 he_data3; - u16 he_data4; - u16 he_data5; - u16 he_data6; - u32 ppdu_len; - u32 prev_ppdu_id; - u32 device_id; - u16 first_data_seq_ctrl; - u8 monitor_direct_used; - u8 data_sequence_control_info_valid; - u8 ltf_size; - u8 rxpcu_filter_pass; - s8 rssi_chain[8][8]; - u32 num_users; - u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - u8 addr4[ETH_ALEN]; - struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS]; - u8 userid; - bool first_msdu_in_mpdu; - bool is_ampdu; - u8 medium_prot_type; - bool ppdu_continuation; - bool eht_usig; - struct hal_rx_u_sig_info u_sig_info; - bool is_eht; - struct hal_rx_eht_info eht_info; - struct hal_rx_tlv_aggr_info tlv_aggr; -}; - #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) #define HAL_RX_PPDU_START_INFO1_CHAN_NUM GENMASK(15, 0) #define HAL_RX_PPDU_START_INFO1_CHAN_FREQ GENMASK(31, 16) @@ -1044,81 +822,6 @@ enum hal_mon_reception_type { #define HAL_RU_PER80(ru_per80, num_80mhz, ru_idx_per80mhz) \ (HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz)) -#define RU_INVALID 0 -#define RU_26 1 -#define RU_52 2 -#define RU_106 4 -#define RU_242 9 -#define RU_484 18 -#define RU_996 37 -#define RU_2X996 74 -#define RU_3X996 111 -#define RU_4X996 148 -#define RU_52_26 (RU_52 + RU_26) -#define RU_106_26 (RU_106 + RU_26) -#define RU_484_242 (RU_484 + RU_242) -#define RU_996_484 (RU_996 + RU_484) -#define RU_996_484_242 (RU_996 + RU_484_242) -#define RU_2X996_484 (RU_2X996 + RU_484) -#define RU_3X996_484 (RU_3X996 + RU_484) - -enum ath12k_eht_ru_size { - ATH12K_EHT_RU_26, - ATH12K_EHT_RU_52, - ATH12K_EHT_RU_106, - ATH12K_EHT_RU_242, - ATH12K_EHT_RU_484, - ATH12K_EHT_RU_996, - ATH12K_EHT_RU_996x2, - ATH12K_EHT_RU_996x4, - ATH12K_EHT_RU_52_26, - ATH12K_EHT_RU_106_26, - ATH12K_EHT_RU_484_242, - ATH12K_EHT_RU_996_484, - ATH12K_EHT_RU_996_484_242, - ATH12K_EHT_RU_996x2_484, - ATH12K_EHT_RU_996x3, - ATH12K_EHT_RU_996x3_484, - - /* Keep last */ - ATH12K_EHT_RU_INVALID, -}; - -#define HAL_RX_RU_ALLOC_TYPE_MAX ATH12K_EHT_RU_INVALID - -static inline -enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) -{ - enum nl80211_he_ru_alloc ret; - - switch (ru_tones) { - case RU_52: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_52; - break; - case RU_106: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_106; - break; - case RU_242: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_242; - break; - case RU_484: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_484; - break; - case RU_996: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_996; - break; - case RU_2X996: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; - break; - case RU_26: - fallthrough; - default: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_26; - break; - } - return ret; -} - void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, struct hal_reo_status *status); From b5639d2c4e4c8c27ee0ae96f13edd7e9852908b9 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:37 +0530 Subject: [PATCH 383/659] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h Move HAL Rx APIs from dp_rx.c to dp_rx.h to facilitate the separation of common and hardware-specific code that are dependent on these HAL Rx ops in upcoming patches. Move the following wrapper APIs to dp_rx.h ath12k_dp_rx_h_enctype ath12k_dp_rx_h_mesh_ctl_present ath12k_dp_rx_h_seq_ctrl_valid ath12k_dp_rx_h_fc_valid ath12k_dp_rx_h_more_frags ath12k_dp_rx_h_frag_no ath12k_dp_rx_h_seq_no ath12k_dp_rx_h_msdu_done ath12k_dp_rx_h_l4_cksum_fail ath12k_dp_rx_h_ip_cksum_fail ath12k_dp_rx_h_is_decrypted ath12k_dp_rx_h_msdu_len ath12k_dp_rx_h_sgi ath12k_dp_rx_h_rate_mcs ath12k_dp_rx_h_rx_bw ath12k_dp_rx_h_freq ath12k_dp_rx_h_pkt_type ath12k_dp_rx_h_nss ath12k_dp_rx_h_tid ath12k_dp_rx_h_peer_id ath12k_dp_rx_h_first_msdu ath12k_dp_rx_h_last_msdu ath12k_dp_rx_desc_end_tlv_copy ath12k_dp_rxdesc_set_msdu_len ath12k_dp_rx_h_is_da_mcbc ath12k_dp_rxdesc_mac_addr2_valid ath12k_dp_rxdesc_get_mpdu_start_addr2 ath12k_dp_rx_desc_get_dot11_hdr ath12k_dp_rx_desc_get_crypto_header ath12k_dp_rx_get_msdu_src_link Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 237 ----------------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 239 +++++++++++++++++++++++- 2 files changed, 238 insertions(+), 238 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 80fb1cc9ed599..dc62601f6221f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -24,243 +24,6 @@ static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, struct ath12k_dp_rx_tid_rxq *rx_tid); -static enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) - return HAL_ENCRYPT_TYPE_OPEN; - - return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); -} - -u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_decap_type(desc); -} - -static u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); -} - -static bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); -} - -static bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); -} - -static bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); - return ieee80211_has_morefrags(hdr->frame_control); -} - -static u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); - return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; -} - -static u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); -} - -static bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); -} - -static bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); -} - -static bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); -} - -static bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); -} - -u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); -} - -static u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); -} - -static u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); -} - -static u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); -} - -static u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); -} - -static u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); -} - -static u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); -} - -static u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); -} - -static u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); -} - -static u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); -} - -u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); -} - -static bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); -} - -static bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); -} - -static void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, - struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); -} - -static void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, - struct hal_rx_desc *desc, - u16 len) -{ - ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); -} - -u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); -} - -bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - -static bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return (ath12k_dp_rx_h_first_msdu(ab, desc) && - ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); -} - -static bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); -} - -static u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); -} - -static void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, - struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); -} - -static void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, - struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); -} - -static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); -} - -static void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(skb_list))) - dev_kfree_skb_any(skb); -} - static size_t ath12k_dp_list_cut_nodes(struct list_head *list, struct list_head *head, size_t count) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 69d0a36a91d88..9d37684c1f011 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_DP_RX_H #define ATH12K_DP_RX_H @@ -117,6 +117,243 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) return ret; } +static inline enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + + return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); +} + +static inline u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_decap_type(desc); +} + +static inline u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); +} + +static inline bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); +} + +static inline bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); +} + +static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + return ieee80211_has_morefrags(hdr->frame_control); +} + +static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; +} + +static inline u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); +} + +static inline bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); +} + +static inline bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); +} + +static inline bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); +} + +static inline bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); +} + +static inline u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); +} + +static inline u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); +} + +static inline u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); +} + +static inline u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); +} + +static inline u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); +} + +static inline u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); +} + +static inline u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); +} + +static inline u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); +} + +static inline u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); +} + +static inline u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); +} + +static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); +} + +static inline bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); +} + +static inline bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); +} + +static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, + struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); +} + +static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, + struct hal_rx_desc *desc, + u16 len) +{ + ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); +} + +static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); +} + +static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} + +static inline bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return (ath12k_dp_rx_h_first_msdu(ab, desc) && + ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); +} + +static inline bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); +} + +static inline u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); +} + +static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, + struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); +} + +static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, + struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); +} + +static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); +} + +static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(skb_list))) + dev_kfree_skb_any(skb); +} + int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); From 786a05bdaa03e5e9dc8d211e319e03ca7c6a7535 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:38 +0530 Subject: [PATCH 384/659] wifi: ath12k: Move Rx error related functions to wifi7 directory Move wifi7 architecture specific Rx error functions from dp_rx.c to wifi7 directory. The new wifi7-specific dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to the ath12k_wifi7.ko arrives in upcoming patches. Move following architecture specific APIs to wifi7 directory: ath12k_dp_rx_h_tkip_mic_err ath12k_dp_rx_h_rxdma_err ath12k_dp_rx_h_reo_err ath12k_dp_rx_wbm_err ath12k_dp_rx_process_wbm_err Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp.c | 2 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 370 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 18 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 350 +++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 14 + 7 files changed, 396 insertions(+), 361 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index b34cf83a24eb1..d7628bb7af029 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -24,6 +24,7 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ + wifi7/dp_rx.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index ec6300eb38921..1faac4ab641c1 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -10,7 +10,7 @@ #include "wifi7/hal_tx.h" #include "hif.h" #include "debug.h" -#include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 39d1967584db8..803de9ca3e51a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,7 +6,7 @@ #include "dp_mon.h" #include "debug.h" -#include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index dc62601f6221f..80338421903b6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -2139,11 +2139,11 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, ether_addr_copy(ieee80211_get_SA(hdr), sa); } -static void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status, - bool decrypted) +void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + enum hal_encrypt_type enctype, + struct ieee80211_rx_status *status, + bool decrypted) { struct ath12k_base *ab = ar->ab; u8 decap; @@ -2443,9 +2443,9 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) ath12k_dp_rx_h_rate(ar, rx_info); } -static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, - struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) +void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, + struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) { struct ath12k_base *ab = ar->ab; struct ieee80211_rx_status *rx_status; @@ -2515,9 +2515,9 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi); } -static bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc, - struct sk_buff *msdu) +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc, + struct sk_buff *msdu) { struct ieee80211_hdr *hdr; u8 decap_type; @@ -3764,9 +3764,9 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, } } -static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list) +int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) { struct ath12k_base *ab = ar->ab; u16 msdu_len; @@ -3834,348 +3834,6 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, return 0; } -static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list) -{ - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - bool drop = false; - - ar->ab->device_stats.reo_error[rxcb->err_code]++; - - switch (rxcb->err_code) { - case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: - if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) - drop = true; - break; - case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: - /* TODO: Do not drop PN failed packets in the driver; - * instead, it is good to drop such packets in mac80211 - * after incrementing the replay counters. - */ - fallthrough; - default: - /* TODO: Review other errors and process them to mac80211 - * as appropriate. - */ - drop = true; - break; - } - - return drop; -} - -static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - u16 msdu_len; - struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); - - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); - - if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "invalid msdu len in tkip mic err %u\n", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc, - sizeof(*desc)); - return true; - } - - skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); - skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) - return true; - - ath12k_dp_rx_h_ppdu(ar, rx_info); - - rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | - RX_FLAG_DECRYPTED); - - ath12k_dp_rx_h_undecap(ar, msdu, desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); - return false; -} - -static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; - bool drop = false; - u32 err_bitmap; - - ar->ab->device_stats.rxdma_error[rxcb->err_code]++; - - switch (rxcb->err_code) { - case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: - case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); - if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); - drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); - break; - } - fallthrough; - default: - /* TODO: Review other rxdma error code to check if anything is - * worth reporting to mac80211 - */ - drop = true; - break; - } - - return drop; -} - -static void ath12k_dp_rx_wbm_err(struct ath12k *ar, - struct napi_struct *napi, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list) -{ - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct ieee80211_rx_status rxs = {}; - struct ath12k_dp_rx_info rx_info; - bool drop = true; - - rx_info.addr2_present = false; - rx_info.rx_status = &rxs; - - switch (rxcb->err_rel_src) { - case HAL_WBM_REL_SRC_MODULE_REO: - drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); - break; - case HAL_WBM_REL_SRC_MODULE_RXDMA: - drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); - break; - default: - /* msdu will get freed */ - break; - } - - if (drop) { - dev_kfree_skb_any(msdu); - return; - } - - rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; - - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); -} - -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget) -{ - struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_group *ag = ab->ag; - struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; - struct dp_rxdma_ring *rx_ring; - struct hal_rx_wbm_rel_info err_info; - struct hal_srng *srng; - struct sk_buff *msdu; - struct sk_buff_head msdu_list, scatter_msdu_list; - struct ath12k_skb_rxcb *rxcb; - void *rx_desc; - int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; - int total_num_buffs_reaped = 0; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_device_dp_stats *device_stats = &ab->device_stats; - struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; - u8 hw_link_id, device_id; - int ret, pdev_id; - struct hal_rx_desc *msdu_data; - - __skb_queue_head_init(&msdu_list); - __skb_queue_head_init(&scatter_msdu_list); - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) - INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - - srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (budget) { - rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng); - if (!rx_desc) - break; - - ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); - if (ret) { - ath12k_warn(ab, - "failed to parse rx error in wbm_rel ring desc %d\n", - ret); - continue; - } - - desc_info = err_info.rx_desc; - - /* retry manual desc retrieval if hw cc is not done */ - if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); - if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", - err_info.cookie); - continue; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); - - msdu = desc_info->skb; - desc_info->skb = NULL; - - device_id = desc_info->device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { - dev_kfree_skb_any(msdu); - - /* In any case continuation bit is set - * in the previous record, cleanup scatter_msdu_list - */ - ath12k_dp_clean_up_skb_list(&scatter_msdu_list); - continue; - } - - list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); - - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - num_buffs_reaped[device_id]++; - total_num_buffs_reaped++; - - if (!err_info.continuation) - budget--; - - if (err_info.push_reason != - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { - dev_kfree_skb_any(msdu); - continue; - } - - msdu_data = (struct hal_rx_desc *)msdu->data; - rxcb->err_rel_src = err_info.err_rel_src; - rxcb->err_code = err_info.err_code; - rxcb->is_first_msdu = err_info.first_msdu; - rxcb->is_last_msdu = err_info.last_msdu; - rxcb->is_continuation = err_info.continuation; - rxcb->rx_desc = msdu_data; - - if (err_info.continuation) { - __skb_queue_tail(&scatter_msdu_list, msdu); - continue; - } - - hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, - msdu_data); - if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { - dev_kfree_skb_any(msdu); - - /* In any case continuation bit is set - * in the previous record, cleanup scatter_msdu_list - */ - ath12k_dp_clean_up_skb_list(&scatter_msdu_list); - continue; - } - - if (!skb_queue_empty(&scatter_msdu_list)) { - struct sk_buff *msdu; - - skb_queue_walk(&scatter_msdu_list, msdu) { - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->hw_link_id = hw_link_id; - } - - skb_queue_splice_tail_init(&scatter_msdu_list, - &msdu_list); - } - - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->hw_link_id = hw_link_id; - __skb_queue_tail(&msdu_list, msdu); - } - - /* In any case continuation bit is set in the - * last record, cleanup scatter_msdu_list - */ - ath12k_dp_clean_up_skb_list(&scatter_msdu_list); - - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - if (!total_num_buffs_reaped) - goto done; - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { - if (!num_buffs_reaped[device_id]) - continue; - - partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; - - ath12k_dp_rx_bufs_replenish(ab, rx_ring, - &rx_desc_used_list[device_id], - num_buffs_reaped[device_id]); - } - - rcu_read_lock(); - while ((msdu = __skb_dequeue(&msdu_list))) { - rxcb = ATH12K_SKB_RXCB(msdu); - hw_link_id = rxcb->hw_link_id; - - device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", - hw_link_id, device_id); - dev_kfree_skb_any(msdu); - continue; - } - - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; - - if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { - dev_kfree_skb_any(msdu); - continue; - } - - if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { - dev_kfree_skb_any(msdu); - continue; - } - - if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { - device_id = ar->ab->device_id; - device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; - } - - ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); - } - rcu_read_unlock(); -done: - return total_num_buffs_reaped; -} - void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 9d37684c1f011..939dc60ec4582 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -354,6 +354,20 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } +void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + enum hal_encrypt_type enctype, + struct ieee80211_rx_status *status, + bool decrypted); +void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, + struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info); +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc, + struct sk_buff *msdu); +int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); @@ -381,8 +395,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget); int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, @@ -404,7 +416,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); @@ -425,4 +436,5 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, enum hal_wbm_rel_bm_act action); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); +void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c new file mode 100644 index 0000000000000..26539a4d4b303 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "dp_rx.h" +#include "../dp_tx.h" + +static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + u8 l3pad_bytes; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); + rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); + + l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); + msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "invalid msdu len in tkip mic err %u\n", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc, + sizeof(*desc)); + return true; + } + + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + return true; + + ath12k_dp_rx_h_ppdu(ar, rx_info); + + rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | + RX_FLAG_DECRYPTED); + + ath12k_dp_rx_h_undecap(ar, msdu, desc, + HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); + return false; +} + +static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + bool drop = false; + u32 err_bitmap; + + ar->ab->device_stats.rxdma_error[rxcb->err_code]++; + + switch (rxcb->err_code) { + case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: + case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: + err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); + if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { + ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + break; + } + fallthrough; + default: + /* TODO: Review other rxdma error code to check if anything is + * worth reporting to mac80211 + */ + drop = true; + break; + } + + return drop; +} + +static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) +{ + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + bool drop = false; + + ar->ab->device_stats.reo_error[rxcb->err_code]++; + + switch (rxcb->err_code) { + case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: + if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + drop = true; + break; + case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: + /* TODO: Do not drop PN failed packets in the driver; + * instead, it is good to drop such packets in mac80211 + * after incrementing the replay counters. + */ + fallthrough; + default: + /* TODO: Review other errors and process them to mac80211 + * as appropriate. + */ + drop = true; + break; + } + + return drop; +} + +static void ath12k_dp_rx_wbm_err(struct ath12k *ar, + struct napi_struct *napi, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list) +{ + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct ieee80211_rx_status rxs = {}; + struct ath12k_dp_rx_info rx_info; + bool drop = true; + + rx_info.addr2_present = false; + rx_info.rx_status = &rxs; + + switch (rxcb->err_rel_src) { + case HAL_WBM_REL_SRC_MODULE_REO: + drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + break; + case HAL_WBM_REL_SRC_MODULE_RXDMA: + drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + break; + default: + /* msdu will get freed */ + break; + } + + if (drop) { + dev_kfree_skb_any(msdu); + return; + } + + rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; + + ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); +} + +int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget) +{ + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_hw_group *ag = ab->ag; + struct ath12k *ar; + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring; + struct hal_rx_wbm_rel_info err_info; + struct hal_srng *srng; + struct sk_buff *msdu; + struct sk_buff_head msdu_list, scatter_msdu_list; + struct ath12k_skb_rxcb *rxcb; + void *rx_desc; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + int total_num_buffs_reaped = 0; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + u8 hw_link_id, device_id; + int ret, pdev_id; + struct hal_rx_desc *msdu_data; + + __skb_queue_head_init(&msdu_list); + __skb_queue_head_init(&scatter_msdu_list); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (budget) { + rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng); + if (!rx_desc) + break; + + ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); + if (ret) { + ath12k_warn(ab, + "failed to parse rx error in wbm_rel ring desc %d\n", + ret); + continue; + } + + desc_info = err_info.rx_desc; + + /* retry manual desc retrieval if hw cc is not done */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", + err_info.cookie); + continue; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + device_id = desc_info->device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + dev_kfree_skb_any(msdu); + + /* In any case continuation bit is set + * in the previous record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + continue; + } + + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(partner_ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + num_buffs_reaped[device_id]++; + total_num_buffs_reaped++; + + if (!err_info.continuation) + budget--; + + if (err_info.push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { + dev_kfree_skb_any(msdu); + continue; + } + + msdu_data = (struct hal_rx_desc *)msdu->data; + rxcb->err_rel_src = err_info.err_rel_src; + rxcb->err_code = err_info.err_code; + rxcb->is_first_msdu = err_info.first_msdu; + rxcb->is_last_msdu = err_info.last_msdu; + rxcb->is_continuation = err_info.continuation; + rxcb->rx_desc = msdu_data; + + if (err_info.continuation) { + __skb_queue_tail(&scatter_msdu_list, msdu); + continue; + } + + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, + msdu_data); + if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { + dev_kfree_skb_any(msdu); + + /* In any case continuation bit is set + * in the previous record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + continue; + } + + if (!skb_queue_empty(&scatter_msdu_list)) { + struct sk_buff *msdu; + + skb_queue_walk(&scatter_msdu_list, msdu) { + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->hw_link_id = hw_link_id; + } + + skb_queue_splice_tail_init(&scatter_msdu_list, + &msdu_list); + } + + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->hw_link_id = hw_link_id; + __skb_queue_tail(&msdu_list, msdu); + } + + /* In any case continuation bit is set in the + * last record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + if (!total_num_buffs_reaped) + goto done; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + rcu_read_lock(); + while ((msdu = __skb_dequeue(&msdu_list))) { + rxcb = ATH12K_SKB_RXCB(msdu); + hw_link_id = rxcb->hw_link_id; + + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", + hw_link_id, device_id); + dev_kfree_skb_any(msdu); + continue; + } + + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + + if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { + dev_kfree_skb_any(msdu); + continue; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + continue; + } + + if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { + device_id = ar->ab->device_id; + device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; + } + + ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + } + rcu_read_unlock(); +done: + return total_num_buffs_reaped; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h new file mode 100644 index 0000000000000..a6da98962345d --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_DP_RX_WIFI7_H +#define ATH12K_DP_RX_WIFI7_H + +#include "../core.h" +#include "../dp_rx.h" + +int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget); +#endif From 693f580ff9b9f96d9d7172c9e3b4e1a3e0e05f2a Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:39 +0530 Subject: [PATCH 385/659] wifi: ath12k: Move hal_desc.h file to wifi7 directory Move wifi7 architecture specific file hal_desc.h to wifi7 directory, and move the common part from it to hal.h file which is in the common directory. It is as part of a broader effort to separate common and hardware-specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/hal.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 149 +++++++++++++++++- .../ath/ath12k/{ => wifi7}/hal_desc.h | 149 +----------------- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 2 +- 8 files changed, 156 insertions(+), 154 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_desc.h (95%) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index dc33a0f85f2af..e0c610f7ff885 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -7,7 +7,7 @@ #ifndef ATH12K_DP_H #define ATH12K_DP_H -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "wifi7/hal_rx.h" #include "hw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 80338421903b6..acae235ec9ebe 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -10,7 +10,7 @@ #include #include "core.h" #include "debug.h" -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "hw.h" #include "dp_rx.h" #include "wifi7/hal_rx.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index f9ce60d22cc1a..144c26586b794 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -7,7 +7,7 @@ #include "wifi7/hal_tx.h" #include "wifi7/hal_rx.h" #include "debug.h" -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "hif.h" static const struct hal_srng_config hw_srng_config_template[] = { diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 322ebfed9b011..8e408b81c7736 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -7,11 +7,13 @@ #ifndef ATH12K_HAL_H #define ATH12K_HAL_H -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "rx_desc.h" struct ath12k_base; +#define HAL_DESC_REO_NON_QOS_TID 16 + #define HAL_INVALID_PEERID 0x3fff #define VHT_SIG_SU_NSS_MASK 0x7 @@ -672,6 +674,128 @@ enum hal_reo_cmd_status { HAL_REO_CMD_DRAIN = 0xff, }; +enum hal_tcl_encap_type { + HAL_TCL_ENCAP_TYPE_RAW, + HAL_TCL_ENCAP_TYPE_NATIVE_WIFI, + HAL_TCL_ENCAP_TYPE_ETHERNET, + HAL_TCL_ENCAP_TYPE_802_3 = 3, + HAL_TCL_ENCAP_TYPE_MAX +}; + +enum hal_tcl_desc_type { + HAL_TCL_DESC_TYPE_BUFFER, + HAL_TCL_DESC_TYPE_EXT_DESC, + HAL_TCL_DESC_TYPE_MAX, +}; + +enum hal_reo_dest_ring_buffer_type { + HAL_REO_DEST_RING_BUFFER_TYPE_MSDU, + HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC, +}; + +enum hal_reo_dest_ring_push_reason { + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED, + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION, +}; + +enum hal_reo_entr_rxdma_push_reason { + HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ERR_DETECTED, + HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ROUTING_INSTRUCTION, + HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_RX_FLUSH, +}; + +enum hal_reo_dest_ring_error_code { + HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO, + HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID, + HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA, + HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE, + HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE, + HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP, + HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP, + HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR, + HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR, + HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION, + HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN, + HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED, + HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET, + HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET, + HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED, + HAL_REO_DEST_RING_ERROR_CODE_MAX, +}; + +enum hal_reo_entr_rxdma_ecode { + HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MAX, +}; + +enum hal_wbm_htt_tx_comp_status { + HAL_WBM_REL_HTT_TX_COMP_STATUS_OK, + HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP, + HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL, + HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ, + HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT, + HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY, + HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH, + HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX, +}; + +enum hal_encrypt_type { + HAL_ENCRYPT_TYPE_WEP_40, + HAL_ENCRYPT_TYPE_WEP_104, + HAL_ENCRYPT_TYPE_TKIP_NO_MIC, + HAL_ENCRYPT_TYPE_WEP_128, + HAL_ENCRYPT_TYPE_TKIP_MIC, + HAL_ENCRYPT_TYPE_WAPI, + HAL_ENCRYPT_TYPE_CCMP_128, + HAL_ENCRYPT_TYPE_OPEN, + HAL_ENCRYPT_TYPE_CCMP_256, + HAL_ENCRYPT_TYPE_GCMP_128, + HAL_ENCRYPT_TYPE_AES_GCMP_256, + HAL_ENCRYPT_TYPE_WAPI_GCM_SM4, +}; + +enum hal_tx_rate_stats_bw { + HAL_TX_RATE_STATS_BW_20, + HAL_TX_RATE_STATS_BW_40, + HAL_TX_RATE_STATS_BW_80, + HAL_TX_RATE_STATS_BW_160, +}; + +enum hal_tx_rate_stats_pkt_type { + HAL_TX_RATE_STATS_PKT_TYPE_11A, + HAL_TX_RATE_STATS_PKT_TYPE_11B, + HAL_TX_RATE_STATS_PKT_TYPE_11N, + HAL_TX_RATE_STATS_PKT_TYPE_11AC, + HAL_TX_RATE_STATS_PKT_TYPE_11AX, + HAL_TX_RATE_STATS_PKT_TYPE_11BA, + HAL_TX_RATE_STATS_PKT_TYPE_11BE, +}; + +enum hal_tx_rate_stats_sgi { + HAL_TX_RATE_STATS_SGI_08US, + HAL_TX_RATE_STATS_SGI_04US, + HAL_TX_RATE_STATS_SGI_16US, + HAL_TX_RATE_STATS_SGI_32US, +}; + struct hal_wbm_idle_scatter_list { dma_addr_t paddr; struct hal_wbm_link_desc *vaddr; @@ -1281,6 +1405,29 @@ struct ath12k_hal_tcl_to_wbm_rbm_map { u8 rbm_id; }; +enum hal_wbm_rel_bm_act { + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE, + HAL_WBM_REL_BM_ACT_REL_MSDU, +}; + +/* hal_wbm_rel_bm_act + * + * put_in_idle_list + * Put the buffer or descriptor back in the idle list. In case of MSDU or + * MDPU link descriptor, BM does not need to check to release any + * individual MSDU buffers. + * + * release_msdu_list + * This BM action can only be used in combination with desc_type being + * msdu_link_descriptor. Field first_msdu_index points out which MSDU + * pointer in the MSDU link descriptor is the first of an MPDU that is + * released. BM shall release all the MSDU buffers linked to this first + * MSDU buffer pointer. All related MSDU buffer pointer entries shall be + * set to value 0, which represents the 'NULL' pointer. When all MSDU + * buffer pointers in the MSDU link descriptor are 'NULL', the MSDU link + * descriptor itself shall also be released. + */ + #define RU_INVALID 0 #define RU_26 1 #define RU_52 2 diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h similarity index 95% rename from drivers/net/wireless/ath/ath12k/hal_desc.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 13ddac4a94125..b884f4f089387 100644 --- a/drivers/net/wireless/ath/ath12k/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "core.h" +#include "../core.h" #ifndef ATH12K_HAL_DESC_H #define ATH12K_HAL_DESC_H @@ -820,35 +820,6 @@ struct rx_msdu_ext_desc { * Set to the link ID of the PMAC that received the frame */ -enum hal_reo_dest_ring_buffer_type { - HAL_REO_DEST_RING_BUFFER_TYPE_MSDU, - HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC, -}; - -enum hal_reo_dest_ring_push_reason { - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED, - HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION, -}; - -enum hal_reo_dest_ring_error_code { - HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO, - HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID, - HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA, - HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE, - HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE, - HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP, - HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP, - HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR, - HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR, - HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION, - HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN, - HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED, - HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET, - HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET, - HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED, - HAL_REO_DEST_RING_ERROR_CODE_MAX, -}; - #define HAL_REO_DEST_RING_INFO0_BUFFER_TYPE BIT(0) #define HAL_REO_DEST_RING_INFO0_PUSH_REASON GENMASK(2, 1) #define HAL_REO_DEST_RING_INFO0_ERROR_CODE GENMASK(7, 3) @@ -986,35 +957,6 @@ struct hal_reo_to_ppe_ring { * More Segments followed */ -enum hal_reo_entr_rxdma_push_reason { - HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ERR_DETECTED, - HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ROUTING_INSTRUCTION, - HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_RX_FLUSH, -}; - -enum hal_reo_entr_rxdma_ecode { - HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MAX, -}; - enum hal_rx_reo_dest_ring { HAL_RX_REO_DEST_RING_TCL, HAL_RX_REO_DEST_RING_SW1, @@ -1269,46 +1211,6 @@ struct hal_reo_flush_cache { #define HAL_TCL_DATA_CMD_INFO5_RING_ID GENMASK(27, 20) #define HAL_TCL_DATA_CMD_INFO5_LOOPING_COUNT GENMASK(31, 28) -enum hal_encrypt_type { - HAL_ENCRYPT_TYPE_WEP_40, - HAL_ENCRYPT_TYPE_WEP_104, - HAL_ENCRYPT_TYPE_TKIP_NO_MIC, - HAL_ENCRYPT_TYPE_WEP_128, - HAL_ENCRYPT_TYPE_TKIP_MIC, - HAL_ENCRYPT_TYPE_WAPI, - HAL_ENCRYPT_TYPE_CCMP_128, - HAL_ENCRYPT_TYPE_OPEN, - HAL_ENCRYPT_TYPE_CCMP_256, - HAL_ENCRYPT_TYPE_GCMP_128, - HAL_ENCRYPT_TYPE_AES_GCMP_256, - HAL_ENCRYPT_TYPE_WAPI_GCM_SM4, -}; - -enum hal_tcl_encap_type { - HAL_TCL_ENCAP_TYPE_RAW, - HAL_TCL_ENCAP_TYPE_NATIVE_WIFI, - HAL_TCL_ENCAP_TYPE_ETHERNET, - HAL_TCL_ENCAP_TYPE_802_3 = 3, - HAL_TCL_ENCAP_TYPE_MAX -}; - -enum hal_tcl_desc_type { - HAL_TCL_DESC_TYPE_BUFFER, - HAL_TCL_DESC_TYPE_EXT_DESC, - HAL_TCL_DESC_TYPE_MAX, -}; - -enum hal_wbm_htt_tx_comp_status { - HAL_WBM_REL_HTT_TX_COMP_STATUS_OK, - HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP, - HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL, - HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ, - HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT, - HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY, - HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH, - HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX, -}; - struct hal_tcl_data_cmd { struct ath12k_buffer_addr buf_addr_info; __le32 info0; @@ -1765,30 +1667,6 @@ struct hal_ce_srng_dst_status_desc { #define HAL_TX_RATE_STATS_INFO0_OFDMA_TX BIT(16) #define HAL_TX_RATE_STATS_INFO0_TONES_IN_RU GENMASK(28, 17) -enum hal_tx_rate_stats_bw { - HAL_TX_RATE_STATS_BW_20, - HAL_TX_RATE_STATS_BW_40, - HAL_TX_RATE_STATS_BW_80, - HAL_TX_RATE_STATS_BW_160, -}; - -enum hal_tx_rate_stats_pkt_type { - HAL_TX_RATE_STATS_PKT_TYPE_11A, - HAL_TX_RATE_STATS_PKT_TYPE_11B, - HAL_TX_RATE_STATS_PKT_TYPE_11N, - HAL_TX_RATE_STATS_PKT_TYPE_11AC, - HAL_TX_RATE_STATS_PKT_TYPE_11AX, - HAL_TX_RATE_STATS_PKT_TYPE_11BA, - HAL_TX_RATE_STATS_PKT_TYPE_11BE, -}; - -enum hal_tx_rate_stats_sgi { - HAL_TX_RATE_STATS_SGI_08US, - HAL_TX_RATE_STATS_SGI_04US, - HAL_TX_RATE_STATS_SGI_16US, - HAL_TX_RATE_STATS_SGI_32US, -}; - struct hal_tx_rate_stats { __le32 info0; __le32 tsf; @@ -1844,28 +1722,6 @@ enum hal_wbm_rel_desc_type { * treat this is the same way as a link descriptor. */ -enum hal_wbm_rel_bm_act { - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE, - HAL_WBM_REL_BM_ACT_REL_MSDU, -}; - -/* hal_wbm_rel_bm_act - * - * put_in_idle_list - * Put the buffer or descriptor back in the idle list. In case of MSDU or - * MDPU link descriptor, BM does not need to check to release any - * individual MSDU buffers. - * - * release_msdu_list - * This BM action can only be used in combination with desc_type being - * msdu_link_descriptor. Field first_msdu_index points out which MSDU - * pointer in the MSDU link descriptor is the first of an MPDU that is - * released. BM shall release all the MSDU buffers linked to this first - * MSDU buffer pointer. All related MSDU buffer pointer entries shall be - * set to value 0, which represents the 'NULL' pointer. When all MSDU - * buffer pointers in the MSDU link descriptor are 'NULL', the MSDU link - * descriptor itself shall also be released. - */ #define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0) #define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3) #define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6) @@ -2331,7 +2187,6 @@ enum hal_desc_buf_type { #define HAL_DESC_REO_OWNED 4 #define HAL_DESC_REO_QUEUE_DESC 8 #define HAL_DESC_REO_QUEUE_EXT_DESC 9 -#define HAL_DESC_REO_NON_QOS_TID 16 #define HAL_DESC_HDR_INFO0_OWNER GENMASK(3, 0) #define HAL_DESC_HDR_INFO0_BUF_TYPE GENMASK(7, 4) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index e8379e660d3a5..e539f3b1eeafc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -9,7 +9,7 @@ #include "../hif.h" #include "hal_tx.h" #include "hal_rx.h" -#include "../hal_desc.h" +#include "hal_desc.h" static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, u8 owner, u8 buffer_type, u32 magic) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 87c1312c4f46d..3a7d3163b1a56 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -4,7 +4,7 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "../hal_desc.h" +#include "hal_desc.h" #include "../hal.h" #include "hal_tx.h" #include "../hif.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index b179320569ff7..412fe1ba22dcc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -7,7 +7,7 @@ #ifndef ATH12K_HAL_TX_H #define ATH12K_HAL_TX_H -#include "../hal_desc.h" +#include "hal_desc.h" #include "../core.h" /* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */ From 691e254f2be850ff66042f07c6b1daedfd66d72e Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:40 +0530 Subject: [PATCH 386/659] wifi: ath12k: Move rx_desc.h file to wifi7 directory Move wifi7 architecture specific file rx_desc.h to wifi7 directory and rename it to hal_rx_desc.h to match the naming convention used, and move the common part from it to hal.h file which is in the common directory. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 48 ++++++++++++++++++- .../ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} | 48 +------------------ 3 files changed, 49 insertions(+), 49 deletions(-) rename drivers/net/wireless/ath/ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} (97%) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 939dc60ec4582..f06c102750733 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -7,7 +7,7 @@ #define ATH12K_DP_RX_H #include "core.h" -#include "rx_desc.h" +#include "wifi7/hal_rx_desc.h" #include "debug.h" #define DP_MAX_NWIFI_HDR_LEN 30 diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 8e408b81c7736..4b512fd3adc41 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -8,7 +8,7 @@ #define ATH12K_HAL_H #include "wifi7/hal_desc.h" -#include "rx_desc.h" +#include "wifi7/hal_rx_desc.h" struct ath12k_base; @@ -30,6 +30,11 @@ struct ath12k_base; #define HAL_RX_MON_MAX_AGGR_SIZE 128 #define HAL_MAX_UL_MU_USERS 37 +#define MAX_USER_POS 8 +#define MAX_MU_GROUP_ID 64 +#define MAX_MU_GROUP_SHOW 16 +#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW) + #define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr) #define HAL_LINK_DESC_SIZE (32 << 2) @@ -824,6 +829,47 @@ enum hal_srng_dir { HAL_SRNG_DIR_DST }; +enum rx_msdu_start_pkt_type { + RX_MSDU_START_PKT_TYPE_11A, + RX_MSDU_START_PKT_TYPE_11B, + RX_MSDU_START_PKT_TYPE_11N, + RX_MSDU_START_PKT_TYPE_11AC, + RX_MSDU_START_PKT_TYPE_11AX, + RX_MSDU_START_PKT_TYPE_11BA, + RX_MSDU_START_PKT_TYPE_11BE, +}; + +enum rx_msdu_start_sgi { + RX_MSDU_START_SGI_0_8_US, + RX_MSDU_START_SGI_0_4_US, + RX_MSDU_START_SGI_1_6_US, + RX_MSDU_START_SGI_3_2_US, +}; + +enum rx_msdu_start_recv_bw { + RX_MSDU_START_RECV_BW_20MHZ, + RX_MSDU_START_RECV_BW_40MHZ, + RX_MSDU_START_RECV_BW_80MHZ, + RX_MSDU_START_RECV_BW_160MHZ, +}; + +enum rx_msdu_start_reception_type { + RX_MSDU_START_RECEPTION_TYPE_SU, + RX_MSDU_START_RECEPTION_TYPE_DL_MU_MIMO, + RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA, + RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA_MIMO, + RX_MSDU_START_RECEPTION_TYPE_UL_MU_MIMO, + RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA, + RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO, +}; + +enum rx_desc_decap_type { + RX_DESC_DECAP_TYPE_RAW, + RX_DESC_DECAP_TYPE_NATIVE_WIFI, + RX_DESC_DECAP_TYPE_ETHERNET2_DIX, + RX_DESC_DECAP_TYPE_8023, +}; + struct hal_rx_user_status { u32 mcs:4, nss:3, diff --git a/drivers/net/wireless/ath/ath12k/rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h similarity index 97% rename from drivers/net/wireless/ath/ath12k/rx_desc.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h index 6c600473b4021..60f165a176e0f 100644 --- a/drivers/net/wireless/ath/ath12k/rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h @@ -1,18 +1,11 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_RX_DESC_H #define ATH12K_RX_DESC_H -enum rx_desc_decap_type { - RX_DESC_DECAP_TYPE_RAW, - RX_DESC_DECAP_TYPE_NATIVE_WIFI, - RX_DESC_DECAP_TYPE_ETHERNET2_DIX, - RX_DESC_DECAP_TYPE_8023, -}; - enum rx_desc_decrypt_status_code { RX_DESC_DECRYPT_STATUS_CODE_OK, RX_DESC_DECRYPT_STATUS_CODE_UNPROTECTED_FRAME, @@ -631,40 +624,6 @@ struct rx_mpdu_start_qcn9274_compact { * */ -enum rx_msdu_start_pkt_type { - RX_MSDU_START_PKT_TYPE_11A, - RX_MSDU_START_PKT_TYPE_11B, - RX_MSDU_START_PKT_TYPE_11N, - RX_MSDU_START_PKT_TYPE_11AC, - RX_MSDU_START_PKT_TYPE_11AX, - RX_MSDU_START_PKT_TYPE_11BA, - RX_MSDU_START_PKT_TYPE_11BE, -}; - -enum rx_msdu_start_sgi { - RX_MSDU_START_SGI_0_8_US, - RX_MSDU_START_SGI_0_4_US, - RX_MSDU_START_SGI_1_6_US, - RX_MSDU_START_SGI_3_2_US, -}; - -enum rx_msdu_start_recv_bw { - RX_MSDU_START_RECV_BW_20MHZ, - RX_MSDU_START_RECV_BW_40MHZ, - RX_MSDU_START_RECV_BW_80MHZ, - RX_MSDU_START_RECV_BW_160MHZ, -}; - -enum rx_msdu_start_reception_type { - RX_MSDU_START_RECEPTION_TYPE_SU, - RX_MSDU_START_RECEPTION_TYPE_DL_MU_MIMO, - RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA, - RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA_MIMO, - RX_MSDU_START_RECEPTION_TYPE_UL_MU_MIMO, - RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA, - RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO, -}; - #define RX_MSDU_END_64_TLV_SRC_LINK_ID GENMASK(24, 22) #define RX_MSDU_END_INFO0_RXPCU_MPDU_FITLER GENMASK(1, 0) @@ -1536,9 +1495,4 @@ struct hal_rx_desc { } u; } __packed; -#define MAX_USER_POS 8 -#define MAX_MU_GROUP_ID 64 -#define MAX_MU_GROUP_SHOW 16 -#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW) - #endif /* ATH12K_RX_DESC_H */ From 71b8da1abd95a52cc87f77d9b3830e289dafae98 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:41 +0530 Subject: [PATCH 387/659] wifi: ath12k: Move rxdma ring config functions to wifi7 directory Move architecture specific RxDMA functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_rxdma_ring_sel_config_qcn9274 ath12k_dp_rxdma_ring_sel_config_wcn7850 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 85 ------------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 3 - drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 85 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +- 5 files changed, 89 insertions(+), 90 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index acae235ec9ebe..f6d083d4eb91f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -3945,91 +3945,6 @@ void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int mac_id) ath12k_dp_rx_pdev_srng_free(ar); } -int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct htt_rx_ring_tlv_filter tlv_filter = {}; - u32 ring_id; - int ret; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; - - ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; - - tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; - tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; - tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; - tlv_filter.offset_valid = true; - tlv_filter.rx_packet_offset = hal_rx_desc_sz; - - tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); - tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); - - if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { - tlv_filter.rx_mpdu_start_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); - tlv_filter.rx_msdu_end_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", - tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); - } - - ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, - HAL_RXDMA_BUF, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - - return ret; -} -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); - -int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct htt_rx_ring_tlv_filter tlv_filter = {}; - u32 ring_id; - int ret = 0; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; - int i; - - ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; - - tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; - tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; - tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; - tlv_filter.offset_valid = true; - tlv_filter.rx_packet_offset = hal_rx_desc_sz; - - tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); - - tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); - tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); - - /* TODO: Selectively subscribe to required qwords within msdu_end - * and mpdu_start and setup the mask in below msg - * and modify the rx_desc struct - */ - - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = dp->rx_mac_buf_ring[i].ring_id; - ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i, - HAL_RXDMA_BUF, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - } - - return ret; -} -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); - int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index f06c102750733..417b18670096e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -416,9 +416,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); -int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); - int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, const void *ptr, void *data), diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 26539a4d4b303..a002e3839fff8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -348,3 +348,88 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, done: return total_num_buffs_reaped; } + +int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct htt_rx_ring_tlv_filter tlv_filter = {}; + u32 ring_id; + int ret; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + + ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; + + tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; + tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; + tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; + tlv_filter.offset_valid = true; + tlv_filter.rx_packet_offset = hal_rx_desc_sz; + + tlv_filter.rx_mpdu_start_offset = + ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + tlv_filter.rx_msdu_end_offset = + ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + + if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { + tlv_filter.rx_mpdu_start_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); + tlv_filter.rx_msdu_end_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", + tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); + } + + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + + return ret; +} +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); + +int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct htt_rx_ring_tlv_filter tlv_filter = {}; + u32 ring_id; + int ret = 0; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + int i; + + ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; + + tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; + tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; + tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; + tlv_filter.offset_valid = true; + tlv_filter.rx_packet_offset = hal_rx_desc_sz; + + tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); + + tlv_filter.rx_mpdu_start_offset = + ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + tlv_filter.rx_msdu_end_offset = + ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + + /* TODO: Selectively subscribe to required qwords within msdu_end + * and mpdu_start and setup the mask in below msg + * and modify the rx_desc struct + */ + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = dp->rx_mac_buf_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + } + + return ret; +} +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index a6da98962345d..154018c221dad 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -11,4 +11,6 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); +int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); +int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 82b4f5b9f5700..909f7311619cd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -16,7 +16,7 @@ #include "hw.h" #include "../mhi.h" #include "mhi.h" -#include "../dp_rx.h" +#include "dp_rx.h" #include "../peer.h" #include "wmi.h" From be3943a765f3ee248d51b796bdf084fec55143e7 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:42 +0530 Subject: [PATCH 388/659] wifi: ath12k: Move rx error and defrag functions to wifi7 directory Move arch specific RX error and defrag functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_rx_h_defrag_validate_incr_pn ath12k_dp_rx_h_defrag_reo_reinject ath12k_dp_rx_h_defrag ath12k_dp_rx_frag_h_mpdu ath12k_dp_process_rx_err_buf ath12k_dp_rx_process_err ath12k_dp_rx_null_q_desc_sg_drop ath12k_dp_rx_h_null_q_desc Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 727 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 21 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 682 ++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 + 4 files changed, 714 insertions(+), 718 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index f6d083d4eb91f..b5630b71ebee3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -19,8 +19,6 @@ #include "dp_mon.h" #include "debugfs_htt_stats.h" -#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) - static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, struct ath12k_dp_rx_tid_rxq *rx_tid); @@ -715,8 +713,8 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, return ret; } -static void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, - bool rel_link_desc) +void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc) { struct ath12k_buffer_addr *buf_addr_info; struct ath12k_base *ab = rx_tid->ab; @@ -2202,10 +2200,10 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) +void ath12k_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct ath12k_dp_rx_info *rx_info) { struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb; @@ -2950,8 +2948,8 @@ static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, return ret; } -static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu) +int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, + struct sk_buff *msdu) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; @@ -3014,8 +3012,8 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer return -EINVAL; } -static void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, - enum hal_encrypt_type enctype, u32 flags) +void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, + enum hal_encrypt_type enctype, u32 flags) { struct ieee80211_hdr *hdr; size_t hdr_len; @@ -3045,222 +3043,6 @@ static void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, } } -static int ath12k_dp_rx_h_defrag(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff **defrag_skb) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; - struct sk_buff *skb, *first_frag, *last_frag; - struct ieee80211_hdr *hdr; - enum hal_encrypt_type enctype; - bool is_decrypted = false; - int msdu_len = 0; - int extra_space; - u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - first_frag = skb_peek(&rx_tid->rx_frags); - last_frag = skb_peek_tail(&rx_tid->rx_frags); - - skb_queue_walk(&rx_tid->rx_frags, skb) { - flags = 0; - rx_desc = (struct hal_rx_desc *)skb->data; - hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); - - enctype = ath12k_dp_rx_h_enctype(ab, rx_desc); - if (enctype != HAL_ENCRYPT_TYPE_OPEN) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, - rx_desc); - - if (is_decrypted) { - if (skb != first_frag) - flags |= RX_FLAG_IV_STRIPPED; - if (skb != last_frag) - flags |= RX_FLAG_ICV_STRIPPED | - RX_FLAG_MIC_STRIPPED; - } - - /* RX fragments are always raw packets */ - if (skb != last_frag) - skb_trim(skb, skb->len - FCS_LEN); - ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); - - if (skb != first_frag) - skb_pull(skb, hal_rx_desc_sz + - ieee80211_hdrlen(hdr->frame_control)); - msdu_len += skb->len; - } - - extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag)); - if (extra_space > 0 && - (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0)) - return -ENOMEM; - - __skb_unlink(first_frag, &rx_tid->rx_frags); - while ((skb = __skb_dequeue(&rx_tid->rx_frags))) { - skb_put_data(first_frag, skb->data, skb->len); - dev_kfree_skb_any(skb); - } - - hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz); - hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); - ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - - if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) - first_frag = NULL; - - *defrag_skb = first_frag; - return 0; -} - -static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff *defrag_skb) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; - struct hal_reo_entrance_ring *reo_ent_ring; - struct hal_reo_dest_ring *reo_dest_ring; - struct dp_link_desc_bank *link_desc_banks; - struct hal_rx_msdu_link *msdu_link; - struct hal_rx_msdu_details *msdu0; - struct hal_srng *srng; - dma_addr_t link_paddr, buf_paddr; - u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info; - u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi; - int ret; - struct ath12k_rx_desc_info *desc_info; - enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm; - u8 dst_ind; - - hal_rx_desc_sz = ab->hal.hal_desc_sz; - link_desc_banks = dp->link_desc_banks; - reo_dest_ring = rx_tid->dst_ring_desc; - - ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, - &link_paddr, &cookie); - desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); - - msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + - (link_paddr - link_desc_banks[desc_bank].paddr)); - msdu0 = &msdu_link->msdu_link[0]; - msdu_ext_info = le32_to_cpu(msdu0->rx_msdu_ext_info.info0); - dst_ind = u32_get_bits(msdu_ext_info, RX_MSDU_EXT_DESC_INFO0_REO_DEST_IND); - - memset(msdu0, 0, sizeof(*msdu0)); - - msdu_info = u32_encode_bits(1, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU) | - u32_encode_bits(1, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU) | - u32_encode_bits(0, RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) | - u32_encode_bits(defrag_skb->len - hal_rx_desc_sz, - RX_MSDU_DESC_INFO0_MSDU_LENGTH) | - u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_SA) | - u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_DA); - msdu0->rx_msdu_info.info0 = cpu_to_le32(msdu_info); - msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info); - - /* change msdu len in hal rx desc */ - ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); - - buf_paddr = dma_map_single(ab->dev, defrag_skb->data, - defrag_skb->len + skb_tailroom(defrag_skb), - DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, buf_paddr)) - return -ENOMEM; - - spin_lock_bh(&dp->rx_desc_lock); - desc_info = list_first_entry_or_null(&dp->rx_desc_free_list, - struct ath12k_rx_desc_info, - list); - if (!desc_info) { - spin_unlock_bh(&dp->rx_desc_lock); - ath12k_warn(ab, "failed to find rx desc for reinject\n"); - ret = -ENOMEM; - goto err_unmap_dma; - } - - desc_info->skb = defrag_skb; - desc_info->in_use = true; - - list_del(&desc_info->list); - spin_unlock_bh(&dp->rx_desc_lock); - - ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; - - ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, - desc_info->cookie, - HAL_RX_BUF_RBM_SW3_BM); - - /* Fill mpdu details into reo entrance ring */ - srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; - - spin_lock_bh(&srng->lock); - ath12k_hal_srng_access_begin(ab, srng); - - reo_ent_ring = ath12k_hal_srng_src_get_next_entry(ab, srng); - if (!reo_ent_ring) { - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - ret = -ENOSPC; - goto err_free_desc; - } - memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); - - ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, - cookie, - idle_link_rbm); - - mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) | - u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) | - u32_encode_bits(1, RX_MPDU_DESC_INFO0_RAW_MPDU) | - u32_encode_bits(1, RX_MPDU_DESC_INFO0_VALID_PN) | - u32_encode_bits(rx_tid->tid, RX_MPDU_DESC_INFO0_TID); - - reo_ent_ring->rx_mpdu_info.info0 = cpu_to_le32(mpdu_info); - reo_ent_ring->rx_mpdu_info.peer_meta_data = - reo_dest_ring->rx_mpdu_info.peer_meta_data; - - if (ab->hw_params->reoq_lut_support) { - reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; - queue_addr_hi = 0; - } else { - reo_ent_ring->queue_addr_lo = - cpu_to_le32(lower_32_bits(rx_tid->qbuf.paddr_aligned)); - queue_addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - } - - reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi, - HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) | - le32_encode_bits(dst_ind, - HAL_REO_ENTR_RING_INFO0_DEST_IND); - - reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn, - HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM); - dest_ring_info0 = le32_get_bits(reo_dest_ring->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - reo_ent_ring->info2 = - cpu_to_le32(u32_get_bits(dest_ring_info0, - HAL_REO_ENTR_RING_INFO2_SRC_LINK_ID)); - - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - return 0; - -err_free_desc: - spin_lock_bh(&dp->rx_desc_lock); - desc_info->in_use = false; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, &dp->rx_desc_free_list); - spin_unlock_bh(&dp->rx_desc_lock); -err_unmap_dma: - dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), - DMA_TO_DEVICE); - return ret; -} - static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, struct sk_buff *a, struct sk_buff *b) { @@ -3272,9 +3054,9 @@ static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, return frag1 - frag2; } -static void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, - struct sk_buff_head *frag_list, - struct sk_buff *cur_frag) +void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, + struct sk_buff_head *frag_list, + struct sk_buff *cur_frag) { struct sk_buff *skb; int cmp; @@ -3289,7 +3071,7 @@ static void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, __skb_queue_tail(frag_list, cur_frag); } -static u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) +u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) { struct ieee80211_hdr *hdr; u64 pn = 0; @@ -3309,244 +3091,6 @@ static u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) return pn; } -static bool -ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) -{ - struct ath12k_base *ab = ar->ab; - enum hal_encrypt_type encrypt_type; - struct sk_buff *first_frag, *skb; - struct hal_rx_desc *desc; - u64 last_pn; - u64 cur_pn; - - first_frag = skb_peek(&rx_tid->rx_frags); - desc = (struct hal_rx_desc *)first_frag->data; - - encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); - if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && - encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && - encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && - encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) - return true; - - last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); - skb_queue_walk(&rx_tid->rx_frags, skb) { - if (skb == first_frag) - continue; - - cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); - if (cur_pn != last_pn + 1) - return false; - last_pn = cur_pn; - } - return true; -} - -static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_reo_dest_ring *ring_desc) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; - struct ath12k_peer *peer; - struct ath12k_dp_rx_tid *rx_tid; - struct sk_buff *defrag_skb = NULL; - u32 peer_id; - u16 seqno, frag_no; - u8 tid; - int ret = 0; - bool more_frags; - - rx_desc = (struct hal_rx_desc *)msdu->data; - peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); - tid = ath12k_dp_rx_h_tid(ab, rx_desc); - seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); - frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); - more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); - - if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || - !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || - tid > IEEE80211_NUM_TIDS) - return -EINVAL; - - /* received unfragmented packet in reo - * exception ring, this shouldn't happen - * as these packets typically come from - * reo2sw srngs. - */ - if (WARN_ON_ONCE(!frag_no && !more_frags)) - return -EINVAL; - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", - peer_id); - ret = -ENOENT; - goto out_unlock; - } - - if (!peer->dp_setup_done) { - ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", - peer->addr, peer_id); - ret = -ENOENT; - goto out_unlock; - } - - rx_tid = &peer->rx_tid[tid]; - - if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || - skb_queue_empty(&rx_tid->rx_frags)) { - /* Flush stored fragments and start a new sequence */ - ath12k_dp_rx_frags_cleanup(rx_tid, true); - rx_tid->cur_sn = seqno; - } - - if (rx_tid->rx_frag_bitmap & BIT(frag_no)) { - /* Fragment already present */ - ret = -EINVAL; - goto out_unlock; - } - - if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) - __skb_queue_tail(&rx_tid->rx_frags, msdu); - else - ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); - - rx_tid->rx_frag_bitmap |= BIT(frag_no); - if (!more_frags) - rx_tid->last_frag_no = frag_no; - - if (frag_no == 0) { - rx_tid->dst_ring_desc = kmemdup(ring_desc, - sizeof(*rx_tid->dst_ring_desc), - GFP_ATOMIC); - if (!rx_tid->dst_ring_desc) { - ret = -ENOMEM; - goto out_unlock; - } - } else { - ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - } - - if (!rx_tid->last_frag_no || - rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) { - mod_timer(&rx_tid->frag_timer, jiffies + - ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS); - goto out_unlock; - } - - spin_unlock_bh(&ab->base_lock); - timer_delete_sync(&rx_tid->frag_timer); - spin_lock_bh(&ab->base_lock); - - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) - goto err_frags_cleanup; - - if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) - goto err_frags_cleanup; - - if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) - goto err_frags_cleanup; - - if (!defrag_skb) - goto err_frags_cleanup; - - if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) - goto err_frags_cleanup; - - ath12k_dp_rx_frags_cleanup(rx_tid, false); - goto out_unlock; - -err_frags_cleanup: - dev_kfree_skb_any(defrag_skb); - ath12k_dp_rx_frags_cleanup(rx_tid, true); -out_unlock: - spin_unlock_bh(&ab->base_lock); - return ret; -} - -static int -ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, - struct list_head *used_list, - bool drop, u32 cookie) -{ - struct ath12k_base *ab = ar->ab; - struct sk_buff *msdu; - struct ath12k_skb_rxcb *rxcb; - struct hal_rx_desc *rx_desc; - u16 msdu_len; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; - struct ath12k_rx_desc_info *desc_info; - u64 desc_va; - - desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | - le32_to_cpu(desc->buf_va_lo)); - desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); - - /* retry manual desc retrieval */ - if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, cookie); - if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", - cookie); - return -EINVAL; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, " RX Exception, Check HW CC implementation"); - - msdu = desc_info->skb; - desc_info->skb = NULL; - - list_add_tail(&desc_info->list, used_list); - - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ar->ab->dev, rxcb->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - if (drop) { - dev_kfree_skb_any(msdu); - return 0; - } - - rcu_read_lock(); - if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) { - dev_kfree_skb_any(msdu); - goto exit; - } - - if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { - dev_kfree_skb_any(msdu); - goto exit; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); - if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, - sizeof(*rx_desc)); - dev_kfree_skb_any(msdu); - goto exit; - } - - skb_put(msdu, hal_rx_desc_sz + msdu_len); - - if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { - dev_kfree_skb_any(msdu); - ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - } -exit: - rcu_read_unlock(); - return 0; -} - static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, struct list_head *list, struct hal_reo_dest_ring *desc) @@ -3591,249 +3135,6 @@ static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, return 0; } -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget) -{ - struct ath12k_hw_group *ag = ab->ag; - struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; - int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; - struct dp_link_desc_bank *link_desc_banks; - enum hal_rx_buf_return_buf_manager rbm; - struct hal_rx_msdu_link *link_desc_va; - int tot_n_bufs_reaped, quota, ret, i; - struct hal_reo_dest_ring *reo_desc; - struct dp_rxdma_ring *rx_ring; - struct dp_srng *reo_except; - struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; - u8 hw_link_id, device_id; - u32 desc_bank, num_msdus; - struct hal_srng *srng; - struct ath12k *ar; - dma_addr_t paddr; - bool is_frag; - bool drop; - int pdev_id; - - tot_n_bufs_reaped = 0; - quota = budget; - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) - INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - - reo_except = &ab->dp.reo_except_ring; - - srng = &ab->hal.srng_list[reo_except->ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (budget && - (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - drop = false; - ab->device_stats.err_ring_pkts++; - - hw_link_id = le32_get_bits(reo_desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - - /* Below case is added to handle data packet from un-associated clients. - * As it is expected that AST lookup will fail for - * un-associated station's data packets. - */ - if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == - HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { - if (!ath12k_dp_h_msdu_buffer_type(partner_ab, - &rx_desc_used_list[device_id], - reo_desc)) { - num_buffs_reaped[device_id]++; - tot_n_bufs_reaped++; - } - goto next_desc; - } - - ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, - &desc_bank); - if (ret) { - ath12k_warn(ab, "failed to parse error reo desc %d\n", - ret); - continue; - } - - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; - - link_desc_banks = partner_ab->dp.link_desc_banks; - link_desc_va = link_desc_banks[desc_bank].vaddr + - (paddr - link_desc_banks[desc_bank].paddr); - ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, - &rbm); - if (rbm != partner_ab->dp.idle_link_rbm && - rbm != HAL_RX_BUF_RBM_SW3_BM && - rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { - ab->device_stats.invalid_rbm++; - ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_REL_MSDU); - continue; - } - - is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) & - RX_MPDU_DESC_INFO0_FRAG_FLAG); - - /* Process only rx fragments with one msdu per link desc below, and drop - * msdu's indicated due to error reasons. - * Dynamic fragmentation not supported in Multi-link client, so drop the - * partner device buffers. - */ - if (!is_frag || num_msdus > 1 || - partner_ab->device_id != ab->device_id) { - drop = true; - - /* Return the link desc back to wbm idle list */ - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - } - - for (i = 0; i < num_msdus; i++) { - if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, - &rx_desc_used_list[device_id], - drop, - msdu_cookies[i])) { - num_buffs_reaped[device_id]++; - tot_n_bufs_reaped++; - } - } - -next_desc: - if (tot_n_bufs_reaped >= quota) { - tot_n_bufs_reaped = quota; - goto exit; - } - - budget = quota - tot_n_bufs_reaped; - } - -exit: - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { - if (!num_buffs_reaped[device_id]) - continue; - - partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; - - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, - &rx_desc_used_list[device_id], - num_buffs_reaped[device_id]); - } - - return tot_n_bufs_reaped; -} - -static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, - int msdu_len, - struct sk_buff_head *msdu_list) -{ - struct sk_buff *skb, *tmp; - struct ath12k_skb_rxcb *rxcb; - int n_buffs; - - n_buffs = DIV_ROUND_UP(msdu_len, - (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); - - skb_queue_walk_safe(msdu_list, skb, tmp) { - rxcb = ATH12K_SKB_RXCB(skb); - if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO && - rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) { - if (!n_buffs) - break; - __skb_unlink(skb, msdu_list); - dev_kfree_skb_any(skb); - n_buffs--; - } - } -} - -int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list) -{ - struct ath12k_base *ab = ar->ab; - u16 msdu_len; - struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); - - if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { - /* First buffer will be freed by the caller, so deduct it's length */ - msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); - ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); - return -EINVAL; - } - - /* Even after cleaning up the sg buffers in the msdu list with above check - * any msdu received with continuation flag needs to be dropped as invalid. - * This protects against some random err frame with continuation flag. - */ - if (rxcb->is_continuation) - return -EINVAL; - - if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { - ath12k_warn(ar->ab, - "msdu_done bit not set in null_q_des processing\n"); - __skb_queue_purge(msdu_list); - return -EIO; - } - - /* Handle NULL queue descriptor violations arising out a missing - * REO queue for a given peer or a given TID. This typically - * may happen if a packet is received on a QOS enabled TID before the - * ADDBA negotiation for that TID, when the TID queue is setup. Or - * it may also happen for MC/BC frames if they are not routed to the - * non-QOS TID queue, in the absence of any other default TID queue. - * This error can show up both in a REO destination or WBM release ring. - */ - - if (rxcb->is_frag) { - skb_pull(msdu, hal_rx_desc_sz); - } else { - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - - if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) - return -EINVAL; - - skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); - skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) - return -EINVAL; - - ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); - - rxcb->tid = rx_info->tid; - - /* Please note that caller will having the access to msdu and completing - * rx with mac80211. Need not worry about cleaning up amsdu_list. - */ - - return 0; -} - void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 417b18670096e..8249eed39a9b7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -59,6 +59,8 @@ struct ath12k_dp_rx_reo_cmd { enum hal_reo_cmd_status status); }; +#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + #define ATH12K_DP_RX_REO_DESC_FREE_THRES 64 #define ATH12K_DP_RX_REO_DESC_FREE_TIMEOUT_MS 1000 @@ -365,9 +367,20 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct sk_buff *msdu); -int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list); +void ath12k_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct ath12k_dp_rx_info *rx_info); +u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); +void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, + struct sk_buff_head *frag_list, + struct sk_buff *cur_frag); +void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, + enum hal_encrypt_type enctype, u32 flags); +int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, + struct sk_buff *msdu); +void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); @@ -395,8 +408,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget); int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, struct napi_struct *napi, int budget); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index a002e3839fff8..c2b108a1005bd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -6,6 +6,688 @@ #include "dp_rx.h" #include "../dp_tx.h" +#include "../peer.h" + +static bool +ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) +{ + struct ath12k_base *ab = ar->ab; + enum hal_encrypt_type encrypt_type; + struct sk_buff *first_frag, *skb; + struct hal_rx_desc *desc; + u64 last_pn; + u64 cur_pn; + + first_frag = skb_peek(&rx_tid->rx_frags); + desc = (struct hal_rx_desc *)first_frag->data; + + encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); + if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && + encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) + return true; + + last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); + skb_queue_walk(&rx_tid->rx_frags, skb) { + if (skb == first_frag) + continue; + + cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); + if (cur_pn != last_pn + 1) + return false; + last_pn = cur_pn; + } + return true; +} + +static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff *defrag_skb) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; + struct hal_reo_entrance_ring *reo_ent_ring; + struct hal_reo_dest_ring *reo_dest_ring; + struct dp_link_desc_bank *link_desc_banks; + struct hal_rx_msdu_link *msdu_link; + struct hal_rx_msdu_details *msdu0; + struct hal_srng *srng; + dma_addr_t link_paddr, buf_paddr; + u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info; + u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi; + int ret; + struct ath12k_rx_desc_info *desc_info; + enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm; + u8 dst_ind; + + hal_rx_desc_sz = ab->hal.hal_desc_sz; + link_desc_banks = dp->link_desc_banks; + reo_dest_ring = rx_tid->dst_ring_desc; + + ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, + &link_paddr, &cookie); + desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); + + msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + + (link_paddr - link_desc_banks[desc_bank].paddr)); + msdu0 = &msdu_link->msdu_link[0]; + msdu_ext_info = le32_to_cpu(msdu0->rx_msdu_ext_info.info0); + dst_ind = u32_get_bits(msdu_ext_info, RX_MSDU_EXT_DESC_INFO0_REO_DEST_IND); + + memset(msdu0, 0, sizeof(*msdu0)); + + msdu_info = u32_encode_bits(1, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU) | + u32_encode_bits(1, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU) | + u32_encode_bits(0, RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) | + u32_encode_bits(defrag_skb->len - hal_rx_desc_sz, + RX_MSDU_DESC_INFO0_MSDU_LENGTH) | + u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_SA) | + u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_DA); + msdu0->rx_msdu_info.info0 = cpu_to_le32(msdu_info); + msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info); + + /* change msdu len in hal rx desc */ + ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); + + buf_paddr = dma_map_single(ab->dev, defrag_skb->data, + defrag_skb->len + skb_tailroom(defrag_skb), + DMA_TO_DEVICE); + if (dma_mapping_error(ab->dev, buf_paddr)) + return -ENOMEM; + + spin_lock_bh(&dp->rx_desc_lock); + desc_info = list_first_entry_or_null(&dp->rx_desc_free_list, + struct ath12k_rx_desc_info, + list); + if (!desc_info) { + spin_unlock_bh(&dp->rx_desc_lock); + ath12k_warn(ab, "failed to find rx desc for reinject\n"); + ret = -ENOMEM; + goto err_unmap_dma; + } + + desc_info->skb = defrag_skb; + desc_info->in_use = true; + + list_del(&desc_info->list); + spin_unlock_bh(&dp->rx_desc_lock); + + ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; + + ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, + desc_info->cookie, + HAL_RX_BUF_RBM_SW3_BM); + + /* Fill mpdu details into reo entrance ring */ + srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; + + spin_lock_bh(&srng->lock); + ath12k_hal_srng_access_begin(ab, srng); + + reo_ent_ring = ath12k_hal_srng_src_get_next_entry(ab, srng); + if (!reo_ent_ring) { + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + ret = -ENOSPC; + goto err_free_desc; + } + memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); + + ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, + cookie, + idle_link_rbm); + + mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) | + u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) | + u32_encode_bits(1, RX_MPDU_DESC_INFO0_RAW_MPDU) | + u32_encode_bits(1, RX_MPDU_DESC_INFO0_VALID_PN) | + u32_encode_bits(rx_tid->tid, RX_MPDU_DESC_INFO0_TID); + + reo_ent_ring->rx_mpdu_info.info0 = cpu_to_le32(mpdu_info); + reo_ent_ring->rx_mpdu_info.peer_meta_data = + reo_dest_ring->rx_mpdu_info.peer_meta_data; + + if (ab->hw_params->reoq_lut_support) { + reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; + queue_addr_hi = 0; + } else { + reo_ent_ring->queue_addr_lo = + cpu_to_le32(lower_32_bits(rx_tid->qbuf.paddr_aligned)); + queue_addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + } + + reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi, + HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) | + le32_encode_bits(dst_ind, + HAL_REO_ENTR_RING_INFO0_DEST_IND); + + reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn, + HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM); + dest_ring_info0 = le32_get_bits(reo_dest_ring->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + reo_ent_ring->info2 = + cpu_to_le32(u32_get_bits(dest_ring_info0, + HAL_REO_ENTR_RING_INFO2_SRC_LINK_ID)); + + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + return 0; + +err_free_desc: + spin_lock_bh(&dp->rx_desc_lock); + desc_info->in_use = false; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, &dp->rx_desc_free_list); + spin_unlock_bh(&dp->rx_desc_lock); +err_unmap_dma: + dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), + DMA_TO_DEVICE); + return ret; +} + +static int ath12k_dp_rx_h_defrag(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff **defrag_skb) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc; + struct sk_buff *skb, *first_frag, *last_frag; + struct ieee80211_hdr *hdr; + enum hal_encrypt_type enctype; + bool is_decrypted = false; + int msdu_len = 0; + int extra_space; + u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + first_frag = skb_peek(&rx_tid->rx_frags); + last_frag = skb_peek_tail(&rx_tid->rx_frags); + + skb_queue_walk(&rx_tid->rx_frags, skb) { + flags = 0; + rx_desc = (struct hal_rx_desc *)skb->data; + hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); + + enctype = ath12k_dp_rx_h_enctype(ab, rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN) + is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, + rx_desc); + + if (is_decrypted) { + if (skb != first_frag) + flags |= RX_FLAG_IV_STRIPPED; + if (skb != last_frag) + flags |= RX_FLAG_ICV_STRIPPED | + RX_FLAG_MIC_STRIPPED; + } + + /* RX fragments are always raw packets */ + if (skb != last_frag) + skb_trim(skb, skb->len - FCS_LEN); + ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); + + if (skb != first_frag) + skb_pull(skb, hal_rx_desc_sz + + ieee80211_hdrlen(hdr->frame_control)); + msdu_len += skb->len; + } + + extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag)); + if (extra_space > 0 && + (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0)) + return -ENOMEM; + + __skb_unlink(first_frag, &rx_tid->rx_frags); + while ((skb = __skb_dequeue(&rx_tid->rx_frags))) { + skb_put_data(first_frag, skb->data, skb->len); + dev_kfree_skb_any(skb); + } + + hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz); + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); + ATH12K_SKB_RXCB(first_frag)->is_frag = 1; + + if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) + first_frag = NULL; + + *defrag_skb = first_frag; + return 0; +} + +static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_reo_dest_ring *ring_desc) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc; + struct ath12k_peer *peer; + struct ath12k_dp_rx_tid *rx_tid; + struct sk_buff *defrag_skb = NULL; + u32 peer_id; + u16 seqno, frag_no; + u8 tid; + int ret = 0; + bool more_frags; + + rx_desc = (struct hal_rx_desc *)msdu->data; + peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); + tid = ath12k_dp_rx_h_tid(ab, rx_desc); + seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); + frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); + more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + + if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || + !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || + tid > IEEE80211_NUM_TIDS) + return -EINVAL; + + /* received unfragmented packet in reo + * exception ring, this shouldn't happen + * as these packets typically come from + * reo2sw srngs. + */ + if (WARN_ON_ONCE(!frag_no && !more_frags)) + return -EINVAL; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", + peer_id); + ret = -ENOENT; + goto out_unlock; + } + + if (!peer->dp_setup_done) { + ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", + peer->addr, peer_id); + ret = -ENOENT; + goto out_unlock; + } + + rx_tid = &peer->rx_tid[tid]; + + if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || + skb_queue_empty(&rx_tid->rx_frags)) { + /* Flush stored fragments and start a new sequence */ + ath12k_dp_rx_frags_cleanup(rx_tid, true); + rx_tid->cur_sn = seqno; + } + + if (rx_tid->rx_frag_bitmap & BIT(frag_no)) { + /* Fragment already present */ + ret = -EINVAL; + goto out_unlock; + } + + if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) + __skb_queue_tail(&rx_tid->rx_frags, msdu); + else + ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); + + rx_tid->rx_frag_bitmap |= BIT(frag_no); + if (!more_frags) + rx_tid->last_frag_no = frag_no; + + if (frag_no == 0) { + rx_tid->dst_ring_desc = kmemdup(ring_desc, + sizeof(*rx_tid->dst_ring_desc), + GFP_ATOMIC); + if (!rx_tid->dst_ring_desc) { + ret = -ENOMEM; + goto out_unlock; + } + } else { + ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + if (!rx_tid->last_frag_no || + rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) { + mod_timer(&rx_tid->frag_timer, jiffies + + ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS); + goto out_unlock; + } + + spin_unlock_bh(&ab->base_lock); + timer_delete_sync(&rx_tid->frag_timer); + spin_lock_bh(&ab->base_lock); + + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) + goto err_frags_cleanup; + + if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) + goto err_frags_cleanup; + + if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) + goto err_frags_cleanup; + + if (!defrag_skb) + goto err_frags_cleanup; + + if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + goto err_frags_cleanup; + + ath12k_dp_rx_frags_cleanup(rx_tid, false); + goto out_unlock; + +err_frags_cleanup: + dev_kfree_skb_any(defrag_skb); + ath12k_dp_rx_frags_cleanup(rx_tid, true); +out_unlock: + spin_unlock_bh(&ab->base_lock); + return ret; +} + +static int +ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, + struct list_head *used_list, + bool drop, u32 cookie) +{ + struct ath12k_base *ab = ar->ab; + struct sk_buff *msdu; + struct ath12k_skb_rxcb *rxcb; + struct hal_rx_desc *rx_desc; + u16 msdu_len; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + struct ath12k_rx_desc_info *desc_info; + u64 desc_va; + + desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo)); + desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); + + /* retry manual desc retrieval */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(ab, cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", + cookie); + return -EINVAL; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, " RX Exception, Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + list_add_tail(&desc_info->list, used_list); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + if (drop) { + dev_kfree_skb_any(msdu); + return 0; + } + + rcu_read_lock(); + if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) { + dev_kfree_skb_any(msdu); + goto exit; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + goto exit; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); + if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { + ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + sizeof(*rx_desc)); + dev_kfree_skb_any(msdu); + goto exit; + } + + skb_put(msdu, hal_rx_desc_sz + msdu_len); + + if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { + dev_kfree_skb_any(msdu); + ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } +exit: + rcu_read_unlock(); + return 0; +} + +int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) +{ + struct ath12k_hw_group *ag = ab->ag; + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + struct dp_link_desc_bank *link_desc_banks; + enum hal_rx_buf_return_buf_manager rbm; + struct hal_rx_msdu_link *link_desc_va; + int tot_n_bufs_reaped, quota, ret, i; + struct hal_reo_dest_ring *reo_desc; + struct dp_rxdma_ring *rx_ring; + struct dp_srng *reo_except; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + u8 hw_link_id, device_id; + u32 desc_bank, num_msdus; + struct hal_srng *srng; + struct ath12k *ar; + dma_addr_t paddr; + bool is_frag; + bool drop; + int pdev_id; + + tot_n_bufs_reaped = 0; + quota = budget; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + reo_except = &ab->dp.reo_except_ring; + + srng = &ab->hal.srng_list[reo_except->ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (budget && + (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + drop = false; + ab->device_stats.err_ring_pkts++; + + ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); + if (ret) { + ath12k_warn(ab, "failed to parse error reo desc %d\n", + ret); + continue; + } + + hw_link_id = le32_get_bits(reo_desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + + link_desc_banks = partner_ab->dp.link_desc_banks; + link_desc_va = link_desc_banks[desc_bank].vaddr + + (paddr - link_desc_banks[desc_bank].paddr); + ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, + &rbm); + if (rbm != partner_ab->dp.idle_link_rbm && + rbm != HAL_RX_BUF_RBM_SW3_BM && + rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + ab->device_stats.invalid_rbm++; + ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); + ath12k_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_REL_MSDU); + continue; + } + + is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) & + RX_MPDU_DESC_INFO0_FRAG_FLAG); + + /* Process only rx fragments with one msdu per link desc below, and drop + * msdu's indicated due to error reasons. + * Dynamic fragmentation not supported in Multi-link client, so drop the + * partner device buffers. + */ + if (!is_frag || num_msdus > 1 || + partner_ab->device_id != ab->device_id) { + drop = true; + + /* Return the link desc back to wbm idle list */ + ath12k_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + for (i = 0; i < num_msdus; i++) { + if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, + &rx_desc_used_list[device_id], + drop, + msdu_cookies[i])) { + num_buffs_reaped[device_id]++; + tot_n_bufs_reaped++; + } + } + + if (tot_n_bufs_reaped >= quota) { + tot_n_bufs_reaped = quota; + goto exit; + } + + budget = quota - tot_n_bufs_reaped; + } + +exit: + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + return tot_n_bufs_reaped; +} + +static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, + int msdu_len, + struct sk_buff_head *msdu_list) +{ + struct sk_buff *skb, *tmp; + struct ath12k_skb_rxcb *rxcb; + int n_buffs; + + n_buffs = DIV_ROUND_UP(msdu_len, + (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); + + skb_queue_walk_safe(msdu_list, skb, tmp) { + rxcb = ATH12K_SKB_RXCB(skb); + if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO && + rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) { + if (!n_buffs) + break; + __skb_unlink(skb, msdu_list); + dev_kfree_skb_any(skb); + n_buffs--; + } + } +} + +static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) +{ + struct ath12k_base *ab = ar->ab; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + u8 l3pad_bytes; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { + /* First buffer will be freed by the caller, so deduct it's length */ + msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); + ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + return -EINVAL; + } + + /* Even after cleaning up the sg buffers in the msdu list with above check + * any msdu received with continuation flag needs to be dropped as invalid. + * This protects against some random err frame with continuation flag. + */ + if (rxcb->is_continuation) + return -EINVAL; + + if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { + ath12k_warn(ar->ab, + "msdu_done bit not set in null_q_des processing\n"); + __skb_queue_purge(msdu_list); + return -EIO; + } + + /* Handle NULL queue descriptor violations arising out a missing + * REO queue for a given peer or a given TID. This typically + * may happen if a packet is received on a QOS enabled TID before the + * ADDBA negotiation for that TID, when the TID queue is setup. Or + * it may also happen for MC/BC frames if they are not routed to the + * non-QOS TID queue, in the absence of any other default TID queue. + * This error can show up both in a REO destination or WBM release ring. + */ + + if (rxcb->is_frag) { + skb_pull(msdu, hal_rx_desc_sz); + } else { + l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) + return -EINVAL; + + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); + } + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + return -EINVAL; + + ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + + rxcb->tid = rx_info->tid; + + /* Please note that caller will having the access to msdu and completing + * rx with mac80211. Need not worry about cleaning up amsdu_list. + */ + + return 0; +} static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, struct ath12k_dp_rx_info *rx_info) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 154018c221dad..9c2114c62ba2e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -11,6 +11,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); +int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif From 82fd6d0894bc38e6be74e59f4aa1e75515fd4440 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:43 +0530 Subject: [PATCH 389/659] wifi: ath12k: Move regular msdu processing functions to wifi7 directory Move arch specific RX MSDU processing related functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_rx_msdu_coalesce ath12k_dp_rx_h_csum_offload ath12k_dp_rx_h_mpdu ath12k_dp_rx_process ath12k_dp_rx_process_received_packets ath12k_dp_rx_h_verify_tkip_mic ath12k_dp_rx_process_msdu Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-11-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 543 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 18 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 527 +++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + 4 files changed, 547 insertions(+), 544 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index b5630b71ebee3..adb67261c751a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1770,95 +1770,8 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); -static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, - struct sk_buff_head *msdu_list, - struct sk_buff *first, struct sk_buff *last, - u8 l3pad_bytes, int msdu_len) -{ - struct ath12k_base *ab = ar->ab; - struct sk_buff *skb; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); - int buf_first_hdr_len, buf_first_len; - struct hal_rx_desc *ldesc; - int space_extra, rem_len, buf_len; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - bool is_continuation; - - /* As the msdu is spread across multiple rx buffers, - * find the offset to the start of msdu for computing - * the length of the msdu in the first buffer. - */ - buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes; - buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len; - - if (WARN_ON_ONCE(msdu_len <= buf_first_len)) { - skb_put(first, buf_first_hdr_len + msdu_len); - skb_pull(first, buf_first_hdr_len); - return 0; - } - - ldesc = (struct hal_rx_desc *)last->data; - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc); - - /* MSDU spans over multiple buffers because the length of the MSDU - * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data - * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. - */ - skb_put(first, DP_RX_BUFFER_SIZE); - skb_pull(first, buf_first_hdr_len); - - /* When an MSDU spread over multiple buffers MSDU_END - * tlvs are valid only in the last buffer. Copy those tlvs. - */ - ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc); - - space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); - if (space_extra > 0 && - (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) { - /* Free up all buffers of the MSDU */ - while ((skb = __skb_dequeue(msdu_list)) != NULL) { - rxcb = ATH12K_SKB_RXCB(skb); - if (!rxcb->is_continuation) { - dev_kfree_skb_any(skb); - break; - } - dev_kfree_skb_any(skb); - } - return -ENOMEM; - } - - rem_len = msdu_len - buf_first_len; - while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { - rxcb = ATH12K_SKB_RXCB(skb); - is_continuation = rxcb->is_continuation; - if (is_continuation) - buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; - else - buf_len = rem_len; - - if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) { - WARN_ON_ONCE(1); - dev_kfree_skb_any(skb); - return -EINVAL; - } - - skb_put(skb, buf_len + hal_rx_desc_sz); - skb_pull(skb, hal_rx_desc_sz); - skb_copy_from_linear_data(skb, skb_put(first, buf_len), - buf_len); - dev_kfree_skb_any(skb); - - rem_len -= buf_len; - if (!is_continuation) - break; - } - - return 0; -} - -static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, - struct sk_buff *first) +struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, + struct sk_buff *first) { struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); @@ -1875,13 +1788,6 @@ static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_ return NULL; } -static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) -{ - msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? - CHECKSUM_NONE : CHECKSUM_UNNECESSARY; -} - int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype) { switch (enctype) { @@ -2200,84 +2106,6 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_skb_rxcb *rxcb; - enum hal_encrypt_type enctype; - bool is_decrypted = false; - struct ieee80211_hdr *hdr; - struct ath12k_peer *peer; - struct ieee80211_rx_status *rx_status = rx_info->rx_status; - u32 err_bitmap; - - /* PN for multicast packets will be checked in mac80211 */ - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->is_mcbc = rx_info->is_mcbc; - - if (rxcb->is_mcbc) - rxcb->peer_id = rx_info->peer_id; - - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info); - if (peer) { - /* resetting mcbc bit because mcbc packets are unicast - * packets only for AP as STA sends unicast packets. - */ - rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only; - - if (rxcb->is_mcbc) - enctype = peer->sec_type_grp; - else - enctype = peer->sec_type; - } else { - enctype = HAL_ENCRYPT_TYPE_OPEN; - } - spin_unlock_bh(&ar->ab->base_lock); - - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); - if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc); - - /* Clear per-MPDU flags while leaving per-PPDU flags intact */ - rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | - RX_FLAG_MMIC_ERROR | - RX_FLAG_DECRYPTED | - RX_FLAG_IV_STRIPPED | - RX_FLAG_MMIC_STRIPPED); - - if (err_bitmap & HAL_RX_MPDU_ERR_FCS) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) - rx_status->flag |= RX_FLAG_MMIC_ERROR; - - if (is_decrypted) { - rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED; - - if (rx_info->is_mcbc) - rx_status->flag |= RX_FLAG_MIC_STRIPPED | - RX_FLAG_ICV_STRIPPED; - else - rx_status->flag |= RX_FLAG_IV_STRIPPED | - RX_FLAG_PN_VALIDATED; - } - - ath12k_dp_rx_h_csum_offload(msdu, rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - enctype, rx_status, is_decrypted); - - if (!is_decrypted || rx_info->is_mcbc) - return; - - if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) { - hdr = (void *)msdu->data; - hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); - } -} - static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) { struct ieee80211_supported_band *sband; @@ -2536,140 +2364,9 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, return false; } -static int ath12k_dp_rx_process_msdu(struct ath12k *ar, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc, *lrx_desc; - struct ath12k_skb_rxcb *rxcb; - struct sk_buff *last_buf; - u8 l3_pad_bytes; - u16 msdu_len; - int ret; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); - if (!last_buf) { - ath12k_warn(ab, - "No valid Rx buffer to access MSDU_END tlv\n"); - ret = -EIO; - goto free_out; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - lrx_desc = (struct hal_rx_desc *)last_buf->data; - if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) { - ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); - ret = -EIO; - goto free_out; - } - - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->rx_desc = rx_desc; - msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc); - l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc); - - if (rxcb->is_frag) { - skb_pull(msdu, hal_rx_desc_sz); - } else if (!rxcb->is_continuation) { - if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ret = -EINVAL; - ath12k_warn(ab, "invalid msdu len %u\n", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, - sizeof(*rx_desc)); - goto free_out; - } - skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); - skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); - } else { - ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, - msdu, last_buf, - l3_pad_bytes, msdu_len); - if (ret) { - ath12k_warn(ab, - "failed to coalesce msdu rx buffer%d\n", ret); - goto free_out; - } - } - - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) { - ret = -EINVAL; - goto free_out; - } - - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); - - rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; - - return 0; - -free_out: - return ret; -} - -static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, - struct napi_struct *napi, - struct sk_buff_head *msdu_list, - int ring_id) -{ - struct ath12k_hw_group *ag = ab->ag; - struct ieee80211_rx_status rx_status = {}; - struct ath12k_skb_rxcb *rxcb; - struct sk_buff *msdu; - struct ath12k *ar; - struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; - struct ath12k_dp_rx_info rx_info; - u8 hw_link_id, pdev_id; - int ret; - - if (skb_queue_empty(msdu_list)) - return; - - rx_info.addr2_present = false; - rx_info.rx_status = &rx_status; - - rcu_read_lock(); - - while ((msdu = __skb_dequeue(msdu_list))) { - rxcb = ATH12K_SKB_RXCB(msdu); - hw_link_id = rxcb->hw_link_id; - partner_ab = ath12k_ag_to_ab(ag, - hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; - if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { - dev_kfree_skb_any(msdu); - continue; - } - - if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { - dev_kfree_skb_any(msdu); - continue; - } - - ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); - if (ret) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Unable to process msdu %d", ret); - dev_kfree_skb_any(msdu); - continue; - } - - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); - } - - rcu_read_unlock(); -} - -static u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, - enum ath12k_peer_metadata_version ver, - __le32 peer_metadata) +u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, + enum ath12k_peer_metadata_version ver, + __le32 peer_metadata) { switch (ver) { default: @@ -2690,166 +2387,6 @@ static u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, } } -int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, - struct napi_struct *napi, int budget) -{ - struct ath12k_hw_group *ag = ab->ag; - struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_link *hw_links = ag->hw_links; - int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_dp *dp = &ab->dp; - struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; - struct hal_reo_dest_ring *desc; - struct ath12k_base *partner_ab; - struct sk_buff_head msdu_list; - struct ath12k_skb_rxcb *rxcb; - int total_msdu_reaped = 0; - u8 hw_link_id, device_id; - struct hal_srng *srng; - struct sk_buff *msdu; - bool done = false; - u64 desc_va; - - __skb_queue_head_init(&msdu_list); - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) - INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - - srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; - - spin_lock_bh(&srng->lock); - -try_again: - ath12k_hal_srng_access_begin(ab, srng); - - while ((desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - struct rx_mpdu_desc *mpdu_info; - struct rx_msdu_desc *msdu_info; - enum hal_reo_dest_ring_push_reason push_reason; - u32 cookie; - - cookie = le32_get_bits(desc->buf_addr_info.info1, - BUFFER_ADDR_INFO1_SW_COOKIE); - - hw_link_id = le32_get_bits(desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - - desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | - le32_to_cpu(desc->buf_va_lo)); - desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); - - device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { - if (desc_info->skb) { - dev_kfree_skb_any(desc_info->skb); - desc_info->skb = NULL; - } - - continue; - } - - /* retry manual desc retrieval */ - if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie); - if (!desc_info) { - ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", - cookie); - continue; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, "Check HW CC implementation"); - - msdu = desc_info->skb; - desc_info->skb = NULL; - - list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); - - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - num_buffs_reaped[device_id]++; - ab->device_stats.reo_rx[ring_id][ab->device_id]++; - - push_reason = le32_get_bits(desc->info0, - HAL_REO_DEST_RING_INFO0_PUSH_REASON); - if (push_reason != - HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { - dev_kfree_skb_any(msdu); - ab->device_stats.hal_reo_error[ring_id]++; - continue; - } - - msdu_info = &desc->rx_msdu_info; - mpdu_info = &desc->rx_mpdu_info; - - rxcb->is_first_msdu = !!(le32_to_cpu(msdu_info->info0) & - RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU); - rxcb->is_last_msdu = !!(le32_to_cpu(msdu_info->info0) & - RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); - rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & - RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); - rxcb->hw_link_id = hw_link_id; - rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, - mpdu_info->peer_meta_data); - rxcb->tid = le32_get_bits(mpdu_info->info0, - RX_MPDU_DESC_INFO0_TID); - - __skb_queue_tail(&msdu_list, msdu); - - if (!rxcb->is_continuation) { - total_msdu_reaped++; - done = true; - } else { - done = false; - } - - if (total_msdu_reaped >= budget) - break; - } - - /* Hw might have updated the head pointer after we cached it. - * In this case, even though there are entries in the ring we'll - * get rx_desc NULL. Give the read another try with updated cached - * head pointer so that we can reap complete MPDU in the current - * rx processing. - */ - if (!done && ath12k_hal_srng_dst_num_free(ab, srng, true)) { - ath12k_hal_srng_access_end(ab, srng); - goto try_again; - } - - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - if (!total_msdu_reaped) - goto exit; - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { - if (!num_buffs_reaped[device_id]) - continue; - - partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; - - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, - &rx_desc_used_list[device_id], - num_buffs_reaped[device_id]); - } - - ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, - ring_id); - -exit: - return total_msdu_reaped; -} - static void ath12k_dp_rx_frag_timer(struct timer_list *timer) { struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer, @@ -2907,9 +2444,9 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev return 0; } -static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, - struct ieee80211_hdr *hdr, u8 *data, - size_t data_len, u8 *mic) +int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, + struct ieee80211_hdr *hdr, u8 *data, + size_t data_len, u8 *mic) { SHASH_DESC_ON_STACK(desc, tfm); u8 mic_hdr[16] = {}; @@ -2948,70 +2485,6 @@ static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, return ret; } -int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; - struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); - struct ieee80211_key_conf *key_conf; - struct ieee80211_hdr *hdr; - struct ath12k_dp_rx_info rx_info; - u8 mic[IEEE80211_CCMP_MIC_LEN]; - int head_len, tail_len, ret; - size_t data_len; - u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - u8 *key, *data; - u8 key_idx; - - if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) - return 0; - - rx_info.addr2_present = false; - rx_info.rx_status = rxs; - - hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); - hdr_len = ieee80211_hdrlen(hdr->frame_control); - head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; - tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; - - if (!is_multicast_ether_addr(hdr->addr1)) - key_idx = peer->ucast_keyidx; - else - key_idx = peer->mcast_keyidx; - - key_conf = peer->keys[key_idx]; - - data = msdu->data + head_len; - data_len = msdu->len - head_len - tail_len; - key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; - - ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); - if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) - goto mic_fail; - - return 0; - -mic_fail: - (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; - (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - - ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info); - - rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | - RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; - skb_pull(msdu, hal_rx_desc_sz); - - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) - return -EINVAL; - - ath12k_dp_rx_h_ppdu(ar, &rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); - ieee80211_rx(ath12k_ar_to_hw(ar), msdu); - return -EINVAL; -} - void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags) { diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 8249eed39a9b7..454e46b9d452a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -6,6 +6,7 @@ #ifndef ATH12K_DP_RX_H #define ATH12K_DP_RX_H +#include #include "core.h" #include "wifi7/hal_rx_desc.h" #include "debug.h" @@ -367,20 +368,20 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct sk_buff *msdu); -void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info); u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff_head *frag_list, struct sk_buff *cur_frag); void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags); -int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu); void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc); +int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, + struct ieee80211_hdr *hdr, u8 *data, + size_t data_len, u8 *mic); +u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, + enum ath12k_peer_metadata_version ver, + __le32 peer_metadata); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); @@ -408,9 +409,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); -int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, - struct napi_struct *napi, - int budget); int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, @@ -445,4 +443,6 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); +struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, + struct sk_buff *first); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index c2b108a1005bd..b55cfb926571f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -8,6 +8,469 @@ #include "../dp_tx.h" #include "../peer.h" +static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? + CHECKSUM_NONE : CHECKSUM_UNNECESSARY; +} + +static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_skb_rxcb *rxcb; + enum hal_encrypt_type enctype; + bool is_decrypted = false; + struct ieee80211_hdr *hdr; + struct ath12k_peer *peer; + struct ieee80211_rx_status *rx_status = rx_info->rx_status; + u32 err_bitmap; + + /* PN for multicast packets will be checked in mac80211 */ + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->is_mcbc = rx_info->is_mcbc; + + if (rxcb->is_mcbc) + rxcb->peer_id = rx_info->peer_id; + + spin_lock_bh(&ar->ab->base_lock); + peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info); + if (peer) { + /* resetting mcbc bit because mcbc packets are unicast + * packets only for AP as STA sends unicast packets. + */ + rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only; + + if (rxcb->is_mcbc) + enctype = peer->sec_type_grp; + else + enctype = peer->sec_type; + } else { + enctype = HAL_ENCRYPT_TYPE_OPEN; + } + spin_unlock_bh(&ar->ab->base_lock); + + err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) + is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc); + + /* Clear per-MPDU flags while leaving per-PPDU flags intact */ + rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | + RX_FLAG_MMIC_ERROR | + RX_FLAG_DECRYPTED | + RX_FLAG_IV_STRIPPED | + RX_FLAG_MMIC_STRIPPED); + + if (err_bitmap & HAL_RX_MPDU_ERR_FCS) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) + rx_status->flag |= RX_FLAG_MMIC_ERROR; + + if (is_decrypted) { + rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED; + + if (rx_info->is_mcbc) + rx_status->flag |= RX_FLAG_MIC_STRIPPED | + RX_FLAG_ICV_STRIPPED; + else + rx_status->flag |= RX_FLAG_IV_STRIPPED | + RX_FLAG_PN_VALIDATED; + } + + ath12k_dp_rx_h_csum_offload(msdu, rx_info); + ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + enctype, rx_status, is_decrypted); + + if (!is_decrypted || rx_info->is_mcbc) + return; + + if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) { + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); + } +} + +static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, + struct sk_buff_head *msdu_list, + struct sk_buff *first, struct sk_buff *last, + u8 l3pad_bytes, int msdu_len) +{ + struct ath12k_base *ab = ar->ab; + struct sk_buff *skb; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); + int buf_first_hdr_len, buf_first_len; + struct hal_rx_desc *ldesc; + int space_extra, rem_len, buf_len; + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + bool is_continuation; + + /* As the msdu is spread across multiple rx buffers, + * find the offset to the start of msdu for computing + * the length of the msdu in the first buffer. + */ + buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes; + buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len; + + if (WARN_ON_ONCE(msdu_len <= buf_first_len)) { + skb_put(first, buf_first_hdr_len + msdu_len); + skb_pull(first, buf_first_hdr_len); + return 0; + } + + ldesc = (struct hal_rx_desc *)last->data; + rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc); + rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc); + + /* MSDU spans over multiple buffers because the length of the MSDU + * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data + * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. + */ + skb_put(first, DP_RX_BUFFER_SIZE); + skb_pull(first, buf_first_hdr_len); + + /* When an MSDU spread over multiple buffers MSDU_END + * tlvs are valid only in the last buffer. Copy those tlvs. + */ + ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc); + + space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); + if (space_extra > 0 && + (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) { + /* Free up all buffers of the MSDU */ + while ((skb = __skb_dequeue(msdu_list)) != NULL) { + rxcb = ATH12K_SKB_RXCB(skb); + if (!rxcb->is_continuation) { + dev_kfree_skb_any(skb); + break; + } + dev_kfree_skb_any(skb); + } + return -ENOMEM; + } + + rem_len = msdu_len - buf_first_len; + while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { + rxcb = ATH12K_SKB_RXCB(skb); + is_continuation = rxcb->is_continuation; + if (is_continuation) + buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; + else + buf_len = rem_len; + + if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) { + WARN_ON_ONCE(1); + dev_kfree_skb_any(skb); + return -EINVAL; + } + + skb_put(skb, buf_len + hal_rx_desc_sz); + skb_pull(skb, hal_rx_desc_sz); + skb_copy_from_linear_data(skb, skb_put(first, buf_len), + buf_len); + dev_kfree_skb_any(skb); + + rem_len -= buf_len; + if (!is_continuation) + break; + } + + return 0; +} + +static int ath12k_dp_rx_process_msdu(struct ath12k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc, *lrx_desc; + struct ath12k_skb_rxcb *rxcb; + struct sk_buff *last_buf; + u8 l3_pad_bytes; + u16 msdu_len; + int ret; + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); + if (!last_buf) { + ath12k_warn(ab, + "No valid Rx buffer to access MSDU_END tlv\n"); + ret = -EIO; + goto free_out; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + lrx_desc = (struct hal_rx_desc *)last_buf->data; + if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) { + ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); + ret = -EIO; + goto free_out; + } + + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->rx_desc = rx_desc; + msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc); + l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc); + + if (rxcb->is_frag) { + skb_pull(msdu, hal_rx_desc_sz); + } else if (!rxcb->is_continuation) { + if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { + ret = -EINVAL; + ath12k_warn(ab, "invalid msdu len %u\n", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + sizeof(*rx_desc)); + goto free_out; + } + skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); + } else { + ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, + msdu, last_buf, + l3_pad_bytes, msdu_len); + if (ret) { + ath12k_warn(ab, + "failed to coalesce msdu rx buffer%d\n", ret); + goto free_out; + } + } + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) { + ret = -EINVAL; + goto free_out; + } + + ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); + + rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; + + return 0; + +free_out: + return ret; +} + +static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, + struct napi_struct *napi, + struct sk_buff_head *msdu_list, + int ring_id) +{ + struct ath12k_hw_group *ag = ab->ag; + struct ieee80211_rx_status rx_status = {}; + struct ath12k_skb_rxcb *rxcb; + struct sk_buff *msdu; + struct ath12k *ar; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + struct ath12k_dp_rx_info rx_info; + u8 hw_link_id, pdev_id; + int ret; + + if (skb_queue_empty(msdu_list)) + return; + + rx_info.addr2_present = false; + rx_info.rx_status = &rx_status; + + rcu_read_lock(); + + while ((msdu = __skb_dequeue(msdu_list))) { + rxcb = ATH12K_SKB_RXCB(msdu); + hw_link_id = rxcb->hw_link_id; + partner_ab = ath12k_ag_to_ab(ag, + hw_links[hw_link_id].device_id); + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { + dev_kfree_skb_any(msdu); + continue; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + continue; + } + + ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); + if (ret) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Unable to process msdu %d", ret); + dev_kfree_skb_any(msdu); + continue; + } + + ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); + } + + rcu_read_unlock(); +} + +int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, + struct napi_struct *napi, int budget) +{ + struct ath12k_hw_group *ag = ab->ag; + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_hw_link *hw_links = ag->hw_links; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + struct hal_reo_dest_ring *desc; + struct ath12k_base *partner_ab; + struct sk_buff_head msdu_list; + struct ath12k_skb_rxcb *rxcb; + int total_msdu_reaped = 0; + u8 hw_link_id, device_id; + struct hal_srng *srng; + struct sk_buff *msdu; + bool done = false; + u64 desc_va; + + __skb_queue_head_init(&msdu_list); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; + + spin_lock_bh(&srng->lock); + +try_again: + ath12k_hal_srng_access_begin(ab, srng); + + while ((desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + struct rx_mpdu_desc *mpdu_info; + struct rx_msdu_desc *msdu_info; + enum hal_reo_dest_ring_push_reason push_reason; + u32 cookie; + + cookie = le32_get_bits(desc->buf_addr_info.info1, + BUFFER_ADDR_INFO1_SW_COOKIE); + + hw_link_id = le32_get_bits(desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + + desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo)); + desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); + + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + if (desc_info->skb) { + dev_kfree_skb_any(desc_info->skb); + desc_info->skb = NULL; + } + + continue; + } + + /* retry manual desc retrieval */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie); + if (!desc_info) { + ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", + cookie); + continue; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, "Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(partner_ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + num_buffs_reaped[device_id]++; + ab->device_stats.reo_rx[ring_id][ab->device_id]++; + + push_reason = le32_get_bits(desc->info0, + HAL_REO_DEST_RING_INFO0_PUSH_REASON); + if (push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { + dev_kfree_skb_any(msdu); + ab->device_stats.hal_reo_error[ring_id]++; + continue; + } + + msdu_info = &desc->rx_msdu_info; + mpdu_info = &desc->rx_mpdu_info; + + rxcb->is_first_msdu = !!(le32_to_cpu(msdu_info->info0) & + RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU); + rxcb->is_last_msdu = !!(le32_to_cpu(msdu_info->info0) & + RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); + rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & + RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); + rxcb->hw_link_id = hw_link_id; + rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, + mpdu_info->peer_meta_data); + rxcb->tid = le32_get_bits(mpdu_info->info0, + RX_MPDU_DESC_INFO0_TID); + + __skb_queue_tail(&msdu_list, msdu); + + if (!rxcb->is_continuation) { + total_msdu_reaped++; + done = true; + } else { + done = false; + } + + if (total_msdu_reaped >= budget) + break; + } + + /* Hw might have updated the head pointer after we cached it. + * In this case, even though there are entries in the ring we'll + * get rx_desc NULL. Give the read another try with updated cached + * head pointer so that we can reap complete MPDU in the current + * rx processing. + */ + if (!done && ath12k_hal_srng_dst_num_free(ab, srng, true)) { + ath12k_hal_srng_access_end(ab, srng); + goto try_again; + } + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + if (!total_msdu_reaped) + goto exit; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, + ring_id); + +exit: + return total_msdu_reaped; +} + static bool ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) { @@ -188,6 +651,70 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } +static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, + struct sk_buff *msdu) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); + struct ieee80211_key_conf *key_conf; + struct ieee80211_hdr *hdr; + struct ath12k_dp_rx_info rx_info; + u8 mic[IEEE80211_CCMP_MIC_LEN]; + int head_len, tail_len, ret; + size_t data_len; + u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u8 *key, *data; + u8 key_idx; + + if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) + return 0; + + rx_info.addr2_present = false; + rx_info.rx_status = rxs; + + hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); + hdr_len = ieee80211_hdrlen(hdr->frame_control); + head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; + tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; + + if (!is_multicast_ether_addr(hdr->addr1)) + key_idx = peer->ucast_keyidx; + else + key_idx = peer->mcast_keyidx; + + key_conf = peer->keys[key_idx]; + + data = msdu->data + head_len; + data_len = msdu->len - head_len - tail_len; + key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; + + ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); + if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) + goto mic_fail; + + return 0; + +mic_fail: + (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; + (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; + + ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info); + + rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | + RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; + skb_pull(msdu, hal_rx_desc_sz); + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) + return -EINVAL; + + ath12k_dp_rx_h_ppdu(ar, &rx_info); + ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); + ieee80211_rx(ath12k_ar_to_hw(ar), msdu); + return -EINVAL; +} + static int ath12k_dp_rx_h_defrag(struct ath12k *ar, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 9c2114c62ba2e..fa44e454cee6c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -13,6 +13,9 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); +int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, + struct napi_struct *napi, + int budget); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif From a65b105989f53c353eee4d746c84e17115d9cf1b Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:44 +0530 Subject: [PATCH 390/659] wifi: ath12k: Move srng processing to wifi7 directory Move ath12k_dp_service_srng API and ath12k_dp_rx_process_reo_status to wifi7 directory. As srng processing is specific to architecture (wifi7 / wifi8), the API ath12k_dp_service_srng is being moved to wifi7 directory. The file wifi7/dp.c can be used to define wifi7-specifi functions that are common to both tx and rx. The API which is invoked as part of service srng, ath12k_dp_rx_process_reo_status is also moved to wifi7 directory, as the implementation is specific to HW due to the usage of wifi7 specific HAL macros. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-12-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 3 +- drivers/net/wireless/ath/ath12k/ahb.c | 3 +- drivers/net/wireless/ath/ath12k/dp.c | 124 ---------------- drivers/net/wireless/ath/ath12k/dp.h | 3 - drivers/net/wireless/ath/ath12k/dp_rx.c | 79 ---------- drivers/net/wireless/ath/ath12k/dp_rx.h | 1 - drivers/net/wireless/ath/ath12k/pci.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 136 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp.h | 15 ++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 79 ++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 1 + 11 files changed, 236 insertions(+), 209 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index d7628bb7af029..ed1f1dba3d3b9 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -24,7 +24,8 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ - wifi7/dp_rx.o + wifi7/dp_rx.o \ + wifi7/dp.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 9348b5aa08c67..8d14813365755 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -15,6 +15,7 @@ #include "ahb.h" #include "debug.h" #include "hif.h" +#include "wifi7/dp.h" #define ATH12K_IRQ_CE0_OFFSET 4 #define ATH12K_MAX_UPDS 1 diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 1faac4ab641c1..2826251602b6b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -883,130 +883,6 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, return ret; } -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget) -{ - struct napi_struct *napi = &irq_grp->napi; - int grp_id = irq_grp->grp_id; - int work_done = 0; - int i = 0, j; - int tot_work_done = 0; - enum dp_monitor_mode monitor_mode; - u8 ring_mask; - - if (ab->hw_params->ring_mask->tx[grp_id]) { - i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; - ath12k_dp_tx_completion_handler(ab, i); - } - - if (ab->hw_params->ring_mask->rx_err[grp_id]) { - work_done = ath12k_dp_rx_process_err(ab, napi, budget); - budget -= work_done; - tot_work_done += work_done; - if (budget <= 0) - goto done; - } - - if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { - work_done = ath12k_dp_rx_process_wbm_err(ab, - napi, - budget); - budget -= work_done; - tot_work_done += work_done; - - if (budget <= 0) - goto done; - } - - if (ab->hw_params->ring_mask->rx[grp_id]) { - i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; - work_done = ath12k_dp_rx_process(ab, i, napi, - budget); - budget -= work_done; - tot_work_done += work_done; - if (budget <= 0) - goto done; - } - - if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { - ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; - - if (ring_mask & BIT(id)) { - work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, - 0); - budget -= work_done; - tot_work_done += work_done; - if (budget <= 0) - goto done; - } - } - } - } - - if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { - monitor_mode = ATH12K_DP_RX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; - - if (ring_mask & BIT(id)) { - work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, - monitor_mode); - budget -= work_done; - tot_work_done += work_done; - - if (budget <= 0) - goto done; - } - } - } - } - - if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { - monitor_mode = ATH12K_DP_TX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; - - if (ring_mask & BIT(id)) { - work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, - monitor_mode); - budget -= work_done; - tot_work_done += work_done; - - if (budget <= 0) - goto done; - } - } - } - } - - if (ab->hw_params->ring_mask->reo_status[grp_id]) - ath12k_dp_rx_process_reo_status(ab); - - if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { - struct ath12k_dp *dp = &ab->dp; - struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; - LIST_HEAD(list); - - ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); - } - - /* TODO: Implement handler for other interrupts */ - -done: - return tot_work_done; -} - void ath12k_dp_pdev_free(struct ath12k_base *ab) { int i; diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index e0c610f7ff885..cfffc51f87bf4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -1940,9 +1940,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget); int ath12k_dp_htt_connect(struct ath12k_dp *dp); void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_free(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index adb67261c751a..096d102c0362d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -2608,85 +2608,6 @@ static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, return 0; } -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct hal_tlv_64_hdr *hdr; - struct hal_srng *srng; - struct ath12k_dp_rx_reo_cmd *cmd, *tmp; - bool found = false; - u16 tag; - struct hal_reo_status reo_status; - - srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; - - memset(&reo_status, 0, sizeof(reo_status)); - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); - - switch (tag) { - case HAL_REO_GET_QUEUE_STATS_STATUS: - ath12k_hal_reo_status_queue_stats(ab, hdr, - &reo_status); - break; - case HAL_REO_FLUSH_QUEUE_STATUS: - ath12k_hal_reo_flush_queue_status(ab, hdr, - &reo_status); - break; - case HAL_REO_FLUSH_CACHE_STATUS: - ath12k_hal_reo_flush_cache_status(ab, hdr, - &reo_status); - break; - case HAL_REO_UNBLOCK_CACHE_STATUS: - ath12k_hal_reo_unblk_cache_status(ab, hdr, - &reo_status); - break; - case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: - ath12k_hal_reo_flush_timeout_list_status(ab, hdr, - &reo_status); - break; - case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: - ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, - &reo_status); - break; - case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: - ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, - &reo_status); - break; - default: - ath12k_warn(ab, "Unknown reo status type %d\n", tag); - continue; - } - - spin_lock_bh(&dp->reo_cmd_lock); - list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { - if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) { - found = true; - list_del(&cmd->list); - break; - } - } - spin_unlock_bh(&dp->reo_cmd_lock); - - if (found) { - cmd->handler(dp, (void *)&cmd->data, - reo_status.uniform_hdr.cmd_status); - kfree(cmd); - } - - found = false; - } - - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); -} - void ath12k_dp_rx_free(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 454e46b9d452a..c1efc8c658db0 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -408,7 +408,6 @@ void ath12k_dp_rx_free(struct ath12k_base *ab); int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index de88ba70bf23b..dfa2896a40757 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -15,6 +15,7 @@ #include "hif.h" #include "mhi.h" #include "debug.h" +#include "wifi7/dp.h" #define ATH12K_PCI_BAR_NUM 0 #define ATH12K_PCI_DMA_MASK 36 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c new file mode 100644 index 0000000000000..2e7b9bbd3d8ed --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include "../core.h" +#include "../debug.h" +#include "../dp_rx.h" +#include "../dp_tx.h" +#include "../dp_mon.h" +#include "dp_rx.h" +#include "dp.h" + +int ath12k_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, + int budget) +{ + struct napi_struct *napi = &irq_grp->napi; + int grp_id = irq_grp->grp_id; + int work_done = 0; + int i = 0, j; + int tot_work_done = 0; + enum dp_monitor_mode monitor_mode; + u8 ring_mask; + + if (ab->hw_params->ring_mask->tx[grp_id]) { + i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; + ath12k_dp_tx_completion_handler(ab, i); + } + + if (ab->hw_params->ring_mask->rx_err[grp_id]) { + work_done = ath12k_dp_rx_process_err(ab, napi, budget); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; + } + + if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { + work_done = ath12k_dp_rx_process_wbm_err(ab, + napi, + budget); + budget -= work_done; + tot_work_done += work_done; + + if (budget <= 0) + goto done; + } + + if (ab->hw_params->ring_mask->rx[grp_id]) { + i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; + work_done = ath12k_dp_rx_process(ab, i, napi, + budget); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; + } + + if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { + ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; + for (i = 0; i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { + int id = i * ab->hw_params->num_rxdma_per_pdev + j; + + if (ring_mask & BIT(id)) { + work_done = + ath12k_dp_mon_process_ring(ab, id, napi, budget, + 0); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; + } + } + } + } + + if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { + monitor_mode = ATH12K_DP_RX_MONITOR_MODE; + ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; + for (i = 0; i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { + int id = i * ab->hw_params->num_rxdma_per_pdev + j; + + if (ring_mask & BIT(id)) { + work_done = + ath12k_dp_mon_process_ring(ab, id, napi, budget, + monitor_mode); + budget -= work_done; + tot_work_done += work_done; + + if (budget <= 0) + goto done; + } + } + } + } + + if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { + monitor_mode = ATH12K_DP_TX_MONITOR_MODE; + ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; + for (i = 0; i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { + int id = i * ab->hw_params->num_rxdma_per_pdev + j; + + if (ring_mask & BIT(id)) { + work_done = + ath12k_dp_mon_process_ring(ab, id, napi, budget, + monitor_mode); + budget -= work_done; + tot_work_done += work_done; + + if (budget <= 0) + goto done; + } + } + } + } + + if (ab->hw_params->ring_mask->reo_status[grp_id]) + ath12k_dp_rx_process_reo_status(ab); + + if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + LIST_HEAD(list); + + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); + } + + /* TODO: Implement handler for other interrupts */ + +done: + return tot_work_done; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h new file mode 100644 index 0000000000000..17255a5671d73 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_WIFI7_H +#define ATH12K_DP_WIFI7_H + +#include "hw.h" + +int ath12k_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, + int budget); +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index b55cfb926571f..cbc51a9a2c42b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1642,3 +1642,82 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); + +void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct hal_tlv_64_hdr *hdr; + struct hal_srng *srng; + struct ath12k_dp_rx_reo_cmd *cmd, *tmp; + bool found = false; + u16 tag; + struct hal_reo_status reo_status; + + srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; + + memset(&reo_status, 0, sizeof(reo_status)); + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); + + switch (tag) { + case HAL_REO_GET_QUEUE_STATS_STATUS: + ath12k_hal_reo_status_queue_stats(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_QUEUE_STATUS: + ath12k_hal_reo_flush_queue_status(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_CACHE_STATUS: + ath12k_hal_reo_flush_cache_status(ab, hdr, + &reo_status); + break; + case HAL_REO_UNBLOCK_CACHE_STATUS: + ath12k_hal_reo_unblk_cache_status(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: + ath12k_hal_reo_flush_timeout_list_status(ab, hdr, + &reo_status); + break; + case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: + ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, + &reo_status); + break; + case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: + ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, + &reo_status); + break; + default: + ath12k_warn(ab, "Unknown reo status type %d\n", tag); + continue; + } + + spin_lock_bh(&dp->reo_cmd_lock); + list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { + if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) { + found = true; + list_del(&cmd->list); + break; + } + } + spin_unlock_bh(&dp->reo_cmd_lock); + + if (found) { + cmd->handler(dp, (void *)&cmd->data, + reo_status.uniform_hdr.cmd_status); + kfree(cmd); + } + + found = false; + } + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index fa44e454cee6c..63176a53c1e76 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -16,6 +16,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, struct napi_struct *napi, int budget); +void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif From 432392e1416621a12c51a500240b8496995d6961 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:45 +0530 Subject: [PATCH 391/659] wifi: ath12k: Separate arch specific part of RX APIs Below API have architecture specific HAL macros. ath12k_dp_rx_peer_pn_replay_config Separate architecture specific parts from these APIs to later move them to wifi7 directory. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-13-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 56 ++++++++++++++----------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 096d102c0362d..a7225221a5f5f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1061,6 +1061,36 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return ret; } +static void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd) +{ + cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd->upd0 = HAL_REO_CMD_UPD0_PN | + HAL_REO_CMD_UPD0_PN_SIZE | + HAL_REO_CMD_UPD0_PN_VALID | + HAL_REO_CMD_UPD0_PN_CHECK | + HAL_REO_CMD_UPD0_SVLD; + + switch (cipher) { + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + if (key_cmd == SET_KEY) { + cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; + cmd->pn_size = 48; + } + break; + default: + break; + } + + cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); +} + int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, const u8 *peer_addr, enum set_key_cmd key_cmd, @@ -1082,28 +1112,6 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return 0; - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.upd0 = HAL_REO_CMD_UPD0_PN | - HAL_REO_CMD_UPD0_PN_SIZE | - HAL_REO_CMD_UPD0_PN_VALID | - HAL_REO_CMD_UPD0_PN_CHECK | - HAL_REO_CMD_UPD0_SVLD; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_TKIP: - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - if (key_cmd == SET_KEY) { - cmd.upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; - cmd.pn_size = 48; - } - break; - default: - break; - } - spin_lock_bh(&ab->base_lock); peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); @@ -1120,8 +1128,8 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, continue; ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - cmd.addr_lo = lower_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid_rxq.qbuf.paddr_aligned); + + ath12k_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, key_cmd); ret = ath12k_dp_reo_cmd_send(ab, &rx_tid_rxq, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL); From 6d9a82a6f364e8822e970d7a947086e81f39d92b Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:46 +0530 Subject: [PATCH 392/659] wifi: ath12k: Move arch specific REO functions to wifi7 directory Move arch specific REO functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_setup_pn_check_reo_cmd ath12k_dp_rx_assign_reoq Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-14-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 82 +------------------ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 80 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 6 ++ 3 files changed, 87 insertions(+), 81 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index a7225221a5f5f..2a097079fc447 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -13,6 +13,7 @@ #include "wifi7/hal_desc.h" #include "hw.h" #include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "wifi7/hal_rx.h" #include "dp_tx.h" #include "peer.h" @@ -793,57 +794,6 @@ static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, return 0; } -static int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, - struct ath12k_sta *ahsta, - struct ath12k_dp_rx_tid *rx_tid, - u16 ssn, enum hal_pn_type pn_type) -{ - u32 ba_win_sz = rx_tid->ba_win_sz; - struct ath12k_reoq_buf *buf; - void *vaddr, *vaddr_aligned; - dma_addr_t paddr_aligned; - u8 tid = rx_tid->tid; - u32 hw_desc_sz; - int ret; - - buf = &ahsta->reoq_bufs[tid]; - if (!buf->vaddr) { - /* TODO: Optimize the memory allocation for qos tid based on - * the actual BA window size in REO tid update path. - */ - if (tid == HAL_DESC_REO_NON_QOS_TID) - hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); - else - hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); - - vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); - if (!vaddr) - return -ENOMEM; - - vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); - - ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, - ssn, pn_type); - - paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, - DMA_BIDIRECTIONAL); - ret = dma_mapping_error(ab->dev, paddr_aligned); - if (ret) { - kfree(vaddr); - return ret; - } - - buf->vaddr = vaddr; - buf->paddr_aligned = paddr_aligned; - buf->size = hw_desc_sz; - } - - rx_tid->qbuf = *buf; - rx_tid->active = true; - - return 0; -} - static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid) @@ -1061,36 +1011,6 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return ret; } -static void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, enum set_key_cmd key_cmd) -{ - cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd->upd0 = HAL_REO_CMD_UPD0_PN | - HAL_REO_CMD_UPD0_PN_SIZE | - HAL_REO_CMD_UPD0_PN_VALID | - HAL_REO_CMD_UPD0_PN_CHECK | - HAL_REO_CMD_UPD0_SVLD; - - switch (cipher) { - case WLAN_CIPHER_SUITE_TKIP: - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - if (key_cmd == SET_KEY) { - cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; - cmd->pn_size = 48; - } - break; - default: - break; - } - - cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); -} - int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, const u8 *peer_addr, enum set_key_cmd key_cmd, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index cbc51a9a2c42b..bcdfa19a2e5f4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -8,6 +8,56 @@ #include "../dp_tx.h" #include "../peer.h" +int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) +{ + u32 ba_win_sz = rx_tid->ba_win_sz; + struct ath12k_reoq_buf *buf; + void *vaddr, *vaddr_aligned; + dma_addr_t paddr_aligned; + u8 tid = rx_tid->tid; + u32 hw_desc_sz; + int ret; + + buf = &ahsta->reoq_bufs[tid]; + if (!buf->vaddr) { + /* TODO: Optimize the memory allocation for qos tid based on + * the actual BA window size in REO tid update path. + */ + if (tid == HAL_DESC_REO_NON_QOS_TID) + hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); + else + hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); + + vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); + if (!vaddr) + return -ENOMEM; + + vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); + + ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, + ssn, pn_type); + + paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, + DMA_BIDIRECTIONAL); + ret = dma_mapping_error(ab->dev, paddr_aligned); + if (ret) { + kfree(vaddr); + return ret; + } + + buf->vaddr = vaddr; + buf->paddr_aligned = paddr_aligned; + buf->size = hw_desc_sz; + } + + rx_tid->qbuf = *buf; + rx_tid->active = true; + + return 0; +} + static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, struct ath12k_dp_rx_info *rx_info) { @@ -1354,6 +1404,36 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); } +void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd) +{ + cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd->upd0 = HAL_REO_CMD_UPD0_PN | + HAL_REO_CMD_UPD0_PN_SIZE | + HAL_REO_CMD_UPD0_PN_VALID | + HAL_REO_CMD_UPD0_PN_CHECK | + HAL_REO_CMD_UPD0_SVLD; + + switch (cipher) { + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + if (key_cmd == SET_KEY) { + cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; + cmd->pn_size = 48; + } + break; + default: + break; + } + + cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); +} + int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 63176a53c1e76..3589db00c9064 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -19,4 +19,10 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); +void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd); +int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type); #endif From 92b431ed43e32e9161440a7c30e705d559a46edd Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:47 +0530 Subject: [PATCH 393/659] wifi: ath12k: Move arch specific rx tid and related functions to wifi7 directory Move arch specific Rx tid related functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_peer_rx_tid_qref_reset ath12k_dp_reo_cache_flush ath12k_dp_reo_cmd_send ath12k_peer_rx_tid_reo_update ath12k_dp_rx_link_desc_return ath12k_dp_rx_peer_tid_delete ath12k_peer_rx_tid_qref_setup Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-15-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 223 +--------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 7 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 240 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 19 ++ 4 files changed, 267 insertions(+), 222 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 2a097079fc447..d2c206fccb201 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -397,8 +397,8 @@ void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab) spin_unlock_bh(&dp->reo_cmd_lock); } -static void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status) +void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) { struct ath12k_dp_rx_tid_rxq *rx_tid = ctx; @@ -409,107 +409,6 @@ static void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, ath12k_dp_rx_tid_cleanup(dp->ab, &rx_tid->qbuf); } -static int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, - struct ath12k_dp_rx_tid_rxq *rx_tid, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd, - void (*cb)(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status)) -{ - struct ath12k_dp *dp = &ab->dp; - struct ath12k_dp_rx_reo_cmd *dp_cmd; - struct hal_srng *cmd_ring; - int cmd_num; - - cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); - - /* cmd_num should start from 1, during failure return the error code */ - if (cmd_num < 0) - return cmd_num; - - /* reo cmd ring descriptors has cmd_num starting from 1 */ - if (cmd_num == 0) - return -EINVAL; - - if (!cb) - return 0; - - /* Can this be optimized so that we keep the pending command list only - * for tid delete command to free up the resource on the command status - * indication? - */ - dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC); - - if (!dp_cmd) - return -ENOMEM; - - memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid)); - dp_cmd->cmd_num = cmd_num; - dp_cmd->handler = cb; - - spin_lock_bh(&dp->reo_cmd_lock); - list_add_tail(&dp_cmd->list, &dp->reo_cmd_list); - spin_unlock_bh(&dp->reo_cmd_lock); - - return 0; -} - -static int ath12k_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid_rxq *rx_tid) -{ - struct ath12k_hal_reo_cmd cmd = {}; - int ret; - - cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - /* HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS - all pending MPDUs - *in the bitmap will be forwarded/flushed to REO output rings - */ - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS | - HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS; - - /* For all QoS TIDs (except NON_QOS), the driver allocates a maximum - * window size of 1024. In such cases, the driver can issue a single - * 1KB descriptor flush command instead of sending multiple 128-byte - * flush commands for each QoS TID, improving efficiency. - */ - - if (rx_tid->tid != HAL_DESC_REO_NON_QOS_TID) - cmd.flag |= HAL_REO_CMD_FLG_FLUSH_QUEUE_1K_DESC; - - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, - &cmd, ath12k_dp_reo_cmd_free); - return ret; -} - -static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) -{ - struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; - bool ml_peer = false; - - if (!ab->hw_params->reoq_lut_support) - return; - - if (peer_id & ATH12K_PEER_ML_ID_VALID) { - peer_id &= ~ATH12K_PEER_ML_ID_VALID; - ml_peer = true; - } - - if (ml_peer) - qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - else - qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - - qref->info0 = u32_encode_bits(0, BUFFER_ADDR_INFO0_ADDR); - qref->info1 = u32_encode_bits(0, BUFFER_ADDR_INFO1_ADDR) | - u32_encode_bits(tid, DP_REO_QREF_NUM); -} - static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp) { struct ath12k_base *ab = dp->ab; @@ -539,8 +438,8 @@ static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp * spin_unlock_bh(&dp->reo_rxq_flush_lock); } -static void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status) +void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) { struct ath12k_base *ab = dp->ab; struct ath12k_dp_rx_tid_rxq *rx_tid = ctx; @@ -619,36 +518,6 @@ static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, ath12k_dp_rx_tid_del_func); } -static void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, - dma_addr_t paddr) -{ - struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; - bool ml_peer = false; - - if (!ab->hw_params->reoq_lut_support) - return; - - if (peer_id & ATH12K_PEER_ML_ID_VALID) { - peer_id &= ~ATH12K_PEER_ML_ID_VALID; - ml_peer = true; - } - - if (ml_peer) - qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - else - qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - - qref->info0 = u32_encode_bits(lower_32_bits(paddr), - BUFFER_ADDR_INFO0_ADDR); - qref->info1 = u32_encode_bits(upper_32_bits(paddr), - BUFFER_ADDR_INFO1_ADDR) | - u32_encode_bits(tid, DP_REO_QREF_NUM); - ath12k_hal_reo_shared_qaddr_cache_clear(ab); -} - static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 tid) { struct dp_reo_update_rx_queue_elem *elem; @@ -667,53 +536,6 @@ static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 spin_unlock_bh(&dp->reo_rxq_flush_lock); } -void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid) -{ - struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - - if (!rx_tid->active) - return; - - rx_tid->active = false; - - ath12k_dp_mark_tid_as_inactive(dp, peer->peer_id, tid); - ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(dp); -} - -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action) -{ - struct hal_wbm_release_ring *desc; - struct ath12k_dp *dp = &ab->dp; - struct hal_srng *srng; - int ret = 0; - - srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - desc = ath12k_hal_srng_src_get_next_entry(ab, srng); - if (!desc) { - ret = -ENOBUFS; - goto exit; - } - - ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); - -exit: - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - return ret; -} - void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc) { @@ -757,43 +579,6 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) } } -static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - u32 ba_win_sz, u16 ssn, - bool update_ssn) -{ - struct ath12k_hal_reo_cmd cmd = {}; - int ret; - struct ath12k_dp_rx_tid_rxq rx_tid_rxq; - - ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - - cmd.addr_lo = lower_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE; - cmd.ba_window_size = ba_win_sz; - - if (update_ssn) { - cmd.upd0 |= HAL_REO_CMD_UPD0_SSN; - cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); - } - - ret = ath12k_dp_reo_cmd_send(ar->ab, &rx_tid_rxq, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - NULL); - if (ret) { - ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", - rx_tid_rxq.tid, ret); - return ret; - } - - rx_tid->ba_win_sz = ba_win_sz; - - return 0; -} - static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index c1efc8c658db0..fc1c4ac161c1a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -436,12 +436,13 @@ u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first); +void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status); +void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index bcdfa19a2e5f4..d95e3c4daa5d5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -8,6 +8,246 @@ #include "../dp_tx.h" #include "../peer.h" +void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr) +{ + struct ath12k_reo_queue_ref *qref; + struct ath12k_dp *dp = &ab->dp; + bool ml_peer = false; + + if (!ab->hw_params->reoq_lut_support) + return; + + if (peer_id & ATH12K_PEER_ML_ID_VALID) { + peer_id &= ~ATH12K_PEER_ML_ID_VALID; + ml_peer = true; + } + + if (ml_peer) + qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + else + qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + + qref->info0 = u32_encode_bits(lower_32_bits(paddr), + BUFFER_ADDR_INFO0_ADDR); + qref->info1 = u32_encode_bits(upper_32_bits(paddr), + BUFFER_ADDR_INFO1_ADDR) | + u32_encode_bits(tid, DP_REO_QREF_NUM); + ath12k_hal_reo_shared_qaddr_cache_clear(ab); +} + +static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) +{ + struct ath12k_reo_queue_ref *qref; + struct ath12k_dp *dp = &ab->dp; + bool ml_peer = false; + + if (!ab->hw_params->reoq_lut_support) + return; + + if (peer_id & ATH12K_PEER_ML_ID_VALID) { + peer_id &= ~ATH12K_PEER_ML_ID_VALID; + ml_peer = true; + } + + if (ml_peer) + qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + else + qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + + qref->info0 = u32_encode_bits(0, BUFFER_ADDR_INFO0_ADDR); + qref->info1 = u32_encode_bits(0, BUFFER_ADDR_INFO1_ADDR) | + u32_encode_bits(tid, DP_REO_QREF_NUM); +} + +void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid) +{ + struct ath12k_hal_reo_cmd cmd = {}; + struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + int ret; + + if (!rx_tid->active) + return; + + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.upd0 = HAL_REO_CMD_UPD0_VLD; + ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + ath12k_dp_rx_tid_del_func); + if (ret) { + ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", + tid, ret); + dma_unmap_single(ar->ab->dev, rx_tid->qbuf.paddr_aligned, + rx_tid->qbuf.size, DMA_BIDIRECTIONAL); + kfree(rx_tid->qbuf.vaddr); + rx_tid->qbuf.vaddr = NULL; + } + + if (peer->mlo) + ath12k_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); + else + ath12k_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); + + rx_tid->active = false; +} + +int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) +{ + struct hal_wbm_release_ring *desc; + struct ath12k_dp *dp = &ab->dp; + struct hal_srng *srng; + int ret = 0; + + srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + desc = ath12k_hal_srng_src_get_next_entry(ab, srng); + if (!desc) { + ret = -ENOBUFS; + goto exit; + } + + ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); + +exit: + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + return ret; +} + +int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)) +{ + struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp_rx_reo_cmd *dp_cmd; + struct hal_srng *cmd_ring; + int cmd_num; + + cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; + cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); + + /* cmd_num should start from 1, during failure return the error code */ + if (cmd_num < 0) + return cmd_num; + + /* reo cmd ring descriptors has cmd_num starting from 1 */ + if (cmd_num == 0) + return -EINVAL; + + if (!cb) + return 0; + + /* Can this be optimized so that we keep the pending command list only + * for tid delete command to free up the resource on the command status + * indication? + */ + dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC); + + if (!dp_cmd) + return -ENOMEM; + + memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid)); + dp_cmd->cmd_num = cmd_num; + dp_cmd->handler = cb; + + spin_lock_bh(&dp->reo_cmd_lock); + list_add_tail(&dp_cmd->list, &dp->reo_cmd_list); + spin_unlock_bh(&dp->reo_cmd_lock); + + return 0; +} + +int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) +{ + struct ath12k_hal_reo_cmd cmd = {}; + int ret; + + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE; + cmd.ba_window_size = ba_win_sz; + + if (update_ssn) { + cmd.upd0 |= HAL_REO_CMD_UPD0_SSN; + cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); + } + + ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + NULL); + if (ret) { + ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", + rx_tid->tid, ret); + return ret; + } + + rx_tid->ba_win_sz = ba_win_sz; + + return 0; +} + +void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid) +{ + struct ath12k_hal_reo_cmd cmd = {}; + unsigned long tot_desc_sz, desc_sz; + int ret; + + tot_desc_sz = rx_tid->qbuf.size; + desc_sz = ath12k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); + + while (tot_desc_sz > desc_sz) { + tot_desc_sz -= desc_sz; + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + ret = ath12k_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); + if (ret) + ath12k_warn(ab, + "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", + rx_tid->tid, ret); + } + + memset(&cmd, 0, sizeof(cmd)); + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + ret = ath12k_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, + &cmd, ath12k_dp_reo_cmd_free); + if (ret) { + ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", + rx_tid->tid, ret); + dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size, + DMA_BIDIRECTIONAL); + kfree(rx_tid->qbuf.vaddr); + rx_tid->qbuf.vaddr = NULL; + } +} + int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 3589db00c9064..45b856aaaa124 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -25,4 +25,23 @@ void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type); +int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); +void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr); +void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid); +int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)); +void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid); +int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn); #endif From 35d637c553f0081d33a21c2c488ba02d9ce790ee Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:48 +0530 Subject: [PATCH 394/659] wifi: ath12k: Move arch specific tx APIs to wifi7 directory Move arch specific TX data path to wifi7 directory as part of Next Generation (NG) Driver Framework. Architecture specific APIs: ath12k_dp_tx_htt_tx_complete_buf ath12k_dp_tx_process_htt_tx_complete ath12k_dp_tx_update_txcompl ath12k_dp_tx_complete_msdu ath12k_dp_tx_status_parse ath12k_dp_tx_completion_handler The moved APIs will be a part of dp_tx.c file inside wifi7 directory. wifi7/dp_tx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-16-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp_tx.c | 564 +----------------- drivers/net/wireless/ath/ath12k/dp_tx.h | 18 +- drivers/net/wireless/ath/ath12k/mac.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 545 +++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 11 + 7 files changed, 590 insertions(+), 551 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index ed1f1dba3d3b9..e72b52d5af6d6 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -25,6 +25,7 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ wifi7/dp_rx.o \ + wifi7/dp_tx.o \ wifi7/dp.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index abc84ca8467a2..f1649744c78b7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "core.h" @@ -12,7 +12,7 @@ #include "peer.h" #include "mac.h" -static enum hal_tcl_encap_type +enum hal_tcl_encap_type ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -26,7 +26,7 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI; } -static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) +void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) { struct ieee80211_hdr *hdr = (void *)skb->data; u8 *qos_ctl; @@ -43,7 +43,7 @@ static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); } -static u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) +u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) { struct ieee80211_hdr *hdr = (void *)skb->data; struct ath12k_skb_cb *cb = ATH12K_SKB_CB(skb); @@ -78,9 +78,9 @@ enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher) } } -static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, - struct ath12k_tx_desc_info *tx_desc, - u8 pool_id) +void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, + struct ath12k_tx_desc_info *tx_desc, + u8 pool_id) { spin_lock_bh(&dp->tx_desc_lock[pool_id]); tx_desc->skb_ext_desc = NULL; @@ -88,8 +88,8 @@ static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, spin_unlock_bh(&dp->tx_desc_lock[pool_id]); } -static struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, - u8 pool_id) +struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, + u8 pool_id) { struct ath12k_tx_desc_info *desc; @@ -129,7 +129,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, #define HTT_META_DATA_ALIGNMENT 0x8 -static void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) +void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) { struct sk_buff *tail; void *metadata; @@ -182,8 +182,8 @@ static void ath12k_dp_tx_move_payload(struct sk_buff *skb, } } -static int ath12k_dp_tx_align_payload(struct ath12k_base *ab, - struct sk_buff **pskb) +int ath12k_dp_tx_align_payload(struct ath12k_base *ab, + struct sk_buff **pskb) { u32 iova_mask = ab->hw_params->iova_mask; unsigned long offset, delta1, delta2; @@ -539,9 +539,9 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, return ret; } -static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, - struct dp_tx_ring *tx_ring, - struct ath12k_tx_desc_params *desc_params) +void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, + struct dp_tx_ring *tx_ring, + struct ath12k_tx_desc_params *desc_params) { struct ath12k *ar; struct sk_buff *msdu = desc_params->skb; @@ -564,540 +564,6 @@ static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, wake_up(&ar->dp.tx_empty_waitq); } -static void -ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, - struct ath12k_tx_desc_params *desc_params, - struct dp_tx_ring *tx_ring, - struct ath12k_dp_htt_wbm_tx_status *ts, - u16 peer_id) -{ - struct ieee80211_tx_info *info; - struct ath12k_link_vif *arvif; - struct ath12k_skb_cb *skb_cb; - struct ieee80211_vif *vif; - struct ath12k_vif *ahvif; - struct ath12k *ar; - struct sk_buff *msdu = desc_params->skb; - s32 noise_floor; - struct ieee80211_tx_status status = {}; - struct ath12k_peer *peer; - - skb_cb = ATH12K_SKB_CB(msdu); - info = IEEE80211_SKB_CB(msdu); - - ar = skb_cb->ar; - ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; - - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); - - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); - if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, - desc_params->skb_ext_desc->len, DMA_TO_DEVICE); - dev_kfree_skb_any(desc_params->skb_ext_desc); - } - - vif = skb_cb->vif; - if (vif) { - ahvif = ath12k_vif_to_ahvif(vif); - rcu_read_lock(); - arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); - if (arvif) { - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_completed++; - spin_unlock_bh(&arvif->link_stats_lock); - } - rcu_read_unlock(); - } - - memset(&info->status, 0, sizeof(info->status)); - - if (ts->acked) { - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts->ack_rssi; - - if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, - ab->wmi_ab.svc_map)) { - spin_lock_bh(&ar->data_lock); - noise_floor = ath12k_pdev_get_noise_floor(ar); - spin_unlock_bh(&ar->data_lock); - - info->status.ack_signal += noise_floor; - } - - info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; - } else { - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - } - } - rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - spin_unlock_bh(&ab->base_lock); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); - goto exit; - } else { - status.sta = peer->sta; - } - spin_unlock_bh(&ab->base_lock); - - status.info = info; - status.skb = msdu; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); -exit: - rcu_read_unlock(); -} - -static void -ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, - struct dp_tx_ring *tx_ring, - struct ath12k_tx_desc_params *desc_params) -{ - struct htt_tx_wbm_completion *status_desc; - struct ath12k_dp_htt_wbm_tx_status ts = {}; - enum hal_wbm_htt_tx_comp_status wbm_status; - u16 peer_id; - - status_desc = desc; - - wbm_status = le32_get_bits(status_desc->info0, - HTT_TX_WBM_COMP_INFO0_STATUS); - ab->device_stats.fw_tx_status[wbm_status]++; - - switch (wbm_status) { - case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: - ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK); - ts.ack_rssi = le32_get_bits(status_desc->info2, - HTT_TX_WBM_COMP_INFO2_ACK_RSSI); - - peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)-> - info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); - - ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id); - break; - case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH: - ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params); - break; - case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: - /* This event is to be handled only when the driver decides to - * use WDS offload functionality. - */ - break; - default: - ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status); - break; - } -} - -static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; - struct ieee80211_sta *sta; - struct ath12k_sta *ahsta; - struct ath12k_link_sta *arsta; - struct rate_info txrate = {}; - u16 rate, ru_tones; - u8 rate_idx = 0; - int ret; - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DP_TX, - "failed to find the peer by id %u\n", ts->peer_id); - spin_unlock_bh(&ab->base_lock); - return; - } - sta = peer->sta; - ahsta = ath12k_sta_to_ahsta(sta); - arsta = &ahsta->deflink; - - /* This is to prefer choose the real NSS value arsta->last_txrate.nss, - * if it is invalid, then choose the NSS value while assoc. - */ - if (arsta->last_txrate.nss) - txrate.nss = arsta->last_txrate.nss; - else - txrate.nss = arsta->peer_nss; - spin_unlock_bh(&ab->base_lock); - - switch (ts->pkt_type) { - case HAL_TX_RATE_STATS_PKT_TYPE_11A: - case HAL_TX_RATE_STATS_PKT_TYPE_11B: - ret = ath12k_mac_hw_ratecode_to_legacy_rate(ts->mcs, - ts->pkt_type, - &rate_idx, - &rate); - if (ret < 0) { - ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret); - return; - } - - txrate.legacy = rate; - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11N: - if (ts->mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs); - return; - } - - if (txrate.nss != 0) - txrate.mcs = ts->mcs + 8 * (txrate.nss - 1); - - txrate.flags = RATE_INFO_FLAGS_MCS; - - if (ts->sgi) - txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11AC: - if (ts->mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs); - return; - } - - txrate.mcs = ts->mcs; - txrate.flags = RATE_INFO_FLAGS_VHT_MCS; - - if (ts->sgi) - txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11AX: - if (ts->mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs); - return; - } - - txrate.mcs = ts->mcs; - txrate.flags = RATE_INFO_FLAGS_HE_MCS; - txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(ts->sgi); - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11BE: - if (ts->mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs); - return; - } - - txrate.mcs = ts->mcs; - txrate.flags = RATE_INFO_FLAGS_EHT_MCS; - txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi); - break; - default: - ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type); - return; - } - - txrate.bw = ath12k_mac_bw_to_mac80211_bw(ts->bw); - - if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) { - txrate.bw = RATE_INFO_BW_HE_RU; - ru_tones = ath12k_mac_he_convert_tones_to_ru_tones(ts->tones); - txrate.he_ru_alloc = - ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); - } - - if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11BE) { - txrate.bw = RATE_INFO_BW_EHT_RU; - txrate.eht_ru_alloc = - ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones); - } - - spin_lock_bh(&ab->base_lock); - arsta->txrate = txrate; - spin_unlock_bh(&ab->base_lock); -} - -static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, - struct ath12k_tx_desc_params *desc_params, - struct hal_tx_status *ts, - int ring) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_hw *ah = ar->ah; - struct ieee80211_tx_info *info; - struct ath12k_link_vif *arvif; - struct ath12k_skb_cb *skb_cb; - struct ieee80211_vif *vif; - struct ath12k_vif *ahvif; - struct sk_buff *msdu = desc_params->skb; - s32 noise_floor; - struct ieee80211_tx_status status = {}; - struct ieee80211_rate_status status_rate = {}; - struct ath12k_peer *peer; - struct ath12k_link_sta *arsta; - struct ath12k_sta *ahsta; - struct rate_info rate; - - if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { - /* Must not happen */ - return; - } - - skb_cb = ATH12K_SKB_CB(msdu); - ab->device_stats.tx_completed[ring]++; - - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); - if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, - desc_params->skb_ext_desc->len, DMA_TO_DEVICE); - dev_kfree_skb_any(desc_params->skb_ext_desc); - } - - rcu_read_lock(); - - if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { - ieee80211_free_txskb(ah->hw, msdu); - goto exit; - } - - if (!skb_cb->vif) { - ieee80211_free_txskb(ah->hw, msdu); - goto exit; - } - - vif = skb_cb->vif; - if (vif) { - ahvif = ath12k_vif_to_ahvif(vif); - arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); - if (arvif) { - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_completed++; - spin_unlock_bh(&arvif->link_stats_lock); - } - } - - info = IEEE80211_SKB_CB(msdu); - memset(&info->status, 0, sizeof(info->status)); - - /* skip tx rate update from ieee80211_status*/ - info->status.rates[0].idx = -1; - - switch (ts->status) { - case HAL_WBM_TQM_REL_REASON_FRAME_ACKED: - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts->ack_rssi; - - if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, - ab->wmi_ab.svc_map)) { - spin_lock_bh(&ar->data_lock); - noise_floor = ath12k_pdev_get_noise_floor(ar); - spin_unlock_bh(&ar->data_lock); - - info->status.ack_signal += noise_floor; - } - - info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; - } - break; - case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX: - if (info->flags & IEEE80211_TX_CTL_NO_ACK) { - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - break; - } - fallthrough; - case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU: - case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD: - case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES: - /* The failure status is due to internal firmware tx failure - * hence drop the frame; do not update the status of frame to - * the upper layer - */ - ieee80211_free_txskb(ah->hw, msdu); - goto exit; - default: - ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n", - ts->status); - break; - } - - /* NOTE: Tx rate status reporting. Tx completion status does not have - * necessary information (for example nss) to build the tx rate. - * Might end up reporting it out-of-band from HTT stats. - */ - - ath12k_dp_tx_update_txcompl(ar, ts); - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); - if (!peer || !peer->sta) { - ath12k_err(ab, - "dp_tx: failed to find the peer with peer_id %d\n", - ts->peer_id); - spin_unlock_bh(&ab->base_lock); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); - goto exit; - } - ahsta = ath12k_sta_to_ahsta(peer->sta); - arsta = &ahsta->deflink; - - spin_unlock_bh(&ab->base_lock); - - status.sta = peer->sta; - status.info = info; - status.skb = msdu; - rate = arsta->last_txrate; - - status_rate.rate_idx = rate; - status_rate.try_count = 1; - - status.rates = &status_rate; - status.n_rates = 1; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); - -exit: - rcu_read_unlock(); -} - -static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, - struct hal_wbm_completion_ring_tx *desc, - struct hal_tx_status *ts) -{ - u32 info0 = le32_to_cpu(desc->rate_stats.info0); - - ts->buf_rel_source = - le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE); - if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && - ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM) - return; - - if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) - return; - - ts->status = le32_get_bits(desc->info0, - HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); - - ts->ppdu_id = le32_get_bits(desc->info1, - HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER); - - ts->peer_id = le32_get_bits(desc->info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); - - ts->ack_rssi = le32_get_bits(desc->info2, - HAL_WBM_COMPL_TX_INFO2_ACK_FRAME_RSSI); - - if (info0 & HAL_TX_RATE_STATS_INFO0_VALID) { - ts->pkt_type = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_PKT_TYPE); - ts->mcs = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_MCS); - ts->sgi = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_SGI); - ts->bw = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_BW); - ts->tones = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_TONES_IN_RU); - ts->ofdma = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_OFDMA_TX); - } -} - -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) -{ - struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; - int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; - struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; - struct ath12k_tx_desc_info *tx_desc = NULL; - struct hal_tx_status ts = {}; - struct ath12k_tx_desc_params desc_params; - struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; - struct hal_wbm_release_ring *desc; - u8 pdev_id; - u64 desc_va; - enum hal_wbm_rel_src_module buf_rel_source; - enum hal_wbm_tqm_rel_reason rel_status; - - spin_lock_bh(&status_ring->lock); - - ath12k_hal_srng_access_begin(ab, status_ring); - - while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) != - tx_ring->tx_status_tail) { - desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring); - if (!desc) - break; - - memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], - desc, sizeof(*desc)); - tx_ring->tx_status_head = - ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head); - } - - if (ath12k_hal_srng_dst_peek(ab, status_ring) && - (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) == - tx_ring->tx_status_tail)) { - /* TODO: Process pending tx_status messages when kfifo_is_full() */ - ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); - } - - ath12k_hal_srng_access_end(ab, status_ring); - - spin_unlock_bh(&status_ring->lock); - - while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail) != - tx_ring->tx_status_head) { - struct hal_wbm_completion_ring_tx *tx_status; - u32 desc_id; - - tx_ring->tx_status_tail = - ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); - tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; - ath12k_dp_tx_status_parse(ab, tx_status, &ts); - - if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { - /* HW done cookie conversion */ - desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 | - le32_to_cpu(tx_status->buf_va_lo)); - tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va); - } else { - /* SW does cookie conversion to VA */ - desc_id = le32_get_bits(tx_status->buf_va_hi, - BUFFER_ADDR_INFO1_SW_COOKIE); - - tx_desc = ath12k_dp_get_tx_desc(ab, desc_id); - } - if (!tx_desc) { - ath12k_warn(ab, "unable to retrieve tx_desc!"); - continue; - } - - desc_params.mac_id = tx_desc->mac_id; - desc_params.skb = tx_desc->skb; - desc_params.skb_ext_desc = tx_desc->skb_ext_desc; - - /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */ - buf_rel_source = le32_get_bits(tx_status->info0, - HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); - ab->device_stats.tx_wbm_rel_source[buf_rel_source]++; - - rel_status = le32_get_bits(tx_status->info0, - HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); - ab->device_stats.tqm_rel_reason[rel_status]++; - - /* Release descriptor as soon as extracting necessary info - * to reduce contention - */ - ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id); - if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) { - ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, - tx_ring, &desc_params); - continue; - } - - pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); - ar = ab->pdevs[pdev_id].ar; - - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); - - ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts, - tx_ring->tcl_data_ring_id); - } -} - static int ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, int mac_id, u32 ring_id, diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index aa2f6397bc83d..67ab7b3f55eaf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -19,8 +19,6 @@ int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); - int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); int ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, @@ -38,4 +36,20 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, int tx_buf_size, struct htt_tx_ring_tlv_filter *htt_tlv_filter); int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset); + +enum hal_tcl_encap_type +ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb); +void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb); +u8 ath12k_dp_tx_get_tid(struct sk_buff *skb); +void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len); +int ath12k_dp_tx_align_payload(struct ath12k_base *ab, + struct sk_buff **pskb); +void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, + struct ath12k_tx_desc_info *tx_desc, + u8 pool_id); +struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, + u8 pool_id); +void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, + struct dp_tx_ring *tx_ring, + struct ath12k_tx_desc_params *desc_params); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index e0e49f782bf8d..cd18ade8fb02e 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -14,6 +14,7 @@ #include "wmi.h" #include "hw.h" #include "dp_tx.h" +#include "wifi7/dp_tx.h" #include "dp_rx.h" #include "testmode.h" #include "peer.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 2e7b9bbd3d8ed..afe791394e6b4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -10,6 +10,7 @@ #include "../dp_mon.h" #include "dp_rx.h" #include "dp.h" +#include "dp_tx.h" int ath12k_dp_service_srng(struct ath12k_base *ab, struct ath12k_ext_irq_grp *irq_grp, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c new file mode 100644 index 0000000000000..149e211aa225e --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -0,0 +1,545 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "../core.h" +#include "../debug.h" +#include "../dp_tx.h" +#include "../peer.h" +#include "dp_tx.h" + +static void +ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, + struct ath12k_tx_desc_params *desc_params, + struct dp_tx_ring *tx_ring, + struct ath12k_dp_htt_wbm_tx_status *ts, + u16 peer_id) +{ + struct ieee80211_tx_info *info; + struct ath12k_link_vif *arvif; + struct ath12k_skb_cb *skb_cb; + struct ieee80211_vif *vif; + struct ath12k_vif *ahvif; + struct ath12k *ar; + struct sk_buff *msdu = desc_params->skb; + s32 noise_floor; + struct ieee80211_tx_status status = {}; + struct ath12k_peer *peer; + + skb_cb = ATH12K_SKB_CB(msdu); + info = IEEE80211_SKB_CB(msdu); + + ar = skb_cb->ar; + ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + if (skb_cb->paddr_ext_desc) { + dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + desc_params->skb_ext_desc->len, DMA_TO_DEVICE); + dev_kfree_skb_any(desc_params->skb_ext_desc); + } + + vif = skb_cb->vif; + if (vif) { + ahvif = ath12k_vif_to_ahvif(vif); + rcu_read_lock(); + arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); + if (arvif) { + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_completed++; + spin_unlock_bh(&arvif->link_stats_lock); + } + rcu_read_unlock(); + } + + memset(&info->status, 0, sizeof(info->status)); + + if (ts->acked) { + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ts->ack_rssi; + + if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, + ab->wmi_ab.svc_map)) { + spin_lock_bh(&ar->data_lock); + noise_floor = ath12k_pdev_get_noise_floor(ar); + spin_unlock_bh(&ar->data_lock); + + info->status.ack_signal += noise_floor; + } + + info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; + } else { + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + } + } + rcu_read_lock(); + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "dp_tx: failed to find the peer with peer_id %d\n", peer_id); + spin_unlock_bh(&ab->base_lock); + ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + goto exit; + } else { + status.sta = peer->sta; + } + spin_unlock_bh(&ab->base_lock); + + status.info = info; + status.skb = msdu; + ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); +exit: + rcu_read_unlock(); +} + +static void +ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, + struct dp_tx_ring *tx_ring, + struct ath12k_tx_desc_params *desc_params) +{ + struct htt_tx_wbm_completion *status_desc; + struct ath12k_dp_htt_wbm_tx_status ts = {}; + enum hal_wbm_htt_tx_comp_status wbm_status; + u16 peer_id; + + status_desc = desc; + + wbm_status = le32_get_bits(status_desc->info0, + HTT_TX_WBM_COMP_INFO0_STATUS); + ab->device_stats.fw_tx_status[wbm_status]++; + + switch (wbm_status) { + case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: + ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK); + ts.ack_rssi = le32_get_bits(status_desc->info2, + HTT_TX_WBM_COMP_INFO2_ACK_RSSI); + + peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)-> + info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); + + ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id); + break; + case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH: + ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params); + break; + case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: + /* This event is to be handled only when the driver decides to + * use WDS offload functionality. + */ + break; + default: + ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status); + break; + } +} + +static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_peer *peer; + struct ieee80211_sta *sta; + struct ath12k_sta *ahsta; + struct ath12k_link_sta *arsta; + struct rate_info txrate = {}; + u16 rate, ru_tones; + u8 rate_idx = 0; + int ret; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, ts->peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DP_TX, + "failed to find the peer by id %u\n", ts->peer_id); + spin_unlock_bh(&ab->base_lock); + return; + } + sta = peer->sta; + ahsta = ath12k_sta_to_ahsta(sta); + arsta = &ahsta->deflink; + + /* This is to prefer choose the real NSS value arsta->last_txrate.nss, + * if it is invalid, then choose the NSS value while assoc. + */ + if (arsta->last_txrate.nss) + txrate.nss = arsta->last_txrate.nss; + else + txrate.nss = arsta->peer_nss; + spin_unlock_bh(&ab->base_lock); + + switch (ts->pkt_type) { + case HAL_TX_RATE_STATS_PKT_TYPE_11A: + case HAL_TX_RATE_STATS_PKT_TYPE_11B: + ret = ath12k_mac_hw_ratecode_to_legacy_rate(ts->mcs, + ts->pkt_type, + &rate_idx, + &rate); + if (ret < 0) { + ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret); + return; + } + + txrate.legacy = rate; + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11N: + if (ts->mcs > ATH12K_HT_MCS_MAX) { + ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs); + return; + } + + if (txrate.nss != 0) + txrate.mcs = ts->mcs + 8 * (txrate.nss - 1); + + txrate.flags = RATE_INFO_FLAGS_MCS; + + if (ts->sgi) + txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11AC: + if (ts->mcs > ATH12K_VHT_MCS_MAX) { + ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs); + return; + } + + txrate.mcs = ts->mcs; + txrate.flags = RATE_INFO_FLAGS_VHT_MCS; + + if (ts->sgi) + txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11AX: + if (ts->mcs > ATH12K_HE_MCS_MAX) { + ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs); + return; + } + + txrate.mcs = ts->mcs; + txrate.flags = RATE_INFO_FLAGS_HE_MCS; + txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(ts->sgi); + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11BE: + if (ts->mcs > ATH12K_EHT_MCS_MAX) { + ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs); + return; + } + + txrate.mcs = ts->mcs; + txrate.flags = RATE_INFO_FLAGS_EHT_MCS; + txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi); + break; + default: + ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type); + return; + } + + txrate.bw = ath12k_mac_bw_to_mac80211_bw(ts->bw); + + if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) { + txrate.bw = RATE_INFO_BW_HE_RU; + ru_tones = ath12k_mac_he_convert_tones_to_ru_tones(ts->tones); + txrate.he_ru_alloc = + ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); + } + + if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11BE) { + txrate.bw = RATE_INFO_BW_EHT_RU; + txrate.eht_ru_alloc = + ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones); + } + + spin_lock_bh(&ab->base_lock); + arsta->txrate = txrate; + spin_unlock_bh(&ab->base_lock); +} + +static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, + struct ath12k_tx_desc_params *desc_params, + struct hal_tx_status *ts, + int ring) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_hw *ah = ar->ah; + struct ieee80211_tx_info *info; + struct ath12k_link_vif *arvif; + struct ath12k_skb_cb *skb_cb; + struct ieee80211_vif *vif; + struct ath12k_vif *ahvif; + struct sk_buff *msdu = desc_params->skb; + s32 noise_floor; + struct ieee80211_tx_status status = {}; + struct ieee80211_rate_status status_rate = {}; + struct ath12k_peer *peer; + struct ath12k_link_sta *arsta; + struct ath12k_sta *ahsta; + struct rate_info rate; + + if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { + /* Must not happen */ + return; + } + + skb_cb = ATH12K_SKB_CB(msdu); + ab->device_stats.tx_completed[ring]++; + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + if (skb_cb->paddr_ext_desc) { + dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + desc_params->skb_ext_desc->len, DMA_TO_DEVICE); + dev_kfree_skb_any(desc_params->skb_ext_desc); + } + + rcu_read_lock(); + + if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { + ieee80211_free_txskb(ah->hw, msdu); + goto exit; + } + + if (!skb_cb->vif) { + ieee80211_free_txskb(ah->hw, msdu); + goto exit; + } + + vif = skb_cb->vif; + if (vif) { + ahvif = ath12k_vif_to_ahvif(vif); + arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); + if (arvif) { + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_completed++; + spin_unlock_bh(&arvif->link_stats_lock); + } + } + + info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); + + /* skip tx rate update from ieee80211_status*/ + info->status.rates[0].idx = -1; + + switch (ts->status) { + case HAL_WBM_TQM_REL_REASON_FRAME_ACKED: + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ts->ack_rssi; + + if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, + ab->wmi_ab.svc_map)) { + spin_lock_bh(&ar->data_lock); + noise_floor = ath12k_pdev_get_noise_floor(ar); + spin_unlock_bh(&ar->data_lock); + + info->status.ack_signal += noise_floor; + } + + info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; + } + break; + case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX: + if (info->flags & IEEE80211_TX_CTL_NO_ACK) { + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + break; + } + fallthrough; + case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU: + case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD: + case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES: + /* The failure status is due to internal firmware tx failure + * hence drop the frame; do not update the status of frame to + * the upper layer + */ + ieee80211_free_txskb(ah->hw, msdu); + goto exit; + default: + ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n", + ts->status); + break; + } + + /* NOTE: Tx rate status reporting. Tx completion status does not have + * necessary information (for example nss) to build the tx rate. + * Might end up reporting it out-of-band from HTT stats. + */ + + ath12k_dp_tx_update_txcompl(ar, ts); + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, ts->peer_id); + if (!peer || !peer->sta) { + ath12k_err(ab, + "dp_tx: failed to find the peer with peer_id %d\n", + ts->peer_id); + spin_unlock_bh(&ab->base_lock); + ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + goto exit; + } + ahsta = ath12k_sta_to_ahsta(peer->sta); + arsta = &ahsta->deflink; + + spin_unlock_bh(&ab->base_lock); + + status.sta = peer->sta; + status.info = info; + status.skb = msdu; + rate = arsta->last_txrate; + + status_rate.rate_idx = rate; + status_rate.try_count = 1; + + status.rates = &status_rate; + status.n_rates = 1; + ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); + +exit: + rcu_read_unlock(); +} + +static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, + struct hal_wbm_completion_ring_tx *desc, + struct hal_tx_status *ts) +{ + u32 info0 = le32_to_cpu(desc->rate_stats.info0); + + ts->buf_rel_source = + le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE); + if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && + ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM) + return; + + if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) + return; + + ts->status = le32_get_bits(desc->info0, + HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); + + ts->ppdu_id = le32_get_bits(desc->info1, + HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER); + + ts->peer_id = le32_get_bits(desc->info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); + + ts->ack_rssi = le32_get_bits(desc->info2, + HAL_WBM_COMPL_TX_INFO2_ACK_FRAME_RSSI); + + if (info0 & HAL_TX_RATE_STATS_INFO0_VALID) { + ts->pkt_type = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_PKT_TYPE); + ts->mcs = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_MCS); + ts->sgi = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_SGI); + ts->bw = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_BW); + ts->tones = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_TONES_IN_RU); + ts->ofdma = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_OFDMA_TX); + } +} + +void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) +{ + struct ath12k *ar; + struct ath12k_dp *dp = &ab->dp; + int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; + struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; + struct ath12k_tx_desc_info *tx_desc = NULL; + struct hal_tx_status ts = {}; + struct ath12k_tx_desc_params desc_params; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + struct hal_wbm_release_ring *desc; + u8 pdev_id; + u64 desc_va; + enum hal_wbm_rel_src_module buf_rel_source; + enum hal_wbm_tqm_rel_reason rel_status; + + spin_lock_bh(&status_ring->lock); + + ath12k_hal_srng_access_begin(ab, status_ring); + + while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) != + tx_ring->tx_status_tail) { + desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring); + if (!desc) + break; + + memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], + desc, sizeof(*desc)); + tx_ring->tx_status_head = + ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head); + } + + if (ath12k_hal_srng_dst_peek(ab, status_ring) && + (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) == + tx_ring->tx_status_tail)) { + /* TODO: Process pending tx_status messages when kfifo_is_full() */ + ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); + } + + ath12k_hal_srng_access_end(ab, status_ring); + + spin_unlock_bh(&status_ring->lock); + + while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail) != + tx_ring->tx_status_head) { + struct hal_wbm_completion_ring_tx *tx_status; + u32 desc_id; + + tx_ring->tx_status_tail = + ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); + tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; + ath12k_dp_tx_status_parse(ab, tx_status, &ts); + + if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { + /* HW done cookie conversion */ + desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 | + le32_to_cpu(tx_status->buf_va_lo)); + tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va); + } else { + /* SW does cookie conversion to VA */ + desc_id = le32_get_bits(tx_status->buf_va_hi, + BUFFER_ADDR_INFO1_SW_COOKIE); + + tx_desc = ath12k_dp_get_tx_desc(ab, desc_id); + } + if (!tx_desc) { + ath12k_warn(ab, "unable to retrieve tx_desc!"); + continue; + } + + desc_params.mac_id = tx_desc->mac_id; + desc_params.skb = tx_desc->skb; + desc_params.skb_ext_desc = tx_desc->skb_ext_desc; + + /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */ + buf_rel_source = le32_get_bits(tx_status->info0, + HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); + ab->device_stats.tx_wbm_rel_source[buf_rel_source]++; + + rel_status = le32_get_bits(tx_status->info0, + HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); + ab->device_stats.tqm_rel_reason[rel_status]++; + + /* Release descriptor as soon as extracting necessary info + * to reduce contention + */ + ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id); + if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) { + ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, + tx_ring, &desc_params); + continue; + } + + pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); + ar = ab->pdevs[pdev_id].ar; + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); + + ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts, + tx_ring->tcl_data_ring_id); + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h new file mode 100644 index 0000000000000..4361beb996660 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_TX_WIFI7_H +#define ATH12K_DP_TX_WIFI7_H + +void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +#endif From 26d084daf5a44c2f846a74525ac64c479df2d041 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:49 +0530 Subject: [PATCH 395/659] wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory Move arch specific TX data path to wifi7 directory as part of Next Generation (NG) Driver Framework. Architecture specific APIs: ath12k_hal_tx_cmd_ext_desc_setup ath12k_dp_prepare_htt_metadata ath12k_dp_tx The moved APIs will be a part of dp_tx.c file inside wifi7 directory. wifi7/dp_tx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-17-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_tx.c | 363 ------------------ drivers/net/wireless/ath/ath12k/dp_tx.h | 3 - drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 363 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 3 + 4 files changed, 366 insertions(+), 366 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index f1649744c78b7..c7b0fc22c1a79 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -109,26 +109,6 @@ struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, return desc; } -static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, - struct hal_tx_msdu_ext_desc *tcl_ext_cmd, - struct hal_tx_info *ti) -{ - tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr, - HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO); - tcl_ext_cmd->info1 = le32_encode_bits(0x0, - HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) | - le32_encode_bits(ti->data_len, - HAL_TX_MSDU_EXT_INFO1_BUF_LEN); - - tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) | - le32_encode_bits(ti->encap_type, - HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) | - le32_encode_bits(ti->encrypt_type, - HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE); -} - -#define HTT_META_DATA_ALIGNMENT 0x8 - void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) { struct sk_buff *tail; @@ -142,29 +122,6 @@ void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) return metadata; } -/* Preparing HTT Metadata when utilized with ext MSDU */ -static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) -{ - struct hal_tx_msdu_metadata *desc_ext; - u8 htt_desc_size; - /* Size rounded of multiple of 8 bytes */ - u8 htt_desc_size_aligned; - - htt_desc_size = sizeof(struct hal_tx_msdu_metadata); - htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); - - desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned); - if (!desc_ext) - return -ENOMEM; - - desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) | - le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) | - le32_encode_bits(1, - HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL); - - return 0; -} - static void ath12k_dp_tx_move_payload(struct sk_buff *skb, unsigned long delta, bool head) @@ -219,326 +176,6 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab, return ret; } -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct hal_tx_info ti = {}; - struct ath12k_tx_desc_info *tx_desc; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); - struct hal_tcl_data_cmd *hal_tcl_desc; - struct hal_tx_msdu_ext_desc *msg; - struct sk_buff *skb_ext_desc = NULL; - struct hal_srng *tcl_ring; - struct ieee80211_hdr *hdr = (void *)skb->data; - struct ath12k_vif *ahvif = arvif->ahvif; - struct dp_tx_ring *tx_ring; - u8 pool_id; - u8 hal_ring_id; - int ret; - u8 ring_selector, ring_map = 0; - bool tcl_ring_retry; - bool msdu_ext_desc = false; - bool add_htt_metadata = false; - u32 iova_mask = ab->hw_params->iova_mask; - bool is_diff_encap = false; - bool is_null_frame = false; - - if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) - return -ESHUTDOWN; - - if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && - !ieee80211_is_data(hdr->frame_control)) - return -EOPNOTSUPP; - - pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1); - - /* Let the default ring selection be based on current processor - * number, where one of the 3 tcl rings are selected based on - * the smp_processor_id(). In case that ring - * is full/busy, we resort to other available rings. - * If all rings are full, we drop the packet. - * TODO: Add throttling logic when all rings are full - */ - ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb); - -tcl_ring_sel: - tcl_ring_retry = false; - ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; - - ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; - - tx_ring = &dp->tx_ring[ti.ring_id]; - - tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id); - if (!tx_desc) - return -ENOMEM; - - ti.bank_id = arvif->bank_id; - ti.meta_data_flags = arvif->tcl_metadata; - - if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && - test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { - if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { - ti.encrypt_type = - ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); - - if (ieee80211_has_protected(hdr->frame_control)) - skb_put(skb, IEEE80211_CCMP_MIC_LEN); - } else { - ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; - } - - msdu_ext_desc = true; - } - - if (gsn_valid) { - /* Reset and Initialize meta_data_flags with Global Sequence - * Number (GSN) info. - */ - ti.meta_data_flags = - u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM, - HTT_TCL_META_DATA_TYPE) | - u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM); - } - - ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); - ti.addr_search_flags = arvif->hal_addr_search_flags; - ti.search_type = arvif->search_type; - ti.type = HAL_TCL_DESC_TYPE_BUFFER; - ti.pkt_offset = 0; - ti.lmac_id = ar->lmac_id; - - ti.vdev_id = arvif->vdev_id; - if (gsn_valid) - ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID; - - ti.bss_ast_hash = arvif->ast_hash; - ti.bss_ast_idx = arvif->ast_idx; - ti.dscp_tid_tbl_idx = 0; - - if (skb->ip_summed == CHECKSUM_PARTIAL && - ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) { - ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN); - } - - ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE); - - ti.tid = ath12k_dp_tx_get_tid(skb); - - switch (ti.encap_type) { - case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: - is_null_frame = ieee80211_is_nullfunc(hdr->frame_control); - if (ahvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) { - if (skb->protocol == cpu_to_be16(ETH_P_PAE) || is_null_frame) - is_diff_encap = true; - - /* Firmware expects msdu ext descriptor for nwifi/raw packets - * received in ETH mode. Without this, observed tx fail for - * Multicast packets in ETH mode. - */ - msdu_ext_desc = true; - } else { - ath12k_dp_tx_encap_nwifi(skb); - } - break; - case HAL_TCL_ENCAP_TYPE_RAW: - if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) { - ret = -EINVAL; - goto fail_remove_tx_buf; - } - break; - case HAL_TCL_ENCAP_TYPE_ETHERNET: - /* no need to encap */ - break; - case HAL_TCL_ENCAP_TYPE_802_3: - default: - /* TODO: Take care of other encap modes as well */ - ret = -EINVAL; - atomic_inc(&ab->device_stats.tx_err.misc_fail); - goto fail_remove_tx_buf; - } - - if (iova_mask && - (unsigned long)skb->data & iova_mask) { - ret = ath12k_dp_tx_align_payload(ab, &skb); - if (ret) { - ath12k_warn(ab, "failed to align TX buffer %d\n", ret); - /* don't bail out, give original buffer - * a chance even unaligned. - */ - goto map; - } - - /* hdr is pointing to a wrong place after alignment, - * so refresh it for later use. - */ - hdr = (void *)skb->data; - } -map: - ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, ti.paddr)) { - atomic_inc(&ab->device_stats.tx_err.misc_fail); - ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); - ret = -ENOMEM; - goto fail_remove_tx_buf; - } - - if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && - !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && - !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && - ieee80211_has_protected(hdr->frame_control)) || - is_diff_encap) { - /* Firmware is not expecting meta data for qos null - * nwifi packet received in ETH encap mode. - */ - if (is_null_frame && msdu_ext_desc) - goto skip_htt_meta; - - /* Add metadata for sw encrypted vlan group traffic - * and EAPOL nwifi packet received in ETH encap mode. - */ - add_htt_metadata = true; - msdu_ext_desc = true; - ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; -skip_htt_meta: - ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW); - ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW; - ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; - } - - tx_desc->skb = skb; - tx_desc->mac_id = ar->pdev_idx; - ti.desc_id = tx_desc->desc_id; - ti.data_len = skb->len; - skb_cb->paddr = ti.paddr; - skb_cb->vif = ahvif->vif; - skb_cb->ar = ar; - - if (msdu_ext_desc) { - skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc)); - if (!skb_ext_desc) { - ret = -ENOMEM; - goto fail_unmap_dma; - } - - skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc)); - memset(skb_ext_desc->data, 0, skb_ext_desc->len); - - msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data; - ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); - - if (add_htt_metadata) { - ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc); - if (ret < 0) { - ath12k_dbg(ab, ATH12K_DBG_DP_TX, - "Failed to add HTT meta data, dropping packet\n"); - goto fail_free_ext_skb; - } - } - - ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data, - skb_ext_desc->len, DMA_TO_DEVICE); - ret = dma_mapping_error(ab->dev, ti.paddr); - if (ret) - goto fail_free_ext_skb; - - ti.data_len = skb_ext_desc->len; - ti.type = HAL_TCL_DESC_TYPE_EXT_DESC; - - skb_cb->paddr_ext_desc = ti.paddr; - tx_desc->skb_ext_desc = skb_ext_desc; - } - - hal_ring_id = tx_ring->tcl_data_ring.ring_id; - tcl_ring = &ab->hal.srng_list[hal_ring_id]; - - spin_lock_bh(&tcl_ring->lock); - - ath12k_hal_srng_access_begin(ab, tcl_ring); - - hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring); - if (!hal_tcl_desc) { - /* NOTE: It is highly unlikely we'll be running out of tcl_ring - * desc because the desc is directly enqueued onto hw queue. - */ - ath12k_hal_srng_access_end(ab, tcl_ring); - ab->device_stats.tx_err.desc_na[ti.ring_id]++; - spin_unlock_bh(&tcl_ring->lock); - ret = -ENOMEM; - - /* Checking for available tcl descriptors in another ring in - * case of failure due to full tcl ring now, is better than - * checking this ring earlier for each pkt tx. - * Restart ring selection if some rings are not checked yet. - */ - if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) && - ab->hw_params->tcl_ring_retry) { - tcl_ring_retry = true; - ring_selector++; - } - - goto fail_unmap_dma_ext; - } - - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_encap_type[ti.encap_type]++; - arvif->link_stats.tx_encrypt_type[ti.encrypt_type]++; - arvif->link_stats.tx_desc_type[ti.type]++; - - if (is_mcast) - arvif->link_stats.tx_bcast_mcast++; - else - arvif->link_stats.tx_enqueued++; - spin_unlock_bh(&arvif->link_stats_lock); - - ab->device_stats.tx_enqueued[ti.ring_id]++; - - ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); - - ath12k_hal_srng_access_end(ab, tcl_ring); - - spin_unlock_bh(&tcl_ring->lock); - - ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", - skb->data, skb->len); - - atomic_inc(&ar->dp.num_tx_pending); - - return 0; - -fail_unmap_dma_ext: - if (skb_cb->paddr_ext_desc) - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, - skb_ext_desc->len, - DMA_TO_DEVICE); -fail_free_ext_skb: - kfree_skb(skb_ext_desc); - -fail_unmap_dma: - dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); - -fail_remove_tx_buf: - ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); - - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_dropped++; - spin_unlock_bh(&arvif->link_stats_lock); - - if (tcl_ring_retry) - goto tcl_ring_sel; - - return ret; -} - void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 67ab7b3f55eaf..8405a0baf95b6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -16,9 +16,6 @@ struct ath12k_dp_htt_wbm_tx_status { }; int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast); int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); int ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 149e211aa225e..49d219a195c5e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -10,6 +10,369 @@ #include "../peer.h" #include "dp_tx.h" +static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, + struct hal_tx_msdu_ext_desc *tcl_ext_cmd, + struct hal_tx_info *ti) +{ + tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr, + HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO); + tcl_ext_cmd->info1 = le32_encode_bits(0x0, + HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) | + le32_encode_bits(ti->data_len, + HAL_TX_MSDU_EXT_INFO1_BUF_LEN); + + tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) | + le32_encode_bits(ti->encap_type, + HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) | + le32_encode_bits(ti->encrypt_type, + HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE); +} + +#define HTT_META_DATA_ALIGNMENT 0x8 + +/* Preparing HTT Metadata when utilized with ext MSDU */ +static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) +{ + struct hal_tx_msdu_metadata *desc_ext; + u8 htt_desc_size; + /* Size rounded of multiple of 8 bytes */ + u8 htt_desc_size_aligned; + + htt_desc_size = sizeof(struct hal_tx_msdu_metadata); + htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); + + desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned); + if (!desc_ext) + return -ENOMEM; + + desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) | + le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) | + le32_encode_bits(1, + HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL); + + return 0; +} + +int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct hal_tx_info ti = {}; + struct ath12k_tx_desc_info *tx_desc; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); + struct hal_tcl_data_cmd *hal_tcl_desc; + struct hal_tx_msdu_ext_desc *msg; + struct sk_buff *skb_ext_desc = NULL; + struct hal_srng *tcl_ring; + struct ieee80211_hdr *hdr = (void *)skb->data; + struct ath12k_vif *ahvif = arvif->ahvif; + struct dp_tx_ring *tx_ring; + u8 pool_id; + u8 hal_ring_id; + int ret; + u8 ring_selector, ring_map = 0; + bool tcl_ring_retry; + bool msdu_ext_desc = false; + bool add_htt_metadata = false; + u32 iova_mask = ab->hw_params->iova_mask; + bool is_diff_encap = false; + bool is_null_frame = false; + + if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) + return -ESHUTDOWN; + + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data(hdr->frame_control)) + return -EOPNOTSUPP; + + pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1); + + /* Let the default ring selection be based on current processor + * number, where one of the 3 tcl rings are selected based on + * the smp_processor_id(). In case that ring + * is full/busy, we resort to other available rings. + * If all rings are full, we drop the packet. + * TODO: Add throttling logic when all rings are full + */ + ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb); + +tcl_ring_sel: + tcl_ring_retry = false; + ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; + + ring_map |= BIT(ti.ring_id); + ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + + tx_ring = &dp->tx_ring[ti.ring_id]; + + tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id); + if (!tx_desc) + return -ENOMEM; + + ti.bank_id = arvif->bank_id; + ti.meta_data_flags = arvif->tcl_metadata; + + if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { + if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { + ti.encrypt_type = + ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); + + if (ieee80211_has_protected(hdr->frame_control)) + skb_put(skb, IEEE80211_CCMP_MIC_LEN); + } else { + ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; + } + + msdu_ext_desc = true; + } + + if (gsn_valid) { + /* Reset and Initialize meta_data_flags with Global Sequence + * Number (GSN) info. + */ + ti.meta_data_flags = + u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM, + HTT_TCL_META_DATA_TYPE) | + u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM); + } + + ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); + ti.addr_search_flags = arvif->hal_addr_search_flags; + ti.search_type = arvif->search_type; + ti.type = HAL_TCL_DESC_TYPE_BUFFER; + ti.pkt_offset = 0; + ti.lmac_id = ar->lmac_id; + + ti.vdev_id = arvif->vdev_id; + if (gsn_valid) + ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID; + + ti.bss_ast_hash = arvif->ast_hash; + ti.bss_ast_idx = arvif->ast_idx; + ti.dscp_tid_tbl_idx = 0; + + if (skb->ip_summed == CHECKSUM_PARTIAL && + ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) { + ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN); + } + + ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE); + + ti.tid = ath12k_dp_tx_get_tid(skb); + + switch (ti.encap_type) { + case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: + is_null_frame = ieee80211_is_nullfunc(hdr->frame_control); + if (ahvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) { + if (skb->protocol == cpu_to_be16(ETH_P_PAE) || is_null_frame) + is_diff_encap = true; + + /* Firmware expects msdu ext descriptor for nwifi/raw packets + * received in ETH mode. Without this, observed tx fail for + * Multicast packets in ETH mode. + */ + msdu_ext_desc = true; + } else { + ath12k_dp_tx_encap_nwifi(skb); + } + break; + case HAL_TCL_ENCAP_TYPE_RAW: + if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) { + ret = -EINVAL; + goto fail_remove_tx_buf; + } + break; + case HAL_TCL_ENCAP_TYPE_ETHERNET: + /* no need to encap */ + break; + case HAL_TCL_ENCAP_TYPE_802_3: + default: + /* TODO: Take care of other encap modes as well */ + ret = -EINVAL; + atomic_inc(&ab->device_stats.tx_err.misc_fail); + goto fail_remove_tx_buf; + } + + if (iova_mask && + (unsigned long)skb->data & iova_mask) { + ret = ath12k_dp_tx_align_payload(ab, &skb); + if (ret) { + ath12k_warn(ab, "failed to align TX buffer %d\n", ret); + /* don't bail out, give original buffer + * a chance even unaligned. + */ + goto map; + } + + /* hdr is pointing to a wrong place after alignment, + * so refresh it for later use. + */ + hdr = (void *)skb->data; + } +map: + ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(ab->dev, ti.paddr)) { + atomic_inc(&ab->device_stats.tx_err.misc_fail); + ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); + ret = -ENOMEM; + goto fail_remove_tx_buf; + } + + if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && + !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && + ieee80211_has_protected(hdr->frame_control)) || + is_diff_encap) { + /* Firmware is not expecting meta data for qos null + * nwifi packet received in ETH encap mode. + */ + if (is_null_frame && msdu_ext_desc) + goto skip_htt_meta; + + /* Add metadata for sw encrypted vlan group traffic + * and EAPOL nwifi packet received in ETH encap mode. + */ + add_htt_metadata = true; + msdu_ext_desc = true; + ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; +skip_htt_meta: + ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW); + ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW; + ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; + } + + tx_desc->skb = skb; + tx_desc->mac_id = ar->pdev_idx; + ti.desc_id = tx_desc->desc_id; + ti.data_len = skb->len; + skb_cb->paddr = ti.paddr; + skb_cb->vif = ahvif->vif; + skb_cb->ar = ar; + + if (msdu_ext_desc) { + skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc)); + if (!skb_ext_desc) { + ret = -ENOMEM; + goto fail_unmap_dma; + } + + skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc)); + memset(skb_ext_desc->data, 0, skb_ext_desc->len); + + msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data; + ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); + + if (add_htt_metadata) { + ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc); + if (ret < 0) { + ath12k_dbg(ab, ATH12K_DBG_DP_TX, + "Failed to add HTT meta data, dropping packet\n"); + goto fail_free_ext_skb; + } + } + + ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data, + skb_ext_desc->len, DMA_TO_DEVICE); + ret = dma_mapping_error(ab->dev, ti.paddr); + if (ret) + goto fail_free_ext_skb; + + ti.data_len = skb_ext_desc->len; + ti.type = HAL_TCL_DESC_TYPE_EXT_DESC; + + skb_cb->paddr_ext_desc = ti.paddr; + tx_desc->skb_ext_desc = skb_ext_desc; + } + + hal_ring_id = tx_ring->tcl_data_ring.ring_id; + tcl_ring = &ab->hal.srng_list[hal_ring_id]; + + spin_lock_bh(&tcl_ring->lock); + + ath12k_hal_srng_access_begin(ab, tcl_ring); + + hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring); + if (!hal_tcl_desc) { + /* NOTE: It is highly unlikely we'll be running out of tcl_ring + * desc because the desc is directly enqueued onto hw queue. + */ + ath12k_hal_srng_access_end(ab, tcl_ring); + ab->device_stats.tx_err.desc_na[ti.ring_id]++; + spin_unlock_bh(&tcl_ring->lock); + ret = -ENOMEM; + + /* Checking for available tcl descriptors in another ring in + * case of failure due to full tcl ring now, is better than + * checking this ring earlier for each pkt tx. + * Restart ring selection if some rings are not checked yet. + */ + if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) && + ab->hw_params->tcl_ring_retry) { + tcl_ring_retry = true; + ring_selector++; + } + + goto fail_unmap_dma_ext; + } + + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_encap_type[ti.encap_type]++; + arvif->link_stats.tx_encrypt_type[ti.encrypt_type]++; + arvif->link_stats.tx_desc_type[ti.type]++; + + if (is_mcast) + arvif->link_stats.tx_bcast_mcast++; + else + arvif->link_stats.tx_enqueued++; + spin_unlock_bh(&arvif->link_stats_lock); + + ab->device_stats.tx_enqueued[ti.ring_id]++; + + ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); + + ath12k_hal_srng_access_end(ab, tcl_ring); + + spin_unlock_bh(&tcl_ring->lock); + + ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", + skb->data, skb->len); + + atomic_inc(&ar->dp.num_tx_pending); + + return 0; + +fail_unmap_dma_ext: + if (skb_cb->paddr_ext_desc) + dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + skb_ext_desc->len, + DMA_TO_DEVICE); +fail_free_ext_skb: + kfree_skb(skb_ext_desc); + +fail_unmap_dma: + dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); + +fail_remove_tx_buf: + ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); + + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_dropped++; + spin_unlock_bh(&arvif->link_stats_lock); + + if (tcl_ring_retry) + goto tcl_ring_sel; + + return ret; +} + static void ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, struct ath12k_tx_desc_params *desc_params, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 4361beb996660..42faf664f8f8b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -7,5 +7,8 @@ #ifndef ATH12K_DP_TX_WIFI7_H #define ATH12K_DP_TX_WIFI7_H +int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast); void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); #endif From 59f94c8321350fc7f5fa256ffc9e24b242b4c010 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:50 +0530 Subject: [PATCH 396/659] wifi: ath12k: Move HTT code in dp.h to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. HTT interface code is spread across multiple files (ex dp_tx.c, dp_rx.c, dp.h etc) and this interface is independent of the underlying architecture Tx and Rx. Relocate HTT specific code from dp.h to newly introduced file dp_htt.h for HTT interface. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-18-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- .../wireless/ath/ath12k/debugfs_htt_stats.h | 4 +- drivers/net/wireless/ath/ath12k/dp.h | 1506 +--------------- drivers/net/wireless/ath/ath12k/dp_htt.h | 1517 +++++++++++++++++ 3 files changed, 1521 insertions(+), 1506 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.h diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h index 9bd3a632b002d..8008658371aae 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h @@ -1,12 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef DEBUG_HTT_STATS_H #define DEBUG_HTT_STATS_H +#include "dp_htt.h" + #define ATH12K_HTT_STATS_BUF_SIZE (1024 * 512) #define ATH12K_HTT_STATS_COOKIE_LSB GENMASK_ULL(31, 0) #define ATH12K_HTT_STATS_COOKIE_MSB GENMASK_ULL(63, 32) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index cfffc51f87bf4..9c860cc8d7d98 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -10,6 +10,7 @@ #include "wifi7/hal_desc.h" #include "wifi7/hal_rx.h" #include "hw.h" +#include "dp_htt.h" #define MAX_RXDMA_PER_PDEV 2 @@ -429,1511 +430,6 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; }; -/* HTT definitions */ -#define HTT_TAG_TCL_METADATA_VERSION 5 - -#define HTT_TCL_META_DATA_TYPE GENMASK(1, 0) -#define HTT_TCL_META_DATA_VALID_HTT BIT(2) - -/* vdev meta data */ -#define HTT_TCL_META_DATA_VDEV_ID GENMASK(10, 3) -#define HTT_TCL_META_DATA_PDEV_ID GENMASK(12, 11) -#define HTT_TCL_META_DATA_HOST_INSPECTED_MISSION BIT(13) - -/* peer meta data */ -#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 3) - -/* Global sequence number */ -#define HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM 3 -#define HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED BIT(2) -#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3) -#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128 - -/* HTT tx completion is overlaid in wbm_release_ring */ -#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13) -#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0) -#define HTT_TX_WBM_COMP_INFO1_EXCEPTION_FRAME BIT(4) - -#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24) - -struct htt_tx_wbm_completion { - __le32 rsvd0[2]; - __le32 info0; - __le32 info1; - __le32 info2; - __le32 info3; - __le32 info4; - __le32 rsvd1; - -} __packed; - -enum htt_h2t_msg_type { - HTT_H2T_MSG_TYPE_VERSION_REQ = 0, - HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb, - HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc, - HTT_H2T_MSG_TYPE_EXT_STATS_CFG = 0x10, - HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11, - HTT_H2T_MSG_TYPE_VDEV_TXRX_STATS_CFG = 0x1a, - HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b, -}; - -#define HTT_VER_REQ_INFO_MSG_ID GENMASK(7, 0) -#define HTT_OPTION_TCL_METADATA_VER_V1 1 -#define HTT_OPTION_TCL_METADATA_VER_V2 2 -#define HTT_OPTION_TAG GENMASK(7, 0) -#define HTT_OPTION_LEN GENMASK(15, 8) -#define HTT_OPTION_VALUE GENMASK(31, 16) -#define HTT_TCL_METADATA_VER_SZ 4 - -struct htt_ver_req_cmd { - __le32 ver_reg_info; - __le32 tcl_metadata_version; -} __packed; - -enum htt_srng_ring_type { - HTT_HW_TO_SW_RING, - HTT_SW_TO_HW_RING, - HTT_SW_TO_SW_RING, -}; - -enum htt_srng_ring_id { - HTT_RXDMA_HOST_BUF_RING, - HTT_RXDMA_MONITOR_STATUS_RING, - HTT_RXDMA_MONITOR_BUF_RING, - HTT_RXDMA_MONITOR_DESC_RING, - HTT_RXDMA_MONITOR_DEST_RING, - HTT_HOST1_TO_FW_RXBUF_RING, - HTT_HOST2_TO_FW_RXBUF_RING, - HTT_RXDMA_NON_MONITOR_DEST_RING, - HTT_RXDMA_HOST_BUF_RING2, - HTT_TX_MON_HOST2MON_BUF_RING, - HTT_TX_MON_MON2HOST_DEST_RING, - HTT_RX_MON_HOST2MON_BUF_RING, - HTT_RX_MON_MON2HOST_DEST_RING, -}; - -/* host -> target HTT_SRING_SETUP message - * - * After target is booted up, Host can send SRING setup message for - * each host facing LMAC SRING. Target setups up HW registers based - * on setup message and confirms back to Host if response_required is set. - * Host should wait for confirmation message before sending new SRING - * setup message - * - * The message would appear as follows: - * - * |31 24|23 20|19|18 16|15|14 8|7 0| - * |--------------- +-----------------+----------------+------------------| - * | ring_type | ring_id | pdev_id | msg_type | - * |----------------------------------------------------------------------| - * | ring_base_addr_lo | - * |----------------------------------------------------------------------| - * | ring_base_addr_hi | - * |----------------------------------------------------------------------| - * |ring_misc_cfg_flag|ring_entry_size| ring_size | - * |----------------------------------------------------------------------| - * | ring_head_offset32_remote_addr_lo | - * |----------------------------------------------------------------------| - * | ring_head_offset32_remote_addr_hi | - * |----------------------------------------------------------------------| - * | ring_tail_offset32_remote_addr_lo | - * |----------------------------------------------------------------------| - * | ring_tail_offset32_remote_addr_hi | - * |----------------------------------------------------------------------| - * | ring_msi_addr_lo | - * |----------------------------------------------------------------------| - * | ring_msi_addr_hi | - * |----------------------------------------------------------------------| - * | ring_msi_data | - * |----------------------------------------------------------------------| - * | intr_timer_th |IM| intr_batch_counter_th | - * |----------------------------------------------------------------------| - * | reserved |RR|PTCF| intr_low_threshold | - * |----------------------------------------------------------------------| - * Where - * IM = sw_intr_mode - * RR = response_required - * PTCF = prefetch_timer_cfg - * - * The message is interpreted as follows: - * dword0 - b'0:7 - msg_type: This will be set to - * HTT_H2T_MSG_TYPE_SRING_SETUP - * b'8:15 - pdev_id: - * 0 (for rings at SOC/UMAC level), - * 1/2/3 mac id (for rings at LMAC level) - * b'16:23 - ring_id: identify which ring is to setup, - * more details can be got from enum htt_srng_ring_id - * b'24:31 - ring_type: identify type of host rings, - * more details can be got from enum htt_srng_ring_type - * dword1 - b'0:31 - ring_base_addr_lo: Lower 32bits of ring base address - * dword2 - b'0:31 - ring_base_addr_hi: Upper 32bits of ring base address - * dword3 - b'0:15 - ring_size: size of the ring in unit of 4-bytes words - * b'16:23 - ring_entry_size: Size of each entry in 4-byte word units - * b'24:31 - ring_misc_cfg_flag: Valid only for HW_TO_SW_RING and - * SW_TO_HW_RING. - * Refer to HTT_SRING_SETUP_RING_MISC_CFG_RING defs. - * dword4 - b'0:31 - ring_head_off32_remote_addr_lo: - * Lower 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the head - * element within the ring. - * (The head offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword5 - b'0:31 - ring_head_off32_remote_addr_hi: - * Upper 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the head - * element within the ring. - * (The head offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword6 - b'0:31 - ring_tail_off32_remote_addr_lo: - * Lower 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the tail - * element within the ring. - * (The tail offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword7 - b'0:31 - ring_tail_off32_remote_addr_hi: - * Upper 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the tail - * element within the ring. - * (The tail offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword8 - b'0:31 - ring_msi_addr_lo: Lower 32bits of MSI cfg address - * valid only for HW_TO_SW_RING and SW_TO_HW_RING - * dword9 - b'0:31 - ring_msi_addr_hi: Upper 32bits of MSI cfg address - * valid only for HW_TO_SW_RING and SW_TO_HW_RING - * dword10 - b'0:31 - ring_msi_data: MSI data - * Refer to HTT_SRING_SETUP_RING_MSC_CFG_xxx defs - * valid only for HW_TO_SW_RING and SW_TO_HW_RING - * dword11 - b'0:14 - intr_batch_counter_th: - * batch counter threshold is in units of 4-byte words. - * HW internally maintains and increments batch count. - * (see SRING spec for detail description). - * When batch count reaches threshold value, an interrupt - * is generated by HW. - * b'15 - sw_intr_mode: - * This configuration shall be static. - * Only programmed at power up. - * 0: generate pulse style sw interrupts - * 1: generate level style sw interrupts - * b'16:31 - intr_timer_th: - * The timer init value when timer is idle or is - * initialized to start downcounting. - * In 8us units (to cover a range of 0 to 524 ms) - * dword12 - b'0:15 - intr_low_threshold: - * Used only by Consumer ring to generate ring_sw_int_p. - * Ring entries low threshold water mark, that is used - * in combination with the interrupt timer as well as - * the clearing of the level interrupt. - * b'16:18 - prefetch_timer_cfg: - * Used only by Consumer ring to set timer mode to - * support Application prefetch handling. - * The external tail offset/pointer will be updated - * at following intervals: - * 3'b000: (Prefetch feature disabled; used only for debug) - * 3'b001: 1 usec - * 3'b010: 4 usec - * 3'b011: 8 usec (default) - * 3'b100: 16 usec - * Others: Reserved - * b'19 - response_required: - * Host needs HTT_T2H_MSG_TYPE_SRING_SETUP_DONE as response - * b'20:31 - reserved: reserved for future use - */ - -#define HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID GENMASK(15, 8) -#define HTT_SRNG_SETUP_CMD_INFO0_RING_ID GENMASK(23, 16) -#define HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE GENMASK(31, 24) - -#define HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE GENMASK(15, 0) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE GENMASK(23, 16) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS BIT(25) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP BIT(27) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP BIT(28) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP BIT(29) - -#define HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH GENMASK(14, 0) -#define HTT_SRNG_SETUP_CMD_INTR_INFO_SW_INTR_MODE BIT(15) -#define HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH GENMASK(31, 16) - -#define HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH GENMASK(15, 0) -#define HTT_SRNG_SETUP_CMD_INFO2_PRE_FETCH_TIMER_CFG GENMASK(18, 16) -#define HTT_SRNG_SETUP_CMD_INFO2_RESPONSE_REQUIRED BIT(19) - -struct htt_srng_setup_cmd { - __le32 info0; - __le32 ring_base_addr_lo; - __le32 ring_base_addr_hi; - __le32 info1; - __le32 ring_head_off32_remote_addr_lo; - __le32 ring_head_off32_remote_addr_hi; - __le32 ring_tail_off32_remote_addr_lo; - __le32 ring_tail_off32_remote_addr_hi; - __le32 ring_msi_addr_lo; - __le32 ring_msi_addr_hi; - __le32 msi_data; - __le32 intr_info; - __le32 info2; -} __packed; - -/* host -> target FW PPDU_STATS config message - * - * @details - * The following field definitions describe the format of the HTT host - * to target FW for PPDU_STATS_CFG msg. - * The message allows the host to configure the PPDU_STATS_IND messages - * produced by the target. - * - * |31 24|23 16|15 8|7 0| - * |-----------------------------------------------------------| - * | REQ bit mask | pdev_mask | msg type | - * |-----------------------------------------------------------| - * Header fields: - * - MSG_TYPE - * Bits 7:0 - * Purpose: identifies this is a req to configure ppdu_stats_ind from target - * Value: 0x11 - * - PDEV_MASK - * Bits 8:15 - * Purpose: identifies which pdevs this PPDU stats configuration applies to - * Value: This is a overloaded field, refer to usage and interpretation of - * PDEV in interface document. - * Bit 8 : Reserved for SOC stats - * Bit 9 - 15 : Indicates PDEV_MASK in DBDC - * Indicates MACID_MASK in DBS - * - REQ_TLV_BIT_MASK - * Bits 16:31 - * Purpose: each set bit indicates the corresponding PPDU stats TLV type - * needs to be included in the target's PPDU_STATS_IND messages. - * Value: refer htt_ppdu_stats_tlv_tag_t << 30 bits - * Refer to PKT_TYPE_ENABLE_FLAG0_xxx_MGMT_xxx defs - * dword3 - b'0:31 - packet_type_enable_flags_1: - * Enable MGMT packet from 0b1010 to 0b1111 - * bits from low to high: FP, MD, MO - 3 bits - * Refer to PKT_TYPE_ENABLE_FLAG1_xxx_MGMT_xxx defs - * dword4 - b'0:31 - packet_type_enable_flags_2: - * Enable CTRL packet from 0b0000 to 0b1001 - * bits from low to high: FP, MD, MO - 3 bits - * Refer to PKT_TYPE_ENABLE_FLAG2_xxx_CTRL_xxx defs - * dword5 - b'0:31 - packet_type_enable_flags_3: - * Enable CTRL packet from 0b1010 to 0b1111, - * MCAST_DATA, UCAST_DATA, NULL_DATA - * bits from low to high: FP, MD, MO - 3 bits - * Refer to PKT_TYPE_ENABLE_FLAG3_xxx_CTRL_xxx defs - * dword6 - b'0:31 - tlv_filter_in_flags: - * Filter in Attention/MPDU/PPDU/Header/User tlvs - * Refer to CFG_TLV_FILTER_IN_FLAG defs - */ - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID BIT(26) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL BIT(27) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON BIT(28) - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(18, 16) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(21, 19) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(24, 22) - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD GENMASK(9, 0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE BIT(17) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE BIT(18) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE BIT(19) - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET BIT(0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET GENMASK(14, 1) - -#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) - -#define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0) - -enum htt_rx_filter_tlv_flags { - HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), - HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1), - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET = BIT(2), - HTT_RX_FILTER_TLV_FLAGS_MSDU_END = BIT(3), - HTT_RX_FILTER_TLV_FLAGS_MPDU_END = BIT(4), - HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER = BIT(5), - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER = BIT(6), - HTT_RX_FILTER_TLV_FLAGS_ATTENTION = BIT(7), - HTT_RX_FILTER_TLV_FLAGS_PPDU_START = BIT(8), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END = BIT(9), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS = BIT(10), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT = BIT(11), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE = BIT(12), - HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO = BIT(13), -}; - -enum htt_rx_mgmt_pkt_filter_tlv_flags0 { - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(0), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(1), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(2), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(3), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(4), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(5), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(6), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(7), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(8), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(9), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(10), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(11), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(12), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(13), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(14), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(15), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(16), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(17), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(18), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(19), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(20), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(21), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(22), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(23), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(24), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(25), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(26), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(27), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(28), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(29), -}; - -enum htt_rx_mgmt_pkt_filter_tlv_flags1 { - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(0), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(1), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(2), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(3), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(4), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(5), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(6), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(7), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(8), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(9), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(10), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(11), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(12), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(13), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(14), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(15), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(16), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(17), -}; - -enum htt_rx_ctrl_pkt_filter_tlv_flags2 { - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(0), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(1), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(2), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(3), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(4), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(5), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(6), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(7), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(8), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(9), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(10), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(11), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(12), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(13), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(14), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(15), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(16), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(17), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(18), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(19), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(20), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(21), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(22), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(23), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(24), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(25), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(26), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(27), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(28), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(29), -}; - -enum htt_rx_ctrl_pkt_filter_tlv_flags3 { - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(0), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(1), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(2), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(3), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(4), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(5), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(6), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(7), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(8), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(9), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(10), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(11), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(12), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(13), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(14), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(15), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(16), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(17), -}; - -enum htt_rx_data_pkt_filter_tlv_flasg3 { - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(18), - HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(19), - HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(20), - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(21), - HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(22), - HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(23), - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(24), - HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(25), - HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(26), -}; - -#define HTT_RX_FP_MGMT_FILTER_FLAGS0 \ - (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) - -#define HTT_RX_MD_MGMT_FILTER_FLAGS0 \ - (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) - -#define HTT_RX_MO_MGMT_FILTER_FLAGS0 \ - (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) - -#define HTT_RX_FP_MGMT_FILTER_FLAGS1 (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) - -#define HTT_RX_MD_MGMT_FILTER_FLAGS1 (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) - -#define HTT_RX_MO_MGMT_FILTER_FLAGS1 (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) - -#define HTT_RX_FP_CTRL_FILTER_FLASG2 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA) - -#define HTT_RX_MD_CTRL_FILTER_FLASG2 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA) - -#define HTT_RX_MO_CTRL_FILTER_FLASG2 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA) - -#define HTT_RX_FP_CTRL_FILTER_FLASG3 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) - -#define HTT_RX_MD_CTRL_FILTER_FLASG3 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) - -#define HTT_RX_MO_CTRL_FILTER_FLASG3 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) - -#define HTT_RX_FP_DATA_FILTER_FLASG3 (HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ - | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ - | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) - -#define HTT_RX_MD_DATA_FILTER_FLASG3 (HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ - | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ - | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) - -#define HTT_RX_MO_DATA_FILTER_FLASG3 (HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ - | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ - | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) - -#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 \ - (HTT_RX_FP_MGMT_FILTER_FLAGS0 | \ - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) - -#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS0 \ - (HTT_RX_MO_MGMT_FILTER_FLAGS0 | \ - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) - -#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 \ - (HTT_RX_FP_MGMT_FILTER_FLAGS1 | \ - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) - -#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS1 \ - (HTT_RX_MO_MGMT_FILTER_FLAGS1 | \ - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) - -#define HTT_RX_MON_FP_CTRL_FILTER_FLASG2 \ - (HTT_RX_FP_CTRL_FILTER_FLASG2 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) - -#define HTT_RX_MON_MO_CTRL_FILTER_FLASG2 \ - (HTT_RX_MO_CTRL_FILTER_FLASG2 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) - -#define HTT_RX_MON_FP_CTRL_FILTER_FLASG3 HTT_RX_FP_CTRL_FILTER_FLASG3 - -#define HTT_RX_MON_MO_CTRL_FILTER_FLASG3 HTT_RX_MO_CTRL_FILTER_FLASG3 - -#define HTT_RX_MON_FP_DATA_FILTER_FLASG3 HTT_RX_FP_DATA_FILTER_FLASG3 - -#define HTT_RX_MON_MO_DATA_FILTER_FLASG3 HTT_RX_MO_DATA_FILTER_FLASG3 - -#define HTT_RX_MON_FILTER_TLV_FLAGS \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) - -#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) - -#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_ATTENTION) - -#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO) - -/* msdu start. mpdu end, attention, rx hdr tlv's are not subscribed */ -#define HTT_RX_TLV_FLAGS_RXDMA_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_END) - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) - -struct htt_rx_ring_selection_cfg_cmd { - __le32 info0; - __le32 info1; - __le32 pkt_type_en_flags0; - __le32 pkt_type_en_flags1; - __le32 pkt_type_en_flags2; - __le32 pkt_type_en_flags3; - __le32 rx_filter_tlv; - __le32 rx_packet_offset; - __le32 rx_mpdu_offset; - __le32 rx_msdu_offset; - __le32 rx_attn_offset; - __le32 info2; - __le32 reserved[2]; - __le32 rx_mpdu_start_end_mask; - __le32 rx_msdu_end_word_mask; - __le32 info3; -} __packed; - -#define HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE 32 -#define HTT_RX_RING_DEFAULT_DMA_LENGTH 0x7 -#define HTT_RX_RING_PKT_TLV_OFFSET 0x1 - -struct htt_rx_ring_tlv_filter { - u32 rx_filter; /* see htt_rx_filter_tlv_flags */ - u32 pkt_filter_flags0; /* MGMT */ - u32 pkt_filter_flags1; /* MGMT */ - u32 pkt_filter_flags2; /* CTRL */ - u32 pkt_filter_flags3; /* DATA */ - bool offset_valid; - u16 rx_packet_offset; - u16 rx_header_offset; - u16 rx_mpdu_end_offset; - u16 rx_mpdu_start_offset; - u16 rx_msdu_end_offset; - u16 rx_msdu_start_offset; - u16 rx_attn_offset; - u16 rx_mpdu_start_wmask; - u16 rx_mpdu_end_wmask; - u32 rx_msdu_end_wmask; - u32 conf_len_ctrl; - u32 conf_len_mgmt; - u32 conf_len_data; - u16 rx_drop_threshold; - bool enable_log_mgmt_type; - bool enable_log_ctrl_type; - bool enable_log_data_type; - bool enable_rx_tlv_offset; - u16 rx_tlv_offset; - bool drop_threshold_valid; - bool rxmon_disable; -}; - -#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 -#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1 -#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2 -#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3 - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE GENMASK(15, 0) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE GENMASK(18, 16) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(21, 19) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(24, 22) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(27, 25) - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG GENMASK(2, 0) - -struct htt_tx_ring_selection_cfg_cmd { - __le32 info0; - __le32 info1; - __le32 info2; - __le32 tlv_filter_mask_in0; - __le32 tlv_filter_mask_in1; - __le32 tlv_filter_mask_in2; - __le32 tlv_filter_mask_in3; - __le32 reserved[3]; -} __packed; - -#define HTT_TX_RING_TLV_FILTER_MGMT_DMA_LEN GENMASK(3, 0) -#define HTT_TX_RING_TLV_FILTER_CTRL_DMA_LEN GENMASK(7, 4) -#define HTT_TX_RING_TLV_FILTER_DATA_DMA_LEN GENMASK(11, 8) - -#define HTT_TX_MON_FILTER_HYBRID_MODE \ - (HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS | \ - HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE | \ - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO | \ - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2) - -struct htt_tx_ring_tlv_filter { - u32 tx_mon_downstream_tlv_flags; - u32 tx_mon_upstream_tlv_flags0; - u32 tx_mon_upstream_tlv_flags1; - u32 tx_mon_upstream_tlv_flags2; - bool tx_mon_mgmt_filter; - bool tx_mon_data_filter; - bool tx_mon_ctrl_filter; - u16 tx_mon_pkt_dma_len; -} __packed; - -enum htt_tx_mon_upstream_tlv_flags0 { - HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS = BIT(1), - HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS = BIT(2), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START = BIT(3), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END = BIT(4), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU = BIT(5), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU = BIT(6), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA = BIT(7), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA = BIT(8), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT = BIT(9), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT = BIT(10), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE = BIT(11), - HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_BITMAP_ACK = BIT(12), - HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_1K_BITMAP_ACK = BIT(13), - HTT_TX_FILTER_TLV_FLAGS0_COEX_TX_STATUS = BIT(14), - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO = BIT(15), - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2 = BIT(16), -}; - -#define HTT_TX_FILTER_TLV_FLAGS2_TXPCU_PHYTX_OTHER_TRANSMIT_INFO32 BIT(11) - -/* HTT message target->host */ - -enum htt_t2h_msg_type { - HTT_T2H_MSG_TYPE_VERSION_CONF, - HTT_T2H_MSG_TYPE_PEER_MAP = 0x3, - HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4, - HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5, - HTT_T2H_MSG_TYPE_PKTLOG = 0x8, - HTT_T2H_MSG_TYPE_SEC_IND = 0xb, - HTT_T2H_MSG_TYPE_PEER_MAP2 = 0x1e, - HTT_T2H_MSG_TYPE_PEER_UNMAP2 = 0x1f, - HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d, - HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c, - HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24, - HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND = 0x28, - HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b, - HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c, -}; - -#define HTT_TARGET_VERSION_MAJOR 3 - -#define HTT_T2H_MSG_TYPE GENMASK(7, 0) -#define HTT_T2H_VERSION_CONF_MINOR GENMASK(15, 8) -#define HTT_T2H_VERSION_CONF_MAJOR GENMASK(23, 16) - -struct htt_t2h_version_conf_msg { - __le32 version; -} __packed; - -#define HTT_T2H_PEER_MAP_INFO_VDEV_ID GENMASK(15, 8) -#define HTT_T2H_PEER_MAP_INFO_PEER_ID GENMASK(31, 16) -#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0) -#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16) -#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0) -#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0) -#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16) -#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16) -#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16 - -struct htt_t2h_peer_map_event { - __le32 info; - __le32 mac_addr_l32; - __le32 info1; - __le32 info2; -} __packed; - -#define HTT_T2H_PEER_UNMAP_INFO_VDEV_ID HTT_T2H_PEER_MAP_INFO_VDEV_ID -#define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID -#define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \ - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 -#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M -#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S - -struct htt_t2h_peer_unmap_event { - __le32 info; - __le32 mac_addr_l32; - __le32 info1; -} __packed; - -struct htt_resp_msg { - union { - struct htt_t2h_version_conf_msg version_msg; - struct htt_t2h_peer_map_event peer_map_ev; - struct htt_t2h_peer_unmap_event peer_unmap_ev; - }; -} __packed; - -#define HTT_VDEV_GET_STATS_U64(msg_l32, msg_u32)\ - (((u64)__le32_to_cpu(msg_u32) << 32) | (__le32_to_cpu(msg_l32))) -#define HTT_T2H_VDEV_STATS_PERIODIC_MSG_TYPE GENMASK(7, 0) -#define HTT_T2H_VDEV_STATS_PERIODIC_PDEV_ID GENMASK(15, 8) -#define HTT_T2H_VDEV_STATS_PERIODIC_NUM_VDEV GENMASK(23, 16) -#define HTT_T2H_VDEV_STATS_PERIODIC_PAYLOAD_BYTES GENMASK(15, 0) -#define HTT_VDEV_TXRX_STATS_COMMON_TLV 0 -#define HTT_VDEV_TXRX_STATS_HW_STATS_TLV 1 - -struct htt_t2h_vdev_txrx_stats_ind { - __le32 vdev_id; - __le32 rx_msdu_byte_cnt_lo; - __le32 rx_msdu_byte_cnt_hi; - __le32 rx_msdu_cnt_lo; - __le32 rx_msdu_cnt_hi; - __le32 tx_msdu_byte_cnt_lo; - __le32 tx_msdu_byte_cnt_hi; - __le32 tx_msdu_cnt_lo; - __le32 tx_msdu_cnt_hi; - __le32 tx_retry_cnt_lo; - __le32 tx_retry_cnt_hi; - __le32 tx_retry_byte_cnt_lo; - __le32 tx_retry_byte_cnt_hi; - __le32 tx_drop_cnt_lo; - __le32 tx_drop_cnt_hi; - __le32 tx_drop_byte_cnt_lo; - __le32 tx_drop_byte_cnt_hi; - __le32 msdu_ttl_cnt_lo; - __le32 msdu_ttl_cnt_hi; - __le32 msdu_ttl_byte_cnt_lo; - __le32 msdu_ttl_byte_cnt_hi; -} __packed; - -struct htt_t2h_vdev_common_stats_tlv { - __le32 soc_drop_count_lo; - __le32 soc_drop_count_hi; -} __packed; - -/* ppdu stats - * - * @details - * The following field definitions describe the format of the HTT target - * to host ppdu stats indication message. - * - * - * |31 16|15 12|11 10|9 8|7 0 | - * |----------------------------------------------------------------------| - * | payload_size | rsvd |pdev_id|mac_id | msg type | - * |----------------------------------------------------------------------| - * | ppdu_id | - * |----------------------------------------------------------------------| - * | Timestamp in us | - * |----------------------------------------------------------------------| - * | reserved | - * |----------------------------------------------------------------------| - * | type-specific stats info | - * | (see htt_ppdu_stats.h) | - * |----------------------------------------------------------------------| - * Header fields: - * - MSG_TYPE - * Bits 7:0 - * Purpose: Identifies this is a PPDU STATS indication - * message. - * Value: 0x1d - * - mac_id - * Bits 9:8 - * Purpose: mac_id of this ppdu_id - * Value: 0-3 - * - pdev_id - * Bits 11:10 - * Purpose: pdev_id of this ppdu_id - * Value: 0-3 - * 0 (for rings at SOC level), - * 1/2/3 PDEV -> 0/1/2 - * - payload_size - * Bits 31:16 - * Purpose: total tlv size - * Value: payload_size in bytes - */ - -#define HTT_T2H_PPDU_STATS_INFO_PDEV_ID GENMASK(11, 10) -#define HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE GENMASK(31, 16) - -struct ath12k_htt_ppdu_stats_msg { - __le32 info; - __le32 ppdu_id; - __le32 timestamp; - __le32 rsvd; - u8 data[]; -} __packed; - -struct htt_tlv { - __le32 header; - u8 value[]; -} __packed; - -#define HTT_TLV_TAG GENMASK(11, 0) -#define HTT_TLV_LEN GENMASK(23, 12) - -enum HTT_PPDU_STATS_BW { - HTT_PPDU_STATS_BANDWIDTH_5MHZ = 0, - HTT_PPDU_STATS_BANDWIDTH_10MHZ = 1, - HTT_PPDU_STATS_BANDWIDTH_20MHZ = 2, - HTT_PPDU_STATS_BANDWIDTH_40MHZ = 3, - HTT_PPDU_STATS_BANDWIDTH_80MHZ = 4, - HTT_PPDU_STATS_BANDWIDTH_160MHZ = 5, /* includes 80+80 */ - HTT_PPDU_STATS_BANDWIDTH_DYN = 6, -}; - -#define HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M GENMASK(7, 0) -#define HTT_PPDU_STATS_CMN_FLAGS_QUEUE_TYPE_M GENMASK(15, 8) -/* bw - HTT_PPDU_STATS_BW */ -#define HTT_PPDU_STATS_CMN_FLAGS_BW_M GENMASK(19, 16) - -struct htt_ppdu_stats_common { - __le32 ppdu_id; - __le16 sched_cmdid; - u8 ring_id; - u8 num_users; - __le32 flags; /* %HTT_PPDU_STATS_COMMON_FLAGS_*/ - __le32 chain_mask; - __le32 fes_duration_us; /* frame exchange sequence */ - __le32 ppdu_sch_eval_start_tstmp_us; - __le32 ppdu_sch_end_tstmp_us; - __le32 ppdu_start_tstmp_us; - /* BIT [15 : 0] - phy mode (WLAN_PHY_MODE) with which ppdu was transmitted - * BIT [31 : 16] - bandwidth (in MHz) with which ppdu was transmitted - */ - __le16 phy_mode; - __le16 bw_mhz; -} __packed; - -enum htt_ppdu_stats_gi { - HTT_PPDU_STATS_SGI_0_8_US, - HTT_PPDU_STATS_SGI_0_4_US, - HTT_PPDU_STATS_SGI_1_6_US, - HTT_PPDU_STATS_SGI_3_2_US, -}; - -#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0) -#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4) - -enum HTT_PPDU_STATS_PPDU_TYPE { - HTT_PPDU_STATS_PPDU_TYPE_SU, - HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO, - HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA, - HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA, - HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG, - HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN, - HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP, - HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG, - HTT_PPDU_STATS_PPDU_TYPE_UL_RESP, - HTT_PPDU_STATS_PPDU_TYPE_MAX -}; - -#define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0) -#define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1) - -#define HTT_PPDU_STATS_USER_RATE_FLAGS_LTF_SIZE_M GENMASK(1, 0) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_STBC_M BIT(2) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_HE_RE_M BIT(3) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_TXBF_M GENMASK(7, 4) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M GENMASK(11, 8) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M GENMASK(15, 12) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M GENMASK(19, 16) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M GENMASK(23, 20) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M GENMASK(27, 24) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M BIT(28) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_LDPC_M BIT(29) - -#define HTT_USR_RATE_PPDU_TYPE(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M) -#define HTT_USR_RATE_PREAMBLE(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M) -#define HTT_USR_RATE_BW(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M) -#define HTT_USR_RATE_NSS(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M) -#define HTT_USR_RATE_MCS(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M) -#define HTT_USR_RATE_GI(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M) -#define HTT_USR_RATE_DCM(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M) - -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_HE_RE_M BIT(3) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_TXBF_M GENMASK(7, 4) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_BW_M GENMASK(11, 8) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_NSS_M GENMASK(15, 12) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_MCS_M GENMASK(19, 16) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_PREAMBLE_M GENMASK(23, 20) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_GI_M GENMASK(27, 24) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_DCM_M BIT(28) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LDPC_M BIT(29) - -struct htt_ppdu_stats_user_rate { - u8 tid_num; - u8 reserved0; - __le16 sw_peer_id; - __le32 info0; /* %HTT_PPDU_STATS_USER_RATE_INFO0_*/ - __le16 ru_end; - __le16 ru_start; - __le16 resp_ru_end; - __le16 resp_ru_start; - __le32 info1; /* %HTT_PPDU_STATS_USER_RATE_INFO1_ */ - __le32 rate_flags; /* %HTT_PPDU_STATS_USER_RATE_FLAGS_ */ - /* Note: resp_rate_info is only valid for if resp_type is UL */ - __le32 resp_rate_flags; /* %HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_ */ -} __packed; - -#define HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M GENMASK(7, 0) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M BIT(8) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M GENMASK(10, 9) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_BW_M GENMASK(13, 11) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_SGI_M BIT(14) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M GENMASK(31, 16) - -#define HTT_TX_INFO_IS_AMSDU(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M) -#define HTT_TX_INFO_BA_ACK_FAILED(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M) -#define HTT_TX_INFO_RATECODE(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M) -#define HTT_TX_INFO_PEERID(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M) - -enum htt_ppdu_stats_usr_compln_status { - HTT_PPDU_STATS_USER_STATUS_OK, - HTT_PPDU_STATS_USER_STATUS_FILTERED, - HTT_PPDU_STATS_USER_STATUS_RESP_TIMEOUT, - HTT_PPDU_STATS_USER_STATUS_RESP_MISMATCH, - HTT_PPDU_STATS_USER_STATUS_ABORT, -}; - -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M GENMASK(3, 0) -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M GENMASK(7, 4) -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M BIT(8) -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_RESP_TYPE_M GENMASK(12, 9) - -#define HTT_USR_CMPLTN_IS_AMPDU(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M) -#define HTT_USR_CMPLTN_LONG_RETRY(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M) -#define HTT_USR_CMPLTN_SHORT_RETRY(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M) - -struct htt_ppdu_stats_usr_cmpltn_cmn { - u8 status; - u8 tid_num; - __le16 sw_peer_id; - /* RSSI value of last ack packet (units = dB above noise floor) */ - __le32 ack_rssi; - __le16 mpdu_tried; - __le16 mpdu_success; - __le32 flags; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRIES*/ -} __packed; - -#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MPDU_M GENMASK(8, 0) -#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M GENMASK(24, 9) -#define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25) - -#define HTT_PPDU_STATS_NON_QOS_TID 16 - -struct htt_ppdu_stats_usr_cmpltn_ack_ba_status { - __le32 ppdu_id; - __le16 sw_peer_id; - __le16 reserved0; - __le32 info; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_INFO_ */ - __le16 current_seq; - __le16 start_seq; - __le32 success_bytes; -} __packed; - -struct htt_ppdu_user_stats { - u16 peer_id; - u16 delay_ba; - u32 tlv_flags; - bool is_valid_peer_id; - struct htt_ppdu_stats_user_rate rate; - struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn; - struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba; -}; - -#define HTT_PPDU_STATS_MAX_USERS 8 -#define HTT_PPDU_DESC_MAX_DEPTH 16 - -struct htt_ppdu_stats { - struct htt_ppdu_stats_common common; - struct htt_ppdu_user_stats user_stats[HTT_PPDU_STATS_MAX_USERS]; -}; - -struct htt_ppdu_stats_info { - u32 tlv_bitmap; - u32 ppdu_id; - u32 frame_type; - u32 frame_ctrl; - u32 delay_ba; - u32 bar_num_users; - struct htt_ppdu_stats ppdu_stats; - struct list_head list; -}; - -/* @brief target -> host MLO offset indiciation message - * - * @details - * The following field definitions describe the format of the HTT target - * to host mlo offset indication message. - * - * - * |31 29|28 |26|25 22|21 16|15 13|12 10 |9 8|7 0| - * |---------------------------------------------------------------------| - * | rsvd1 | mac_freq |chip_id |pdev_id|msgtype| - * |---------------------------------------------------------------------| - * | sync_timestamp_lo_us | - * |---------------------------------------------------------------------| - * | sync_timestamp_hi_us | - * |---------------------------------------------------------------------| - * | mlo_offset_lo | - * |---------------------------------------------------------------------| - * | mlo_offset_hi | - * |---------------------------------------------------------------------| - * | mlo_offset_clcks | - * |---------------------------------------------------------------------| - * | rsvd2 | mlo_comp_clks |mlo_comp_us | - * |---------------------------------------------------------------------| - * | rsvd3 |mlo_comp_timer | - * |---------------------------------------------------------------------| - * Header fields - * - MSG_TYPE - * Bits 7:0 - * Purpose: Identifies this is a MLO offset indication msg - * - PDEV_ID - * Bits 9:8 - * Purpose: Pdev of this MLO offset - * - CHIP_ID - * Bits 12:10 - * Purpose: chip_id of this MLO offset - * - MAC_FREQ - * Bits 28:13 - * - SYNC_TIMESTAMP_LO_US - * Purpose: clock frequency of the mac HW block in MHz - * Bits: 31:0 - * Purpose: lower 32 bits of the WLAN global time stamp at which - * last sync interrupt was received - * - SYNC_TIMESTAMP_HI_US - * Bits: 31:0 - * Purpose: upper 32 bits of WLAN global time stamp at which - * last sync interrupt was received - * - MLO_OFFSET_LO - * Bits: 31:0 - * Purpose: lower 32 bits of the MLO offset in us - * - MLO_OFFSET_HI - * Bits: 31:0 - * Purpose: upper 32 bits of the MLO offset in us - * - MLO_COMP_US - * Bits: 15:0 - * Purpose: MLO time stamp compensation applied in us - * - MLO_COMP_CLCKS - * Bits: 25:16 - * Purpose: MLO time stamp compensation applied in clock ticks - * - MLO_COMP_TIMER - * Bits: 21:0 - * Purpose: Periodic timer at which compensation is applied - */ - -#define HTT_T2H_MLO_OFFSET_INFO_MSG_TYPE GENMASK(7, 0) -#define HTT_T2H_MLO_OFFSET_INFO_PDEV_ID GENMASK(9, 8) - -struct ath12k_htt_mlo_offset_msg { - __le32 info; - __le32 sync_timestamp_lo_us; - __le32 sync_timestamp_hi_us; - __le32 mlo_offset_hi; - __le32 mlo_offset_lo; - __le32 mlo_offset_clks; - __le32 mlo_comp_clks; - __le32 mlo_comp_timer; -} __packed; - -/* @brief host -> target FW extended statistics retrieve - * - * @details - * The following field definitions describe the format of the HTT host - * to target FW extended stats retrieve message. - * The message specifies the type of stats the host wants to retrieve. - * - * |31 24|23 16|15 8|7 0| - * |-----------------------------------------------------------| - * | reserved | stats type | pdev_mask | msg type | - * |-----------------------------------------------------------| - * | config param [0] | - * |-----------------------------------------------------------| - * | config param [1] | - * |-----------------------------------------------------------| - * | config param [2] | - * |-----------------------------------------------------------| - * | config param [3] | - * |-----------------------------------------------------------| - * | reserved | - * |-----------------------------------------------------------| - * | cookie LSBs | - * |-----------------------------------------------------------| - * | cookie MSBs | - * |-----------------------------------------------------------| - * Header fields: - * - MSG_TYPE - * Bits 7:0 - * Purpose: identifies this is a extended stats upload request message - * Value: 0x10 - * - PDEV_MASK - * Bits 8:15 - * Purpose: identifies the mask of PDEVs to retrieve stats from - * Value: This is a overloaded field, refer to usage and interpretation of - * PDEV in interface document. - * Bit 8 : Reserved for SOC stats - * Bit 9 - 15 : Indicates PDEV_MASK in DBDC - * Indicates MACID_MASK in DBS - * - STATS_TYPE - * Bits 23:16 - * Purpose: identifies which FW statistics to upload - * Value: Defined by htt_dbg_ext_stats_type (see htt_stats.h) - * - Reserved - * Bits 31:24 - * - CONFIG_PARAM [0] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - CONFIG_PARAM [1] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - CONFIG_PARAM [2] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - CONFIG_PARAM [3] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - Reserved [31:0] for future use. - * - COOKIE_LSBS - * Bits 31:0 - * Purpose: Provide a mechanism to match a target->host stats confirmation - * message with its preceding host->target stats request message. - * Value: LSBs of the opaque cookie specified by the host-side requestor - * - COOKIE_MSBS - * Bits 31:0 - * Purpose: Provide a mechanism to match a target->host stats confirmation - * message with its preceding host->target stats request message. - * Value: MSBs of the opaque cookie specified by the host-side requestor - */ - -struct htt_ext_stats_cfg_hdr { - u8 msg_type; - u8 pdev_mask; - u8 stats_type; - u8 reserved; -} __packed; - -struct htt_ext_stats_cfg_cmd { - struct htt_ext_stats_cfg_hdr hdr; - __le32 cfg_param0; - __le32 cfg_param1; - __le32 cfg_param2; - __le32 cfg_param3; - __le32 reserved; - __le32 cookie_lsb; - __le32 cookie_msb; -} __packed; - -/* htt stats config default params */ -#define HTT_STAT_DEFAULT_RESET_START_OFFSET 0 -#define HTT_STAT_DEFAULT_CFG0_ALL_HWQS 0xffffffff -#define HTT_STAT_DEFAULT_CFG0_ALL_TXQS 0xffffffff -#define HTT_STAT_DEFAULT_CFG0_ALL_CMDQS 0xffff -#define HTT_STAT_DEFAULT_CFG0_ALL_RINGS 0xffff -#define HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS 0xff -#define HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE 0x00 -#define HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS 0x00 - -/* HTT_DBG_EXT_STATS_PEER_INFO - * PARAMS: - * @config_param0: - * [Bit0] - [0] for sw_peer_id, [1] for mac_addr based request - * [Bit15 : Bit 1] htt_peer_stats_req_mode_t - * [Bit31 : Bit16] sw_peer_id - * @config_param1: - * peer_stats_req_type_mask:32 (enum htt_peer_stats_tlv_enum) - * 0 bit htt_peer_stats_cmn_tlv - * 1 bit htt_peer_details_tlv - * 2 bit htt_tx_peer_rate_stats_tlv - * 3 bit htt_rx_peer_rate_stats_tlv - * 4 bit htt_tx_tid_stats_tlv/htt_tx_tid_stats_v1_tlv - * 5 bit htt_rx_tid_stats_tlv - * 6 bit htt_msdu_flow_stats_tlv - * @config_param2: [Bit31 : Bit0] mac_addr31to0 - * @config_param3: [Bit15 : Bit0] mac_addr47to32 - * [Bit31 : Bit16] reserved - */ -#define HTT_STAT_PEER_INFO_MAC_ADDR BIT(0) -#define HTT_STAT_DEFAULT_PEER_REQ_TYPE 0x7f - -/* Used to set different configs to the specified stats type.*/ -struct htt_ext_stats_cfg_params { - u32 cfg0; - u32 cfg1; - u32 cfg2; - u32 cfg3; -}; - -enum vdev_stats_offload_timer_duration { - ATH12K_STATS_TIMER_DUR_500MS = 1, - ATH12K_STATS_TIMER_DUR_1SEC = 2, - ATH12K_STATS_TIMER_DUR_2SEC = 3, -}; - -#define ATH12K_HTT_MAC_ADDR_L32_0 GENMASK(7, 0) -#define ATH12K_HTT_MAC_ADDR_L32_1 GENMASK(15, 8) -#define ATH12K_HTT_MAC_ADDR_L32_2 GENMASK(23, 16) -#define ATH12K_HTT_MAC_ADDR_L32_3 GENMASK(31, 24) -#define ATH12K_HTT_MAC_ADDR_H16_0 GENMASK(7, 0) -#define ATH12K_HTT_MAC_ADDR_H16_1 GENMASK(15, 8) - -struct htt_mac_addr { - __le32 mac_addr_l32; - __le32 mac_addr_h16; -} __packed; - static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) { memcpy(addr, &addr_l32, 4); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h new file mode 100644 index 0000000000000..ce9064628d343 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -0,0 +1,1517 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_HTT_H +#define ATH12K_DP_HTT_H + +struct ath12k_dp; + +/* HTT definitions */ +#define HTT_TAG_TCL_METADATA_VERSION 5 + +#define HTT_TCL_META_DATA_TYPE GENMASK(1, 0) +#define HTT_TCL_META_DATA_VALID_HTT BIT(2) + +/* vdev meta data */ +#define HTT_TCL_META_DATA_VDEV_ID GENMASK(10, 3) +#define HTT_TCL_META_DATA_PDEV_ID GENMASK(12, 11) +#define HTT_TCL_META_DATA_HOST_INSPECTED_MISSION BIT(13) + +/* peer meta data */ +#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 3) + +/* Global sequence number */ +#define HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM 3 +#define HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED BIT(2) +#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3) +#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128 + +/* HTT tx completion is overlaid in wbm_release_ring */ +#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13) +#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0) +#define HTT_TX_WBM_COMP_INFO1_EXCEPTION_FRAME BIT(4) + +#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24) + +struct htt_tx_wbm_completion { + __le32 rsvd0[2]; + __le32 info0; + __le32 info1; + __le32 info2; + __le32 info3; + __le32 info4; + __le32 rsvd1; + +} __packed; + +enum htt_h2t_msg_type { + HTT_H2T_MSG_TYPE_VERSION_REQ = 0, + HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb, + HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc, + HTT_H2T_MSG_TYPE_EXT_STATS_CFG = 0x10, + HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11, + HTT_H2T_MSG_TYPE_VDEV_TXRX_STATS_CFG = 0x1a, + HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b, +}; + +#define HTT_VER_REQ_INFO_MSG_ID GENMASK(7, 0) +#define HTT_OPTION_TCL_METADATA_VER_V1 1 +#define HTT_OPTION_TCL_METADATA_VER_V2 2 +#define HTT_OPTION_TAG GENMASK(7, 0) +#define HTT_OPTION_LEN GENMASK(15, 8) +#define HTT_OPTION_VALUE GENMASK(31, 16) +#define HTT_TCL_METADATA_VER_SZ 4 + +struct htt_ver_req_cmd { + __le32 ver_reg_info; + __le32 tcl_metadata_version; +} __packed; + +enum htt_srng_ring_type { + HTT_HW_TO_SW_RING, + HTT_SW_TO_HW_RING, + HTT_SW_TO_SW_RING, +}; + +enum htt_srng_ring_id { + HTT_RXDMA_HOST_BUF_RING, + HTT_RXDMA_MONITOR_STATUS_RING, + HTT_RXDMA_MONITOR_BUF_RING, + HTT_RXDMA_MONITOR_DESC_RING, + HTT_RXDMA_MONITOR_DEST_RING, + HTT_HOST1_TO_FW_RXBUF_RING, + HTT_HOST2_TO_FW_RXBUF_RING, + HTT_RXDMA_NON_MONITOR_DEST_RING, + HTT_RXDMA_HOST_BUF_RING2, + HTT_TX_MON_HOST2MON_BUF_RING, + HTT_TX_MON_MON2HOST_DEST_RING, + HTT_RX_MON_HOST2MON_BUF_RING, + HTT_RX_MON_MON2HOST_DEST_RING, +}; + +/* host -> target HTT_SRING_SETUP message + * + * After target is booted up, Host can send SRING setup message for + * each host facing LMAC SRING. Target setups up HW registers based + * on setup message and confirms back to Host if response_required is set. + * Host should wait for confirmation message before sending new SRING + * setup message + * + * The message would appear as follows: + * + * |31 24|23 20|19|18 16|15|14 8|7 0| + * |--------------- +-----------------+----------------+------------------| + * | ring_type | ring_id | pdev_id | msg_type | + * |----------------------------------------------------------------------| + * | ring_base_addr_lo | + * |----------------------------------------------------------------------| + * | ring_base_addr_hi | + * |----------------------------------------------------------------------| + * |ring_misc_cfg_flag|ring_entry_size| ring_size | + * |----------------------------------------------------------------------| + * | ring_head_offset32_remote_addr_lo | + * |----------------------------------------------------------------------| + * | ring_head_offset32_remote_addr_hi | + * |----------------------------------------------------------------------| + * | ring_tail_offset32_remote_addr_lo | + * |----------------------------------------------------------------------| + * | ring_tail_offset32_remote_addr_hi | + * |----------------------------------------------------------------------| + * | ring_msi_addr_lo | + * |----------------------------------------------------------------------| + * | ring_msi_addr_hi | + * |----------------------------------------------------------------------| + * | ring_msi_data | + * |----------------------------------------------------------------------| + * | intr_timer_th |IM| intr_batch_counter_th | + * |----------------------------------------------------------------------| + * | reserved |RR|PTCF| intr_low_threshold | + * |----------------------------------------------------------------------| + * Where + * IM = sw_intr_mode + * RR = response_required + * PTCF = prefetch_timer_cfg + * + * The message is interpreted as follows: + * dword0 - b'0:7 - msg_type: This will be set to + * HTT_H2T_MSG_TYPE_SRING_SETUP + * b'8:15 - pdev_id: + * 0 (for rings at SOC/UMAC level), + * 1/2/3 mac id (for rings at LMAC level) + * b'16:23 - ring_id: identify which ring is to setup, + * more details can be got from enum htt_srng_ring_id + * b'24:31 - ring_type: identify type of host rings, + * more details can be got from enum htt_srng_ring_type + * dword1 - b'0:31 - ring_base_addr_lo: Lower 32bits of ring base address + * dword2 - b'0:31 - ring_base_addr_hi: Upper 32bits of ring base address + * dword3 - b'0:15 - ring_size: size of the ring in unit of 4-bytes words + * b'16:23 - ring_entry_size: Size of each entry in 4-byte word units + * b'24:31 - ring_misc_cfg_flag: Valid only for HW_TO_SW_RING and + * SW_TO_HW_RING. + * Refer to HTT_SRING_SETUP_RING_MISC_CFG_RING defs. + * dword4 - b'0:31 - ring_head_off32_remote_addr_lo: + * Lower 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the head + * element within the ring. + * (The head offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword5 - b'0:31 - ring_head_off32_remote_addr_hi: + * Upper 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the head + * element within the ring. + * (The head offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword6 - b'0:31 - ring_tail_off32_remote_addr_lo: + * Lower 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the tail + * element within the ring. + * (The tail offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword7 - b'0:31 - ring_tail_off32_remote_addr_hi: + * Upper 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the tail + * element within the ring. + * (The tail offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword8 - b'0:31 - ring_msi_addr_lo: Lower 32bits of MSI cfg address + * valid only for HW_TO_SW_RING and SW_TO_HW_RING + * dword9 - b'0:31 - ring_msi_addr_hi: Upper 32bits of MSI cfg address + * valid only for HW_TO_SW_RING and SW_TO_HW_RING + * dword10 - b'0:31 - ring_msi_data: MSI data + * Refer to HTT_SRING_SETUP_RING_MSC_CFG_xxx defs + * valid only for HW_TO_SW_RING and SW_TO_HW_RING + * dword11 - b'0:14 - intr_batch_counter_th: + * batch counter threshold is in units of 4-byte words. + * HW internally maintains and increments batch count. + * (see SRING spec for detail description). + * When batch count reaches threshold value, an interrupt + * is generated by HW. + * b'15 - sw_intr_mode: + * This configuration shall be static. + * Only programmed at power up. + * 0: generate pulse style sw interrupts + * 1: generate level style sw interrupts + * b'16:31 - intr_timer_th: + * The timer init value when timer is idle or is + * initialized to start downcounting. + * In 8us units (to cover a range of 0 to 524 ms) + * dword12 - b'0:15 - intr_low_threshold: + * Used only by Consumer ring to generate ring_sw_int_p. + * Ring entries low threshold water mark, that is used + * in combination with the interrupt timer as well as + * the clearing of the level interrupt. + * b'16:18 - prefetch_timer_cfg: + * Used only by Consumer ring to set timer mode to + * support Application prefetch handling. + * The external tail offset/pointer will be updated + * at following intervals: + * 3'b000: (Prefetch feature disabled; used only for debug) + * 3'b001: 1 usec + * 3'b010: 4 usec + * 3'b011: 8 usec (default) + * 3'b100: 16 usec + * Others: Reserved + * b'19 - response_required: + * Host needs HTT_T2H_MSG_TYPE_SRING_SETUP_DONE as response + * b'20:31 - reserved: reserved for future use + */ + +#define HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID GENMASK(15, 8) +#define HTT_SRNG_SETUP_CMD_INFO0_RING_ID GENMASK(23, 16) +#define HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE GENMASK(31, 24) + +#define HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE GENMASK(15, 0) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE GENMASK(23, 16) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS BIT(25) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP BIT(27) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP BIT(28) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP BIT(29) + +#define HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH GENMASK(14, 0) +#define HTT_SRNG_SETUP_CMD_INTR_INFO_SW_INTR_MODE BIT(15) +#define HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH GENMASK(31, 16) + +#define HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH GENMASK(15, 0) +#define HTT_SRNG_SETUP_CMD_INFO2_PRE_FETCH_TIMER_CFG GENMASK(18, 16) +#define HTT_SRNG_SETUP_CMD_INFO2_RESPONSE_REQUIRED BIT(19) + +struct htt_srng_setup_cmd { + __le32 info0; + __le32 ring_base_addr_lo; + __le32 ring_base_addr_hi; + __le32 info1; + __le32 ring_head_off32_remote_addr_lo; + __le32 ring_head_off32_remote_addr_hi; + __le32 ring_tail_off32_remote_addr_lo; + __le32 ring_tail_off32_remote_addr_hi; + __le32 ring_msi_addr_lo; + __le32 ring_msi_addr_hi; + __le32 msi_data; + __le32 intr_info; + __le32 info2; +} __packed; + +/* host -> target FW PPDU_STATS config message + * + * @details + * The following field definitions describe the format of the HTT host + * to target FW for PPDU_STATS_CFG msg. + * The message allows the host to configure the PPDU_STATS_IND messages + * produced by the target. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | REQ bit mask | pdev_mask | msg type | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this is a req to configure ppdu_stats_ind from target + * Value: 0x11 + * - PDEV_MASK + * Bits 8:15 + * Purpose: identifies which pdevs this PPDU stats configuration applies to + * Value: This is a overloaded field, refer to usage and interpretation of + * PDEV in interface document. + * Bit 8 : Reserved for SOC stats + * Bit 9 - 15 : Indicates PDEV_MASK in DBDC + * Indicates MACID_MASK in DBS + * - REQ_TLV_BIT_MASK + * Bits 16:31 + * Purpose: each set bit indicates the corresponding PPDU stats TLV type + * needs to be included in the target's PPDU_STATS_IND messages. + * Value: refer htt_ppdu_stats_tlv_tag_t << 30 bits + * Refer to PKT_TYPE_ENABLE_FLAG0_xxx_MGMT_xxx defs + * dword3 - b'0:31 - packet_type_enable_flags_1: + * Enable MGMT packet from 0b1010 to 0b1111 + * bits from low to high: FP, MD, MO - 3 bits + * Refer to PKT_TYPE_ENABLE_FLAG1_xxx_MGMT_xxx defs + * dword4 - b'0:31 - packet_type_enable_flags_2: + * Enable CTRL packet from 0b0000 to 0b1001 + * bits from low to high: FP, MD, MO - 3 bits + * Refer to PKT_TYPE_ENABLE_FLAG2_xxx_CTRL_xxx defs + * dword5 - b'0:31 - packet_type_enable_flags_3: + * Enable CTRL packet from 0b1010 to 0b1111, + * MCAST_DATA, UCAST_DATA, NULL_DATA + * bits from low to high: FP, MD, MO - 3 bits + * Refer to PKT_TYPE_ENABLE_FLAG3_xxx_CTRL_xxx defs + * dword6 - b'0:31 - tlv_filter_in_flags: + * Filter in Attention/MPDU/PPDU/Header/User tlvs + * Refer to CFG_TLV_FILTER_IN_FLAG defs + */ + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID BIT(26) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL BIT(27) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON BIT(28) + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(18, 16) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(21, 19) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(24, 22) + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD GENMASK(9, 0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE BIT(17) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE BIT(18) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE BIT(19) + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET BIT(0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET GENMASK(14, 1) + +#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) + +#define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0) + +enum htt_rx_filter_tlv_flags { + HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), + HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1), + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET = BIT(2), + HTT_RX_FILTER_TLV_FLAGS_MSDU_END = BIT(3), + HTT_RX_FILTER_TLV_FLAGS_MPDU_END = BIT(4), + HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER = BIT(5), + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER = BIT(6), + HTT_RX_FILTER_TLV_FLAGS_ATTENTION = BIT(7), + HTT_RX_FILTER_TLV_FLAGS_PPDU_START = BIT(8), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END = BIT(9), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS = BIT(10), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT = BIT(11), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE = BIT(12), + HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO = BIT(13), +}; + +enum htt_rx_mgmt_pkt_filter_tlv_flags0 { + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(0), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(1), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(2), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(3), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(4), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(5), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(6), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(7), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(8), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(9), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(10), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(11), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(12), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(13), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(14), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(15), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(16), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(17), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(18), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(19), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(20), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(21), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(22), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(23), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(24), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(25), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(26), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(27), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(28), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(29), +}; + +enum htt_rx_mgmt_pkt_filter_tlv_flags1 { + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(0), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(1), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(2), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(3), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(4), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(5), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(6), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(7), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(8), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(9), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(10), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(11), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(12), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(13), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(14), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(15), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(16), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(17), +}; + +enum htt_rx_ctrl_pkt_filter_tlv_flags2 { + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(0), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(1), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(2), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(3), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(4), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(5), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(6), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(7), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(8), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(9), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(10), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(11), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(12), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(13), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(14), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(15), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(16), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(17), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(18), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(19), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(20), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(21), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(22), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(23), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(24), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(25), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(26), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(27), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(28), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(29), +}; + +enum htt_rx_ctrl_pkt_filter_tlv_flags3 { + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(0), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(1), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(2), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(3), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(4), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(5), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(6), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(7), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(8), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(9), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(10), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(11), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(12), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(13), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(14), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(15), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(16), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(17), +}; + +enum htt_rx_data_pkt_filter_tlv_flasg3 { + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(18), + HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(19), + HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(20), + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(21), + HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(22), + HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(23), + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(24), + HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(25), + HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(26), +}; + +#define HTT_RX_FP_MGMT_FILTER_FLAGS0 \ + (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) + +#define HTT_RX_MD_MGMT_FILTER_FLAGS0 \ + (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) + +#define HTT_RX_MO_MGMT_FILTER_FLAGS0 \ + (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) + +#define HTT_RX_FP_MGMT_FILTER_FLAGS1 (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) + +#define HTT_RX_MD_MGMT_FILTER_FLAGS1 (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) + +#define HTT_RX_MO_MGMT_FILTER_FLAGS1 (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) + +#define HTT_RX_FP_CTRL_FILTER_FLASG2 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA) + +#define HTT_RX_MD_CTRL_FILTER_FLASG2 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA) + +#define HTT_RX_MO_CTRL_FILTER_FLASG2 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA) + +#define HTT_RX_FP_CTRL_FILTER_FLASG3 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) + +#define HTT_RX_MD_CTRL_FILTER_FLASG3 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) + +#define HTT_RX_MO_CTRL_FILTER_FLASG3 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) + +#define HTT_RX_FP_DATA_FILTER_FLASG3 (HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ + | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ + | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) + +#define HTT_RX_MD_DATA_FILTER_FLASG3 (HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ + | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ + | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) + +#define HTT_RX_MO_DATA_FILTER_FLASG3 (HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ + | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ + | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) + +#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 \ + (HTT_RX_FP_MGMT_FILTER_FLAGS0 | \ + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) + +#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS0 \ + (HTT_RX_MO_MGMT_FILTER_FLAGS0 | \ + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) + +#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 \ + (HTT_RX_FP_MGMT_FILTER_FLAGS1 | \ + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) + +#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS1 \ + (HTT_RX_MO_MGMT_FILTER_FLAGS1 | \ + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) + +#define HTT_RX_MON_FP_CTRL_FILTER_FLASG2 \ + (HTT_RX_FP_CTRL_FILTER_FLASG2 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) + +#define HTT_RX_MON_MO_CTRL_FILTER_FLASG2 \ + (HTT_RX_MO_CTRL_FILTER_FLASG2 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) + +#define HTT_RX_MON_FP_CTRL_FILTER_FLASG3 HTT_RX_FP_CTRL_FILTER_FLASG3 + +#define HTT_RX_MON_MO_CTRL_FILTER_FLASG3 HTT_RX_MO_CTRL_FILTER_FLASG3 + +#define HTT_RX_MON_FP_DATA_FILTER_FLASG3 HTT_RX_FP_DATA_FILTER_FLASG3 + +#define HTT_RX_MON_MO_DATA_FILTER_FLASG3 HTT_RX_MO_DATA_FILTER_FLASG3 + +#define HTT_RX_MON_FILTER_TLV_FLAGS \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) + +#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) + +#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_ATTENTION) + +#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO) + +/* msdu start. mpdu end, attention, rx hdr tlv's are not subscribed */ +#define HTT_RX_TLV_FLAGS_RXDMA_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_END) + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) + +struct htt_rx_ring_selection_cfg_cmd { + __le32 info0; + __le32 info1; + __le32 pkt_type_en_flags0; + __le32 pkt_type_en_flags1; + __le32 pkt_type_en_flags2; + __le32 pkt_type_en_flags3; + __le32 rx_filter_tlv; + __le32 rx_packet_offset; + __le32 rx_mpdu_offset; + __le32 rx_msdu_offset; + __le32 rx_attn_offset; + __le32 info2; + __le32 reserved[2]; + __le32 rx_mpdu_start_end_mask; + __le32 rx_msdu_end_word_mask; + __le32 info3; +} __packed; + +#define HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE 32 +#define HTT_RX_RING_DEFAULT_DMA_LENGTH 0x7 +#define HTT_RX_RING_PKT_TLV_OFFSET 0x1 + +struct htt_rx_ring_tlv_filter { + u32 rx_filter; /* see htt_rx_filter_tlv_flags */ + u32 pkt_filter_flags0; /* MGMT */ + u32 pkt_filter_flags1; /* MGMT */ + u32 pkt_filter_flags2; /* CTRL */ + u32 pkt_filter_flags3; /* DATA */ + bool offset_valid; + u16 rx_packet_offset; + u16 rx_header_offset; + u16 rx_mpdu_end_offset; + u16 rx_mpdu_start_offset; + u16 rx_msdu_end_offset; + u16 rx_msdu_start_offset; + u16 rx_attn_offset; + u16 rx_mpdu_start_wmask; + u16 rx_mpdu_end_wmask; + u32 rx_msdu_end_wmask; + u32 conf_len_ctrl; + u32 conf_len_mgmt; + u32 conf_len_data; + u16 rx_drop_threshold; + bool enable_log_mgmt_type; + bool enable_log_ctrl_type; + bool enable_log_data_type; + bool enable_rx_tlv_offset; + u16 rx_tlv_offset; + bool drop_threshold_valid; + bool rxmon_disable; +}; + +#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 +#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1 +#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2 +#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3 + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE GENMASK(15, 0) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE GENMASK(18, 16) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(21, 19) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(24, 22) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(27, 25) + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG GENMASK(2, 0) + +struct htt_tx_ring_selection_cfg_cmd { + __le32 info0; + __le32 info1; + __le32 info2; + __le32 tlv_filter_mask_in0; + __le32 tlv_filter_mask_in1; + __le32 tlv_filter_mask_in2; + __le32 tlv_filter_mask_in3; + __le32 reserved[3]; +} __packed; + +#define HTT_TX_RING_TLV_FILTER_MGMT_DMA_LEN GENMASK(3, 0) +#define HTT_TX_RING_TLV_FILTER_CTRL_DMA_LEN GENMASK(7, 4) +#define HTT_TX_RING_TLV_FILTER_DATA_DMA_LEN GENMASK(11, 8) + +#define HTT_TX_MON_FILTER_HYBRID_MODE \ + (HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS | \ + HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE | \ + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO | \ + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2) + +struct htt_tx_ring_tlv_filter { + u32 tx_mon_downstream_tlv_flags; + u32 tx_mon_upstream_tlv_flags0; + u32 tx_mon_upstream_tlv_flags1; + u32 tx_mon_upstream_tlv_flags2; + bool tx_mon_mgmt_filter; + bool tx_mon_data_filter; + bool tx_mon_ctrl_filter; + u16 tx_mon_pkt_dma_len; +} __packed; + +enum htt_tx_mon_upstream_tlv_flags0 { + HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS = BIT(1), + HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS = BIT(2), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START = BIT(3), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END = BIT(4), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU = BIT(5), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU = BIT(6), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA = BIT(7), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA = BIT(8), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT = BIT(9), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT = BIT(10), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE = BIT(11), + HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_BITMAP_ACK = BIT(12), + HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_1K_BITMAP_ACK = BIT(13), + HTT_TX_FILTER_TLV_FLAGS0_COEX_TX_STATUS = BIT(14), + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO = BIT(15), + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2 = BIT(16), +}; + +#define HTT_TX_FILTER_TLV_FLAGS2_TXPCU_PHYTX_OTHER_TRANSMIT_INFO32 BIT(11) + +/* HTT message target->host */ + +enum htt_t2h_msg_type { + HTT_T2H_MSG_TYPE_VERSION_CONF, + HTT_T2H_MSG_TYPE_PEER_MAP = 0x3, + HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4, + HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5, + HTT_T2H_MSG_TYPE_PKTLOG = 0x8, + HTT_T2H_MSG_TYPE_SEC_IND = 0xb, + HTT_T2H_MSG_TYPE_PEER_MAP2 = 0x1e, + HTT_T2H_MSG_TYPE_PEER_UNMAP2 = 0x1f, + HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d, + HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c, + HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24, + HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND = 0x28, + HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b, + HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c, +}; + +#define HTT_TARGET_VERSION_MAJOR 3 + +#define HTT_T2H_MSG_TYPE GENMASK(7, 0) +#define HTT_T2H_VERSION_CONF_MINOR GENMASK(15, 8) +#define HTT_T2H_VERSION_CONF_MAJOR GENMASK(23, 16) + +struct htt_t2h_version_conf_msg { + __le32 version; +} __packed; + +#define HTT_T2H_PEER_MAP_INFO_VDEV_ID GENMASK(15, 8) +#define HTT_T2H_PEER_MAP_INFO_PEER_ID GENMASK(31, 16) +#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0) +#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16) +#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0) +#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0) +#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16) +#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16) +#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16 + +struct htt_t2h_peer_map_event { + __le32 info; + __le32 mac_addr_l32; + __le32 info1; + __le32 info2; +} __packed; + +#define HTT_T2H_PEER_UNMAP_INFO_VDEV_ID HTT_T2H_PEER_MAP_INFO_VDEV_ID +#define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID +#define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \ + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 +#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M +#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S + +struct htt_t2h_peer_unmap_event { + __le32 info; + __le32 mac_addr_l32; + __le32 info1; +} __packed; + +struct htt_resp_msg { + union { + struct htt_t2h_version_conf_msg version_msg; + struct htt_t2h_peer_map_event peer_map_ev; + struct htt_t2h_peer_unmap_event peer_unmap_ev; + }; +} __packed; + +#define HTT_VDEV_GET_STATS_U64(msg_l32, msg_u32)\ + (((u64)__le32_to_cpu(msg_u32) << 32) | (__le32_to_cpu(msg_l32))) +#define HTT_T2H_VDEV_STATS_PERIODIC_MSG_TYPE GENMASK(7, 0) +#define HTT_T2H_VDEV_STATS_PERIODIC_PDEV_ID GENMASK(15, 8) +#define HTT_T2H_VDEV_STATS_PERIODIC_NUM_VDEV GENMASK(23, 16) +#define HTT_T2H_VDEV_STATS_PERIODIC_PAYLOAD_BYTES GENMASK(15, 0) +#define HTT_VDEV_TXRX_STATS_COMMON_TLV 0 +#define HTT_VDEV_TXRX_STATS_HW_STATS_TLV 1 + +struct htt_t2h_vdev_txrx_stats_ind { + __le32 vdev_id; + __le32 rx_msdu_byte_cnt_lo; + __le32 rx_msdu_byte_cnt_hi; + __le32 rx_msdu_cnt_lo; + __le32 rx_msdu_cnt_hi; + __le32 tx_msdu_byte_cnt_lo; + __le32 tx_msdu_byte_cnt_hi; + __le32 tx_msdu_cnt_lo; + __le32 tx_msdu_cnt_hi; + __le32 tx_retry_cnt_lo; + __le32 tx_retry_cnt_hi; + __le32 tx_retry_byte_cnt_lo; + __le32 tx_retry_byte_cnt_hi; + __le32 tx_drop_cnt_lo; + __le32 tx_drop_cnt_hi; + __le32 tx_drop_byte_cnt_lo; + __le32 tx_drop_byte_cnt_hi; + __le32 msdu_ttl_cnt_lo; + __le32 msdu_ttl_cnt_hi; + __le32 msdu_ttl_byte_cnt_lo; + __le32 msdu_ttl_byte_cnt_hi; +} __packed; + +struct htt_t2h_vdev_common_stats_tlv { + __le32 soc_drop_count_lo; + __le32 soc_drop_count_hi; +} __packed; + +/* ppdu stats + * + * @details + * The following field definitions describe the format of the HTT target + * to host ppdu stats indication message. + * + * + * |31 16|15 12|11 10|9 8|7 0 | + * |----------------------------------------------------------------------| + * | payload_size | rsvd |pdev_id|mac_id | msg type | + * |----------------------------------------------------------------------| + * | ppdu_id | + * |----------------------------------------------------------------------| + * | Timestamp in us | + * |----------------------------------------------------------------------| + * | reserved | + * |----------------------------------------------------------------------| + * | type-specific stats info | + * | (see htt_ppdu_stats.h) | + * |----------------------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this is a PPDU STATS indication + * message. + * Value: 0x1d + * - mac_id + * Bits 9:8 + * Purpose: mac_id of this ppdu_id + * Value: 0-3 + * - pdev_id + * Bits 11:10 + * Purpose: pdev_id of this ppdu_id + * Value: 0-3 + * 0 (for rings at SOC level), + * 1/2/3 PDEV -> 0/1/2 + * - payload_size + * Bits 31:16 + * Purpose: total tlv size + * Value: payload_size in bytes + */ + +#define HTT_T2H_PPDU_STATS_INFO_PDEV_ID GENMASK(11, 10) +#define HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE GENMASK(31, 16) + +struct ath12k_htt_ppdu_stats_msg { + __le32 info; + __le32 ppdu_id; + __le32 timestamp; + __le32 rsvd; + u8 data[]; +} __packed; + +struct htt_tlv { + __le32 header; + u8 value[]; +} __packed; + +#define HTT_TLV_TAG GENMASK(11, 0) +#define HTT_TLV_LEN GENMASK(23, 12) + +enum HTT_PPDU_STATS_BW { + HTT_PPDU_STATS_BANDWIDTH_5MHZ = 0, + HTT_PPDU_STATS_BANDWIDTH_10MHZ = 1, + HTT_PPDU_STATS_BANDWIDTH_20MHZ = 2, + HTT_PPDU_STATS_BANDWIDTH_40MHZ = 3, + HTT_PPDU_STATS_BANDWIDTH_80MHZ = 4, + HTT_PPDU_STATS_BANDWIDTH_160MHZ = 5, /* includes 80+80 */ + HTT_PPDU_STATS_BANDWIDTH_DYN = 6, +}; + +#define HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M GENMASK(7, 0) +#define HTT_PPDU_STATS_CMN_FLAGS_QUEUE_TYPE_M GENMASK(15, 8) +/* bw - HTT_PPDU_STATS_BW */ +#define HTT_PPDU_STATS_CMN_FLAGS_BW_M GENMASK(19, 16) + +struct htt_ppdu_stats_common { + __le32 ppdu_id; + __le16 sched_cmdid; + u8 ring_id; + u8 num_users; + __le32 flags; /* %HTT_PPDU_STATS_COMMON_FLAGS_*/ + __le32 chain_mask; + __le32 fes_duration_us; /* frame exchange sequence */ + __le32 ppdu_sch_eval_start_tstmp_us; + __le32 ppdu_sch_end_tstmp_us; + __le32 ppdu_start_tstmp_us; + /* BIT [15 : 0] - phy mode (WLAN_PHY_MODE) with which ppdu was transmitted + * BIT [31 : 16] - bandwidth (in MHz) with which ppdu was transmitted + */ + __le16 phy_mode; + __le16 bw_mhz; +} __packed; + +enum htt_ppdu_stats_gi { + HTT_PPDU_STATS_SGI_0_8_US, + HTT_PPDU_STATS_SGI_0_4_US, + HTT_PPDU_STATS_SGI_1_6_US, + HTT_PPDU_STATS_SGI_3_2_US, +}; + +#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0) +#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4) + +enum HTT_PPDU_STATS_PPDU_TYPE { + HTT_PPDU_STATS_PPDU_TYPE_SU, + HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO, + HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA, + HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA, + HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG, + HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN, + HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP, + HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG, + HTT_PPDU_STATS_PPDU_TYPE_UL_RESP, + HTT_PPDU_STATS_PPDU_TYPE_MAX +}; + +#define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0) +#define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1) + +#define HTT_PPDU_STATS_USER_RATE_FLAGS_LTF_SIZE_M GENMASK(1, 0) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_STBC_M BIT(2) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_HE_RE_M BIT(3) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_TXBF_M GENMASK(7, 4) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M GENMASK(11, 8) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M GENMASK(15, 12) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M GENMASK(19, 16) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M GENMASK(23, 20) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M GENMASK(27, 24) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M BIT(28) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_LDPC_M BIT(29) + +#define HTT_USR_RATE_PPDU_TYPE(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M) +#define HTT_USR_RATE_PREAMBLE(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M) +#define HTT_USR_RATE_BW(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M) +#define HTT_USR_RATE_NSS(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M) +#define HTT_USR_RATE_MCS(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M) +#define HTT_USR_RATE_GI(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M) +#define HTT_USR_RATE_DCM(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M) + +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_HE_RE_M BIT(3) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_TXBF_M GENMASK(7, 4) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_BW_M GENMASK(11, 8) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_NSS_M GENMASK(15, 12) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_MCS_M GENMASK(19, 16) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_PREAMBLE_M GENMASK(23, 20) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_GI_M GENMASK(27, 24) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_DCM_M BIT(28) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LDPC_M BIT(29) + +struct htt_ppdu_stats_user_rate { + u8 tid_num; + u8 reserved0; + __le16 sw_peer_id; + __le32 info0; /* %HTT_PPDU_STATS_USER_RATE_INFO0_*/ + __le16 ru_end; + __le16 ru_start; + __le16 resp_ru_end; + __le16 resp_ru_start; + __le32 info1; /* %HTT_PPDU_STATS_USER_RATE_INFO1_ */ + __le32 rate_flags; /* %HTT_PPDU_STATS_USER_RATE_FLAGS_ */ + /* Note: resp_rate_info is only valid for if resp_type is UL */ + __le32 resp_rate_flags; /* %HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_ */ +} __packed; + +#define HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M GENMASK(7, 0) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M BIT(8) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M GENMASK(10, 9) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_BW_M GENMASK(13, 11) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_SGI_M BIT(14) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M GENMASK(31, 16) + +#define HTT_TX_INFO_IS_AMSDU(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M) +#define HTT_TX_INFO_BA_ACK_FAILED(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M) +#define HTT_TX_INFO_RATECODE(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M) +#define HTT_TX_INFO_PEERID(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M) + +enum htt_ppdu_stats_usr_compln_status { + HTT_PPDU_STATS_USER_STATUS_OK, + HTT_PPDU_STATS_USER_STATUS_FILTERED, + HTT_PPDU_STATS_USER_STATUS_RESP_TIMEOUT, + HTT_PPDU_STATS_USER_STATUS_RESP_MISMATCH, + HTT_PPDU_STATS_USER_STATUS_ABORT, +}; + +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M GENMASK(3, 0) +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M GENMASK(7, 4) +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M BIT(8) +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_RESP_TYPE_M GENMASK(12, 9) + +#define HTT_USR_CMPLTN_IS_AMPDU(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M) +#define HTT_USR_CMPLTN_LONG_RETRY(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M) +#define HTT_USR_CMPLTN_SHORT_RETRY(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M) + +struct htt_ppdu_stats_usr_cmpltn_cmn { + u8 status; + u8 tid_num; + __le16 sw_peer_id; + /* RSSI value of last ack packet (units = dB above noise floor) */ + __le32 ack_rssi; + __le16 mpdu_tried; + __le16 mpdu_success; + __le32 flags; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRIES*/ +} __packed; + +#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MPDU_M GENMASK(8, 0) +#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M GENMASK(24, 9) +#define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25) + +#define HTT_PPDU_STATS_NON_QOS_TID 16 + +struct htt_ppdu_stats_usr_cmpltn_ack_ba_status { + __le32 ppdu_id; + __le16 sw_peer_id; + __le16 reserved0; + __le32 info; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_INFO_ */ + __le16 current_seq; + __le16 start_seq; + __le32 success_bytes; +} __packed; + +struct htt_ppdu_user_stats { + u16 peer_id; + u16 delay_ba; + u32 tlv_flags; + bool is_valid_peer_id; + struct htt_ppdu_stats_user_rate rate; + struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn; + struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba; +}; + +#define HTT_PPDU_STATS_MAX_USERS 8 +#define HTT_PPDU_DESC_MAX_DEPTH 16 + +struct htt_ppdu_stats { + struct htt_ppdu_stats_common common; + struct htt_ppdu_user_stats user_stats[HTT_PPDU_STATS_MAX_USERS]; +}; + +struct htt_ppdu_stats_info { + u32 tlv_bitmap; + u32 ppdu_id; + u32 frame_type; + u32 frame_ctrl; + u32 delay_ba; + u32 bar_num_users; + struct htt_ppdu_stats ppdu_stats; + struct list_head list; +}; + +/* @brief target -> host MLO offset indiciation message + * + * @details + * The following field definitions describe the format of the HTT target + * to host mlo offset indication message. + * + * + * |31 29|28 |26|25 22|21 16|15 13|12 10 |9 8|7 0| + * |---------------------------------------------------------------------| + * | rsvd1 | mac_freq |chip_id |pdev_id|msgtype| + * |---------------------------------------------------------------------| + * | sync_timestamp_lo_us | + * |---------------------------------------------------------------------| + * | sync_timestamp_hi_us | + * |---------------------------------------------------------------------| + * | mlo_offset_lo | + * |---------------------------------------------------------------------| + * | mlo_offset_hi | + * |---------------------------------------------------------------------| + * | mlo_offset_clcks | + * |---------------------------------------------------------------------| + * | rsvd2 | mlo_comp_clks |mlo_comp_us | + * |---------------------------------------------------------------------| + * | rsvd3 |mlo_comp_timer | + * |---------------------------------------------------------------------| + * Header fields + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this is a MLO offset indication msg + * - PDEV_ID + * Bits 9:8 + * Purpose: Pdev of this MLO offset + * - CHIP_ID + * Bits 12:10 + * Purpose: chip_id of this MLO offset + * - MAC_FREQ + * Bits 28:13 + * - SYNC_TIMESTAMP_LO_US + * Purpose: clock frequency of the mac HW block in MHz + * Bits: 31:0 + * Purpose: lower 32 bits of the WLAN global time stamp at which + * last sync interrupt was received + * - SYNC_TIMESTAMP_HI_US + * Bits: 31:0 + * Purpose: upper 32 bits of WLAN global time stamp at which + * last sync interrupt was received + * - MLO_OFFSET_LO + * Bits: 31:0 + * Purpose: lower 32 bits of the MLO offset in us + * - MLO_OFFSET_HI + * Bits: 31:0 + * Purpose: upper 32 bits of the MLO offset in us + * - MLO_COMP_US + * Bits: 15:0 + * Purpose: MLO time stamp compensation applied in us + * - MLO_COMP_CLCKS + * Bits: 25:16 + * Purpose: MLO time stamp compensation applied in clock ticks + * - MLO_COMP_TIMER + * Bits: 21:0 + * Purpose: Periodic timer at which compensation is applied + */ + +#define HTT_T2H_MLO_OFFSET_INFO_MSG_TYPE GENMASK(7, 0) +#define HTT_T2H_MLO_OFFSET_INFO_PDEV_ID GENMASK(9, 8) + +struct ath12k_htt_mlo_offset_msg { + __le32 info; + __le32 sync_timestamp_lo_us; + __le32 sync_timestamp_hi_us; + __le32 mlo_offset_hi; + __le32 mlo_offset_lo; + __le32 mlo_offset_clks; + __le32 mlo_comp_clks; + __le32 mlo_comp_timer; +} __packed; + +/* @brief host -> target FW extended statistics retrieve + * + * @details + * The following field definitions describe the format of the HTT host + * to target FW extended stats retrieve message. + * The message specifies the type of stats the host wants to retrieve. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | reserved | stats type | pdev_mask | msg type | + * |-----------------------------------------------------------| + * | config param [0] | + * |-----------------------------------------------------------| + * | config param [1] | + * |-----------------------------------------------------------| + * | config param [2] | + * |-----------------------------------------------------------| + * | config param [3] | + * |-----------------------------------------------------------| + * | reserved | + * |-----------------------------------------------------------| + * | cookie LSBs | + * |-----------------------------------------------------------| + * | cookie MSBs | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this is a extended stats upload request message + * Value: 0x10 + * - PDEV_MASK + * Bits 8:15 + * Purpose: identifies the mask of PDEVs to retrieve stats from + * Value: This is a overloaded field, refer to usage and interpretation of + * PDEV in interface document. + * Bit 8 : Reserved for SOC stats + * Bit 9 - 15 : Indicates PDEV_MASK in DBDC + * Indicates MACID_MASK in DBS + * - STATS_TYPE + * Bits 23:16 + * Purpose: identifies which FW statistics to upload + * Value: Defined by htt_dbg_ext_stats_type (see htt_stats.h) + * - Reserved + * Bits 31:24 + * - CONFIG_PARAM [0] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - CONFIG_PARAM [1] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - CONFIG_PARAM [2] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - CONFIG_PARAM [3] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - Reserved [31:0] for future use. + * - COOKIE_LSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: LSBs of the opaque cookie specified by the host-side requestor + * - COOKIE_MSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: MSBs of the opaque cookie specified by the host-side requestor + */ + +struct htt_ext_stats_cfg_hdr { + u8 msg_type; + u8 pdev_mask; + u8 stats_type; + u8 reserved; +} __packed; + +struct htt_ext_stats_cfg_cmd { + struct htt_ext_stats_cfg_hdr hdr; + __le32 cfg_param0; + __le32 cfg_param1; + __le32 cfg_param2; + __le32 cfg_param3; + __le32 reserved; + __le32 cookie_lsb; + __le32 cookie_msb; +} __packed; + +/* htt stats config default params */ +#define HTT_STAT_DEFAULT_RESET_START_OFFSET 0 +#define HTT_STAT_DEFAULT_CFG0_ALL_HWQS 0xffffffff +#define HTT_STAT_DEFAULT_CFG0_ALL_TXQS 0xffffffff +#define HTT_STAT_DEFAULT_CFG0_ALL_CMDQS 0xffff +#define HTT_STAT_DEFAULT_CFG0_ALL_RINGS 0xffff +#define HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS 0xff +#define HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE 0x00 +#define HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS 0x00 + +/* HTT_DBG_EXT_STATS_PEER_INFO + * PARAMS: + * @config_param0: + * [Bit0] - [0] for sw_peer_id, [1] for mac_addr based request + * [Bit15 : Bit 1] htt_peer_stats_req_mode_t + * [Bit31 : Bit16] sw_peer_id + * @config_param1: + * peer_stats_req_type_mask:32 (enum htt_peer_stats_tlv_enum) + * 0 bit htt_peer_stats_cmn_tlv + * 1 bit htt_peer_details_tlv + * 2 bit htt_tx_peer_rate_stats_tlv + * 3 bit htt_rx_peer_rate_stats_tlv + * 4 bit htt_tx_tid_stats_tlv/htt_tx_tid_stats_v1_tlv + * 5 bit htt_rx_tid_stats_tlv + * 6 bit htt_msdu_flow_stats_tlv + * @config_param2: [Bit31 : Bit0] mac_addr31to0 + * @config_param3: [Bit15 : Bit0] mac_addr47to32 + * [Bit31 : Bit16] reserved + */ +#define HTT_STAT_PEER_INFO_MAC_ADDR BIT(0) +#define HTT_STAT_DEFAULT_PEER_REQ_TYPE 0x7f + +/* Used to set different configs to the specified stats type.*/ +struct htt_ext_stats_cfg_params { + u32 cfg0; + u32 cfg1; + u32 cfg2; + u32 cfg3; +}; + +enum vdev_stats_offload_timer_duration { + ATH12K_STATS_TIMER_DUR_500MS = 1, + ATH12K_STATS_TIMER_DUR_1SEC = 2, + ATH12K_STATS_TIMER_DUR_2SEC = 3, +}; + +#define ATH12K_HTT_MAC_ADDR_L32_0 GENMASK(7, 0) +#define ATH12K_HTT_MAC_ADDR_L32_1 GENMASK(15, 8) +#define ATH12K_HTT_MAC_ADDR_L32_2 GENMASK(23, 16) +#define ATH12K_HTT_MAC_ADDR_L32_3 GENMASK(31, 24) +#define ATH12K_HTT_MAC_ADDR_H16_0 GENMASK(7, 0) +#define ATH12K_HTT_MAC_ADDR_H16_1 GENMASK(15, 8) + +struct htt_mac_addr { + __le32 mac_addr_l32; + __le32 mac_addr_h16; +} __packed; + +#endif From 8d11716285b15ab11dadde1dd562c4cfa5a5771e Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:51 +0530 Subject: [PATCH 397/659] wifi: ath12k: Move HTT Rx specific code to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. HTT interface code is spread across multiple files (ex dp_tx.c, dp_rx.c etc) and this interface is independent of the underlying architecture Tx and Rx. Relocate HTT specific code from dp_rx.c to newly introduced file dp_htt.c for HTT interface. This new file is compiled as part of the common module ath12k.ko. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-19-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp_htt.c | 644 +++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_htt.h | 6 + drivers/net/wireless/ath/ath12k/dp_rx.c | 633 ---------------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 6 - 5 files changed, 651 insertions(+), 639 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.c diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index e72b52d5af6d6..70d4daa48c902 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -10,6 +10,7 @@ ath12k-y += core.o \ dp.o \ dp_tx.o \ dp_rx.o \ + dp_htt.o \ debug.o \ ce.o \ peer.o \ diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c new file mode 100644 index 0000000000000..00847d579b958 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -0,0 +1,644 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "core.h" +#include "peer.h" +#include "htc.h" +#include "dp_htt.h" +#include "debugfs_htt_stats.h" + +static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, + u16 peer_id) +{ + int i; + + for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) { + if (ppdu_stats->user_stats[i].is_valid_peer_id) { + if (peer_id == ppdu_stats->user_stats[i].peer_id) + return i; + } else { + return i; + } + } + + return -EINVAL; +} + +static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab, + u16 tag, u16 len, const void *ptr, + void *data) +{ + const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status; + const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn; + const struct htt_ppdu_stats_user_rate *user_rate; + struct htt_ppdu_stats_info *ppdu_info; + struct htt_ppdu_user_stats *user_stats; + int cur_user; + u16 peer_id; + + ppdu_info = data; + + switch (tag) { + case HTT_PPDU_STATS_TAG_COMMON: + if (len < sizeof(struct htt_ppdu_stats_common)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + memcpy(&ppdu_info->ppdu_stats.common, ptr, + sizeof(struct htt_ppdu_stats_common)); + break; + case HTT_PPDU_STATS_TAG_USR_RATE: + if (len < sizeof(struct htt_ppdu_stats_user_rate)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + user_rate = ptr; + peer_id = le16_to_cpu(user_rate->sw_peer_id); + cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, + peer_id); + if (cur_user < 0) + return -EINVAL; + user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; + user_stats->peer_id = peer_id; + user_stats->is_valid_peer_id = true; + memcpy(&user_stats->rate, ptr, + sizeof(struct htt_ppdu_stats_user_rate)); + user_stats->tlv_flags |= BIT(tag); + break; + case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON: + if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + + cmplt_cmn = ptr; + peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id); + cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, + peer_id); + if (cur_user < 0) + return -EINVAL; + user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; + user_stats->peer_id = peer_id; + user_stats->is_valid_peer_id = true; + memcpy(&user_stats->cmpltn_cmn, ptr, + sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)); + user_stats->tlv_flags |= BIT(tag); + break; + case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS: + if (len < + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + + ba_status = ptr; + peer_id = le16_to_cpu(ba_status->sw_peer_id); + cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, + peer_id); + if (cur_user < 0) + return -EINVAL; + user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; + user_stats->peer_id = peer_id; + user_stats->is_valid_peer_id = true; + memcpy(&user_stats->ack_ba, ptr, + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); + user_stats->tlv_flags |= BIT(tag); + break; + } + return 0; +} + +int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, + int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, + const void *ptr, void *data), + void *data) +{ + const struct htt_tlv *tlv; + const void *begin = ptr; + u16 tlv_tag, tlv_len; + int ret = -EINVAL; + + while (len > 0) { + if (len < sizeof(*tlv)) { + ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", + ptr - begin, len, sizeof(*tlv)); + return -EINVAL; + } + tlv = (struct htt_tlv *)ptr; + tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG); + tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN); + ptr += sizeof(*tlv); + len -= sizeof(*tlv); + + if (tlv_len > len) { + ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", + tlv_tag, ptr - begin, len, tlv_len); + return -EINVAL; + } + ret = iter(ab, tlv_tag, tlv_len, ptr, data); + if (ret == -ENOMEM) + return ret; + + ptr += tlv_len; + len -= tlv_len; + } + return 0; +} + +static void +ath12k_update_per_peer_tx_stats(struct ath12k *ar, + struct htt_ppdu_stats *ppdu_stats, u8 user) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_peer *peer; + struct ath12k_link_sta *arsta; + struct htt_ppdu_stats_user_rate *user_rate; + struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats; + struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; + struct htt_ppdu_stats_common *common = &ppdu_stats->common; + int ret; + u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0; + u32 v, succ_bytes = 0; + u16 tones, rate = 0, succ_pkts = 0; + u32 tx_duration = 0; + u8 tid = HTT_PPDU_STATS_NON_QOS_TID; + u16 tx_retry_failed = 0, tx_retry_count = 0; + bool is_ampdu = false, is_ofdma; + + if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) + return; + + if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) { + is_ampdu = + HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags); + tx_retry_failed = + __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) - + __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success); + tx_retry_count = + HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); + } + + if (usr_stats->tlv_flags & + BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) { + succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes); + succ_pkts = le32_get_bits(usr_stats->ack_ba.info, + HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M); + tid = le32_get_bits(usr_stats->ack_ba.info, + HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM); + } + + if (common->fes_duration_us) + tx_duration = le32_to_cpu(common->fes_duration_us); + + user_rate = &usr_stats->rate; + flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags); + bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2; + nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1; + mcs = HTT_USR_RATE_MCS(user_rate->rate_flags); + sgi = HTT_USR_RATE_GI(user_rate->rate_flags); + dcm = HTT_USR_RATE_DCM(user_rate->rate_flags); + + ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1); + is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) || + (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA); + + /* Note: If host configured fixed rates and in some other special + * cases, the broadcast/management frames are sent in different rates. + * Firmware rate's control to be skipped for this? + */ + + if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) { + ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs); + return; + } + + if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) { + ath12k_warn(ab, "Invalid VHT mcs %d peer stats", mcs); + return; + } + + if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) { + ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats", + mcs, nss); + return; + } + + if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) { + ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs, + flags, + &rate_idx, + &rate); + if (ret < 0) + return; + } + + rcu_read_lock(); + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id); + + if (!peer || !peer->sta) { + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); + return; + } + + arsta = ath12k_peer_get_link_sta(ab, peer); + if (!arsta) { + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); + return; + } + + memset(&arsta->txrate, 0, sizeof(arsta->txrate)); + + arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); + + switch (flags) { + case WMI_RATE_PREAMBLE_OFDM: + arsta->txrate.legacy = rate; + break; + case WMI_RATE_PREAMBLE_CCK: + arsta->txrate.legacy = rate; + break; + case WMI_RATE_PREAMBLE_HT: + arsta->txrate.mcs = mcs + 8 * (nss - 1); + arsta->txrate.flags = RATE_INFO_FLAGS_MCS; + if (sgi) + arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case WMI_RATE_PREAMBLE_VHT: + arsta->txrate.mcs = mcs; + arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; + if (sgi) + arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case WMI_RATE_PREAMBLE_HE: + arsta->txrate.mcs = mcs; + arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS; + arsta->txrate.he_dcm = dcm; + arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); + tones = le16_to_cpu(user_rate->ru_end) - + le16_to_cpu(user_rate->ru_start) + 1; + v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones); + arsta->txrate.he_ru_alloc = v; + if (is_ofdma) + arsta->txrate.bw = RATE_INFO_BW_HE_RU; + break; + case WMI_RATE_PREAMBLE_EHT: + arsta->txrate.mcs = mcs; + arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; + arsta->txrate.he_dcm = dcm; + arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); + tones = le16_to_cpu(user_rate->ru_end) - + le16_to_cpu(user_rate->ru_start) + 1; + v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones); + arsta->txrate.eht_ru_alloc = v; + if (is_ofdma) + arsta->txrate.bw = RATE_INFO_BW_EHT_RU; + break; + } + + arsta->tx_retry_failed += tx_retry_failed; + arsta->tx_retry_count += tx_retry_count; + arsta->txrate.nss = nss; + arsta->tx_duration += tx_duration; + memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); + + /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. + * So skip peer stats update for mgmt packets. + */ + if (tid < HTT_PPDU_STATS_NON_QOS_TID) { + memset(peer_stats, 0, sizeof(*peer_stats)); + peer_stats->succ_pkts = succ_pkts; + peer_stats->succ_bytes = succ_bytes; + peer_stats->is_ampdu = is_ampdu; + peer_stats->duration = tx_duration; + peer_stats->ba_fails = + HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); + } + + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); +} + +static void ath12k_htt_update_ppdu_stats(struct ath12k *ar, + struct htt_ppdu_stats *ppdu_stats) +{ + u8 user; + + for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++) + ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user); +} + +static +struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, + u32 ppdu_id) +{ + struct htt_ppdu_stats_info *ppdu_info; + + lockdep_assert_held(&ar->data_lock); + if (!list_empty(&ar->ppdu_stats_info)) { + list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { + if (ppdu_info->ppdu_id == ppdu_id) + return ppdu_info; + } + + if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { + ppdu_info = list_first_entry(&ar->ppdu_stats_info, + typeof(*ppdu_info), list); + list_del(&ppdu_info->list); + ar->ppdu_stat_list_depth--; + ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); + kfree(ppdu_info); + } + } + + ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); + if (!ppdu_info) + return NULL; + + list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); + ar->ppdu_stat_list_depth++; + + return ppdu_info; +} + +static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, + struct htt_ppdu_user_stats *usr_stats) +{ + peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id); + peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0); + peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end); + peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start); + peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1); + peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags); + peer->ppdu_stats_delayba.resp_rate_flags = + le32_to_cpu(usr_stats->rate.resp_rate_flags); + + peer->delayba_flag = true; +} + +static void ath12k_copy_to_bar(struct ath12k_peer *peer, + struct htt_ppdu_user_stats *usr_stats) +{ + usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id); + usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0); + usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end); + usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start); + usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1); + usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags); + usr_stats->rate.resp_rate_flags = + cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags); + + peer->delayba_flag = false; +} + +static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ath12k_htt_ppdu_stats_msg *msg; + struct htt_ppdu_stats_info *ppdu_info; + struct ath12k_peer *peer = NULL; + struct htt_ppdu_user_stats *usr_stats = NULL; + u32 peer_id = 0; + struct ath12k *ar; + int ret, i; + u8 pdev_id; + u32 ppdu_id, len; + + msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; + len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE); + if (len > (skb->len - struct_size(msg, data, 0))) { + ath12k_warn(ab, + "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n", + len, skb->len); + return -EINVAL; + } + + pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); + ppdu_id = le32_to_cpu(msg->ppdu_id); + + rcu_read_lock(); + ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); + if (!ar) { + ret = -EINVAL; + goto exit; + } + + spin_lock_bh(&ar->data_lock); + ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id); + if (!ppdu_info) { + spin_unlock_bh(&ar->data_lock); + ret = -EINVAL; + goto exit; + } + + ppdu_info->ppdu_id = ppdu_id; + ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len, + ath12k_htt_tlv_ppdu_stats_parse, + (void *)ppdu_info); + if (ret) { + spin_unlock_bh(&ar->data_lock); + ath12k_warn(ab, "Failed to parse tlv %d\n", ret); + goto exit; + } + + if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { + spin_unlock_bh(&ar->data_lock); + ath12k_warn(ab, + "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", + ppdu_info->ppdu_stats.common.num_users, + HTT_PPDU_STATS_MAX_USERS); + ret = -EINVAL; + goto exit; + } + + /* back up data rate tlv for all peers */ + if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && + ppdu_info->delay_ba) { + for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { + peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + spin_unlock_bh(&ab->base_lock); + continue; + } + + usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; + if (usr_stats->delay_ba) + ath12k_copy_to_delay_stats(peer, usr_stats); + spin_unlock_bh(&ab->base_lock); + } + } + + /* restore all peers' data rate tlv to mu-bar tlv */ + if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { + for (i = 0; i < ppdu_info->bar_num_users; i++) { + peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + spin_unlock_bh(&ab->base_lock); + continue; + } + + usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; + if (peer->delayba_flag) + ath12k_copy_to_bar(peer, usr_stats); + spin_unlock_bh(&ab->base_lock); + } + } + + spin_unlock_bh(&ar->data_lock); + +exit: + rcu_read_unlock(); + + return ret; +} + +static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ath12k_htt_mlo_offset_msg *msg; + struct ath12k_pdev *pdev; + struct ath12k *ar; + u8 pdev_id; + + msg = (struct ath12k_htt_mlo_offset_msg *)skb->data; + pdev_id = u32_get_bits(__le32_to_cpu(msg->info), + HTT_T2H_MLO_OFFSET_INFO_PDEV_ID); + + rcu_read_lock(); + ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); + if (!ar) { + /* It is possible that the ar is not yet active (started). + * The above function will only look for the active pdev + * and hence %NULL return is possible. Just silently + * discard this message + */ + goto exit; + } + + spin_lock_bh(&ar->data_lock); + pdev = ar->pdev; + + pdev->timestamp.info = __le32_to_cpu(msg->info); + pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us); + pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us); + pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo); + pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi); + pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks); + pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks); + pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer); + + spin_unlock_bh(&ar->data_lock); +exit: + rcu_read_unlock(); +} + +void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ath12k_dp *dp = &ab->dp; + struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data; + enum htt_t2h_msg_type type; + u16 peer_id; + u8 vdev_id; + u8 mac_addr[ETH_ALEN]; + u16 peer_mac_h16; + u16 ast_hash = 0; + u16 hw_peer_id; + + type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE); + + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); + + switch (type) { + case HTT_T2H_MSG_TYPE_VERSION_CONF: + dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version, + HTT_T2H_VERSION_CONF_MAJOR); + dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version, + HTT_T2H_VERSION_CONF_MINOR); + complete(&dp->htt_tgt_version_received); + break; + /* TODO: remove unused peer map versions after testing */ + case HTT_T2H_MSG_TYPE_PEER_MAP: + vdev_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_VDEV_ID); + peer_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_PEER_ID); + peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); + ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), + peer_mac_h16, mac_addr); + ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); + break; + case HTT_T2H_MSG_TYPE_PEER_MAP2: + vdev_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_VDEV_ID); + peer_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_PEER_ID); + peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); + ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), + peer_mac_h16, mac_addr); + ast_hash = le32_get_bits(resp->peer_map_ev.info2, + HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL); + hw_peer_id = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID); + ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); + break; + case HTT_T2H_MSG_TYPE_PEER_MAP3: + vdev_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_VDEV_ID); + peer_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_PEER_ID); + peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); + ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), + peer_mac_h16, mac_addr); + ast_hash = le32_get_bits(resp->peer_map_ev.info2, + HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL); + hw_peer_id = le32_get_bits(resp->peer_map_ev.info2, + HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID); + ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); + break; + case HTT_T2H_MSG_TYPE_PEER_UNMAP: + case HTT_T2H_MSG_TYPE_PEER_UNMAP2: + peer_id = le32_get_bits(resp->peer_unmap_ev.info, + HTT_T2H_PEER_UNMAP_INFO_PEER_ID); + ath12k_peer_unmap_event(ab, peer_id); + break; + case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: + ath12k_htt_pull_ppdu_stats(ab, skb); + break; + case HTT_T2H_MSG_TYPE_EXT_STATS_CONF: + ath12k_debugfs_htt_ext_stats_handler(ab, skb); + break; + case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND: + ath12k_htt_mlo_offset_event_handler(ab, skb); + break; + default: + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n", + type); + break; + } + + dev_kfree_skb_any(skb); +} +EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h index ce9064628d343..9ae3a750f6081 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.h +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -1514,4 +1514,10 @@ struct htt_mac_addr { __le32 mac_addr_h16; } __packed; +int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, + int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, + const void *ptr, void *data), + void *data); +void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, + struct sk_buff *skb); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index d2c206fccb201..c2a32b61d62ff 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -850,639 +850,6 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, return ret; } -static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, - u16 peer_id) -{ - int i; - - for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) { - if (ppdu_stats->user_stats[i].is_valid_peer_id) { - if (peer_id == ppdu_stats->user_stats[i].peer_id) - return i; - } else { - return i; - } - } - - return -EINVAL; -} - -static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab, - u16 tag, u16 len, const void *ptr, - void *data) -{ - const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status; - const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn; - const struct htt_ppdu_stats_user_rate *user_rate; - struct htt_ppdu_stats_info *ppdu_info; - struct htt_ppdu_user_stats *user_stats; - int cur_user; - u16 peer_id; - - ppdu_info = data; - - switch (tag) { - case HTT_PPDU_STATS_TAG_COMMON: - if (len < sizeof(struct htt_ppdu_stats_common)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - memcpy(&ppdu_info->ppdu_stats.common, ptr, - sizeof(struct htt_ppdu_stats_common)); - break; - case HTT_PPDU_STATS_TAG_USR_RATE: - if (len < sizeof(struct htt_ppdu_stats_user_rate)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - user_rate = ptr; - peer_id = le16_to_cpu(user_rate->sw_peer_id); - cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, - peer_id); - if (cur_user < 0) - return -EINVAL; - user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; - user_stats->peer_id = peer_id; - user_stats->is_valid_peer_id = true; - memcpy(&user_stats->rate, ptr, - sizeof(struct htt_ppdu_stats_user_rate)); - user_stats->tlv_flags |= BIT(tag); - break; - case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON: - if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - - cmplt_cmn = ptr; - peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id); - cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, - peer_id); - if (cur_user < 0) - return -EINVAL; - user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; - user_stats->peer_id = peer_id; - user_stats->is_valid_peer_id = true; - memcpy(&user_stats->cmpltn_cmn, ptr, - sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)); - user_stats->tlv_flags |= BIT(tag); - break; - case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS: - if (len < - sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - - ba_status = ptr; - peer_id = le16_to_cpu(ba_status->sw_peer_id); - cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, - peer_id); - if (cur_user < 0) - return -EINVAL; - user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; - user_stats->peer_id = peer_id; - user_stats->is_valid_peer_id = true; - memcpy(&user_stats->ack_ba, ptr, - sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); - user_stats->tlv_flags |= BIT(tag); - break; - } - return 0; -} - -int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, - int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, - const void *ptr, void *data), - void *data) -{ - const struct htt_tlv *tlv; - const void *begin = ptr; - u16 tlv_tag, tlv_len; - int ret = -EINVAL; - - while (len > 0) { - if (len < sizeof(*tlv)) { - ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", - ptr - begin, len, sizeof(*tlv)); - return -EINVAL; - } - tlv = (struct htt_tlv *)ptr; - tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG); - tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN); - ptr += sizeof(*tlv); - len -= sizeof(*tlv); - - if (tlv_len > len) { - ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", - tlv_tag, ptr - begin, len, tlv_len); - return -EINVAL; - } - ret = iter(ab, tlv_tag, tlv_len, ptr, data); - if (ret == -ENOMEM) - return ret; - - ptr += tlv_len; - len -= tlv_len; - } - return 0; -} - -static void -ath12k_update_per_peer_tx_stats(struct ath12k *ar, - struct htt_ppdu_stats *ppdu_stats, u8 user) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; - struct ath12k_link_sta *arsta; - struct htt_ppdu_stats_user_rate *user_rate; - struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats; - struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; - struct htt_ppdu_stats_common *common = &ppdu_stats->common; - int ret; - u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0; - u32 v, succ_bytes = 0; - u16 tones, rate = 0, succ_pkts = 0; - u32 tx_duration = 0; - u8 tid = HTT_PPDU_STATS_NON_QOS_TID; - u16 tx_retry_failed = 0, tx_retry_count = 0; - bool is_ampdu = false, is_ofdma; - - if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) - return; - - if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) { - is_ampdu = - HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags); - tx_retry_failed = - __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) - - __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success); - tx_retry_count = - HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + - HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); - } - - if (usr_stats->tlv_flags & - BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) { - succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes); - succ_pkts = le32_get_bits(usr_stats->ack_ba.info, - HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M); - tid = le32_get_bits(usr_stats->ack_ba.info, - HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM); - } - - if (common->fes_duration_us) - tx_duration = le32_to_cpu(common->fes_duration_us); - - user_rate = &usr_stats->rate; - flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags); - bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2; - nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1; - mcs = HTT_USR_RATE_MCS(user_rate->rate_flags); - sgi = HTT_USR_RATE_GI(user_rate->rate_flags); - dcm = HTT_USR_RATE_DCM(user_rate->rate_flags); - - ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1); - is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) || - (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA); - - /* Note: If host configured fixed rates and in some other special - * cases, the broadcast/management frames are sent in different rates. - * Firmware rate's control to be skipped for this? - */ - - if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs); - return; - } - - if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ab, "Invalid VHT mcs %d peer stats", mcs); - return; - } - - if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) { - ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats", - mcs, nss); - return; - } - - if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) { - ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs, - flags, - &rate_idx, - &rate); - if (ret < 0) - return; - } - - rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id); - - if (!peer || !peer->sta) { - spin_unlock_bh(&ab->base_lock); - rcu_read_unlock(); - return; - } - - arsta = ath12k_peer_get_link_sta(ab, peer); - if (!arsta) { - spin_unlock_bh(&ab->base_lock); - rcu_read_unlock(); - return; - } - - memset(&arsta->txrate, 0, sizeof(arsta->txrate)); - - arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); - - switch (flags) { - case WMI_RATE_PREAMBLE_OFDM: - arsta->txrate.legacy = rate; - break; - case WMI_RATE_PREAMBLE_CCK: - arsta->txrate.legacy = rate; - break; - case WMI_RATE_PREAMBLE_HT: - arsta->txrate.mcs = mcs + 8 * (nss - 1); - arsta->txrate.flags = RATE_INFO_FLAGS_MCS; - if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case WMI_RATE_PREAMBLE_VHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; - if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case WMI_RATE_PREAMBLE_HE: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); - tones = le16_to_cpu(user_rate->ru_end) - - le16_to_cpu(user_rate->ru_start) + 1; - v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones); - arsta->txrate.he_ru_alloc = v; - if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_HE_RU; - break; - case WMI_RATE_PREAMBLE_EHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); - tones = le16_to_cpu(user_rate->ru_end) - - le16_to_cpu(user_rate->ru_start) + 1; - v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones); - arsta->txrate.eht_ru_alloc = v; - if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_EHT_RU; - break; - } - - arsta->tx_retry_failed += tx_retry_failed; - arsta->tx_retry_count += tx_retry_count; - arsta->txrate.nss = nss; - arsta->tx_duration += tx_duration; - memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); - - /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. - * So skip peer stats update for mgmt packets. - */ - if (tid < HTT_PPDU_STATS_NON_QOS_TID) { - memset(peer_stats, 0, sizeof(*peer_stats)); - peer_stats->succ_pkts = succ_pkts; - peer_stats->succ_bytes = succ_bytes; - peer_stats->is_ampdu = is_ampdu; - peer_stats->duration = tx_duration; - peer_stats->ba_fails = - HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + - HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); - } - - spin_unlock_bh(&ab->base_lock); - rcu_read_unlock(); -} - -static void ath12k_htt_update_ppdu_stats(struct ath12k *ar, - struct htt_ppdu_stats *ppdu_stats) -{ - u8 user; - - for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++) - ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user); -} - -static -struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, - u32 ppdu_id) -{ - struct htt_ppdu_stats_info *ppdu_info; - - lockdep_assert_held(&ar->data_lock); - if (!list_empty(&ar->ppdu_stats_info)) { - list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { - if (ppdu_info->ppdu_id == ppdu_id) - return ppdu_info; - } - - if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { - ppdu_info = list_first_entry(&ar->ppdu_stats_info, - typeof(*ppdu_info), list); - list_del(&ppdu_info->list); - ar->ppdu_stat_list_depth--; - ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); - kfree(ppdu_info); - } - } - - ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); - if (!ppdu_info) - return NULL; - - list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); - ar->ppdu_stat_list_depth++; - - return ppdu_info; -} - -static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, - struct htt_ppdu_user_stats *usr_stats) -{ - peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id); - peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0); - peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end); - peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start); - peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1); - peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags); - peer->ppdu_stats_delayba.resp_rate_flags = - le32_to_cpu(usr_stats->rate.resp_rate_flags); - - peer->delayba_flag = true; -} - -static void ath12k_copy_to_bar(struct ath12k_peer *peer, - struct htt_ppdu_user_stats *usr_stats) -{ - usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id); - usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0); - usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end); - usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start); - usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1); - usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags); - usr_stats->rate.resp_rate_flags = - cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags); - - peer->delayba_flag = false; -} - -static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ath12k_htt_ppdu_stats_msg *msg; - struct htt_ppdu_stats_info *ppdu_info; - struct ath12k_peer *peer = NULL; - struct htt_ppdu_user_stats *usr_stats = NULL; - u32 peer_id = 0; - struct ath12k *ar; - int ret, i; - u8 pdev_id; - u32 ppdu_id, len; - - msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; - len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE); - if (len > (skb->len - struct_size(msg, data, 0))) { - ath12k_warn(ab, - "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n", - len, skb->len); - return -EINVAL; - } - - pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); - ppdu_id = le32_to_cpu(msg->ppdu_id); - - rcu_read_lock(); - ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { - ret = -EINVAL; - goto exit; - } - - spin_lock_bh(&ar->data_lock); - ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id); - if (!ppdu_info) { - spin_unlock_bh(&ar->data_lock); - ret = -EINVAL; - goto exit; - } - - ppdu_info->ppdu_id = ppdu_id; - ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len, - ath12k_htt_tlv_ppdu_stats_parse, - (void *)ppdu_info); - if (ret) { - spin_unlock_bh(&ar->data_lock); - ath12k_warn(ab, "Failed to parse tlv %d\n", ret); - goto exit; - } - - if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { - spin_unlock_bh(&ar->data_lock); - ath12k_warn(ab, - "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", - ppdu_info->ppdu_stats.common.num_users, - HTT_PPDU_STATS_MAX_USERS); - ret = -EINVAL; - goto exit; - } - - /* back up data rate tlv for all peers */ - if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && - (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && - ppdu_info->delay_ba) { - for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { - peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - spin_unlock_bh(&ab->base_lock); - continue; - } - - usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; - if (usr_stats->delay_ba) - ath12k_copy_to_delay_stats(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); - } - } - - /* restore all peers' data rate tlv to mu-bar tlv */ - if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR && - (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { - for (i = 0; i < ppdu_info->bar_num_users; i++) { - peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - spin_unlock_bh(&ab->base_lock); - continue; - } - - usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; - if (peer->delayba_flag) - ath12k_copy_to_bar(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); - } - } - - spin_unlock_bh(&ar->data_lock); - -exit: - rcu_read_unlock(); - - return ret; -} - -static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ath12k_htt_mlo_offset_msg *msg; - struct ath12k_pdev *pdev; - struct ath12k *ar; - u8 pdev_id; - - msg = (struct ath12k_htt_mlo_offset_msg *)skb->data; - pdev_id = u32_get_bits(__le32_to_cpu(msg->info), - HTT_T2H_MLO_OFFSET_INFO_PDEV_ID); - - rcu_read_lock(); - ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { - /* It is possible that the ar is not yet active (started). - * The above function will only look for the active pdev - * and hence %NULL return is possible. Just silently - * discard this message - */ - goto exit; - } - - spin_lock_bh(&ar->data_lock); - pdev = ar->pdev; - - pdev->timestamp.info = __le32_to_cpu(msg->info); - pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us); - pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us); - pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo); - pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi); - pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks); - pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks); - pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer); - - spin_unlock_bh(&ar->data_lock); -exit: - rcu_read_unlock(); -} - -void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ath12k_dp *dp = &ab->dp; - struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data; - enum htt_t2h_msg_type type; - u16 peer_id; - u8 vdev_id; - u8 mac_addr[ETH_ALEN]; - u16 peer_mac_h16; - u16 ast_hash = 0; - u16 hw_peer_id; - - type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE); - - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); - - switch (type) { - case HTT_T2H_MSG_TYPE_VERSION_CONF: - dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version, - HTT_T2H_VERSION_CONF_MAJOR); - dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version, - HTT_T2H_VERSION_CONF_MINOR); - complete(&dp->htt_tgt_version_received); - break; - /* TODO: remove unused peer map versions after testing */ - case HTT_T2H_MSG_TYPE_PEER_MAP: - vdev_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_VDEV_ID); - peer_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_PEER_ID); - peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); - ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), - peer_mac_h16, mac_addr); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); - break; - case HTT_T2H_MSG_TYPE_PEER_MAP2: - vdev_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_VDEV_ID); - peer_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_PEER_ID); - peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); - ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), - peer_mac_h16, mac_addr); - ast_hash = le32_get_bits(resp->peer_map_ev.info2, - HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL); - hw_peer_id = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); - break; - case HTT_T2H_MSG_TYPE_PEER_MAP3: - vdev_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_VDEV_ID); - peer_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_PEER_ID); - peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); - ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), - peer_mac_h16, mac_addr); - ast_hash = le32_get_bits(resp->peer_map_ev.info2, - HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL); - hw_peer_id = le32_get_bits(resp->peer_map_ev.info2, - HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); - break; - case HTT_T2H_MSG_TYPE_PEER_UNMAP: - case HTT_T2H_MSG_TYPE_PEER_UNMAP2: - peer_id = le32_get_bits(resp->peer_unmap_ev.info, - HTT_T2H_PEER_UNMAP_INFO_PEER_ID); - ath12k_peer_unmap_event(ab, peer_id); - break; - case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: - ath12k_htt_pull_ppdu_stats(ab, skb); - break; - case HTT_T2H_MSG_TYPE_EXT_STATS_CONF: - ath12k_debugfs_htt_ext_stats_handler(ab, skb); - break; - case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND: - ath12k_htt_mlo_offset_event_handler(ab, skb); - break; - default: - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n", - type); - break; - } - - dev_kfree_skb_any(skb); -} -EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); - struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first) { diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index fc1c4ac161c1a..a6b6fea4c5e2e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -398,8 +398,6 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type); -void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, - struct sk_buff *skb); int ath12k_dp_rx_pdev_reo_setup(struct ath12k_base *ab); void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab); int ath12k_dp_rx_htt_setup(struct ath12k_base *ab); @@ -424,10 +422,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, - int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, - const void *ptr, void *data), - void *data); void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct ath12k_dp_rx_info *rx_info); From 4415fdd256fabeedbe9346c12368d9adf947abe7 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:52 +0530 Subject: [PATCH 398/659] wifi: ath12k: Move HTT Tx specific code to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. Relocate HTT specific code from dp_tx.c to dp_htt.c introduced for HTT interface. These code is compiled as part of the common module ath12k.ko. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-20-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 2 - drivers/net/wireless/ath/ath12k/dp_htt.c | 683 +++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_htt.h | 24 +- drivers/net/wireless/ath/ath12k/dp_tx.c | 682 ---------------------- drivers/net/wireless/ath/ath12k/dp_tx.h | 18 - 5 files changed, 705 insertions(+), 704 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9c860cc8d7d98..852b35ff1ecd4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -445,8 +445,6 @@ void ath12k_dp_partner_cc_init(struct ath12k_base *ab); int ath12k_dp_pdev_alloc(struct ath12k_base *ab); void ath12k_dp_pdev_pre_alloc(struct ath12k *ar); void ath12k_dp_pdev_free(struct ath12k_base *ab); -int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type); int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr); void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr); void ath12k_dp_srng_cleanup(struct ath12k_base *ab, struct dp_srng *ring); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 00847d579b958..45aa8ae86a14c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -9,6 +9,7 @@ #include "htc.h" #include "dp_htt.h" #include "debugfs_htt_stats.h" +#include "debugfs.h" static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, u16 peer_id) @@ -642,3 +643,685 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); + +static int +ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, + int mac_id, u32 ring_id, + enum hal_ring_type ring_type, + enum htt_srng_ring_type *htt_ring_type, + enum htt_srng_ring_id *htt_ring_id) +{ + int ret = 0; + + switch (ring_type) { + case HAL_RXDMA_BUF: + /* for some targets, host fills rx buffer to fw and fw fills to + * rxbuf ring for each rxdma + */ + if (!ab->hw_params->rx_mac_buf_ring) { + if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 || + ring_id == HAL_SRNG_SW2RXDMA_BUF1)) { + ret = -EINVAL; + } + *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + } else { + if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) { + *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING; + *htt_ring_type = HTT_SW_TO_SW_RING; + } else { + *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + } + } + break; + case HAL_RXDMA_DST: + *htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING; + *htt_ring_type = HTT_HW_TO_SW_RING; + break; + case HAL_RXDMA_MONITOR_BUF: + *htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + break; + case HAL_RXDMA_MONITOR_STATUS: + *htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + break; + case HAL_RXDMA_MONITOR_DST: + *htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING; + *htt_ring_type = HTT_HW_TO_SW_RING; + break; + case HAL_RXDMA_MONITOR_DESC: + *htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + break; + default: + ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type); + ret = -EINVAL; + } + return ret; +} + +int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type) +{ + struct htt_srng_setup_cmd *cmd; + struct hal_srng *srng = &ab->hal.srng_list[ring_id]; + struct hal_srng_params params; + struct sk_buff *skb; + u32 ring_entry_sz; + int len = sizeof(*cmd); + dma_addr_t hp_addr, tp_addr; + enum htt_srng_ring_type htt_ring_type; + enum htt_srng_ring_id htt_ring_id; + int ret; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + memset(¶ms, 0, sizeof(params)); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + + hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng); + tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng); + + ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, + ring_type, &htt_ring_type, + &htt_ring_id); + if (ret) + goto err_free; + + skb_put(skb, len); + cmd = (struct htt_srng_setup_cmd *)skb->data; + cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP, + HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE); + if (htt_ring_type == HTT_SW_TO_HW_RING || + htt_ring_type == HTT_HW_TO_SW_RING) + cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id), + HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); + else + cmd->info0 |= le32_encode_bits(mac_id, + HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); + cmd->info0 |= le32_encode_bits(htt_ring_type, + HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE); + cmd->info0 |= le32_encode_bits(htt_ring_id, + HTT_SRNG_SETUP_CMD_INFO0_RING_ID); + + cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr & + HAL_ADDR_LSB_REG_MASK); + + cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >> + HAL_ADDR_MSB_REG_SHIFT); + + ret = ath12k_hal_srng_get_entrysize(ab, ring_type); + if (ret < 0) + goto err_free; + + ring_entry_sz = ret; + + ring_entry_sz >>= 2; + cmd->info1 = le32_encode_bits(ring_entry_sz, + HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE); + cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz, + HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE); + cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), + HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP); + cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), + HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP); + cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP), + HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP); + if (htt_ring_type == HTT_SW_TO_HW_RING) + cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS); + + cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr)); + cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr)); + + cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr)); + cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr)); + + cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr)); + cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr)); + cmd->msi_data = cpu_to_le32(params.msi_data); + + cmd->intr_info = + le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz, + HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH); + cmd->intr_info |= + le32_encode_bits(params.intr_timer_thres_us >> 3, + HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH); + + cmd->info2 = 0; + if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { + cmd->info2 = le32_encode_bits(params.low_threshold, + HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH); + } + + ath12k_dbg(ab, ATH12K_DBG_HAL, + "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n", + __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi, + cmd->msi_data); + + ath12k_dbg(ab, ATH12K_DBG_HAL, + "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n", + ring_id, ring_type, cmd->intr_info, cmd->info2); + + ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; + + return 0; + +err_free: + dev_kfree_skb_any(skb); + + return ret; +} + +#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) + +int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct sk_buff *skb; + struct htt_ver_req_cmd *cmd; + int len = sizeof(*cmd); + u32 metadata_version; + int ret; + + init_completion(&dp->htt_tgt_version_received); + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + skb_put(skb, len); + cmd = (struct htt_ver_req_cmd *)skb->data; + cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ, + HTT_OPTION_TAG); + metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 : + HTT_OPTION_TCL_METADATA_VER_V2; + + cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION, + HTT_OPTION_TAG) | + le32_encode_bits(HTT_TCL_METADATA_VER_SZ, + HTT_OPTION_LEN) | + le32_encode_bits(metadata_version, + HTT_OPTION_VALUE); + + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); + if (ret) { + dev_kfree_skb_any(skb); + return ret; + } + + ret = wait_for_completion_timeout(&dp->htt_tgt_version_received, + HTT_TARGET_VERSION_TIMEOUT_HZ); + if (ret == 0) { + ath12k_warn(ab, "htt target version request timed out\n"); + return -ETIMEDOUT; + } + + if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) { + ath12k_err(ab, "unsupported htt major version %d supported version is %d\n", + dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR); + return -EOPNOTSUPP; + } + + return 0; +} + +int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct sk_buff *skb; + struct htt_ppdu_stats_cfg_cmd *cmd; + int len = sizeof(*cmd); + u8 pdev_mask; + int ret; + int i; + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + skb_put(skb, len); + cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data; + cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG, + HTT_PPDU_STATS_CFG_MSG_TYPE); + + pdev_mask = 1 << (i + ar->pdev_idx); + cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID); + cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK); + + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); + if (ret) { + dev_kfree_skb_any(skb); + return ret; + } + } + + return 0; +} + +int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int rx_buf_size, + struct htt_rx_ring_tlv_filter *tlv_filter) +{ + struct htt_rx_ring_selection_cfg_cmd *cmd; + struct hal_srng *srng = &ab->hal.srng_list[ring_id]; + struct hal_srng_params params; + struct sk_buff *skb; + int len = sizeof(*cmd); + enum htt_srng_ring_type htt_ring_type; + enum htt_srng_ring_id htt_ring_id; + int ret; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + memset(¶ms, 0, sizeof(params)); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + + ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, + ring_type, &htt_ring_type, + &htt_ring_id); + if (ret) + goto err_free; + + skb_put(skb, len); + cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data; + cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); + if (htt_ring_type == HTT_SW_TO_HW_RING || + htt_ring_type == HTT_HW_TO_SW_RING) + cmd->info0 |= + le32_encode_bits(DP_SW2HW_MACID(mac_id), + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + else + cmd->info0 |= + le32_encode_bits(mac_id, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + cmd->info0 |= le32_encode_bits(htt_ring_id, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS); + cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID); + cmd->info0 |= + le32_encode_bits(tlv_filter->drop_threshold_valid, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL); + cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON); + + cmd->info1 = le32_encode_bits(rx_buf_size, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE); + cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); + cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); + cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); + cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0); + cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1); + cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2); + cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3); + cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter); + + cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD); + cmd->info2 |= + le32_encode_bits(tlv_filter->enable_log_mgmt_type, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE); + cmd->info2 |= + le32_encode_bits(tlv_filter->enable_log_ctrl_type, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE); + cmd->info2 |= + le32_encode_bits(tlv_filter->enable_log_data_type, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE); + + cmd->info3 = + le32_encode_bits(tlv_filter->enable_rx_tlv_offset, + HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET); + cmd->info3 |= + le32_encode_bits(tlv_filter->rx_tlv_offset, + HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET); + + if (tlv_filter->offset_valid) { + cmd->rx_packet_offset = + le32_encode_bits(tlv_filter->rx_packet_offset, + HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET); + + cmd->rx_packet_offset |= + le32_encode_bits(tlv_filter->rx_header_offset, + HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET); + + cmd->rx_mpdu_offset = + le32_encode_bits(tlv_filter->rx_mpdu_end_offset, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET); + + cmd->rx_mpdu_offset |= + le32_encode_bits(tlv_filter->rx_mpdu_start_offset, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET); + + cmd->rx_msdu_offset = + le32_encode_bits(tlv_filter->rx_msdu_end_offset, + HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET); + + cmd->rx_msdu_offset |= + le32_encode_bits(tlv_filter->rx_msdu_start_offset, + HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET); + + cmd->rx_attn_offset = + le32_encode_bits(tlv_filter->rx_attn_offset, + HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET); + } + + if (tlv_filter->rx_mpdu_start_wmask > 0 && + tlv_filter->rx_msdu_end_wmask > 0) { + cmd->info2 |= + le32_encode_bits(true, + HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET); + cmd->rx_mpdu_start_end_mask = + le32_encode_bits(tlv_filter->rx_mpdu_start_wmask, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK); + /* mpdu_end is not used for any hardwares so far + * please assign it in future if any chip is + * using through hal ops + */ + cmd->rx_mpdu_start_end_mask |= + le32_encode_bits(tlv_filter->rx_mpdu_end_wmask, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK); + cmd->rx_msdu_end_word_mask = + le32_encode_bits(tlv_filter->rx_msdu_end_wmask, + HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); + } + + ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; + + return 0; + +err_free: + dev_kfree_skb_any(skb); + + return ret; +} + +int +ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, + struct htt_ext_stats_cfg_params *cfg_params, + u64 cookie) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct sk_buff *skb; + struct htt_ext_stats_cfg_cmd *cmd; + int len = sizeof(*cmd); + int ret; + u32 pdev_id; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + skb_put(skb, len); + + cmd = (struct htt_ext_stats_cfg_cmd *)skb->data; + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG; + + pdev_id = ath12k_mac_get_target_pdev_id(ar); + cmd->hdr.pdev_mask = 1 << pdev_id; + + cmd->hdr.stats_type = type; + cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0); + cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1); + cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2); + cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3); + cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie)); + cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie)); + + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); + if (ret) { + ath12k_warn(ab, "failed to send htt type stats request: %d", + ret); + dev_kfree_skb_any(skb); + return ret; + } + + return 0; +} + +int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset) +{ + struct ath12k_base *ab = ar->ab; + int ret; + + ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset); + if (ret) { + ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret); + return ret; + } + + return 0; +} + +int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) +{ + struct ath12k_base *ab = ar->ab; + struct htt_rx_ring_tlv_filter tlv_filter = {}; + int ret, ring_id, i; + + tlv_filter.offset_valid = false; + + if (!reset) { + tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING; + + tlv_filter.drop_threshold_valid = true; + tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE; + + tlv_filter.enable_log_mgmt_type = true; + tlv_filter.enable_log_ctrl_type = true; + tlv_filter.enable_log_data_type = true; + + tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH; + tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH; + tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH; + + tlv_filter.enable_rx_tlv_offset = true; + tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET; + + tlv_filter.pkt_filter_flags0 = + HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 | + HTT_RX_MON_MO_MGMT_FILTER_FLAGS0; + tlv_filter.pkt_filter_flags1 = + HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 | + HTT_RX_MON_MO_MGMT_FILTER_FLAGS1; + tlv_filter.pkt_filter_flags2 = + HTT_RX_MON_FP_CTRL_FILTER_FLASG2 | + HTT_RX_MON_MO_CTRL_FILTER_FLASG2; + tlv_filter.pkt_filter_flags3 = + HTT_RX_MON_FP_CTRL_FILTER_FLASG3 | + HTT_RX_MON_MO_CTRL_FILTER_FLASG3 | + HTT_RX_MON_FP_DATA_FILTER_FLASG3 | + HTT_RX_MON_MO_DATA_FILTER_FLASG3; + } else { + tlv_filter = ath12k_mac_mon_status_filter_default; + + if (ath12k_debugfs_is_extd_rx_stats_enabled(ar)) + tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar); + } + + if (ab->hw_params->rxdma1_enable) { + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, + ar->dp.mac_id + i, + HAL_RXDMA_MONITOR_DST, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + if (ret) { + ath12k_err(ab, + "failed to setup filter for monitor buf %d\n", + ret); + return ret; + } + } + return 0; + } + + if (!reset) { + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = ab->dp.rx_mac_buf_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, + i, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + if (ret) { + ath12k_err(ab, + "failed to setup filter for mon rx buf %d\n", + ret); + return ret; + } + } + } + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; + if (!reset) { + tlv_filter.rx_filter = + HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; + } + + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, + i, + HAL_RXDMA_MONITOR_STATUS, + RX_MON_STATUS_BUF_SIZE, + &tlv_filter); + if (ret) { + ath12k_err(ab, + "failed to setup filter for mon status buf %d\n", + ret); + return ret; + } + } + + return 0; +} + +int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int tx_buf_size, + struct htt_tx_ring_tlv_filter *htt_tlv_filter) +{ + struct htt_tx_ring_selection_cfg_cmd *cmd; + struct hal_srng *srng = &ab->hal.srng_list[ring_id]; + struct hal_srng_params params; + struct sk_buff *skb; + int len = sizeof(*cmd); + enum htt_srng_ring_type htt_ring_type; + enum htt_srng_ring_id htt_ring_id; + int ret; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + memset(¶ms, 0, sizeof(params)); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + + ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, + ring_type, &htt_ring_type, + &htt_ring_id); + + if (ret) + goto err_free; + + skb_put(skb, len); + cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data; + cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG, + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); + if (htt_ring_type == HTT_SW_TO_HW_RING || + htt_ring_type == HTT_HW_TO_SW_RING) + cmd->info0 |= + le32_encode_bits(DP_SW2HW_MACID(mac_id), + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + else + cmd->info0 |= + le32_encode_bits(mac_id, + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + cmd->info0 |= le32_encode_bits(htt_ring_id, + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS); + + cmd->info1 |= + le32_encode_bits(tx_buf_size, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE); + + if (htt_tlv_filter->tx_mon_mgmt_filter) { + cmd->info1 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); + cmd->info1 |= + le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); + cmd->info2 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, + HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); + } + + if (htt_tlv_filter->tx_mon_data_filter) { + cmd->info1 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); + cmd->info1 |= + le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); + cmd->info2 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, + HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); + } + + if (htt_tlv_filter->tx_mon_ctrl_filter) { + cmd->info1 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); + cmd->info1 |= + le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); + cmd->info2 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, + HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); + } + + cmd->tlv_filter_mask_in0 = + cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags); + cmd->tlv_filter_mask_in1 = + cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0); + cmd->tlv_filter_mask_in2 = + cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1); + cmd->tlv_filter_mask_in3 = + cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2); + + ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; + + return 0; + +err_free: + dev_kfree_skb_any(skb); + return ret; +} diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h index 9ae3a750f6081..b13af1c69253d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.h +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -1514,10 +1514,30 @@ struct htt_mac_addr { __le32 mac_addr_h16; } __packed; +int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type); + +void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, + struct sk_buff *skb); int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, const void *ptr, void *data), void *data); -void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, - struct sk_buff *skb); +int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); +int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); +int +ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, + struct htt_ext_stats_cfg_params *cfg_params, + u64 cookie); +int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset); + +int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int rx_buf_size, + struct htt_rx_ring_tlv_filter *tlv_filter); +int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int tx_buf_size, + struct htt_tx_ring_tlv_filter *htt_tlv_filter); +int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index c7b0fc22c1a79..8d5e10781377e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -200,685 +200,3 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); } - -static int -ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, - int mac_id, u32 ring_id, - enum hal_ring_type ring_type, - enum htt_srng_ring_type *htt_ring_type, - enum htt_srng_ring_id *htt_ring_id) -{ - int ret = 0; - - switch (ring_type) { - case HAL_RXDMA_BUF: - /* for some targets, host fills rx buffer to fw and fw fills to - * rxbuf ring for each rxdma - */ - if (!ab->hw_params->rx_mac_buf_ring) { - if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 || - ring_id == HAL_SRNG_SW2RXDMA_BUF1)) { - ret = -EINVAL; - } - *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - } else { - if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) { - *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING; - *htt_ring_type = HTT_SW_TO_SW_RING; - } else { - *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - } - } - break; - case HAL_RXDMA_DST: - *htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING; - *htt_ring_type = HTT_HW_TO_SW_RING; - break; - case HAL_RXDMA_MONITOR_BUF: - *htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - break; - case HAL_RXDMA_MONITOR_STATUS: - *htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - break; - case HAL_RXDMA_MONITOR_DST: - *htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING; - *htt_ring_type = HTT_HW_TO_SW_RING; - break; - case HAL_RXDMA_MONITOR_DESC: - *htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - break; - default: - ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type); - ret = -EINVAL; - } - return ret; -} - -int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type) -{ - struct htt_srng_setup_cmd *cmd; - struct hal_srng *srng = &ab->hal.srng_list[ring_id]; - struct hal_srng_params params; - struct sk_buff *skb; - u32 ring_entry_sz; - int len = sizeof(*cmd); - dma_addr_t hp_addr, tp_addr; - enum htt_srng_ring_type htt_ring_type; - enum htt_srng_ring_id htt_ring_id; - int ret; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - memset(¶ms, 0, sizeof(params)); - ath12k_hal_srng_get_params(ab, srng, ¶ms); - - hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng); - tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng); - - ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, - ring_type, &htt_ring_type, - &htt_ring_id); - if (ret) - goto err_free; - - skb_put(skb, len); - cmd = (struct htt_srng_setup_cmd *)skb->data; - cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP, - HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE); - if (htt_ring_type == HTT_SW_TO_HW_RING || - htt_ring_type == HTT_HW_TO_SW_RING) - cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id), - HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); - else - cmd->info0 |= le32_encode_bits(mac_id, - HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); - cmd->info0 |= le32_encode_bits(htt_ring_type, - HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE); - cmd->info0 |= le32_encode_bits(htt_ring_id, - HTT_SRNG_SETUP_CMD_INFO0_RING_ID); - - cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr & - HAL_ADDR_LSB_REG_MASK); - - cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >> - HAL_ADDR_MSB_REG_SHIFT); - - ret = ath12k_hal_srng_get_entrysize(ab, ring_type); - if (ret < 0) - goto err_free; - - ring_entry_sz = ret; - - ring_entry_sz >>= 2; - cmd->info1 = le32_encode_bits(ring_entry_sz, - HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE); - cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz, - HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE); - cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), - HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP); - cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), - HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP); - cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP), - HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP); - if (htt_ring_type == HTT_SW_TO_HW_RING) - cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS); - - cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr)); - cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr)); - - cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr)); - cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr)); - - cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr)); - cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr)); - cmd->msi_data = cpu_to_le32(params.msi_data); - - cmd->intr_info = - le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz, - HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH); - cmd->intr_info |= - le32_encode_bits(params.intr_timer_thres_us >> 3, - HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH); - - cmd->info2 = 0; - if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { - cmd->info2 = le32_encode_bits(params.low_threshold, - HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH); - } - - ath12k_dbg(ab, ATH12K_DBG_HAL, - "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n", - __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi, - cmd->msi_data); - - ath12k_dbg(ab, ATH12K_DBG_HAL, - "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n", - ring_id, ring_type, cmd->intr_info, cmd->info2); - - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; - - return 0; - -err_free: - dev_kfree_skb_any(skb); - - return ret; -} - -#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) - -int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct sk_buff *skb; - struct htt_ver_req_cmd *cmd; - int len = sizeof(*cmd); - u32 metadata_version; - int ret; - - init_completion(&dp->htt_tgt_version_received); - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - skb_put(skb, len); - cmd = (struct htt_ver_req_cmd *)skb->data; - cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ, - HTT_OPTION_TAG); - metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 : - HTT_OPTION_TCL_METADATA_VER_V2; - - cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION, - HTT_OPTION_TAG) | - le32_encode_bits(HTT_TCL_METADATA_VER_SZ, - HTT_OPTION_LEN) | - le32_encode_bits(metadata_version, - HTT_OPTION_VALUE); - - ret = ath12k_htc_send(&ab->htc, dp->eid, skb); - if (ret) { - dev_kfree_skb_any(skb); - return ret; - } - - ret = wait_for_completion_timeout(&dp->htt_tgt_version_received, - HTT_TARGET_VERSION_TIMEOUT_HZ); - if (ret == 0) { - ath12k_warn(ab, "htt target version request timed out\n"); - return -ETIMEDOUT; - } - - if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) { - ath12k_err(ab, "unsupported htt major version %d supported version is %d\n", - dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR); - return -EOPNOTSUPP; - } - - return 0; -} - -int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct sk_buff *skb; - struct htt_ppdu_stats_cfg_cmd *cmd; - int len = sizeof(*cmd); - u8 pdev_mask; - int ret; - int i; - - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - skb_put(skb, len); - cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data; - cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG, - HTT_PPDU_STATS_CFG_MSG_TYPE); - - pdev_mask = 1 << (i + ar->pdev_idx); - cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID); - cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK); - - ret = ath12k_htc_send(&ab->htc, dp->eid, skb); - if (ret) { - dev_kfree_skb_any(skb); - return ret; - } - } - - return 0; -} - -int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int rx_buf_size, - struct htt_rx_ring_tlv_filter *tlv_filter) -{ - struct htt_rx_ring_selection_cfg_cmd *cmd; - struct hal_srng *srng = &ab->hal.srng_list[ring_id]; - struct hal_srng_params params; - struct sk_buff *skb; - int len = sizeof(*cmd); - enum htt_srng_ring_type htt_ring_type; - enum htt_srng_ring_id htt_ring_id; - int ret; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - memset(¶ms, 0, sizeof(params)); - ath12k_hal_srng_get_params(ab, srng, ¶ms); - - ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, - ring_type, &htt_ring_type, - &htt_ring_id); - if (ret) - goto err_free; - - skb_put(skb, len); - cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data; - cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); - if (htt_ring_type == HTT_SW_TO_HW_RING || - htt_ring_type == HTT_HW_TO_SW_RING) - cmd->info0 |= - le32_encode_bits(DP_SW2HW_MACID(mac_id), - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - else - cmd->info0 |= - le32_encode_bits(mac_id, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - cmd->info0 |= le32_encode_bits(htt_ring_id, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS); - cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID); - cmd->info0 |= - le32_encode_bits(tlv_filter->drop_threshold_valid, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL); - cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON); - - cmd->info1 = le32_encode_bits(rx_buf_size, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE); - cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); - cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); - cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); - cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0); - cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1); - cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2); - cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3); - cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter); - - cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD); - cmd->info2 |= - le32_encode_bits(tlv_filter->enable_log_mgmt_type, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE); - cmd->info2 |= - le32_encode_bits(tlv_filter->enable_log_ctrl_type, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE); - cmd->info2 |= - le32_encode_bits(tlv_filter->enable_log_data_type, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE); - - cmd->info3 = - le32_encode_bits(tlv_filter->enable_rx_tlv_offset, - HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET); - cmd->info3 |= - le32_encode_bits(tlv_filter->rx_tlv_offset, - HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET); - - if (tlv_filter->offset_valid) { - cmd->rx_packet_offset = - le32_encode_bits(tlv_filter->rx_packet_offset, - HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET); - - cmd->rx_packet_offset |= - le32_encode_bits(tlv_filter->rx_header_offset, - HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET); - - cmd->rx_mpdu_offset = - le32_encode_bits(tlv_filter->rx_mpdu_end_offset, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET); - - cmd->rx_mpdu_offset |= - le32_encode_bits(tlv_filter->rx_mpdu_start_offset, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET); - - cmd->rx_msdu_offset = - le32_encode_bits(tlv_filter->rx_msdu_end_offset, - HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET); - - cmd->rx_msdu_offset |= - le32_encode_bits(tlv_filter->rx_msdu_start_offset, - HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET); - - cmd->rx_attn_offset = - le32_encode_bits(tlv_filter->rx_attn_offset, - HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET); - } - - if (tlv_filter->rx_mpdu_start_wmask > 0 && - tlv_filter->rx_msdu_end_wmask > 0) { - cmd->info2 |= - le32_encode_bits(true, - HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET); - cmd->rx_mpdu_start_end_mask = - le32_encode_bits(tlv_filter->rx_mpdu_start_wmask, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK); - /* mpdu_end is not used for any hardwares so far - * please assign it in future if any chip is - * using through hal ops - */ - cmd->rx_mpdu_start_end_mask |= - le32_encode_bits(tlv_filter->rx_mpdu_end_wmask, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK); - cmd->rx_msdu_end_word_mask = - le32_encode_bits(tlv_filter->rx_msdu_end_wmask, - HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); - } - - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; - - return 0; - -err_free: - dev_kfree_skb_any(skb); - - return ret; -} - -int -ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, - struct htt_ext_stats_cfg_params *cfg_params, - u64 cookie) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct sk_buff *skb; - struct htt_ext_stats_cfg_cmd *cmd; - int len = sizeof(*cmd); - int ret; - u32 pdev_id; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - skb_put(skb, len); - - cmd = (struct htt_ext_stats_cfg_cmd *)skb->data; - memset(cmd, 0, sizeof(*cmd)); - cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG; - - pdev_id = ath12k_mac_get_target_pdev_id(ar); - cmd->hdr.pdev_mask = 1 << pdev_id; - - cmd->hdr.stats_type = type; - cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0); - cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1); - cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2); - cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3); - cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie)); - cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie)); - - ret = ath12k_htc_send(&ab->htc, dp->eid, skb); - if (ret) { - ath12k_warn(ab, "failed to send htt type stats request: %d", - ret); - dev_kfree_skb_any(skb); - return ret; - } - - return 0; -} - -int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset) -{ - struct ath12k_base *ab = ar->ab; - int ret; - - ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset); - if (ret) { - ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret); - return ret; - } - - return 0; -} - -int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) -{ - struct ath12k_base *ab = ar->ab; - struct htt_rx_ring_tlv_filter tlv_filter = {}; - int ret, ring_id, i; - - tlv_filter.offset_valid = false; - - if (!reset) { - tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING; - - tlv_filter.drop_threshold_valid = true; - tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE; - - tlv_filter.enable_log_mgmt_type = true; - tlv_filter.enable_log_ctrl_type = true; - tlv_filter.enable_log_data_type = true; - - tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH; - tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH; - tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH; - - tlv_filter.enable_rx_tlv_offset = true; - tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET; - - tlv_filter.pkt_filter_flags0 = - HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 | - HTT_RX_MON_MO_MGMT_FILTER_FLAGS0; - tlv_filter.pkt_filter_flags1 = - HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 | - HTT_RX_MON_MO_MGMT_FILTER_FLAGS1; - tlv_filter.pkt_filter_flags2 = - HTT_RX_MON_FP_CTRL_FILTER_FLASG2 | - HTT_RX_MON_MO_CTRL_FILTER_FLASG2; - tlv_filter.pkt_filter_flags3 = - HTT_RX_MON_FP_CTRL_FILTER_FLASG3 | - HTT_RX_MON_MO_CTRL_FILTER_FLASG3 | - HTT_RX_MON_FP_DATA_FILTER_FLASG3 | - HTT_RX_MON_MO_DATA_FILTER_FLASG3; - } else { - tlv_filter = ath12k_mac_mon_status_filter_default; - - if (ath12k_debugfs_is_extd_rx_stats_enabled(ar)) - tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar); - } - - if (ab->hw_params->rxdma1_enable) { - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id; - ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, - ar->dp.mac_id + i, - HAL_RXDMA_MONITOR_DST, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - if (ret) { - ath12k_err(ab, - "failed to setup filter for monitor buf %d\n", - ret); - return ret; - } - } - return 0; - } - - if (!reset) { - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mac_buf_ring[i].ring_id; - ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, - i, - HAL_RXDMA_BUF, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - if (ret) { - ath12k_err(ab, - "failed to setup filter for mon rx buf %d\n", - ret); - return ret; - } - } - } - - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; - if (!reset) { - tlv_filter.rx_filter = - HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; - } - - ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, - i, - HAL_RXDMA_MONITOR_STATUS, - RX_MON_STATUS_BUF_SIZE, - &tlv_filter); - if (ret) { - ath12k_err(ab, - "failed to setup filter for mon status buf %d\n", - ret); - return ret; - } - } - - return 0; -} - -int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int tx_buf_size, - struct htt_tx_ring_tlv_filter *htt_tlv_filter) -{ - struct htt_tx_ring_selection_cfg_cmd *cmd; - struct hal_srng *srng = &ab->hal.srng_list[ring_id]; - struct hal_srng_params params; - struct sk_buff *skb; - int len = sizeof(*cmd); - enum htt_srng_ring_type htt_ring_type; - enum htt_srng_ring_id htt_ring_id; - int ret; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - memset(¶ms, 0, sizeof(params)); - ath12k_hal_srng_get_params(ab, srng, ¶ms); - - ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, - ring_type, &htt_ring_type, - &htt_ring_id); - - if (ret) - goto err_free; - - skb_put(skb, len); - cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data; - cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG, - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); - if (htt_ring_type == HTT_SW_TO_HW_RING || - htt_ring_type == HTT_HW_TO_SW_RING) - cmd->info0 |= - le32_encode_bits(DP_SW2HW_MACID(mac_id), - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - else - cmd->info0 |= - le32_encode_bits(mac_id, - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - cmd->info0 |= le32_encode_bits(htt_ring_id, - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS); - - cmd->info1 |= - le32_encode_bits(tx_buf_size, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE); - - if (htt_tlv_filter->tx_mon_mgmt_filter) { - cmd->info1 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); - cmd->info1 |= - le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); - cmd->info2 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, - HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); - } - - if (htt_tlv_filter->tx_mon_data_filter) { - cmd->info1 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); - cmd->info1 |= - le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); - cmd->info2 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, - HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); - } - - if (htt_tlv_filter->tx_mon_ctrl_filter) { - cmd->info1 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); - cmd->info1 |= - le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); - cmd->info2 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, - HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); - } - - cmd->tlv_filter_mask_in0 = - cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags); - cmd->tlv_filter_mask_in1 = - cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0); - cmd->tlv_filter_mask_in2 = - cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1); - cmd->tlv_filter_mask_in3 = - cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2); - - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; - - return 0; - -err_free: - dev_kfree_skb_any(skb); - return ret; -} diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 8405a0baf95b6..5b8fe280c32ae 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -15,25 +15,7 @@ struct ath12k_dp_htt_wbm_tx_status { s8 ack_rssi; }; -int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); -int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); -int -ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, - struct htt_ext_stats_cfg_params *cfg_params, - u64 cookie); -int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset); - -int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int rx_buf_size, - struct htt_rx_ring_tlv_filter *tlv_filter); void ath12k_dp_tx_put_bank_profile(struct ath12k_dp *dp, u8 bank_id); -int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int tx_buf_size, - struct htt_tx_ring_tlv_filter *htt_tlv_filter); -int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset); - enum hal_tcl_encap_type ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb); void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb); From f2bc97d66f47f37299cbead8c02dcce8c28d1be5 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:53 +0530 Subject: [PATCH 399/659] wifi: ath12k: Move HTT specific code from dp.c to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. Relocate HTT specific code from dp.c to newly introduced file dp_htt.c for HTT interface. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-21-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 29 ---------------------- drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/dp_htt.c | 31 ++++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/dp_htt.h | 3 +++ 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 2826251602b6b..b4f287fb46441 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -19,12 +19,6 @@ enum ath12k_dp_desc_type { ATH12K_DP_RX_DESC, }; -static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab, - struct sk_buff *skb) -{ - dev_kfree_skb_any(skb); -} - void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; @@ -957,29 +951,6 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) return ret; } -int ath12k_dp_htt_connect(struct ath12k_dp *dp) -{ - struct ath12k_htc_svc_conn_req conn_req = {}; - struct ath12k_htc_svc_conn_resp conn_resp = {}; - int status; - - conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete; - conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler; - - /* connect to control service */ - conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG; - - status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req, - &conn_resp); - - if (status) - return status; - - dp->eid = conn_resp.eid; - - return 0; -} - static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif) { switch (arvif->ahvif->vdev_type) { diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 852b35ff1ecd4..9b82e1cf74dc3 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -436,7 +436,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } -int ath12k_dp_htt_connect(struct ath12k_dp *dp); void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_free(struct ath12k_base *ab); int ath12k_dp_alloc(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 45aa8ae86a14c..6ab5b2d8aac94 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -11,6 +11,35 @@ #include "debugfs_htt_stats.h" #include "debugfs.h" +static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab, + struct sk_buff *skb) +{ + dev_kfree_skb_any(skb); +} + +int ath12k_dp_htt_connect(struct ath12k_dp *dp) +{ + struct ath12k_htc_svc_conn_req conn_req = {}; + struct ath12k_htc_svc_conn_resp conn_resp = {}; + int status; + + conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete; + conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler; + + /* connect to control service */ + conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG; + + status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req, + &conn_resp); + + if (status) + return status; + + dp->eid = conn_resp.eid; + + return 0; +} + static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, u16 peer_id) { @@ -818,8 +847,6 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, return ret; } -#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) - int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h index b13af1c69253d..6020e632f74ec 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.h +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -36,6 +36,8 @@ struct ath12k_dp; #define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24) +#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) + struct htt_tx_wbm_completion { __le32 rsvd0[2]; __le32 info0; @@ -1514,6 +1516,7 @@ struct htt_mac_addr { __le32 mac_addr_h16; } __packed; +int ath12k_dp_htt_connect(struct ath12k_dp *dp); int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, int mac_id, enum hal_ring_type ring_type); From 5937da8603674b46b7149e664e5497ee271a3cd7 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:07 +0530 Subject: [PATCH 400/659] wifi: ath12k: Remove non-compact TLV support from QCN Set compact TLV ops as the default ops by registering them in hal_rx_ops by default for QCN, and remove non-compact TLV ops and the corresponding hal APIs for QCN. Please note that compact TLVs have been supported by the firmware since the beginning of Wi-Fi 7, so backward compatibility has been maintained. These changes are specific to QCN as WCN only support non-compact TLVs. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 20 +- drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 339 +----------------- drivers/net/wireless/ath/ath12k/hal.h | 2 - drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 16 +- .../wireless/ath/ath12k/wifi7/hal_rx_desc.h | 7 - drivers/net/wireless/ath/ath12k/wifi7/pci.c | 2 +- 7 files changed, 11 insertions(+), 376 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index b4f287fb46441..4c6caa8905fdd 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -895,27 +895,9 @@ void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) /* TODO: Add any RXDMA setup required per pdev */ } -bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab) -{ - if (test_bit(WMI_TLV_SERVICE_WMSK_COMPACTION_RX_TLVS, ab->wmi_ab.svc_map) && - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start && - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end && - ab->hw_params->hal_ops->get_hal_rx_compact_ops) { - return true; - } - return false; -} - void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) { - if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { - /* RX TLVS compaction is supported, hence change the hal_rx_ops - * to compact hal_rx_ops. - */ - ab->hal_rx_ops = ab->hw_params->hal_ops->get_hal_rx_compact_ops(); - } - ab->hal.hal_desc_sz = - ab->hal_rx_ops->rx_desc_get_desc_size(); + ab->hal.hal_desc_sz = ab->hal_rx_ops->rx_desc_get_desc_size(); } int ath12k_dp_pdev_alloc(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9b82e1cf74dc3..5c8e6089f9e94 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -461,6 +461,5 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, u32 cookie); struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, u32 desc_id); -bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab); void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 144c26586b794..980f17791c1aa 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -294,230 +294,6 @@ static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); } -static bool ath12k_hw_qcn9274_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_FIRST_MSDU); -} - -static bool ath12k_hw_qcn9274_rx_desc_get_last_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_LAST_MSDU); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_L3_HDR_PADDING); -} - -static bool ath12k_hw_qcn9274_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.mpdu_start.info2, - RX_MPDU_START_INFO2_ENC_TYPE); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_decap_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info11, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info11, - RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); -} - -static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); -} - -static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); -} - -static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_NUM); -} - -static u16 ath12k_hw_qcn9274_rx_desc_get_msdu_len(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info10, - RX_MSDU_END_INFO10_MSDU_LENGTH); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_SGI); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_RATE_MCS); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_RECV_BW); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274.msdu_end.phy_meta_data); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_PKT_TYPE); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_MIMO_SS_BITMAP); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_TID); -} - -static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274.mpdu_start.sw_peer_id); -} - -static void ath12k_hw_qcn9274_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - memcpy(&fdesc->u.qcn9274.msdu_end, &ldesc->u.qcn9274.msdu_end, - sizeof(struct rx_msdu_end_qcn9274)); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274.mpdu_start.phy_ppdu_id); -} - -static void ath12k_hw_qcn9274_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info10); - - info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; - info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); - - desc->u.qcn9274.msdu_end.info10 = __cpu_to_le32(info); -} - -static u8 *ath12k_hw_qcn9274_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -{ - return &desc->u.qcn9274.msdu_payload[0]; -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274, mpdu_start); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274, msdu_end); -} - -static bool ath12k_hw_qcn9274_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR2_VALID; -} - -static u8 *ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -{ - return desc->u.qcn9274.mpdu_start.addr2; -} - -static bool ath12k_hw_qcn9274_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274.msdu_end.info5) & - RX_MSDU_END_INFO5_DA_IS_MCBC; -} - -static void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - hdr->frame_control = desc->u.qcn9274.mpdu_start.frame_ctrl; - hdr->duration_id = desc->u.qcn9274.mpdu_start.duration; - ether_addr_copy(hdr->addr1, desc->u.qcn9274.mpdu_start.addr1); - ether_addr_copy(hdr->addr2, desc->u.qcn9274.mpdu_start.addr2); - ether_addr_copy(hdr->addr3, desc->u.qcn9274.mpdu_start.addr3); - if (__le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { - ether_addr_copy(hdr->addr4, desc->u.qcn9274.mpdu_start.addr4); - } - hdr->seq_ctrl = desc->u.qcn9274.mpdu_start.seq_ctrl; -} - -static void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - unsigned int key_id; - - switch (enctype) { - case HAL_ENCRYPT_TYPE_OPEN: - return; - case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: - case HAL_ENCRYPT_TYPE_TKIP_MIC: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[1] = 0; - crypto_hdr[2] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]); - break; - case HAL_ENCRYPT_TYPE_CCMP_128: - case HAL_ENCRYPT_TYPE_CCMP_256: - case HAL_ENCRYPT_TYPE_GCMP_128: - case HAL_ENCRYPT_TYPE_AES_GCMP_256: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[1] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[2] = 0; - break; - case HAL_ENCRYPT_TYPE_WEP_40: - case HAL_ENCRYPT_TYPE_WEP_104: - case HAL_ENCRYPT_TYPE_WEP_128: - case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: - case HAL_ENCRYPT_TYPE_WAPI: - return; - } - key_id = le32_get_bits(desc->u.qcn9274.mpdu_start.info5, - RX_MPDU_START_INFO5_KEY_ID); - crypto_hdr[3] = 0x20 | (key_id << 6); - crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[1]); - crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]); -} - static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; @@ -638,116 +414,6 @@ static u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) return QCN9274_MSDU_END_WMASK; } -static const struct hal_rx_ops *ath12k_hal_qcn9274_get_hal_rx_compact_ops(void) -{ - return &hal_rx_qcn9274_compact_ops; -} - -static bool ath12k_hw_qcn9274_dp_rx_h_msdu_done(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.msdu_end.info14, - RX_MSDU_END_INFO14_MSDU_DONE); -} - -static bool ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13, - RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13, - RX_MSDU_END_INFO13_IP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) -{ - return (le32_get_bits(desc->u.qcn9274.msdu_end.info14, - RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == - RX_DESC_DECRYPT_STATUS_CODE_OK); -} - -static u32 ath12k_hw_qcn9274_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info13); - u32 errmap = 0; - - if (info & RX_MSDU_END_INFO13_FCS_ERR) - errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; - - return errmap; -} - -static u32 ath12k_hw_qcn9274_get_rx_desc_size(void) -{ - return sizeof(struct hal_rx_desc_qcn9274); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) -{ - return 0; -} - -const struct hal_rx_ops hal_rx_qcn9274_ops = { - .rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu, - .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes, - .rx_desc_encrypt_valid = ath12k_hw_qcn9274_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = ath12k_hw_qcn9274_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = ath12k_hw_qcn9274_rx_desc_get_decap_type, - .rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_rx_desc_get_mesh_ctl, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no, - .rx_desc_get_msdu_len = ath12k_hw_qcn9274_rx_desc_get_msdu_len, - .rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw, - .rx_desc_get_msdu_freq = ath12k_hw_qcn9274_rx_desc_get_msdu_freq, - .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_qcn9274_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_end_tlv = ath12k_hw_qcn9274_rx_desc_copy_end_tlv, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_qcn9274_rx_desc_set_msdu_len, - .rx_desc_get_msdu_payload = ath12k_hw_qcn9274_rx_desc_get_msdu_payload, - .rx_desc_get_mpdu_start_offset = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset, - .rx_desc_get_msdu_end_offset = ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset, - .rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2, - .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_rx_desc_is_da_mcbc, - .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr, - .rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr, - .dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done, - .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail, - .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail, - .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted, - .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err, - .rx_desc_get_desc_size = ath12k_hw_qcn9274_get_rx_desc_size, - .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_rx_desc_get_msdu_src_link, -}; -EXPORT_SYMBOL(hal_rx_qcn9274_ops); - static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, @@ -786,7 +452,7 @@ static u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *d static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) { - return le32_get_bits(desc->u.qcn9274.msdu_end.info11, + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } @@ -1086,13 +752,13 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link, }; +EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_qcn9274_rx_mpdu_start_wmask_get, .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, - .get_hal_rx_compact_ops = ath12k_hal_qcn9274_get_hal_rx_compact_ops, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -1561,7 +1227,6 @@ const struct hal_ops hal_wcn7850_ops = { .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, .rxdma_ring_wmask_rx_mpdu_start = NULL, .rxdma_ring_wmask_rx_msdu_end = NULL, - .get_hal_rx_compact_ops = NULL, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 4b512fd3adc41..2e086909ce25e 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1600,14 +1600,12 @@ struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); u16 (*rxdma_ring_wmask_rx_mpdu_start)(void); u32 (*rxdma_ring_wmask_rx_msdu_end)(void); - const struct hal_rx_ops *(*get_hal_rx_compact_ops)(void); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; extern const struct hal_ops hal_qcn9274_ops; extern const struct hal_ops hal_wcn7850_ops; -extern const struct hal_rx_ops hal_rx_qcn9274_ops; extern const struct hal_rx_ops hal_rx_qcn9274_compact_ops; extern const struct hal_rx_ops hal_rx_wcn7850_ops; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d95e3c4daa5d5..2105d9e949768 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1901,15 +1901,13 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) tlv_filter.rx_msdu_end_offset = ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); - if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { - tlv_filter.rx_mpdu_start_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); - tlv_filter.rx_msdu_end_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", - tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); - } + tlv_filter.rx_mpdu_start_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); + tlv_filter.rx_msdu_end_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", + tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, HAL_RXDMA_BUF, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h index 60f165a176e0f..cc5e1d336376a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h @@ -1454,12 +1454,6 @@ struct rx_msdu_end_qcn9274_compact { * */ -struct hal_rx_desc_qcn9274 { - struct rx_msdu_end_qcn9274 msdu_end; - struct rx_mpdu_start_qcn9274 mpdu_start; - u8 msdu_payload[]; -} __packed; - struct hal_rx_desc_qcn9274_compact { struct rx_msdu_end_qcn9274_compact msdu_end; struct rx_mpdu_start_qcn9274_compact mpdu_start; @@ -1489,7 +1483,6 @@ struct hal_rx_desc_wcn7850 { struct hal_rx_desc { union { - struct hal_rx_desc_qcn9274 qcn9274; struct hal_rx_desc_qcn9274_compact qcn9274_compact; struct hal_rx_desc_wcn7850 wcn7850; } u; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 9b1acf6c7aa31..abdb3b8ff658c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -101,7 +101,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; - ab->hal_rx_ops = &hal_rx_qcn9274_ops; + ab->hal_rx_ops = &hal_rx_qcn9274_compact_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ath12k_core_get_memory_mode(ab); From 77a739123125cde51f66c55c68ff9ba1ee69281d Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Wed, 10 Sep 2025 23:44:08 +0530 Subject: [PATCH 401/659] wifi: ath12k: Move the hal APIs to hardware specific files Move the hal APIs from the existing common hal files to hardware specific hal files. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 4 +- drivers/net/wireless/ath/ath12k/hal.c | 600 +----------------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 307 +++++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 58 ++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 302 +++++++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 55 ++ 6 files changed, 727 insertions(+), 599 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 70d4daa48c902..e148444021633 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -27,7 +27,9 @@ ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ wifi7/dp_rx.o \ wifi7/dp_tx.o \ - wifi7/dp.o + wifi7/dp.o \ + wifi7/hal_qcn9274.o \ + wifi7/hal_wcn7850.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 980f17791c1aa..77024c99d0bf0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -9,6 +9,8 @@ #include "debug.h" #include "wifi7/hal_desc.h" #include "hif.h" +#include "wifi7/hal_qcn9274.h" +#include "wifi7/hal_wcn7850.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -404,310 +406,6 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return 0; } -static u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) -{ - return QCN9274_MPDU_START_WMASK; -} - -static u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) -{ - return QCN9274_MSDU_END_WMASK; -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_FIRST_MSDU); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_LAST_MSDU); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_L3_HDR_PADDING); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, - RX_MPDU_START_INFO2_ENC_TYPE); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, - RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); -} - -static bool -ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); -} - -static u16 -ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_NUM); -} - -static u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, - RX_MSDU_END_INFO10_MSDU_LENGTH); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_SGI); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_RATE_MCS); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_RECV_BW); -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_PKT_TYPE); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_MIMO_SS_BITMAP); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_TID); -} - -static u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); -} - -static void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); -} - -static void -ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); - - info = u32_replace_bits(info, len, RX_MSDU_END_INFO10_MSDU_LENGTH); - desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); -} - -static u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -{ - return &desc->u.qcn9274_compact.msdu_payload[0]; -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR2_VALID; -} - -static u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -{ - return desc->u.qcn9274_compact.mpdu_start.addr2; -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & - RX_MSDU_END_INFO5_DA_IS_MCBC; -} - -static void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; - hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; - ether_addr_copy(hdr->addr1, desc->u.qcn9274_compact.mpdu_start.addr1); - ether_addr_copy(hdr->addr2, desc->u.qcn9274_compact.mpdu_start.addr2); - ether_addr_copy(hdr->addr3, desc->u.qcn9274_compact.mpdu_start.addr3); - if (__le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { - ether_addr_copy(hdr->addr4, desc->u.qcn9274_compact.mpdu_start.addr4); - } - hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; -} - -static void -ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - unsigned int key_id; - - switch (enctype) { - case HAL_ENCRYPT_TYPE_OPEN: - return; - case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: - case HAL_ENCRYPT_TYPE_TKIP_MIC: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[1] = 0; - crypto_hdr[2] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); - break; - case HAL_ENCRYPT_TYPE_CCMP_128: - case HAL_ENCRYPT_TYPE_CCMP_256: - case HAL_ENCRYPT_TYPE_GCMP_128: - case HAL_ENCRYPT_TYPE_AES_GCMP_256: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[1] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[2] = 0; - break; - case HAL_ENCRYPT_TYPE_WEP_40: - case HAL_ENCRYPT_TYPE_WEP_104: - case HAL_ENCRYPT_TYPE_WEP_128: - case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: - case HAL_ENCRYPT_TYPE_WAPI: - return; - } - key_id = le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info5, - RX_MPDU_START_INFO5_KEY_ID); - crypto_hdr[3] = 0x20 | (key_id << 6); - crypto_hdr[4] = - HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[5] = - HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[6] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[1]); - crypto_hdr[7] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, - RX_MSDU_END_INFO14_MSDU_DONE); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, - RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, - RX_MSDU_END_INFO13_IP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) -{ - return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, - RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == - RX_DESC_DECRYPT_STATUS_CODE_OK); -} - -static u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); - u32 errmap = 0; - - if (info & RX_MSDU_END_INFO13_FCS_ERR) - errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; - - return errmap; -} - -static u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) -{ - return sizeof(struct hal_rx_desc_qcn9274_compact); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) -{ - return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, - RX_MSDU_END_64_TLV_SRC_LINK_ID); -} - const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_first_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu, @@ -762,236 +460,6 @@ const struct hal_ops hal_qcn9274_ops = { }; EXPORT_SYMBOL(hal_qcn9274_ops); -static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, - RX_MSDU_END_INFO5_FIRST_MSDU); -} - -static bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, - RX_MSDU_END_INFO5_LAST_MSDU); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.wcn7850.msdu_end.info5, - RX_MSDU_END_INFO5_L3_HDR_PADDING); -} - -static bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, - RX_MPDU_START_INFO2_ENC_TYPE); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info11, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info11, - RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); -} - -static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); -} - -static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); -} - -static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_NUM); -} - -static u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info10, - RX_MSDU_END_INFO10_MSDU_LENGTH); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_SGI); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_RATE_MCS); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_RECV_BW); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_PKT_TYPE); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_MIMO_SS_BITMAP); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, - RX_MPDU_START_INFO2_TID); -} - -static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); -} - -static void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, - sizeof(struct rx_msdu_end_qcn9274)); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) -{ - return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, - HAL_TLV_HDR_TAG); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); -} - -static void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) -{ - u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); - - info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; - info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); - - desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); -} - -static u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -{ - return &desc->u.wcn7850.msdu_payload[0]; -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) -{ - return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) -{ - return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); -} - -static bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR2_VALID; -} - -static u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -{ - return desc->u.wcn7850.mpdu_start.addr2; -} - -static bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & - RX_MSDU_END_INFO13_MCAST_BCAST; -} - -static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; - hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; - ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1); - ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2); - ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3); - if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { - ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4); - } - hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; -} - -static void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - unsigned int key_id; - - switch (enctype) { - case HAL_ENCRYPT_TYPE_OPEN: - return; - case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: - case HAL_ENCRYPT_TYPE_TKIP_MIC: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[1] = 0; - crypto_hdr[2] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); - break; - case HAL_ENCRYPT_TYPE_CCMP_128: - case HAL_ENCRYPT_TYPE_CCMP_256: - case HAL_ENCRYPT_TYPE_GCMP_128: - case HAL_ENCRYPT_TYPE_AES_GCMP_256: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[1] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[2] = 0; - break; - case HAL_ENCRYPT_TYPE_WEP_40: - case HAL_ENCRYPT_TYPE_WEP_104: - case HAL_ENCRYPT_TYPE_WEP_128: - case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: - case HAL_ENCRYPT_TYPE_WAPI: - return; - } - key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5), - RX_MPDU_START_INFO5_KEY_ID); - crypto_hdr[3] = 0x20 | (key_id << 6); - crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]); - crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); -} - static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; @@ -1116,70 +584,6 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return 0; } -static bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, - RX_MSDU_END_INFO14_MSDU_DONE); -} - -static bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, - RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); -} - -static bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, - RX_MSDU_END_INFO13_IP_CKSUM_FAIL); -} - -static bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) -{ - return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, - RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == - RX_DESC_DECRYPT_STATUS_CODE_OK); -} - -static u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) -{ - u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); - u32 errmap = 0; - - if (info & RX_MSDU_END_INFO13_FCS_ERR) - errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; - - return errmap; -} - -static u32 ath12k_hw_wcn7850_get_rx_desc_size(void) -{ - return sizeof(struct hal_rx_desc_wcn7850); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) -{ - return 0; -} - const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c new file mode 100644 index 0000000000000..bd114e82d55be --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include "hal_desc.h" +#include "hal_qcn9274.h" + +bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_FIRST_MSDU); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_LAST_MSDU); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_L3_HDR_PADDING); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, + RX_MPDU_START_INFO2_ENC_TYPE); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); +} + +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); +} + +u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, + RX_MSDU_END_INFO10_MSDU_LENGTH); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_SGI); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_RATE_MCS); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_RECV_BW); +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_PKT_TYPE); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_MIMO_SS_BITMAP); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_TID); +} + +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); +} + +void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); +} + +void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); + + info = u32_replace_bits(info, len, RX_MSDU_END_INFO10_MSDU_LENGTH); + desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); +} + +u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +{ + return &desc->u.qcn9274_compact.msdu_payload[0]; +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) +{ + return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) +{ + return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; +} + +u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.qcn9274_compact.mpdu_start.addr2; +} + +bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & + RX_MSDU_END_INFO5_DA_IS_MCBC; +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, + RX_MSDU_END_INFO14_MSDU_DONE); +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +{ + return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == + RX_DESC_DECRYPT_STATUS_CODE_OK); +} + +u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) +{ + return sizeof(struct hal_rx_desc_qcn9274_compact); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, + RX_MSDU_END_64_TLV_SRC_LINK_ID); +} + +u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) +{ + return QCN9274_MPDU_START_WMASK; +} + +u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) +{ + return QCN9274_MSDU_END_WMASK; +} + +u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +{ + u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); + u32 errmap = 0; + + if (info & RX_MSDU_END_INFO13_FCS_ERR) + errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; + + return errmap; +} + +void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + unsigned int key_id; + + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: + return; + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: + case HAL_ENCRYPT_TYPE_TKIP_MIC: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[1] = 0; + crypto_hdr[2] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); + break; + case HAL_ENCRYPT_TYPE_CCMP_128: + case HAL_ENCRYPT_TYPE_CCMP_256: + case HAL_ENCRYPT_TYPE_GCMP_128: + case HAL_ENCRYPT_TYPE_AES_GCMP_256: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[1] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[2] = 0; + break; + case HAL_ENCRYPT_TYPE_WEP_40: + case HAL_ENCRYPT_TYPE_WEP_104: + case HAL_ENCRYPT_TYPE_WEP_128: + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: + case HAL_ENCRYPT_TYPE_WAPI: + return; + } + key_id = le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info5, + RX_MPDU_START_INFO5_KEY_ID); + crypto_hdr[3] = 0x20 | (key_id << 6); + crypto_hdr[4] = + HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[5] = + HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[6] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[1]); + crypto_hdr[7] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); +} + +void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; + hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; + ether_addr_copy(hdr->addr1, desc->u.qcn9274_compact.mpdu_start.addr1); + ether_addr_copy(hdr->addr2, desc->u.qcn9274_compact.mpdu_start.addr2); + ether_addr_copy(hdr->addr3, desc->u.qcn9274_compact.mpdu_start.addr3); + if (__le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { + ether_addr_copy(hdr->addr4, desc->u.qcn9274_compact.mpdu_start.addr4); + } + hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h new file mode 100644 index 0000000000000..d066e5bc00dbc --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear*/ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_HAL_QCN9274_H +#define ATH12K_HAL_QCN9274_H + +#include +#include +#include "../hal.h" +#include "hal_rx.h" + +bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); +u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); +void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); +void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void); +bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); +u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); +u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void); +u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void); +u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); +void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c new file mode 100644 index 0000000000000..1e23665aabc91 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_desc.h" +#include "hal_wcn7850.h" + +bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, + RX_MSDU_END_INFO5_FIRST_MSDU); +} + +bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, + RX_MSDU_END_INFO5_LAST_MSDU); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.wcn7850.msdu_end.info5, + RX_MSDU_END_INFO5_L3_HDR_PADDING); +} + +bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, + RX_MPDU_START_INFO2_ENC_TYPE); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info11, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info11, + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); +} + +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); +} + +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); +} + +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); +} + +u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info10, + RX_MSDU_END_INFO10_MSDU_LENGTH); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_SGI); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_RATE_MCS); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_RECV_BW); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_PKT_TYPE); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_MIMO_SS_BITMAP); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, + RX_MPDU_START_INFO2_TID); +} + +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); +} + +void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, + sizeof(struct rx_msdu_end_qcn9274)); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) +{ + return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, + HAL_TLV_HDR_TAG); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); +} + +void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); + + info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; + info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); + + desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); +} + +u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +{ + return &desc->u.wcn7850.msdu_payload[0]; +} + +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) +{ + return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) +{ + return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); +} + +bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; +} + +u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.wcn7850.mpdu_start.addr2; +} + +bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & + RX_MSDU_END_INFO13_MCAST_BCAST; +} + +bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, + RX_MSDU_END_INFO14_MSDU_DONE); +} + +bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); +} + +bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); +} + +bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +{ + return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == + RX_DESC_DECRYPT_STATUS_CODE_OK); +} + +u32 ath12k_hw_wcn7850_get_rx_desc_size(void) +{ + return sizeof(struct hal_rx_desc_wcn7850); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return 0; +} + +u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +{ + u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); + u32 errmap = 0; + + if (info & RX_MSDU_END_INFO13_FCS_ERR) + errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; + + return errmap; +} + +void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + unsigned int key_id; + + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: + return; + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: + case HAL_ENCRYPT_TYPE_TKIP_MIC: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[1] = 0; + crypto_hdr[2] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); + break; + case HAL_ENCRYPT_TYPE_CCMP_128: + case HAL_ENCRYPT_TYPE_CCMP_256: + case HAL_ENCRYPT_TYPE_GCMP_128: + case HAL_ENCRYPT_TYPE_AES_GCMP_256: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[1] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[2] = 0; + break; + case HAL_ENCRYPT_TYPE_WEP_40: + case HAL_ENCRYPT_TYPE_WEP_104: + case HAL_ENCRYPT_TYPE_WEP_128: + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: + case HAL_ENCRYPT_TYPE_WAPI: + return; + } + key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5), + RX_MPDU_START_INFO5_KEY_ID); + crypto_hdr[3] = 0x20 | (key_id << 6); + crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]); + crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); +} + +void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; + hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; + ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1); + ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2); + ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3); + if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { + ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4); + } + hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h new file mode 100644 index 0000000000000..a5395a0053834 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_HAL_WCN7850_H +#define ATH12K_HAL_WCN7850_H + +#include "../hal.h" +#include "hal_rx.h" + +bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); +u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); +void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); +void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void); +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void); +bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); +u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_get_rx_desc_size(void); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); +void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); +#endif From 541fe68eaffcde16319db53d267b23e93f5b8a7b Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Wed, 10 Sep 2025 23:44:09 +0530 Subject: [PATCH 402/659] wifi: ath12k: unify HAL ops naming across chips Rename HAL ops to follow a consistent hal ops format: ath12k_hal_rx_xxxx_. Remove "compact" references as non-compacts variant is no longer used. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 154 +++++++++--------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 86 +++++----- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 86 +++++----- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 84 +++++----- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 84 +++++----- 5 files changed, 247 insertions(+), 247 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 77024c99d0bf0..1fba023d0859d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -407,56 +407,56 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { - .rx_desc_get_first_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu, - .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes, - .rx_desc_encrypt_valid = ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = ath12k_hw_qcn9274_compact_rx_desc_get_decap_type, - .rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl, + .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcn9274, + .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcn9274, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, + .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_qcn9274, + .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_qcn9274, + .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_qcn9274, + .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_qcn9274, .rx_desc_get_mpdu_seq_ctl_vld = - ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid, + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274, + .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274, .rx_desc_get_mpdu_start_seq_no = - ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no, - .rx_desc_get_msdu_len = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len, - .rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw, - .rx_desc_get_msdu_freq = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq, - .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_end_tlv = ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len, - .rx_desc_get_msdu_payload = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload, + ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274, + .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcn9274, + .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcn9274, + .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274, + .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274, + .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_qcn9274, + .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274, + .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_qcn9274, + .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274, + .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, .rx_desc_get_mpdu_start_offset = - ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset, + ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274, .rx_desc_get_msdu_end_offset = - ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset, - .rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2, - .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc, - .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr, - .rx_desc_get_crypto_header = ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr, - .dp_rx_h_msdu_done = ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done, - .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail, - .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail, - .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted, - .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err, - .rx_desc_get_desc_size = ath12k_hw_qcn9274_compact_get_rx_desc_size, + ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274, + .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, + .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, + .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, + .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274, + .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274, + .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274, + .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274, + .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_qcn9274, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, .rx_desc_get_msdu_src_link_id = - ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link, + ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, }; EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, - .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_qcn9274_rx_mpdu_start_wmask_get, - .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, + .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_rx_mpdu_start_wmask_get_qcn9274, + .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_rx_msdu_end_wmask_get_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -585,44 +585,44 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_wcn7850_ops = { - .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, - .rx_desc_get_l3_pad_bytes = ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes, - .rx_desc_encrypt_valid = ath12k_hw_wcn7850_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = ath12k_hw_wcn7850_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = ath12k_hw_wcn7850_rx_desc_get_decap_type, - .rx_desc_get_mesh_ctl = ath12k_hw_wcn7850_rx_desc_get_mesh_ctl, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no, - .rx_desc_get_msdu_len = ath12k_hw_wcn7850_rx_desc_get_msdu_len, - .rx_desc_get_msdu_sgi = ath12k_hw_wcn7850_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw, - .rx_desc_get_msdu_freq = ath12k_hw_wcn7850_rx_desc_get_msdu_freq, - .rx_desc_get_msdu_pkt_type = ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_wcn7850_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_wcn7850_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_end_tlv = ath12k_hw_wcn7850_rx_desc_copy_end_tlv, - .rx_desc_get_mpdu_start_tag = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_wcn7850_rx_desc_set_msdu_len, - .rx_desc_get_msdu_payload = ath12k_hw_wcn7850_rx_desc_get_msdu_payload, - .rx_desc_get_mpdu_start_offset = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset, - .rx_desc_get_msdu_end_offset = ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset, - .rx_desc_mac_addr2_valid = ath12k_hw_wcn7850_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2, - .rx_desc_is_da_mcbc = ath12k_hw_wcn7850_rx_desc_is_da_mcbc, - .rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr, - .rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr, - .dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done, - .dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail, - .dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail, - .dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted, - .dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err, - .rx_desc_get_desc_size = ath12k_hw_wcn7850_get_rx_desc_size, - .rx_desc_get_msdu_src_link_id = ath12k_hw_wcn7850_rx_desc_get_msdu_src_link, + .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_wcn7850, + .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_wcn7850, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, + .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_wcn7850, + .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_wcn7850, + .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_wcn7850, + .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_wcn7850, + .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850, + .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850, + .rx_desc_get_mpdu_start_seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850, + .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_wcn7850, + .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_wcn7850, + .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850, + .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850, + .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_wcn7850, + .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850, + .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_wcn7850, + .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850, + .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, + .rx_desc_get_mpdu_start_offset = ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850, + .rx_desc_get_msdu_end_offset = ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850, + .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, + .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, + .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, + .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850, + .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850, + .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850, + .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850, + .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_wcn7850, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, }; EXPORT_SYMBOL(hal_rx_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index bd114e82d55be..bf09a40c91d9d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -6,130 +6,130 @@ #include "hal_desc.h" #include "hal_qcn9274.h" -bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } -bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_LAST_MSDU); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_L3_HDR_PADDING); } -bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } -u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_TID); } -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); } -void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) +void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) { fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); } -void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +void ath12k_hal_rx_desc_set_msdu_len_qcn9274(struct hal_rx_desc *desc, u16 len) { u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); @@ -137,85 +137,85 @@ void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u1 desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); } -u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_get_msdu_payload_qcn9274(struct hal_rx_desc *desc) { return &desc->u.qcn9274_compact.msdu_payload[0]; } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(void) { return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void) { return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); } -bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } -u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc) { return desc->u.qcn9274_compact.mpdu_start.addr2; } -bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & RX_MSDU_END_INFO5_DA_IS_MCBC; } -bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } -bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } -bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } -bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == RX_DESC_DECRYPT_STATUS_CODE_OK); } -u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) +u32 ath12k_hal_get_rx_desc_size_qcn9274(void) { return sizeof(struct hal_rx_desc_qcn9274_compact); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc) { return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, RX_MSDU_END_64_TLV_SRC_LINK_ID); } -u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) +u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void) { return QCN9274_MPDU_START_WMASK; } -u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) +u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void) { return QCN9274_MSDU_END_WMASK; } -u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); u32 errmap = 0; @@ -244,9 +244,9 @@ u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) return errmap; } -void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) +void ath12k_hal_rx_desc_get_crypto_hdr_qcn9274(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) { unsigned int key_id; @@ -291,8 +291,8 @@ void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); } -void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) +void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) { hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index d066e5bc00dbc..562156bbd726d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,47 +12,47 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); -u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); -void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); -void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); -u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void); -bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); -u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); -u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void); -u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void); -u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); -void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype); -void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr); +bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_set_msdu_len_qcn9274(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hal_rx_desc_get_msdu_payload_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(void); +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void); +bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc); +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_get_rx_desc_size_qcn9274(void); +u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void); +u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void); +u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_get_crypto_hdr_qcn9274(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 1e23665aabc91..11b03452494c5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -7,137 +7,137 @@ #include "hal_desc.h" #include "hal_wcn7850.h" -bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } -bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_LAST_MSDU); } -u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_L3_HDR_PADDING); } -bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } -u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } -u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } -u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } -u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } -u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_TID); } -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); } -void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) +void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) { memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, sizeof(struct rx_msdu_end_qcn9274)); } -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850(struct hal_rx_desc *desc) { return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, HAL_TLV_HDR_TAG); } -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); } -void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +void ath12k_hal_rx_desc_set_msdu_len_wcn7850(struct hal_rx_desc *desc, u16 len) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); @@ -147,74 +147,74 @@ void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); } -u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc) { return &desc->u.wcn7850.msdu_payload[0]; } -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void) { return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); } -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) +u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void) { return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); } -bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } -u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc) { return desc->u.wcn7850.mpdu_start.addr2; } -bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & RX_MSDU_END_INFO13_MCAST_BCAST; } -bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } -bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } -bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } -bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == RX_DESC_DECRYPT_STATUS_CODE_OK); } -u32 ath12k_hw_wcn7850_get_rx_desc_size(void) +u32 ath12k_hal_get_rx_desc_size_wcn7850(void) { return sizeof(struct hal_rx_desc_wcn7850); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc) { return 0; } -u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); u32 errmap = 0; @@ -243,9 +243,9 @@ u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) return errmap; } -void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) +void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) { unsigned int key_id; @@ -286,8 +286,8 @@ void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); } -void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) +void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) { hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index a5395a0053834..c9a6b7ffb6078 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,46 +10,46 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); -u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); -void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc); -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); -void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); -u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void); -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void); -bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); -u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_get_rx_desc_size(void); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); -void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype); -void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr); +bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_set_msdu_len_wcn7850(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void); +u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void); +bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc); +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_get_rx_desc_size_wcn7850(void); +u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); #endif From 9da4b851c86d826c3f52f45c0b5719193c88232a Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:10 +0530 Subject: [PATCH 403/659] wifi: ath12k: Replace ops with direct calls for rxdma ring mask Replace following ops with direct function calls rxdma_ring_wmask_rx_mpdu_start rxdma_ring_wmask_rx_msdu_end rx_desc_get_mpdu_start_offset rx_desc_get_msdu_end_offset Remove redundant ops entries following the switch to direct function calls. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 10 ---------- drivers/net/wireless/ath/ath12k/hal.h | 4 ---- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 16 ++++++++-------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 1fba023d0859d..329c458d1fe25 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -432,10 +432,6 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, - .rx_desc_get_mpdu_start_offset = - ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274, - .rx_desc_get_msdu_end_offset = - ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, @@ -455,8 +451,6 @@ EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, - .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_rx_mpdu_start_wmask_get_qcn9274, - .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_rx_msdu_end_wmask_get_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -609,8 +603,6 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, - .rx_desc_get_mpdu_start_offset = ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850, - .rx_desc_get_msdu_end_offset = ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, @@ -629,8 +621,6 @@ EXPORT_SYMBOL(hal_rx_wcn7850_ops); const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, - .rxdma_ring_wmask_rx_mpdu_start = NULL, - .rxdma_ring_wmask_rx_msdu_end = NULL, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 2e086909ce25e..7e61d073b98d3 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1577,8 +1577,6 @@ struct hal_rx_ops { void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_mpdu_start_offset)(void); - u32 (*rx_desc_get_msdu_end_offset)(void); bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc); @@ -1598,8 +1596,6 @@ struct hal_rx_ops { struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); - u16 (*rxdma_ring_wmask_rx_mpdu_start)(void); - u32 (*rxdma_ring_wmask_rx_msdu_end)(void); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 2105d9e949768..99ff560384520 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -7,6 +7,8 @@ #include "dp_rx.h" #include "../dp_tx.h" #include "../peer.h" +#include "hal_qcn9274.h" +#include "hal_wcn7850.h" void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr) @@ -1897,14 +1899,12 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) tlv_filter.rx_packet_offset = hal_rx_desc_sz; tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(); tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(); - tlv_filter.rx_mpdu_start_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); - tlv_filter.rx_msdu_end_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); + tlv_filter.rx_mpdu_start_wmask = ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(); + tlv_filter.rx_msdu_end_wmask = ath12k_hal_rx_msdu_end_wmask_get_qcn9274(); ath12k_dbg(ab, ATH12K_DBG_DATA, "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); @@ -1940,9 +1940,9 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(); tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(); /* TODO: Selectively subscribe to required qwords within msdu_end * and mpdu_start and setup the mask in below msg From 11c6a1a8d087029911a9ba42914de4a97c55d420 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:11 +0530 Subject: [PATCH 404/659] wifi: ath12k: Move hal_rx_ops callbacks to hal_ops Move the following callbacks from hal_rx_ops to hal_ops for use in non-performance-critical paths: rx_desc_set_msdu_len rx_desc_get_dot11_hdr rx_desc_get_crypto_header rx_desc_copy_end_tlv rx_desc_get_msdu_src_link_id rx_desc_get_desc_size hal_rx_ops currently includes callbacks used in both critical and non-critical Rx paths. To reduce function pointer indirection in hot path, performance-critical ops will be consolidated into a single extraction API in a follow-up patch. Begin cleanup by migrating non-performance-critical callbacks from hal_rx_ops to hal_ops. Once the extraction API is in place, remove hal_rx_ops entirely to simplify the HAL interface. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 10 +++++----- drivers/net/wireless/ath/ath12k/hal.c | 25 ++++++++++++------------- drivers/net/wireless/ath/ath12k/hal.h | 20 ++++++++++---------- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4c6caa8905fdd..4cc4006b18bbc 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -897,7 +897,7 @@ void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) { - ab->hal.hal_desc_sz = ab->hal_rx_ops->rx_desc_get_desc_size(); + ab->hal.hal_desc_sz = ab->hw_params->hal_ops->rx_desc_get_desc_size(); } int ath12k_dp_pdev_alloc(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index a6b6fea4c5e2e..0b92a996f68f8 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -283,14 +283,14 @@ static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); + ab->hw_params->hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); } static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, struct hal_rx_desc *desc, u16 len) { - ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); + ab->hw_params->hal_ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, @@ -332,7 +332,7 @@ static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); + ab->hw_params->hal_ops->rx_desc_get_dot11_hdr(desc, hdr); } static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, @@ -340,13 +340,13 @@ static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + ab->hw_params->hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); + return ab->hw_params->hal_ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 329c458d1fe25..60a4e5766f513 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -428,29 +428,28 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_qcn9274, .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274, .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274, .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274, .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274, .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274, .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_qcn9274, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, - .rx_desc_get_msdu_src_link_id = - ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, }; EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -598,29 +597,29 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_wcn7850, .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850, .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850, .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850, .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850, .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850, .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_wcn7850, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, - .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, }; EXPORT_SYMBOL(hal_rx_wcn7850_ops); const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 7e61d073b98d3..79d3eba6e7959 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1570,33 +1570,33 @@ struct hal_rx_ops { u8 (*rx_desc_get_msdu_nss)(struct hal_rx_desc *desc); u8 (*rx_desc_get_mpdu_tid)(struct hal_rx_desc *desc); u16 (*rx_desc_get_mpdu_peer_id)(struct hal_rx_desc *desc); - void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc); u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); - void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc); - void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr); - void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype); bool (*dp_rx_h_msdu_done)(struct hal_rx_desc *desc); bool (*dp_rx_h_l4_cksum_fail)(struct hal_rx_desc *desc); bool (*dp_rx_h_ip_cksum_fail)(struct hal_rx_desc *desc); bool (*dp_rx_h_is_decrypted)(struct hal_rx_desc *desc); u32 (*dp_rx_h_mpdu_err)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_desc_size)(void); - u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); }; struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; + void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); + void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); + void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); + void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); + u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_desc_size)(void); }; extern const struct hal_ops hal_qcn9274_ops; From 35516cd2ce168492221a141e21e1f931bf80cab8 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:12 +0530 Subject: [PATCH 405/659] wifi: ath12k: Add new infra for the rx path The existing usage of rx_ops to reach the hal APIs at multiple place uses function pointer indirections. In order to avoid multiple function pointer indirections, add an API to extract the required hal parameters in the rx path right at the beginning and store them in a structure which is then leveraged by rest of the rx path. rx_desc_get_first_msdu rx_desc_get_last_msdu rx_desc_encrypt_valid rx_desc_get_encrypt_type rx_desc_get_decap_type rx_desc_get_mesh_ctl rx_desc_get_mpdu_seq_ctl_vld rx_desc_get_mpdu_fc_valid rx_desc_get_mpdu_start_seq_no rx_desc_get_msdu_len rx_desc_get_msdu_sgi rx_desc_get_msdu_rate_mcs rx_desc_get_msdu_rx_bw rx_desc_get_msdu_freq rx_desc_get_msdu_pkt_type rx_desc_get_msdu_nss rx_desc_get_mpdu_tid rx_desc_get_mpdu_peer_id rx_desc_mac_addr2_valid rx_desc_mpdu_start_addr2 rx_desc_is_da_mcbc dp_rx_h_msdu_done dp_rx_h_l4_cksum_fail dp_rx_h_ip_cksum_fail dp_rx_h_is_decrypted dp_rx_h_mpdu_err Remove following unused HAL rx ops rx_desc_get_hdr_status rx_desc_get_attention Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/dp_mon.c | 5 + drivers/net/wireless/ath/ath12k/dp_rx.c | 85 +++----- drivers/net/wireless/ath/ath12k/dp_rx.h | 188 +----------------- drivers/net/wireless/ath/ath12k/hal.c | 56 +----- drivers/net/wireless/ath/ath12k/hal.h | 61 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 163 +++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 8 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 64 +++++- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 29 +-- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 64 +++++- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 29 +-- 12 files changed, 290 insertions(+), 463 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 301d1337ab8bd..ca38f1f133708 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -15,6 +15,7 @@ #include "core.h" #include "dp_tx.h" #include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "debug.h" #include "debugfs.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 803de9ca3e51a..bb98257c8d427 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,6 +6,7 @@ #include "dp_mon.h" #include "debug.h" +#include "wifi7/hal_qcn9274.h" #include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" @@ -2292,8 +2293,10 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct struct ieee80211_sta *pubsta = NULL; struct ath12k_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct hal_rx_desc_data rx_info; bool is_mcbc = rxcb->is_mcbc; bool is_eapol_tkip = rxcb->is_eapol; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; status->link_valid = 0; @@ -2304,6 +2307,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct status->flag |= RX_FLAG_RADIOTAP_HE; } + ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + spin_lock_bh(&ar->ab->base_lock); peer = ath12k_peer_find_by_id(ar->ab, ppduinfo->peer_id); if (peer && peer->sta) { diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c2a32b61d62ff..b4c4bbcce7a92 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -950,9 +950,8 @@ static int ath12k_dp_rx_crypto_icv_len(struct ath12k *ar, static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status) + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; @@ -973,7 +972,7 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, qos_ctl = rxcb->tid; - if (ath12k_dp_rx_h_mesh_ctl_present(ab, rxcb->rx_desc)) + if (rx_info->mesh_ctrl_present) qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; /* TODO: Add other QoS ctl fields when required */ @@ -982,7 +981,7 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, memcpy(decap_hdr, hdr, hdr_len); /* Rebuild crypto header for mac80211 use */ - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_hdr = skb_push(msdu, ath12k_dp_rx_crypto_param_len(ar, enctype)); ath12k_dp_rx_desc_get_crypto_header(ar->ab, rxcb->rx_desc, crypto_hdr, @@ -1056,21 +1055,20 @@ static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, struct sk_buff *msdu, struct ath12k_skb_rxcb *rxcb, - struct ieee80211_rx_status *status, - enum hal_encrypt_type enctype) + enum hal_encrypt_type enctype, + struct hal_rx_desc_data *rx_info) { struct hal_rx_desc *rx_desc = rxcb->rx_desc; struct ath12k_base *ab = ar->ab; size_t hdr_len, crypto_len; struct ieee80211_hdr hdr; __le16 qos_ctl; - u8 *crypto_hdr, mesh_ctrl; + u8 *crypto_hdr; ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr); hdr_len = ieee80211_hdrlen(hdr.frame_control); - mesh_ctrl = ath12k_dp_rx_h_mesh_ctl_present(ab, rx_desc); - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); crypto_hdr = skb_push(msdu, crypto_len); ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); @@ -1080,14 +1078,14 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, memcpy(msdu->data, &hdr, min(hdr_len, sizeof(hdr))); if (rxcb->is_mcbc) - status->flag &= ~RX_FLAG_PN_VALIDATED; + rx_info->rx_status->flag &= ~RX_FLAG_PN_VALIDATED; /* Add QOS header */ if (ieee80211_is_data_qos(hdr.frame_control)) { struct ieee80211_hdr *qos_ptr = (struct ieee80211_hdr *)msdu->data; qos_ctl = cpu_to_le16(rxcb->tid & IEEE80211_QOS_CTL_TID_MASK); - if (mesh_ctrl) + if (rx_info->mesh_ctrl_present) qos_ctl |= cpu_to_le16(IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT); memcpy(ieee80211_get_qos_ctl(qos_ptr), &qos_ctl, IEEE80211_QOS_CTL_LEN); @@ -1097,7 +1095,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status) + struct hal_rx_desc_data *rx_info) { struct ieee80211_hdr *hdr; struct ethhdr *eth; @@ -1113,7 +1111,7 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, skb_pull(msdu, sizeof(*eth)); memcpy(skb_push(msdu, sizeof(rfc)), &rfc, sizeof(rfc)); - ath12k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); + ath12k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, enctype, rx_info); /* original 802.11 header has a different DA and in * case of 4addr it may also have different SA @@ -1126,21 +1124,17 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status, - bool decrypted) + bool decrypted, + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; - u8 decap; struct ethhdr *ehdr; - decap = ath12k_dp_rx_h_decap_type(ab, rx_desc); - - switch (decap) { + switch (rx_info->decap_type) { case DP_RX_DECAP_TYPE_NATIVE_WIFI: - ath12k_dp_rx_h_undecap_nwifi(ar, msdu, enctype, status); + ath12k_dp_rx_h_undecap_nwifi(ar, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_RAW: - ath12k_dp_rx_h_undecap_raw(ar, msdu, enctype, status, + ath12k_dp_rx_h_undecap_raw(ar, msdu, enctype, rx_info->rx_status, decrypted); break; case DP_RX_DECAP_TYPE_ETHERNET2_DIX: @@ -1149,7 +1143,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, /* mac80211 allows fast path only for authorized STA */ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) { ATH12K_SKB_RXCB(msdu)->is_eapol = true; - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, status); + ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); break; } @@ -1157,7 +1151,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, * remove eth header and add 802.11 header. */ if (ATH12K_SKB_RXCB(msdu)->is_mcbc && decrypted) - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, status); + ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_8023: /* TODO: Handle undecap for these formats */ @@ -1167,7 +1161,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, struct ath12k_peer * ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ath12k_peer *peer = NULL; @@ -1186,7 +1180,7 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) +static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_info) { struct ieee80211_supported_band *sband; struct ieee80211_rx_status *rx_status = rx_info->rx_status; @@ -1263,33 +1257,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_ } } -void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) -{ - rx_info->ip_csum_fail = ath12k_dp_rx_h_ip_cksum_fail(ab, rx_desc); - rx_info->l4_csum_fail = ath12k_dp_rx_h_l4_cksum_fail(ab, rx_desc); - rx_info->is_mcbc = ath12k_dp_rx_h_is_da_mcbc(ab, rx_desc); - rx_info->decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc); - rx_info->pkt_type = ath12k_dp_rx_h_pkt_type(ab, rx_desc); - rx_info->sgi = ath12k_dp_rx_h_sgi(ab, rx_desc); - rx_info->rate_mcs = ath12k_dp_rx_h_rate_mcs(ab, rx_desc); - rx_info->bw = ath12k_dp_rx_h_rx_bw(ab, rx_desc); - rx_info->nss = ath12k_dp_rx_h_nss(ab, rx_desc); - rx_info->tid = ath12k_dp_rx_h_tid(ab, rx_desc); - rx_info->peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); - rx_info->phy_meta_data = ath12k_dp_rx_h_freq(ab, rx_desc); - - if (ath12k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)) { - ether_addr_copy(rx_info->addr2, - ath12k_dp_rxdesc_get_mpdu_start_addr2(ab, rx_desc)); - rx_info->addr2_present = true; - } - - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "rx_desc: ", - rx_desc, sizeof(*rx_desc)); -} - -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) +void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) { struct ieee80211_rx_status *rx_status = rx_info->rx_status; u8 channel_num; @@ -1351,7 +1319,7 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct ieee80211_rx_status *rx_status; @@ -1382,7 +1350,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, peer ? peer->addr : NULL, rxcb->tid, is_mcbc ? "mcast" : "ucast", - ath12k_dp_rx_h_seq_no(ab, rxcb->rx_desc), + rx_info->seq_no, (status->encoding == RX_ENC_LEGACY) ? "legacy" : "", (status->encoding == RX_ENC_HT) ? "ht" : "", (status->encoding == RX_ENC_VHT) ? "vht" : "", @@ -1423,14 +1391,13 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct sk_buff *msdu) + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ieee80211_hdr *hdr; - u8 decap_type; u32 hdr_len; - decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc); - if (decap_type != DP_RX_DECAP_TYPE_NATIVE_WIFI) + if (rx_info->decap_type != DP_RX_DECAP_TYPE_NATIVE_WIFI) return true; hdr = (struct ieee80211_hdr *)msdu->data; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 0b92a996f68f8..38d9b11eff762 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -80,24 +80,6 @@ struct ath12k_dp_rx_rfc1042_hdr { __be16 snap_type; } __packed; -struct ath12k_dp_rx_info { - struct ieee80211_rx_status *rx_status; - u32 phy_meta_data; - u16 peer_id; - u8 decap_type; - u8 pkt_type; - u8 sgi; - u8 rate_mcs; - u8 bw; - u8 nss; - u8 addr2[ETH_ALEN]; - u8 tid; - bool ip_csum_fail; - bool l4_csum_fail; - bool is_mcbc; - bool addr2_present; -}; - static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) { u32 ret = 0; @@ -120,39 +102,6 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) return ret; } -static inline enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) - return HAL_ENCRYPT_TYPE_OPEN; - - return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); -} - -static inline u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_decap_type(desc); -} - -static inline u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); -} - -static inline bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); -} - -static inline bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); -} - static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, struct sk_buff *skb) { @@ -171,114 +120,12 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; } -static inline u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); -} - -static inline bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); -} - -static inline bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); -} - -static inline bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); -} - -static inline bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); -} - -static inline u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); -} - -static inline u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); -} - -static inline u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); -} - -static inline u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); -} - -static inline u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); -} - -static inline u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); -} - -static inline u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); -} - -static inline u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); -} - -static inline u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); -} - -static inline u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); -} - static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); } -static inline bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); -} - -static inline bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); -} - static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) @@ -309,25 +156,6 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, return tlv_tag == HAL_RX_MPDU_START; } -static inline bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return (ath12k_dp_rx_h_first_msdu(ab, desc) && - ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); -} - -static inline bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); -} - -static inline u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); -} - static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) @@ -360,14 +188,15 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status, - bool decrypted); + bool decrypted, + struct hal_rx_desc_data *rx_info); void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info); + struct hal_rx_desc_data *rx_info); bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct sk_buff *msdu); + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info); u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff_head *frag_list, @@ -417,14 +246,11 @@ u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); struct ath12k_peer * ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info); + struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info); - int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype); u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); @@ -432,7 +258,7 @@ bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); +void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first); void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 60a4e5766f513..db6294ba6771b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -407,37 +407,9 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { - .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcn9274, - .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcn9274, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, - .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_qcn9274, - .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_qcn9274, - .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_qcn9274, - .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_qcn9274, - .rx_desc_get_mpdu_seq_ctl_vld = - ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274, - .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274, - .rx_desc_get_mpdu_start_seq_no = - ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274, - .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcn9274, - .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcn9274, - .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274, - .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274, - .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_qcn9274, - .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274, - .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_qcn9274, - .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274, - .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, - .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, - .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, - .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, - .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274, - .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274, - .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274, - .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274, - .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_qcn9274, }; EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); @@ -449,6 +421,7 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -578,36 +551,10 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_wcn7850_ops = { - .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_wcn7850, - .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_wcn7850, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, - .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_wcn7850, - .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_wcn7850, - .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_wcn7850, - .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_wcn7850, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850, - .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850, - .rx_desc_get_mpdu_start_seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850, - .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_wcn7850, - .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_wcn7850, - .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850, - .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850, - .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_wcn7850, - .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850, - .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_wcn7850, - .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850, - .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, - .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, - .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, - .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, - .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850, - .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850, - .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850, - .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850, - .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_wcn7850, }; EXPORT_SYMBOL(hal_rx_wcn7850_ops); @@ -619,6 +566,7 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 79d3eba6e7959..38f07f5a72000 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1022,6 +1022,36 @@ struct hal_rx_mon_ppdu_info { struct hal_rx_tlv_aggr_info tlv_aggr; }; +struct hal_rx_desc_data { + struct ieee80211_rx_status *rx_status; + u32 phy_meta_data; + u32 err_bitmap; + u32 enctype; + u32 msdu_done:1, + is_decrypted:1, + ip_csum_fail:1, + l4_csum_fail:1, + is_first_msdu:1, + is_last_msdu:1, + mesh_ctrl_present:1, + addr2_present:1, + is_mcbc:1, + seq_ctl_valid:1, + fc_valid:1; + u16 msdu_len; + u16 peer_id; + u16 seq_no; + u8 *addr2; + u8 pkt_type; + u8 l3_pad_bytes; + u8 decap_type; + u8 bw; + u8 rate_mcs; + u8 nss; + u8 sgi; + u8 tid; +}; + /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 #define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010 @@ -1550,38 +1580,10 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) } struct hal_rx_ops { - bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); - bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); - u8 *(*rx_desc_get_hdr_status)(struct hal_rx_desc *desc); - bool (*rx_desc_encrypt_valid)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_encrypt_type)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_decap_type)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_mesh_ctl)(struct hal_rx_desc *desc); - bool (*rx_desc_get_mpdu_seq_ctl_vld)(struct hal_rx_desc *desc); - bool (*rx_desc_get_mpdu_fc_valid)(struct hal_rx_desc *desc); - u16 (*rx_desc_get_mpdu_start_seq_no)(struct hal_rx_desc *desc); - u16 (*rx_desc_get_msdu_len)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_sgi)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_rate_mcs)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_rx_bw)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_msdu_freq)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_pkt_type)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_nss)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_mpdu_tid)(struct hal_rx_desc *desc); - u16 (*rx_desc_get_mpdu_peer_id)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); - struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); - bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); - u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); - bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc); - bool (*dp_rx_h_msdu_done)(struct hal_rx_desc *desc); - bool (*dp_rx_h_l4_cksum_fail)(struct hal_rx_desc *desc); - bool (*dp_rx_h_ip_cksum_fail)(struct hal_rx_desc *desc); - bool (*dp_rx_h_is_decrypted)(struct hal_rx_desc *desc); - u32 (*dp_rx_h_mpdu_err)(struct hal_rx_desc *desc); }; struct hal_ops { @@ -1596,6 +1598,9 @@ struct hal_ops { void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); + void (*extract_rx_desc_data)(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc); u32 (*rx_desc_get_desc_size)(void); }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 99ff560384520..f19c5612bb7c0 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -301,7 +301,7 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, } static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? CHECKSUM_NONE : CHECKSUM_UNNECESSARY; @@ -310,16 +310,15 @@ static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; struct ieee80211_hdr *hdr; struct ath12k_peer *peer; struct ieee80211_rx_status *rx_status = rx_info->rx_status; - u32 err_bitmap; + u32 err_bitmap = rx_info->err_bitmap; /* PN for multicast packets will be checked in mac80211 */ rxcb = ATH12K_SKB_RXCB(msdu); @@ -345,9 +344,8 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, } spin_unlock_bh(&ar->ab->base_lock); - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc); + is_decrypted = rx_info->is_decrypted; /* Clear per-MPDU flags while leaving per-PPDU flags intact */ rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | @@ -374,7 +372,7 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, ath12k_dp_rx_h_csum_offload(msdu, rx_info); ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - enctype, rx_status, is_decrypted); + enctype, is_decrypted, rx_info); if (!is_decrypted || rx_info->is_mcbc) return; @@ -388,7 +386,8 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, struct sk_buff_head *msdu_list, struct sk_buff *first, struct sk_buff *last, - u8 l3pad_bytes, int msdu_len) + u8 l3pad_bytes, int msdu_len, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct sk_buff *skb; @@ -413,8 +412,8 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, } ldesc = (struct hal_rx_desc *)last->data; - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc); + rxcb->is_first_msdu = rx_info->is_first_msdu; + rxcb->is_last_msdu = rx_info->is_last_msdu; /* MSDU spans over multiple buffers because the length of the MSDU * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data @@ -475,7 +474,7 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, static int ath12k_dp_rx_process_msdu(struct ath12k *ar, struct sk_buff *msdu, struct sk_buff_head *msdu_list, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; @@ -496,7 +495,9 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) { + + ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, lrx_desc); + if (!rx_info->msdu_done) { ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; goto free_out; @@ -504,8 +505,8 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, rxcb = ATH12K_SKB_RXCB(msdu); rxcb->rx_desc = rx_desc; - msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc); - l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc); + msdu_len = rx_info->msdu_len; + l3_pad_bytes = rx_info->l3_pad_bytes; if (rxcb->is_frag) { skb_pull(msdu, hal_rx_desc_sz); @@ -522,7 +523,8 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, } else { ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, msdu, last_buf, - l3_pad_bytes, msdu_len); + l3_pad_bytes, msdu_len, + rx_info); if (ret) { ath12k_warn(ab, "failed to coalesce msdu rx buffer%d\n", ret); @@ -530,12 +532,12 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, } } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) { + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + rx_info))) { ret = -EINVAL; goto free_out; } - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); ath12k_dp_rx_h_ppdu(ar, rx_info); ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); @@ -559,7 +561,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k *ar; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; - struct ath12k_dp_rx_info rx_info; + struct hal_rx_desc_data rx_info; u8 hw_link_id, pdev_id; int ret; @@ -764,19 +766,16 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, } static bool -ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) +ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_encrypt_type encrypt_type) { - struct ath12k_base *ab = ar->ab; - enum hal_encrypt_type encrypt_type; struct sk_buff *first_frag, *skb; - struct hal_rx_desc *desc; u64 last_pn; u64 cur_pn; first_frag = skb_peek(&rx_tid->rx_frags); - desc = (struct hal_rx_desc *)first_frag->data; - encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && @@ -943,27 +942,29 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } -static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu) +static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, + struct ath12k_peer *peer, + enum hal_encrypt_type enctype, + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); struct ieee80211_key_conf *key_conf; struct ieee80211_hdr *hdr; - struct ath12k_dp_rx_info rx_info; u8 mic[IEEE80211_CCMP_MIC_LEN]; int head_len, tail_len, ret; size_t data_len; - u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hdr_len, hal_rx_desc_sz = ab->hal.hal_desc_sz; u8 *key, *data; u8 key_idx; - if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) + if (enctype != HAL_ENCRYPT_TYPE_TKIP_MIC) return 0; - rx_info.addr2_present = false; - rx_info.rx_status = rxs; + rx_info->addr2_present = false; + rx_info->rx_status = rxs; hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); hdr_len = ieee80211_hdrlen(hdr->frame_control); @@ -991,18 +992,19 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info); + ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; skb_pull(msdu, hal_rx_desc_sz); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + rx_info))) return -EINVAL; - ath12k_dp_rx_h_ppdu(ar, &rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); + HAL_ENCRYPT_TYPE_TKIP_MIC, true, rx_info); ieee80211_rx(ath12k_ar_to_hw(ar), msdu); return -EINVAL; } @@ -1010,13 +1012,12 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer static int ath12k_dp_rx_h_defrag(struct ath12k *ar, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff **defrag_skb) + struct sk_buff **defrag_skb, + enum hal_encrypt_type enctype, + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; - enum hal_encrypt_type enctype; bool is_decrypted = false; int msdu_len = 0; int extra_space; @@ -1027,13 +1028,10 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, skb_queue_walk(&rx_tid->rx_frags, skb) { flags = 0; - rx_desc = (struct hal_rx_desc *)skb->data; hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); - enctype = ath12k_dp_rx_h_enctype(ab, rx_desc); if (enctype != HAL_ENCRYPT_TYPE_OPEN) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, - rx_desc); + is_decrypted = rx_info->is_decrypted; if (is_decrypted) { if (skb != first_frag) @@ -1069,7 +1067,7 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) + if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) first_frag = NULL; *defrag_skb = first_frag; @@ -1078,28 +1076,25 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, struct sk_buff *msdu, - struct hal_reo_dest_ring *ring_desc) + struct hal_reo_dest_ring *ring_desc, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; struct ath12k_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; - u32 peer_id; + u32 peer_id = rx_info->peer_id; u16 seqno, frag_no; - u8 tid; + u8 tid = rx_info->tid; int ret = 0; bool more_frags; + enum hal_encrypt_type enctype = rx_info->enctype; - rx_desc = (struct hal_rx_desc *)msdu->data; - peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); - tid = ath12k_dp_rx_h_tid(ab, rx_desc); - seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + seqno = rx_info->seq_no; - if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || - !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || + if (!rx_info->seq_ctl_valid || !rx_info->fc_valid || tid > IEEE80211_NUM_TIDS) return -EINVAL; @@ -1179,10 +1174,11 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, if (!peer) goto err_frags_cleanup; - if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) + if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) goto err_frags_cleanup; - if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) + if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, + enctype, rx_info)) goto err_frags_cleanup; if (!defrag_skb) @@ -1210,6 +1206,7 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, struct ath12k_base *ab = ar->ab; struct sk_buff *msdu; struct ath12k_skb_rxcb *rxcb; + struct hal_rx_desc_data rx_info; struct hal_rx_desc *rx_desc; u16 msdu_len; u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; @@ -1260,7 +1257,9 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, } rx_desc = (struct hal_rx_desc *)msdu->data; - msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + + msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, @@ -1271,7 +1270,7 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, skb_put(msdu, hal_rx_desc_sz + msdu_len); - if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { + if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); @@ -1439,18 +1438,16 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, } static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, + struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { struct ath12k_base *ab = ar->ab; - u16 msdu_len; + u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; + u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); - if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); @@ -1465,7 +1462,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, if (rxcb->is_continuation) return -EINVAL; - if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { + if (!rx_info->msdu_done) { ath12k_warn(ar->ab, "msdu_done bit not set in null_q_des processing\n"); __skb_queue_purge(msdu_list); @@ -1484,18 +1481,15 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, if (rxcb->is_frag) { skb_pull(msdu, hal_rx_desc_sz); } else { - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) return -EINVAL; skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return -EINVAL; - ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); ath12k_dp_rx_h_ppdu(ar, rx_info); ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); @@ -1509,20 +1503,17 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, } static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; - u16 msdu_len; + u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; + u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); - - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + rxcb->is_first_msdu = rx_info->is_first_msdu; + rxcb->is_last_msdu = rx_info->is_last_msdu; if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { ath12k_dbg(ab, ATH12K_DBG_DATA, @@ -1535,7 +1526,7 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return true; ath12k_dp_rx_h_ppdu(ar, rx_info); @@ -1544,27 +1535,22 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, RX_FLAG_DECRYPTED); ath12k_dp_rx_h_undecap(ar, msdu, desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); + HAL_ENCRYPT_TYPE_TKIP_MIC, false, rx_info); return false; } static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; bool drop = false; - u32 err_bitmap; ar->ab->device_stats.rxdma_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); - if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); break; } @@ -1581,7 +1567,7 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, } static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, + struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); @@ -1616,14 +1602,17 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, struct sk_buff *msdu, struct sk_buff_head *msdu_list) { + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status rxs = {}; - struct ath12k_dp_rx_info rx_info; + struct hal_rx_desc_data rx_info; bool drop = true; rx_info.addr2_present = false; rx_info.rx_status = &rxs; + ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 45b856aaaa124..f258472bc1fc6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -44,4 +44,12 @@ int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); +static inline +void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, + struct hal_rx_desc_data *rx_info, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + ab->hw_params->hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); +} #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index bf09a40c91d9d..2e84c830d9b2b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -6,12 +6,14 @@ #include "hal_desc.h" #include "hal_qcn9274.h" +static inline bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } +static inline bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, @@ -24,95 +26,114 @@ u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc) RX_MSDU_END_INFO5_L3_HDR_PADDING); } +static inline bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } +static inline u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc) { + if (!ath12k_hal_rx_desc_encrypt_valid_qcn9274(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } +static inline u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } +static inline bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } +static inline bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } +static inline u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } +static inline u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } +static inline u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); } +static inline u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } +static inline u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_TID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); @@ -152,41 +173,48 @@ u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void) return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); } +static inline bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } +static inline u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc) { return desc->u.qcn9274_compact.mpdu_start.addr2; } +static inline bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & RX_MSDU_END_INFO5_DA_IS_MCBC; } +static inline bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } +static inline bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, @@ -215,7 +243,7 @@ u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void) return QCN9274_MSDU_END_WMASK; } -u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc) +static u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); u32 errmap = 0; @@ -305,3 +333,37 @@ void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, } hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; } + +void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcn9274(ldesc); + rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcn9274(ldesc); + rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(ldesc); + rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_qcn9274(rx_desc); + rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_qcn9274(rx_desc); + rx_desc_data->mesh_ctrl_present = + ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(rx_desc); + rx_desc_data->seq_ctl_valid = + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(rx_desc); + rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(rx_desc); + rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(rx_desc); + rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcn9274(ldesc); + rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(rx_desc); + rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(rx_desc); + rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(rx_desc); + rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_qcn9274(rx_desc); + rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(rx_desc); + rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_qcn9274(rx_desc)); + rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(rx_desc); + rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(rx_desc); + rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(rx_desc); + rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(rx_desc); + rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274(rx_desc); + rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274(ldesc); + rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274(rx_desc); + rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274(rx_desc); + rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274(rx_desc); + rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 562156bbd726d..9a918824e093f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,25 +12,7 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc); u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274(struct hal_rx_desc *desc); @@ -38,21 +20,16 @@ void ath12k_hal_rx_desc_set_msdu_len_qcn9274(struct hal_rx_desc *desc, u16 len); u8 *ath12k_hal_rx_desc_get_msdu_payload_qcn9274(struct hal_rx_desc *desc); u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(void); u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void); -bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc); -u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc); u32 ath12k_hal_get_rx_desc_size_qcn9274(void); u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc); u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void); u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void); -u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_get_crypto_hdr_qcn9274(struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype); void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); +void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 11b03452494c5..0fa1d9fad2e19 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -7,12 +7,14 @@ #include "hal_desc.h" #include "hal_wcn7850.h" +static inline bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } +static inline bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, @@ -25,95 +27,114 @@ u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc) RX_MSDU_END_INFO5_L3_HDR_PADDING); } +static inline bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } +static inline u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc) { + if (!ath12k_hal_rx_desc_encrypt_valid_wcn7850(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } +static inline u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } +static inline bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } +static inline bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } +static inline u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } +static inline u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } +static inline u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); } +static inline u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } +static inline u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_TID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); @@ -162,41 +183,48 @@ u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void) return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); } +static inline bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } +static inline u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc) { return desc->u.wcn7850.mpdu_start.addr2; } +static inline bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & RX_MSDU_END_INFO13_MCAST_BCAST; } +static inline bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } +static inline bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, @@ -214,7 +242,7 @@ u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc) return 0; } -u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) +static u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); u32 errmap = 0; @@ -300,3 +328,37 @@ void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, } hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; } + +void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_wcn7850(ldesc); + rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_wcn7850(ldesc); + rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(ldesc); + rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_wcn7850(rx_desc); + rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_wcn7850(rx_desc); + rx_desc_data->mesh_ctrl_present = + ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(rx_desc); + rx_desc_data->seq_ctl_valid = + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(rx_desc); + rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(rx_desc); + rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(rx_desc); + rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_wcn7850(ldesc); + rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(rx_desc); + rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(rx_desc); + rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(rx_desc); + rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_wcn7850(rx_desc); + rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(rx_desc); + rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_wcn7850(rx_desc)); + rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(rx_desc); + rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(rx_desc); + rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(rx_desc); + rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(rx_desc); + rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850(rx_desc); + rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850(ldesc); + rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850(rx_desc); + rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850(rx_desc); + rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850(rx_desc); + rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index c9a6b7ffb6078..a90978b2a4543 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,25 +10,7 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc); u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u32 ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850(struct hal_rx_desc *desc); @@ -37,19 +19,14 @@ void ath12k_hal_rx_desc_set_msdu_len_wcn7850(struct hal_rx_desc *desc, u16 len); u8 *ath12k_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc); u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void); u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void); -bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc); -u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc); u32 ath12k_hal_get_rx_desc_size_wcn7850(void); u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype); void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); +void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc); #endif From 134168c042418fca40fc85f42a48981ae61a1137 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Wed, 10 Sep 2025 23:44:13 +0530 Subject: [PATCH 406/659] wifi: ath12k: Remove hal_rx_ops and merge into hal_ops Move following ops from hal_rx_ops to hal_ops to simplify the HAL interface. rx_desc_get_l3_pad_bytes rx_desc_get_mpdu_start_tag rx_desc_get_mpdu_ppdu_id rx_desc_get_msdu_payload Remove the hal_rx_ops as they become unused with this change. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 -- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 6 +++--- drivers/net/wireless/ath/ath12k/hal.c | 22 +++++++-------------- drivers/net/wireless/ath/ath12k/hal.h | 14 ++++--------- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 2 -- 6 files changed, 15 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 7eaf098ccc8f5..985616950b0d7 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1203,8 +1203,6 @@ struct ath12k_base { bool fw_features_valid; } fw; - const struct hal_rx_ops *hal_rx_ops; - struct completion restart_completed; #ifdef CONFIG_ACPI diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index bb98257c8d427..a292658a78c24 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2076,7 +2076,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, rx_desc = (struct hal_rx_desc *)head_msdu->data; hdr_desc = - ab->hal_rx_ops->rx_desc_get_msdu_payload(rx_desc); + ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 38d9b11eff762..1a8802c37443b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -123,7 +123,7 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); + return ab->hw_params->hal_ops->rx_desc_get_l3_pad_bytes(desc); } static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, @@ -143,7 +143,7 @@ static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc) { - return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); + return ab->hw_params->hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, @@ -151,7 +151,7 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, { u32 tlv_tag; - tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc); + tlv_tag = ab->hw_params->hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); return tlv_tag == HAL_RX_MPDU_START; } diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index db6294ba6771b..a14a7d8dc69f2 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -406,13 +406,6 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return 0; } -const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, -}; -EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); - const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, @@ -423,6 +416,9 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -550,14 +546,6 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return 0; } -const struct hal_rx_ops hal_rx_wcn7850_ops = { - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, - .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, -}; -EXPORT_SYMBOL(hal_rx_wcn7850_ops); - const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, @@ -568,6 +556,10 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 38f07f5a72000..81ceb296cb91c 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1579,13 +1579,6 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) return ret; } -struct hal_rx_ops { - u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); - u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); -}; - struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; @@ -1602,14 +1595,15 @@ struct hal_ops { struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); u32 (*rx_desc_get_desc_size)(void); + u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); + u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); }; extern const struct hal_ops hal_qcn9274_ops; extern const struct hal_ops hal_wcn7850_ops; -extern const struct hal_rx_ops hal_rx_qcn9274_compact_ops; -extern const struct hal_rx_ops hal_rx_wcn7850_ops; - u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, int tid, u32 ba_window_size, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index abdb3b8ff658c..ba8c19c24ae6a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -101,7 +101,6 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; - ab->hal_rx_ops = &hal_rx_qcn9274_compact_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ath12k_core_get_memory_mode(ab); @@ -124,7 +123,6 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = false; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; - ab->hal_rx_ops = &hal_rx_wcn7850_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; From bb679506d8d661a04aa34f43d4d3ef074bb032a4 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:14 +0530 Subject: [PATCH 407/659] wifi: ath12k: Change the API prefixes to ath12k_wifi7 in tx/rx Change the API prefixes to ath12k_wifi7_ from ath12k_ in all the tx and rx related files within wifi7 directory. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 2 +- drivers/net/wireless/ath/ath12k/dbring.c | 5 +- drivers/net/wireless/ath/ath12k/dp.c | 11 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 28 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 36 +- drivers/net/wireless/ath/ath12k/hal.h | 15 +- drivers/net/wireless/ath/ath12k/mac.c | 6 +- drivers/net/wireless/ath/ath12k/pci.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 19 +- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 5 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 372 +++++++++--------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 66 ++-- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 49 +-- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 8 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 161 ++++---- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 82 ++-- .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 13 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 18 +- 18 files changed, 465 insertions(+), 433 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 8d14813365755..f49f117b90754 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -527,7 +527,7 @@ static int ath12k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) struct ath12k_base *ab = irq_grp->ab; int work_done; - work_done = ath12k_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); ath12k_ahb_ext_grp_enable(irq_grp); diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c index 6604dacea2ae5..093298f8acabd 100644 --- a/drivers/net/wireless/ath/ath12k/dbring.c +++ b/drivers/net/wireless/ath/ath12k/dbring.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ @@ -55,7 +54,7 @@ static int ath12k_dbring_bufs_replenish(struct ath12k *ar, cookie = u32_encode_bits(ar->pdev_idx, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); + ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); ath12k_hal_srng_access_end(ab, srng); @@ -298,7 +297,7 @@ int ath12k_dbring_buffer_release_event(struct ath12k_base *ab, num_buff_reaped++; - ath12k_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4cc4006b18bbc..296d7b17c15bd 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -96,7 +96,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) } for (tid--; tid >= 0; tid--) - ath12k_dp_rx_peer_tid_delete(ar, peer, tid); + ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, tid); spin_unlock_bh(&ab->base_lock); @@ -418,7 +418,8 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, spin_unlock_bh(&dp->tx_bank_lock); if (configure_register) - ath12k_hal_tx_configure_bank_register(ab, bank_config, bank_id); + ath12k_wifi7_hal_tx_configure_bank_register(ab, bank_config, + bank_id); ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt tcl bank_id %d input 0x%x match 0x%x num_users %u", bank_id, bank_config, dp->bank_profiles[bank_id].bank_config, @@ -554,7 +555,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } srng = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - ath12k_hal_reo_init_cmd_ring(ab, srng); + ath12k_wifi7_hal_reo_init_cmd_ring(ab, srng); ret = ath12k_dp_srng_setup(ab, &dp->reo_status_ring, HAL_REO_STATUS, 0, 0, DP_REO_STATUS_RING_SIZE); @@ -578,7 +579,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) HAL_HASH_ROUTING_RING_SW3 << 24 | HAL_HASH_ROUTING_RING_SW4 << 28; - ath12k_hal_reo_hw_setup(ab, ring_hash_map); + ath12k_wifi7_hal_reo_hw_setup(ab, ring_hash_map); return 0; @@ -1637,7 +1638,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) } for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++) - ath12k_hal_tx_set_dscp_tid_map(ab, i); + ath12k_wifi7_hal_tx_set_dscp_tid_map(ab, i); ret = ath12k_dp_rx_alloc(ab); if (ret) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index a292658a78c24..9085bf8d3dee1 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1843,7 +1843,7 @@ ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, if (!status_desc) return DP_MON_STATUS_NO_DMA; - ath12k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -1895,7 +1895,7 @@ void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, buf_addr_info = &msdu_link->buf_addr_info; - ath12k_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); *pp_buf_addr_info = buf_addr_info; } @@ -2761,7 +2761,7 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); } ath12k_hal_srng_access_end(ab, srng); @@ -3980,8 +3980,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, pmon->buf_state = DP_MON_STATUS_REPLINISH; break; } - ath12k_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, - &cookie, &rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, + &cookie, &rbm); if (paddr) { buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -4062,12 +4062,12 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, move_next: skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, &buf_id); + hal_params = ab->hw_params->hal_params; if (!skb) { ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - hal_params = ab->hw_params->hal_params; - ath12k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, - hal_params->rx_buf_rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, + hal_params->rx_buf_rbm); num_buffs_reaped++; break; } @@ -4076,9 +4076,9 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, - cookie, - ab->hw_params->hal_params->rx_buf_rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, + cookie, + hal_params->rx_buf_rbm); ath12k_hal_srng_src_get_next_entry(ab, srng); num_buffs_reaped++; } @@ -4247,14 +4247,14 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, list_add_tail(&desc_info->list, used_list); } - ath12k_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); ath12k_dp_mon_next_link_desc_get(msdu_link_desc, &paddr, &sw_cookie, &rbm, &p_buf_addr_info); - ath12k_dp_rx_link_desc_return(ar->ab, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); p_last_buf_addr_info = p_buf_addr_info; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index b4c4bbcce7a92..6771c4409d9dd 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -148,7 +148,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); } goto out; @@ -486,7 +486,7 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, * will be called during core destroy. */ - if (ath12k_dp_reo_cache_flush(ab, &elem->data)) + if (ath12k_wifi7_dp_reo_cache_flush(ab, &elem->data)) break; list_del(&elem->list); @@ -547,8 +547,9 @@ void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, if (rx_tid->dst_ring_desc) { if (rel_link_desc) { buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_dp_rx_link_desc_return(ab, buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return + (ab, buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } kfree(rx_tid->dst_ring_desc); rx_tid->dst_ring_desc = NULL; @@ -570,7 +571,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->rx_tid[i]; - ath12k_dp_rx_peer_tid_delete(ar, peer, i); + ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); spin_unlock_bh(&ar->ab->base_lock); @@ -648,8 +649,8 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid = &peer->rx_tid[tid]; /* Update the tid queue if it is already setup */ if (rx_tid->active) { - ret = ath12k_peer_rx_tid_reo_update(ar, peer, rx_tid, - ba_win_sz, ssn, true); + ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, + ba_win_sz, ssn, true); spin_unlock_bh(&ab->base_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d\n", tid); @@ -677,7 +678,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid->ba_win_sz = ba_win_sz; ahsta = ath12k_sta_to_ahsta(peer->sta); - ret = ath12k_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); + ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); if (ret) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); @@ -703,11 +704,11 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ * and tid with qaddr. */ if (peer->mlo) - ath12k_peer_rx_tid_qref_setup(ab, peer->ml_id, tid, - paddr_aligned); + ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->ml_id, tid, + paddr_aligned); else - ath12k_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, - paddr_aligned); + ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, + paddr_aligned); spin_unlock_bh(&ab->base_lock); } else { @@ -785,7 +786,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return 0; } - ret = ath12k_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); + ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); spin_unlock_bh(&ab->base_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", @@ -834,10 +835,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - ath12k_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, key_cmd); - ret = ath12k_dp_reo_cmd_send(ab, &rx_tid_rxq, - HAL_REO_CMD_UPDATE_RX_QUEUE, - &cmd, NULL); + ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, + key_cmd); + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, + &cmd, NULL); if (ret) { ath12k_warn(ab, "failed to configure rx tid %d queue of peer %pM for pn replay detection %d\n", tid, peer_addr, ret); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 81ceb296cb91c..8d539b72d6677 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1604,13 +1604,14 @@ struct hal_ops { extern const struct hal_ops hal_qcn9274_ops; extern const struct hal_ops hal_wcn7850_ops; -u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); -void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, - int tid, u32 ba_window_size, - u32 start_seq, enum hal_pn_type type); -void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng); -void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); +u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); +void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type); +void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); + void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, struct hal_wbm_idle_scatter_list *sbuf, u32 nsbufs, u32 tot_link_desc, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index cd18ade8fb02e..4e70421fff470 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9227,7 +9227,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (!vif->valid_links || !is_mcast || is_dvlan || (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { - ret = ath12k_dp_tx(ar, arvif, skb, false, 0, is_mcast); + ret = ath12k_wifi7_dp_tx(ar, arvif, skb, false, 0, is_mcast); if (unlikely(ret)) { ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); ieee80211_free_txskb(ar->ah->hw, skb); @@ -9288,8 +9288,8 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, spin_unlock_bh(&tmp_ar->ab->base_lock); skip_peer_find: - ret = ath12k_dp_tx(tmp_ar, tmp_arvif, - msdu_copied, true, mcbc_gsn, is_mcast); + ret = ath12k_wifi7_dp_tx(tmp_ar, tmp_arvif, + msdu_copied, true, mcbc_gsn, is_mcast); if (unlikely(ret)) { if (ret == -ENOMEM) { /* Drops are expected during heavy multicast diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index dfa2896a40757..886ecc0589100 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -500,7 +500,7 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) int work_done; int i; - work_done = ath12k_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); for (i = 0; i < irq_grp->num_irq; i++) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index afe791394e6b4..05c278467cb32 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -12,9 +12,9 @@ #include "dp.h" #include "dp_tx.h" -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget) +int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, + int budget) { struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; @@ -26,11 +26,11 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, if (ab->hw_params->ring_mask->tx[grp_id]) { i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; - ath12k_dp_tx_completion_handler(ab, i); + ath12k_wifi7_dp_tx_completion_handler(ab, i); } if (ab->hw_params->ring_mask->rx_err[grp_id]) { - work_done = ath12k_dp_rx_process_err(ab, napi, budget); + work_done = ath12k_wifi7_dp_rx_process_err(ab, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -38,9 +38,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, } if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { - work_done = ath12k_dp_rx_process_wbm_err(ab, - napi, - budget); + work_done = ath12k_wifi7_dp_rx_process_wbm_err(ab, napi, budget); budget -= work_done; tot_work_done += work_done; @@ -50,8 +48,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, if (ab->hw_params->ring_mask->rx[grp_id]) { i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; - work_done = ath12k_dp_rx_process(ab, i, napi, - budget); + work_done = ath12k_wifi7_dp_rx_process(ab, i, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -120,7 +117,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, } if (ab->hw_params->ring_mask->reo_status[grp_id]) - ath12k_dp_rx_process_reo_status(ab); + ath12k_wifi7_dp_rx_process_reo_status(ab); if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 17255a5671d73..9332b9401bbf7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -9,7 +9,6 @@ #include "hw.h" -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget); +int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, int budget); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index f19c5612bb7c0..76bfa33120f3a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -10,8 +10,8 @@ #include "hal_qcn9274.h" #include "hal_wcn7850.h" -void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, - dma_addr_t paddr) +void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr) { struct ath12k_reo_queue_ref *qref; struct ath12k_dp *dp = &ab->dp; @@ -40,7 +40,8 @@ void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, ath12k_hal_reo_shared_qaddr_cache_clear(ab); } -static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) +static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, + u16 peer_id, u16 tid) { struct ath12k_reo_queue_ref *qref; struct ath12k_dp *dp = &ab->dp; @@ -66,8 +67,8 @@ static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u u32_encode_bits(tid, DP_REO_QREF_NUM); } -void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid) +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; @@ -80,9 +81,9 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); cmd.upd0 = HAL_REO_CMD_UPD0_VLD; - ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - ath12k_dp_rx_tid_del_func); + ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + ath12k_dp_rx_tid_del_func); if (ret) { ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", tid, ret); @@ -93,16 +94,16 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, } if (peer->mlo) - ath12k_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); else - ath12k_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); rx_tid->active = false; } -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action) +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) { struct hal_wbm_release_ring *desc; struct ath12k_dp *dp = &ab->dp; @@ -121,7 +122,7 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, goto exit; } - ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); + ath12k_wifi7_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); exit: ath12k_hal_srng_access_end(ab, srng); @@ -131,11 +132,12 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, return ret; } -int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd, - void (*cb)(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status)) +int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)) { struct ath12k_dp *dp = &ab->dp; struct ath12k_dp_rx_reo_cmd *dp_cmd; @@ -143,7 +145,7 @@ int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_t int cmd_num; cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); + cmd_num = ath12k_wifi7_hal_reo_cmd_send(ab, cmd_ring, type, cmd); /* cmd_num should start from 1, during failure return the error code */ if (cmd_num < 0) @@ -176,11 +178,11 @@ int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_t return 0; } -int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - u32 ba_win_sz, u16 ssn, - bool update_ssn) +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) { struct ath12k_hal_reo_cmd cmd = {}; int ret; @@ -196,9 +198,9 @@ int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); } - ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - NULL); + ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + NULL); if (ret) { ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", rx_tid->tid, ret); @@ -210,23 +212,23 @@ int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, return 0; } -void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid) +void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid) { struct ath12k_hal_reo_cmd cmd = {}; unsigned long tot_desc_sz, desc_sz; int ret; tot_desc_sz = rx_tid->qbuf.size; - desc_sz = ath12k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); + desc_sz = ath12k_wifi7_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); while (tot_desc_sz > desc_sz) { tot_desc_sz -= desc_sz; cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, &cmd, - NULL); + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); if (ret) ath12k_warn(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", @@ -237,9 +239,9 @@ void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, - &cmd, ath12k_dp_reo_cmd_free); + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, + &cmd, ath12k_dp_reo_cmd_free); if (ret) { ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", rx_tid->tid, ret); @@ -250,9 +252,9 @@ void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, } } -int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, - struct ath12k_dp_rx_tid *rx_tid, - u16 ssn, enum hal_pn_type pn_type) +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) { u32 ba_win_sz = rx_tid->ba_win_sz; struct ath12k_reoq_buf *buf; @@ -268,9 +270,10 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, * the actual BA window size in REO tid update path. */ if (tid == HAL_DESC_REO_NON_QOS_TID) - hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); + hw_desc_sz = ath12k_wifi7_hal_reo_qdesc_size(ba_win_sz, tid); else - hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); + hw_desc_sz = ath12k_wifi7_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, + tid); vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); if (!vaddr) @@ -278,8 +281,8 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); - ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, - ssn, pn_type); + ath12k_wifi7_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, + ssn, pn_type); paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, DMA_BIDIRECTIONAL); @@ -300,17 +303,17 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, return 0; } -static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static void ath12k_wifi7_dp_rx_h_csum_offload(struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } -static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct hal_rx_desc_data *rx_info) +static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; @@ -364,13 +367,13 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, if (rx_info->is_mcbc) rx_status->flag |= RX_FLAG_MIC_STRIPPED | - RX_FLAG_ICV_STRIPPED; + RX_FLAG_ICV_STRIPPED; else rx_status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_PN_VALIDATED; } - ath12k_dp_rx_h_csum_offload(msdu, rx_info); + ath12k_wifi7_dp_rx_h_csum_offload(msdu, rx_info); ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, enctype, is_decrypted, rx_info); @@ -383,11 +386,11 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, } } -static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, - struct sk_buff_head *msdu_list, - struct sk_buff *first, struct sk_buff *last, - u8 l3pad_bytes, int msdu_len, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k *ar, + struct sk_buff_head *msdu_list, + struct sk_buff *first, struct sk_buff *last, + u8 l3pad_bytes, int msdu_len, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct sk_buff *skb; @@ -471,10 +474,10 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, return 0; } -static int ath12k_dp_rx_process_msdu(struct ath12k *ar, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; @@ -521,10 +524,10 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { - ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, - msdu, last_buf, - l3_pad_bytes, msdu_len, - rx_info); + ret = ath12k_wifi7_dp_rx_msdu_coalesce(ar, msdu_list, + msdu, last_buf, + l3_pad_bytes, msdu_len, + rx_info); if (ret) { ath12k_warn(ab, "failed to coalesce msdu rx buffer%d\n", ret); @@ -539,7 +542,7 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, } ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; @@ -549,10 +552,11 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, return ret; } -static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, - struct napi_struct *napi, - struct sk_buff_head *msdu_list, - int ring_id) +static void +ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, + struct napi_struct *napi, + struct sk_buff_head *msdu_list, + int ring_id) { struct ath12k_hw_group *ag = ab->ag; struct ieee80211_rx_status rx_status = {}; @@ -591,7 +595,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, continue; } - ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); + ret = ath12k_wifi7_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); if (ret) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process msdu %d", ret); @@ -605,8 +609,8 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, rcu_read_unlock(); } -int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, - struct napi_struct *napi, int budget) +int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, + struct napi_struct *napi, int budget) { struct ath12k_hw_group *ag = ab->ag; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; @@ -758,17 +762,17 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, num_buffs_reaped[device_id]); } - ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, - ring_id); + ath12k_wifi7_dp_rx_process_received_packets(ab, napi, &msdu_list, + ring_id); exit: return total_msdu_reaped; } static bool -ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, - struct ath12k_dp_rx_tid *rx_tid, - enum hal_encrypt_type encrypt_type) +ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_encrypt_type encrypt_type) { struct sk_buff *first_frag, *skb; u64 last_pn; @@ -795,9 +799,9 @@ ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, return true; } -static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff *defrag_skb) +static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff *defrag_skb) { struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = &ab->dp; @@ -820,8 +824,8 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, link_desc_banks = dp->link_desc_banks; reo_dest_ring = rx_tid->dst_ring_desc; - ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, - &link_paddr, &cookie); + ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, + &link_paddr, &cookie); desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + @@ -870,9 +874,9 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; - ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, - desc_info->cookie, - HAL_RX_BUF_RBM_SW3_BM); + ath12k_wifi7_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, + desc_info->cookie, + HAL_RX_BUF_RBM_SW3_BM); /* Fill mpdu details into reo entrance ring */ srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; @@ -889,9 +893,8 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, } memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); - ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, - cookie, - idle_link_rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, + cookie, idle_link_rbm); mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) | u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) | @@ -942,11 +945,11 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } -static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, - struct ath12k_peer *peer, - enum hal_encrypt_type enctype, - struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k *ar, + struct ath12k_peer *peer, + enum hal_encrypt_type enctype, + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; @@ -982,7 +985,8 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, data_len = msdu->len - head_len - tail_len; key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; - ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); + ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, + data_len, mic); if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) goto mic_fail; @@ -1009,12 +1013,12 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, return -EINVAL; } -static int ath12k_dp_rx_h_defrag(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff **defrag_skb, - enum hal_encrypt_type enctype, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff **defrag_skb, + enum hal_encrypt_type enctype, + struct hal_rx_desc_data *rx_info) { struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; @@ -1038,7 +1042,7 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, flags |= RX_FLAG_IV_STRIPPED; if (skb != last_frag) flags |= RX_FLAG_ICV_STRIPPED | - RX_FLAG_MIC_STRIPPED; + RX_FLAG_MIC_STRIPPED; } /* RX fragments are always raw packets */ @@ -1067,17 +1071,17 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) + if (ath12k_wifi7_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) first_frag = NULL; *defrag_skb = first_frag; return 0; } -static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_reo_dest_ring *ring_desc, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_reo_dest_ring *ring_desc, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct ath12k_peer *peer; @@ -1155,8 +1159,8 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, goto out_unlock; } } else { - ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } if (!rx_tid->last_frag_no || @@ -1174,17 +1178,17 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, if (!peer) goto err_frags_cleanup; - if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) + if (!ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) goto err_frags_cleanup; - if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, - enctype, rx_info)) + if (ath12k_wifi7_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, + enctype, rx_info)) goto err_frags_cleanup; if (!defrag_skb) goto err_frags_cleanup; - if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) goto err_frags_cleanup; ath12k_dp_rx_frags_cleanup(rx_tid, false); @@ -1199,9 +1203,10 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, } static int -ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, - struct list_head *used_list, - bool drop, u32 cookie) +ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, + struct hal_reo_dest_ring *desc, + struct list_head *used_list, + bool drop, u32 cookie) { struct ath12k_base *ab = ar->ab; struct sk_buff *msdu; @@ -1270,18 +1275,18 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, skb_put(msdu, hal_rx_desc_sz + msdu_len); - if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { + if (ath12k_wifi7_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); - ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } exit: rcu_read_unlock(); return 0; } -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget) +int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) { struct ath12k_hw_group *ag = ab->ag; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; @@ -1304,6 +1309,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, bool is_frag; bool drop; int pdev_id; + struct list_head *used_list; + enum hal_wbm_rel_bm_act act; tot_n_bufs_reaped = 0; quota = budget; @@ -1324,8 +1331,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, drop = false; ab->device_stats.err_ring_pkts++; - ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, - &desc_bank); + ret = ath12k_wifi7_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); if (ret) { ath12k_warn(ab, "failed to parse error reo desc %d\n", ret); @@ -1344,16 +1351,17 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, link_desc_banks = partner_ab->dp.link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + (paddr - link_desc_banks[desc_bank].paddr); - ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, - &rbm); + ath12k_wifi7_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, + msdu_cookies, &rbm); if (rbm != partner_ab->dp.idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + act = HAL_WBM_REL_BM_ACT_REL_MSDU; ab->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_REL_MSDU); + ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + act); continue; } @@ -1368,18 +1376,21 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, if (!is_frag || num_msdus > 1 || partner_ab->device_id != ab->device_id) { drop = true; + act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; /* Return the link desc back to wbm idle list */ - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + act); } for (i = 0; i < num_msdus; i++) { - if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, - &rx_desc_used_list[device_id], - drop, - msdu_cookies[i])) { + used_list = &rx_desc_used_list[device_id]; + + if (!ath12k_wifi7_dp_process_rx_err_buf(ar, reo_desc, + used_list, + drop, + msdu_cookies[i])) { num_buffs_reaped[device_id]++; tot_n_bufs_reaped++; } @@ -1413,9 +1424,9 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, return tot_n_bufs_reaped; } -static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, - int msdu_len, - struct sk_buff_head *msdu_list) +static void +ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, + struct sk_buff_head *msdu_list) { struct sk_buff *skb, *tmp; struct ath12k_skb_rxcb *rxcb; @@ -1437,9 +1448,9 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, } } -static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info, - struct sk_buff_head *msdu_list) +static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info, + struct sk_buff_head *msdu_list) { struct ath12k_base *ab = ar->ab; u16 msdu_len = rx_info->msdu_len; @@ -1451,7 +1462,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); - ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + ath12k_wifi7_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); return -EINVAL; } @@ -1491,7 +1502,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, return -EINVAL; ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, desc, rx_info); rxcb->tid = rx_info->tid; @@ -1502,8 +1513,8 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, return 0; } -static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; u16 msdu_len = rx_info->msdu_len; @@ -1539,8 +1550,8 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, return false; } -static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; @@ -1551,7 +1562,7 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + drop = ath12k_wifi7_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); break; } fallthrough; @@ -1566,9 +1577,9 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, return drop; } -static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info, - struct sk_buff_head *msdu_list) +static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info, + struct sk_buff_head *msdu_list) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; @@ -1577,7 +1588,7 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, switch (rxcb->err_code) { case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: - if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + if (ath12k_wifi7_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) drop = true; break; case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: @@ -1597,10 +1608,10 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, return drop; } -static void ath12k_dp_rx_wbm_err(struct ath12k *ar, - struct napi_struct *napi, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list) +static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, + struct napi_struct *napi, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list) { struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); @@ -1615,10 +1626,10 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: - drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + drop = ath12k_wifi7_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); break; case HAL_WBM_REL_SRC_MODULE_RXDMA: - drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + drop = ath12k_wifi7_dp_rx_h_rxdma_err(ar, msdu, &rx_info); break; default: /* msdu will get freed */ @@ -1635,9 +1646,9 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); } -void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, enum set_key_cmd key_cmd) +void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd) { cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; cmd->upd0 = HAL_REO_CMD_UPD0_PN | @@ -1665,8 +1676,8 @@ void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); } -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget) +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_group *ag = ab->ag; @@ -1705,7 +1716,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!rx_desc) break; - ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); + ret = ath12k_wifi7_hal_wbm_desc_parse_err(ab, rx_desc, + &err_info); if (ret) { ath12k_warn(ab, "failed to parse rx error in wbm_rel ring desc %d\n", @@ -1862,7 +1874,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; } - ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + ath12k_wifi7_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); } rcu_read_unlock(); done: @@ -1950,7 +1962,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) } EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; struct hal_tlv_64_hdr *hdr; @@ -1973,32 +1985,32 @@ void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) switch (tag) { case HAL_REO_GET_QUEUE_STATS_STATUS: - ath12k_hal_reo_status_queue_stats(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_status_queue_stats(ab, hdr, + &reo_status); break; case HAL_REO_FLUSH_QUEUE_STATUS: - ath12k_hal_reo_flush_queue_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_flush_queue_status(ab, hdr, + &reo_status); break; case HAL_REO_FLUSH_CACHE_STATUS: - ath12k_hal_reo_flush_cache_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_flush_cache_status(ab, hdr, + &reo_status); break; case HAL_REO_UNBLOCK_CACHE_STATUS: - ath12k_hal_reo_unblk_cache_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_unblk_cache_status(ab, hdr, + &reo_status); break; case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: - ath12k_hal_reo_flush_timeout_list_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, hdr, + &reo_status); break; case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: - ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, hdr, + &reo_status); break; case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: - ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, hdr, + &reo_status); break; default: ath12k_warn(ab, "Unknown reo status type %d\n", tag); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index f258472bc1fc6..35709dfccbcf3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -9,41 +9,41 @@ #include "../core.h" #include "../dp_rx.h" -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget); -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget); -int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, - struct napi_struct *napi, - int budget); -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget); +int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget); +int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int mac_id, + struct napi_struct *napi, + int budget); +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); -void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, enum set_key_cmd key_cmd); -int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, - struct ath12k_dp_rx_tid *rx_tid, - u16 ssn, enum hal_pn_type pn_type); -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action); -void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, - dma_addr_t paddr); -void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid); -int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd, - void (*cb)(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status)); -void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid); -int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - u32 ba_win_sz, u16 ssn, - bool update_ssn); +void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd); +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type); +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); +void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr); +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid); +int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)); +void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid); +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn); static inline void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, struct hal_rx_desc_data *rx_info, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 49d219a195c5e..b3928c3d007df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -10,9 +10,10 @@ #include "../peer.h" #include "dp_tx.h" -static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, - struct hal_tx_msdu_ext_desc *tcl_ext_cmd, - struct hal_tx_info *ti) +static void +ath12k_wifi7_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, + struct hal_tx_msdu_ext_desc *tcl_ext_cmd, + struct hal_tx_info *ti) { tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr, HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO); @@ -31,7 +32,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, #define HTT_META_DATA_ALIGNMENT 0x8 /* Preparing HTT Metadata when utilized with ext MSDU */ -static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) +static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb) { struct hal_tx_msdu_metadata *desc_ext; u8 htt_desc_size; @@ -53,9 +54,9 @@ static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) return 0; } -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast) +int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast) { struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = &ab->dp; @@ -268,10 +269,10 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, memset(skb_ext_desc->data, 0, skb_ext_desc->len); msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data; - ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); + ath12k_wifi7_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); if (add_htt_metadata) { - ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc); + ret = ath12k_wifi7_dp_prepare_htt_metadata(skb_ext_desc); if (ret < 0) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "Failed to add HTT meta data, dropping packet\n"); @@ -336,7 +337,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ab->device_stats.tx_enqueued[ti.ring_id]++; - ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); + ath12k_wifi7_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); ath12k_hal_srng_access_end(ab, tcl_ring); @@ -507,7 +508,8 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, } } -static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) +static void +ath12k_wifi7_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) { struct ath12k_base *ab = ar->ab; struct ath12k_peer *peer; @@ -625,10 +627,10 @@ static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status spin_unlock_bh(&ab->base_lock); } -static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, - struct ath12k_tx_desc_params *desc_params, - struct hal_tx_status *ts, - int ring) +static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, + struct ath12k_tx_desc_params *desc_params, + struct hal_tx_status *ts, + int ring) { struct ath12k_base *ab = ar->ab; struct ath12k_hw *ah = ar->ah; @@ -734,7 +736,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, * Might end up reporting it out-of-band from HTT stats. */ - ath12k_dp_tx_update_txcompl(ar, ts); + ath12k_wifi7_dp_tx_update_txcompl(ar, ts); spin_lock_bh(&ab->base_lock); peer = ath12k_peer_find_by_id(ab, ts->peer_id); @@ -767,9 +769,10 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, rcu_read_unlock(); } -static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, - struct hal_wbm_completion_ring_tx *desc, - struct hal_tx_status *ts) +static void +ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, + struct hal_wbm_completion_ring_tx *desc, + struct hal_tx_status *ts) { u32 info0 = le32_to_cpu(desc->rate_stats.info0); @@ -803,7 +806,7 @@ static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, } } -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) { struct ath12k *ar; struct ath12k_dp *dp = &ab->dp; @@ -854,7 +857,7 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) tx_ring->tx_status_tail = ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; - ath12k_dp_tx_status_parse(ab, tx_status, &ts); + ath12k_wifi7_dp_tx_status_parse(ab, tx_status, &ts); if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { /* HW done cookie conversion */ @@ -902,7 +905,7 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); - ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts, - tx_ring->tcl_data_ring_id); + ath12k_wifi7_dp_tx_complete_msdu(ar, &desc_params, &ts, + tx_ring->tcl_data_ring_id); } } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 42faf664f8f8b..061c4de4d4e62 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -7,8 +7,8 @@ #ifndef ATH12K_DP_TX_WIFI7_H #define ATH12K_DP_TX_WIFI7_H -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast); -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast); +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index e539f3b1eeafc..dc3447b74d791 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -11,8 +11,9 @@ #include "hal_rx.h" #include "hal_desc.h" -static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, - u8 owner, u8 buffer_type, u32 magic) +static +void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, + u8 owner, u8 buffer_type, u32 magic) { hdr->info0 = le32_encode_bits(owner, HAL_DESC_HDR_INFO0_OWNER) | le32_encode_bits(buffer_type, HAL_DESC_HDR_INFO0_BUF_TYPE); @@ -21,8 +22,8 @@ static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, hdr->info0 |= le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED); } -static int ath12k_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, - struct ath12k_hal_reo_cmd *cmd) +static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, + struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_get_queue_stats *desc; @@ -45,9 +46,9 @@ static int ath12k_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -static int ath12k_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, - struct hal_tlv_64_hdr *tlv, - struct ath12k_hal_reo_cmd *cmd) +static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, + struct hal_tlv_64_hdr *tlv, + struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_flush_cache *desc; u8 avail_slot = ffz(hal->avail_blk_resource); @@ -95,8 +96,9 @@ static int ath12k_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -static int ath12k_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, - struct ath12k_hal_reo_cmd *cmd) +static int +ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, + struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_update_rx_queue *desc; @@ -220,9 +222,9 @@ static int ath12k_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd) +int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd) { struct hal_tlv_64_hdr *reo_desc; int ret; @@ -238,13 +240,14 @@ int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, switch (type) { case HAL_REO_CMD_GET_QUEUE_STATS: - ret = ath12k_hal_reo_cmd_queue_stats(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_queue_stats(reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_CACHE: - ret = ath12k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, + cmd); break; case HAL_REO_CMD_UPDATE_RX_QUEUE: - ret = ath12k_hal_reo_cmd_update_rx_queue(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_QUEUE: case HAL_REO_CMD_UNBLOCK_CACHE: @@ -265,8 +268,9 @@ int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, return ret; } -void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, - dma_addr_t paddr, u32 cookie, u8 manager) +void ath12k_wifi7_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, + u8 manager) { u32 paddr_lo, paddr_hi; @@ -278,9 +282,9 @@ void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, le32_encode_bits(manager, BUFFER_ADDR_INFO1_RET_BUF_MGR); } -void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, - dma_addr_t *paddr, - u32 *cookie, u8 *rbm) +void ath12k_wifi7_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, + u32 *cookie, u8 *rbm) { *paddr = (((u64)le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_ADDR)) << 32) | le32_get_bits(binfo->info0, BUFFER_ADDR_INFO0_ADDR); @@ -288,9 +292,10 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, *rbm = le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_RET_BUF_MGR); } -void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, - u32 *msdu_cookies, - enum hal_rx_buf_return_buf_manager *rbm) +void +ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, + u32 *num_msdus, u32 *msdu_cookies, + enum hal_rx_buf_return_buf_manager *rbm) { struct hal_rx_msdu_details *msdu; u32 val; @@ -317,9 +322,9 @@ void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_ms } } -int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, - struct hal_reo_dest_ring *desc, - dma_addr_t *paddr, u32 *desc_bank) +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, + struct hal_reo_dest_ring *desc, + dma_addr_t *paddr, u32 *desc_bank) { enum hal_reo_dest_ring_push_reason push_reason; enum hal_reo_dest_ring_error_code err_code; @@ -338,14 +343,15 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, return -EINVAL; } - ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie); + ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, + &cookie); *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); return 0; } -int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, - struct hal_rx_wbm_rel_info *rel_info) +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, + struct hal_rx_wbm_rel_info *rel_info) { struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; @@ -432,9 +438,9 @@ int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, return 0; } -void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, - dma_addr_t *paddr, u32 *cookie) +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, + struct ath12k_buffer_addr *buff_addr, + dma_addr_t *paddr, u32 *cookie) { *paddr = ((u64)(le32_get_bits(buff_addr->info1, BUFFER_ADDR_INFO1_ADDR)) << 32) | @@ -523,10 +529,11 @@ void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, *num_msdus = i; } -void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, - struct hal_wbm_release_ring *desc, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action) +void +ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, + struct hal_wbm_release_ring *desc, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) { desc->buf_addr_info = *buf_addr_info; desc->info0 |= le32_encode_bits(HAL_WBM_REL_SRC_MODULE_SW, @@ -536,8 +543,9 @@ void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, HAL_WBM_RELEASE_INFO0_DESC_TYPE); } -void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_get_queue_stats_status *desc = (struct hal_reo_get_queue_stats_status *)tlv->value; @@ -599,8 +607,9 @@ void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64 HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT)); } -void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_flush_queue_status *desc = (struct hal_reo_flush_queue_status *)tlv->value; @@ -616,8 +625,10 @@ void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, struct hal_tlv_64 HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED); } -void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void +ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; struct hal_reo_flush_cache_status *desc = @@ -657,8 +668,9 @@ void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, struct hal_tlv_64 HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT); } -void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; struct hal_reo_unblock_cache_status *desc = @@ -684,9 +696,10 @@ void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, struct hal_tlv_64 hal->avail_blk_resource &= ~BIT(hal->current_blk_index); } -void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void +ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_flush_timeout_list_status *desc = (struct hal_reo_flush_timeout_list_status *)tlv->value; @@ -713,9 +726,10 @@ void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT); } -void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void +ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_desc_thresh_reached_status *desc = (struct hal_reo_desc_thresh_reached_status *)tlv->value; @@ -748,9 +762,9 @@ void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM); } -void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_status_hdr *desc = (struct hal_reo_status_hdr *)tlv->value; @@ -763,7 +777,7 @@ void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); } -u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) +u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) { u32 num_ext_desc, num_1k_desc = 0; @@ -789,15 +803,15 @@ u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) (num_1k_desc * sizeof(struct hal_rx_reo_queue_1k)); } -void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, - int tid, u32 ba_window_size, - u32 start_seq, enum hal_pn_type type) +void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type) { struct hal_rx_reo_queue_ext *ext_desc; - ath12k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); + ath12k_wifi7_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); qdesc->rx_queue_num = le32_encode_bits(tid, HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER); @@ -855,21 +869,24 @@ void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, * queue descriptor in Rx peer entry as part of dp_rx_tid_update. */ memset(ext_desc, 0, 3 * sizeof(*ext_desc)); - ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_EXT_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); + ath12k_wifi7_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); ext_desc++; - ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_EXT_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); + ath12k_wifi7_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); ext_desc++; - ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_EXT_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); + ath12k_wifi7_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); } -void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng) +void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, + struct hal_srng *srng) { struct hal_srng_params params; struct hal_tlv_64_hdr *tlv; @@ -893,7 +910,7 @@ void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, } } -void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) +void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 val; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index d8d9d469c6704..458282343ff30 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -822,47 +822,47 @@ enum hal_mon_reception_type { #define HAL_RU_PER80(ru_per80, num_80mhz, ru_idx_per80mhz) \ (HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz)) -void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, - u32 *msdu_cookies, - enum hal_rx_buf_return_buf_manager *rbm); -void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, - struct hal_wbm_release_ring *desc, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action); -void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, - dma_addr_t paddr, u32 cookie, u8 manager); -void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, - dma_addr_t *paddr, - u32 *cookie, u8 *rbm); -int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, - struct hal_reo_dest_ring *desc, - dma_addr_t *paddr, u32 *desc_bank); -int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, - struct hal_rx_wbm_rel_info *rel_info); -void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, - dma_addr_t *paddr, u32 *cookie); +void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, + u32 *msdu_cookies, + enum hal_rx_buf_return_buf_manager *rbm); +void ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, + struct hal_wbm_release_ring *desc, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); +void ath12k_wifi7_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager); +void ath12k_wifi7_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, + u32 *cookie, u8 *rbm); +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, + struct hal_reo_dest_ring *desc, + dma_addr_t *paddr, u32 *desc_bank); +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, + struct hal_rx_wbm_rel_info *rel_info); +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, + struct ath12k_buffer_addr *buff_addr, + dma_addr_t *paddr, u32 *cookie); void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 3a7d3163b1a56..027e02141ec2c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -29,9 +29,9 @@ static inline u8 dscp2tid(u8 dscp) return dscp >> 3; } -void ath12k_hal_tx_cmd_desc_setup(struct ath12k_base *ab, - struct hal_tcl_data_cmd *tcl_cmd, - struct hal_tx_info *ti) +void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab, + struct hal_tcl_data_cmd *tcl_cmd, + struct hal_tx_info *ti) { tcl_cmd->buf_addr_info.info0 = le32_encode_bits(ti->paddr, BUFFER_ADDR_INFO0_ADDR); @@ -66,7 +66,7 @@ void ath12k_hal_tx_cmd_desc_setup(struct ath12k_base *ab, tcl_cmd->info5 = 0; } -void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) +void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) { u32 ctrl_reg_val; u32 addr; @@ -137,8 +137,9 @@ void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) ctrl_reg_val); } -void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, u32 bank_config, - u8 bank_id) +void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, + u8 bank_id) { ath12k_hif_write32(ab, HAL_TCL_SW_CONFIG_BANK_ADDR + 4 * bank_id, bank_config); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index 412fe1ba22dcc..d0f6a174f347c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -181,13 +181,13 @@ struct hal_tx_fes_status_end { /* STA mode will have MCAST_PKT_CTRL instead of DSCP_TID_MAP bitfield */ #define HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID GENMASK(22, 17) -void ath12k_hal_tx_cmd_desc_setup(struct ath12k_base *ab, - struct hal_tcl_data_cmd *tcl_cmd, - struct hal_tx_info *ti); -void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); -int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd); -void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, u32 bank_config, - u8 bank_id); +void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab, + struct hal_tcl_data_cmd *tcl_cmd, + struct hal_tx_info *ti); +void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); +int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd); +void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, u8 bank_id); #endif From eb57c691ed6d18a64cacdf5c96aa11cd3fb42704 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:00 +0530 Subject: [PATCH 408/659] wifi: ath12k: Convert ath12k_dp member in ath12k_base to pointer Currently, the Data Path (DP) specific device object (ath12k_dp) is embedded directly within the ath12k_base structure. The DP object cannot be extended with architecture-specific fields within a contiguous memory block with this design. To address this, convert ath12k_dp into a dynamically allocated object and store it as a pointer in ath12k_base. This change allows allocation and initialization of ath12k_dp based on the underlying hardware architecture. Architecture-specific fields can now be maintained as private data within a contiguous memory block of ath12k_dp. This patch (and the forthcoming patches) are intended to serve the purpose of refactoring different DP objects for the Next Generation ath12k driver. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 2 +- drivers/net/wireless/ath/ath12k/core.h | 12 +++- drivers/net/wireless/ath/ath12k/dp.c | 58 +++++++++++-------- drivers/net/wireless/ath/ath12k/dp_htt.c | 22 ++++--- drivers/net/wireless/ath/ath12k/dp_mon.c | 15 +++-- drivers/net/wireless/ath/ath12k/dp_rx.c | 20 +++---- drivers/net/wireless/ath/ath12k/mac.c | 4 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 40 ++++++++----- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 4 +- drivers/net/wireless/ath/ath12k/wmi.c | 3 +- 11 files changed, 110 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index ca38f1f133708..4b9a49eaa3396 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -896,7 +896,7 @@ static int ath12k_core_start(struct ath12k_base *ab) goto err_hif_stop; } - ret = ath12k_dp_htt_connect(&ab->dp); + ret = ath12k_dp_htt_connect(ath12k_ab_to_dp(ab)); if (ret) { ath12k_err(ab, "failed to connect to HTT: %d\n", ret); goto err_hif_stop; diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 985616950b0d7..28bf34e420195 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1060,7 +1060,7 @@ struct ath12k_base { struct ath12k_htc htc; - struct ath12k_dp dp; + struct ath12k_dp *dp; void __iomem *mem; unsigned long mem_len; @@ -1521,4 +1521,14 @@ static inline s32 ath12k_pdev_get_noise_floor(struct ath12k *ar) return ar->rssi_info.noise_floor; } +/* The @ab->dp NULL check or assertion is intentionally omitted because + * @ab->dp is guaranteed to be non-NULL after a successful probe and + * remains valid until teardown. Invoking this before allocation or + * after teardown is considered invalid usage. + */ +static inline struct ath12k_dp *ath12k_ab_to_dp(struct ath12k_base *ab) +{ + return ab->dp; +} + #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 296d7b17c15bd..5a76bc58dab8d 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -437,7 +437,7 @@ void ath12k_dp_tx_put_bank_profile(struct ath12k_dp *dp, u8 bank_id) static void ath12k_dp_deinit_bank_profiles(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); kfree(dp->bank_profiles); dp->bank_profiles = NULL; @@ -445,7 +445,7 @@ static void ath12k_dp_deinit_bank_profiles(struct ath12k_base *ab) static int ath12k_dp_init_bank_profiles(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 num_tcl_banks = ab->hw_params->num_tcl_banks; int i; @@ -468,7 +468,7 @@ static int ath12k_dp_init_bank_profiles(struct ath12k_base *ab) static void ath12k_dp_srng_common_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; ath12k_dp_srng_cleanup(ab, &dp->reo_status_ring); @@ -485,7 +485,7 @@ static void ath12k_dp_srng_common_cleanup(struct ath12k_base *ab) static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *map; struct hal_srng *srng; int i, ret, tx_comp_ring_num; @@ -591,7 +591,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) static void ath12k_dp_scatter_idle_link_desc_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_wbm_idle_scatter_list *slist = dp->scatter_list; int i; @@ -611,7 +611,7 @@ static int ath12k_dp_scatter_idle_link_desc_setup(struct ath12k_base *ab, u32 n_link_desc, u32 last_bank_sz) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_link_desc_bank *link_desc_banks = dp->link_desc_banks; struct hal_wbm_idle_scatter_list *slist = dp->scatter_list; u32 n_entries_per_buf; @@ -705,7 +705,7 @@ static int ath12k_dp_link_desc_bank_alloc(struct ath12k_base *ab, int n_link_desc_bank, int last_bank_sz) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; int ret = 0; int desc_sz = DP_LINK_DESC_ALLOC_SIZE_THRESH; @@ -753,7 +753,7 @@ void ath12k_dp_link_desc_cleanup(struct ath12k_base *ab, static int ath12k_wbm_idle_ring_setup(struct ath12k_base *ab, u32 *n_link_desc) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 n_mpdu_link_desc, n_mpdu_queue_desc; u32 n_tx_msdu_link_desc, n_rx_msdu_link_desc; int ret = 0; @@ -792,6 +792,7 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, u32 ring_type, struct hal_srng *srng, u32 n_link_desc) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 tot_mem_sz; u32 n_link_desc_bank, last_bank_sz; u32 entry_sz, align_bytes, n_entries; @@ -799,7 +800,7 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, u32 paddr; int i, ret; u32 cookie; - enum hal_rx_buf_return_buf_manager rbm = ab->dp.idle_link_rbm; + enum hal_rx_buf_return_buf_manager rbm = dp->idle_link_rbm; tot_mem_sz = n_link_desc * HAL_LINK_DESC_SIZE; tot_mem_sz += HAL_LINK_DESC_ALIGN; @@ -967,7 +968,7 @@ void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif) ath12k_dp_update_vdev_search(arvif); arvif->vdev_id_check_en = true; - arvif->bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, &ab->dp); + arvif->bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, ath12k_ab_to_dp(ab)); /* TODO: error path for bank id failure */ if (arvif->bank_id == DP_INVALID_BANK_ID) { @@ -980,7 +981,7 @@ static void ath12k_dp_cc_cleanup(struct ath12k_base *ab) { struct ath12k_rx_desc_info *desc_info; struct ath12k_tx_desc_info *tx_desc_info, *tmp1; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_skb_cb *skb_cb; struct sk_buff *skb; struct ath12k *ar; @@ -1103,7 +1104,7 @@ static void ath12k_dp_cc_cleanup(struct ath12k_base *ab) static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); if (!ab->hw_params->reoq_lut_support) return; @@ -1131,7 +1132,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) void ath12k_dp_free(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; if (!dp->ab) @@ -1154,7 +1155,8 @@ void ath12k_dp_free(struct ath12k_base *ab) ath12k_dp_rx_free(ab); /* Deinit any SOC level resource */ - dp->ab = NULL; + kfree(ab->dp); + ab->dp = NULL; } void ath12k_dp_cc_config(struct ath12k_base *ab) @@ -1218,7 +1220,7 @@ static u32 ath12k_dp_cc_cookie_gen(u16 ppt_idx, u16 spt_idx) static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab, u16 ppt_idx, u16 spt_idx) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); return dp->spt_info[ppt_idx].vaddr + spt_idx; } @@ -1226,7 +1228,7 @@ static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab, struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, u32 cookie) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info **desc_addr_ptr; u16 start_ppt_idx, end_ppt_idx, ppt_idx, spt_idx; @@ -1272,7 +1274,7 @@ struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_descs, **rx_desc_addr; struct ath12k_tx_desc_info *tx_descs, **tx_desc_addr; u32 num_rx_spt_pages = ATH12K_NUM_RX_SPT_PAGES(ab); @@ -1401,7 +1403,7 @@ void ath12k_dp_partner_cc_init(struct ath12k_base *ab) if (ag->ab[i] == ab) continue; - ath12k_dp_cmem_init(ab, &ag->ab[i]->dp, ATH12K_DP_RX_DESC); + ath12k_dp_cmem_init(ab, ath12k_ab_to_dp(ag->ab[i]), ATH12K_DP_RX_DESC); } } @@ -1412,7 +1414,7 @@ static u32 ath12k_dp_get_num_spt_pages(struct ath12k_base *ab) static int ath12k_dp_cc_init(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i, ret = 0; INIT_LIST_HEAD(&dp->rx_desc_free_list); @@ -1498,7 +1500,7 @@ static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab, static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 val; int ret; @@ -1564,13 +1566,19 @@ ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab) int ath12k_dp_alloc(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp; struct hal_srng *srng = NULL; size_t size = 0; u32 n_link_desc = 0; int ret; int i; + /* TODO: align dp later if cache alignment becomes a bottleneck */ + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + + ab->dp = dp; dp->ab = ab; INIT_LIST_HEAD(&dp->reo_cmd_list); @@ -1585,7 +1593,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret); - return ret; + goto fail_dp_free; } srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id]; @@ -1594,7 +1602,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) HAL_WBM_IDLE_LINK, srng, n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup link desc: %d\n", ret); - return ret; + goto fail_dp_free; } ret = ath12k_dp_cc_init(ab); @@ -1667,5 +1675,9 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); +fail_dp_free: + kfree(ab->dp); + ab->dp = NULL; + return ret; } diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 6ab5b2d8aac94..267220f43fd2c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -582,7 +582,7 @@ static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab, void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, struct sk_buff *skb) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data; enum htt_t2h_msg_type type; u16 peer_id; @@ -734,6 +734,7 @@ ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, int mac_id, enum hal_ring_type ring_type) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_srng_setup_cmd *cmd; struct hal_srng *srng = &ab->hal.srng_list[ring_id]; struct hal_srng_params params; @@ -835,7 +836,7 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n", ring_id, ring_type, cmd->intr_info, cmd->info2); - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); if (ret) goto err_free; @@ -849,7 +850,7 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct sk_buff *skb; struct htt_ver_req_cmd *cmd; int len = sizeof(*cmd); @@ -901,7 +902,7 @@ int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct sk_buff *skb; struct htt_ppdu_stats_cfg_cmd *cmd; int len = sizeof(*cmd); @@ -938,6 +939,7 @@ int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, int rx_buf_size, struct htt_rx_ring_tlv_filter *tlv_filter) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_selection_cfg_cmd *cmd; struct hal_srng *srng = &ab->hal.srng_list[ring_id]; struct hal_srng_params params; @@ -1070,7 +1072,7 @@ int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); } - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); if (ret) goto err_free; @@ -1088,7 +1090,7 @@ ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, u64 cookie) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct sk_buff *skb; struct htt_ext_stats_cfg_cmd *cmd; int len = sizeof(*cmd); @@ -1144,6 +1146,7 @@ int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset) int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) { struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_tlv_filter tlv_filter = {}; int ret, ring_id, i; @@ -1207,7 +1210,7 @@ int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) if (!reset) { for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mac_buf_ring[i].ring_id; + ring_id = dp->rx_mac_buf_ring[i].ring_id; ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, i, HAL_RXDMA_BUF, @@ -1223,7 +1226,7 @@ int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) } for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; + ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; if (!reset) { tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; @@ -1250,6 +1253,7 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, int tx_buf_size, struct htt_tx_ring_tlv_filter *htt_tlv_filter) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_tx_ring_selection_cfg_cmd *cmd; struct hal_srng *srng = &ab->hal.srng_list[ring_id]; struct hal_srng_params params; @@ -1342,7 +1346,7 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, cmd->tlv_filter_mask_in3 = cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2); - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); if (ret) goto err_free; diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 9085bf8d3dee1..c853c96ab220c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2470,7 +2470,8 @@ ath12k_dp_mon_parse_status_buf(struct ath12k *ar, const struct dp_mon_packet_info *packet_info) { struct ath12k_base *ab = ar->ab; - struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct dp_rxdma_mon_ring *buf_ring = &dp->rxdma_mon_buf_ring; struct sk_buff *msdu; int buf_id; u32 offset; @@ -3782,7 +3783,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, struct ath12k_pdev_dp *pdev_dp = &ar->dp; struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_mon_dest_desc *mon_dst_desc; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb; @@ -3962,7 +3963,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, u8 rbm; ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; - dp = &ab->dp; + dp = ath12k_ab_to_dp(ab); pmon = &ar->dp.mon_data; srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; @@ -4096,6 +4097,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, u32 *npackets, u32 *ppdu_id) { struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; u32 rx_buf_size, rx_pkt_offset, sw_cookie; @@ -4147,8 +4150,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); msdu_link_desc = - ar->ab->dp.link_desc_banks[desc_bank].vaddr + - (paddr - ar->ab->dp.link_desc_banks[desc_bank].paddr); + dp->link_desc_banks[desc_bank].vaddr + + (paddr - dp->link_desc_banks[desc_bank].paddr); ath12k_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, &num_msdus); @@ -4286,8 +4289,8 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, struct ath12k_pdev_mon_stats *rx_mon_stats; u32 ppdu_id, rx_bufs_used = 0, ring_id; u32 mpdu_rx_bufs_used, npackets = 0; - struct ath12k_dp *dp = &ar->ab->dp; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); void *ring_entry, *mon_dst_srng; struct dp_mon_mpdu *tmp_mpdu; LIST_HEAD(rx_desc_used_list); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 6771c4409d9dd..8d4f0a673595f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -79,7 +79,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int num_remain; u32 cookie; dma_addr_t paddr; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_desc; enum hal_rx_buf_return_buf_manager mgr = ab->hw_params->hal_params->rx_buf_rbm; @@ -194,7 +194,7 @@ static int ath12k_dp_rxdma_mon_buf_ring_free(struct ath12k_base *ab, static int ath12k_dp_rxdma_buf_free(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->rxdma_mon_buf_ring); @@ -244,7 +244,7 @@ static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab, static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_mon_ring *mon_ring; int ret, i; @@ -291,7 +291,7 @@ static void ath12k_dp_rx_pdev_srng_free(struct ath12k *ar) void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; for (i = 0; i < DP_REO_DST_RING_MAX; i++) @@ -300,7 +300,7 @@ void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab) int ath12k_dp_rx_pdev_reo_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int ret; int i; @@ -367,7 +367,7 @@ static void ath12k_dp_rx_tid_cleanup(struct ath12k_base *ab, void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_rx_reo_cmd *cmd, *tmp; struct ath12k_dp_rx_reo_cache_flush_elem *cmd_cache, *tmp_cache; struct dp_reo_update_rx_queue_elem *cmd_queue, *tmp_queue; @@ -610,7 +610,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ enum hal_pn_type pn_type) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_peer *peer; struct ath12k_sta *ahsta; struct ath12k_dp_rx_tid *rx_tid; @@ -1659,7 +1659,7 @@ static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, void ath12k_dp_rx_free(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_srng *srng; int i; @@ -1691,7 +1691,7 @@ void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int mac_id) int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 ring_id; int i, ret; @@ -1763,7 +1763,7 @@ int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) int ath12k_dp_rx_alloc(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_srng *srng; int i, ret; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 4e70421fff470..90d45f11deba6 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -10530,8 +10530,8 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv idr_for_each(&ar->txmgmt_idr, ath12k_mac_vif_txmgmt_idr_remove, vif); - ath12k_mac_vif_unref(&ab->dp, vif); - ath12k_dp_tx_put_bank_profile(&ab->dp, arvif->bank_id); + ath12k_mac_vif_unref(ath12k_ab_to_dp(ab), vif); + ath12k_dp_tx_put_bank_profile(ath12k_ab_to_dp(ab), arvif->bank_id); /* Recalc txpower for remaining vdev */ ath12k_mac_txpower_recalc(ar); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 05c278467cb32..4310f06163c93 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -120,7 +120,7 @@ int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, ath12k_wifi7_dp_rx_process_reo_status(ab); if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; LIST_HEAD(list); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 76bfa33120f3a..6353c2f1f709e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -14,7 +14,7 @@ void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u1 dma_addr_t paddr) { struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); bool ml_peer = false; if (!ab->hw_params->reoq_lut_support) @@ -44,7 +44,7 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) { struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); bool ml_peer = false; if (!ab->hw_params->reoq_lut_support) @@ -106,7 +106,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, enum hal_wbm_rel_bm_act action) { struct hal_wbm_release_ring *desc; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_srng *srng; int ret = 0; @@ -139,7 +139,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, void (*cb)(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status)) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_rx_reo_cmd *dp_cmd; struct hal_srng *cmd_ring; int cmd_num; @@ -617,9 +617,10 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct ath12k_hw_link *hw_links = ag->hw_links; int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; struct ath12k_rx_desc_info *desc_info; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; + struct ath12k_dp *partner_dp; struct ath12k_base *partner_ab; struct sk_buff_head msdu_list; struct ath12k_skb_rxcb *rxcb; @@ -755,7 +756,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; + partner_dp = ath12k_ab_to_dp(partner_ab); + rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, &rx_desc_used_list[device_id], @@ -804,7 +806,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, struct sk_buff *defrag_skb) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; struct hal_reo_entrance_ring *reo_ent_ring; struct hal_reo_dest_ring *reo_dest_ring; @@ -1289,6 +1291,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n int budget) { struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *partner_dp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; @@ -1318,7 +1322,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - reo_except = &ab->dp.reo_except_ring; + reo_except = &dp->reo_except_ring; srng = &ab->hal.srng_list[reo_except->ring_id]; @@ -1343,17 +1347,18 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; partner_ab = ath12k_ag_to_ab(ag, device_id); + partner_dp = ath12k_ab_to_dp(partner_ab); pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, hw_links[hw_link_id].pdev_idx); ar = partner_ab->pdevs[pdev_id].ar; - link_desc_banks = partner_ab->dp.link_desc_banks; + link_desc_banks = partner_dp->link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + (paddr - link_desc_banks[desc_bank].paddr); ath12k_wifi7_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, &rbm); - if (rbm != partner_ab->dp.idle_link_rbm && + if (rbm != partner_dp->idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; @@ -1414,7 +1419,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n continue; partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; + partner_dp = ath12k_ab_to_dp(partner_ab); + rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, &rx_desc_used_list[device_id], @@ -1682,7 +1688,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_group *ag = ab->ag; struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *partner_dp; struct dp_rxdma_ring *rx_ring; struct hal_rx_wbm_rel_info err_info; struct hal_srng *srng; @@ -1833,7 +1840,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; + partner_dp = ath12k_ab_to_dp(partner_ab); + rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list[device_id], @@ -1883,7 +1891,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_tlv_filter tlv_filter = {}; u32 ring_id; int ret; @@ -1921,7 +1929,7 @@ EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_tlv_filter tlv_filter = {}; u32 ring_id; int ret = 0; @@ -1964,7 +1972,7 @@ EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_tlv_64_hdr *hdr; struct hal_srng *srng; struct ath12k_dp_rx_reo_cmd *cmd, *tmp; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index b3928c3d007df..6a5d6f5259515 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -59,7 +59,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, bool is_mcast) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_tx_info ti = {}; struct ath12k_tx_desc_info *tx_desc; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -809,7 +809,7 @@ ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) { struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; struct ath12k_tx_desc_info *tx_desc = NULL; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 8f0171c7aa4d1..743e56020906c 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4089,6 +4089,7 @@ int ath12k_wmi_wait_for_unified_ready(struct ath12k_base *ab) int ath12k_wmi_set_hw_mode(struct ath12k_base *ab, enum wmi_host_hw_mode_config_type mode) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_wmi_pdev_set_hw_mode_cmd *cmd; struct sk_buff *skb; struct ath12k_wmi_base *wmi_ab = &ab->wmi_ab; @@ -4140,7 +4141,7 @@ int ath12k_wmi_cmd_init(struct ath12k_base *ab) arg.num_band_to_mac = ab->num_radios; ath12k_fill_band_to_mac_param(ab, arg.band_to_mac); - ab->dp.peer_metadata_ver = arg.res_cfg.peer_metadata_ver; + dp->peer_metadata_ver = arg.res_cfg.peer_metadata_ver; return ath12k_init_cmd_send(&wmi_ab->wmi[0], &arg); } From f0aaf4075fd275502a7459ada3c87d1669e37a6e Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:01 +0530 Subject: [PATCH 409/659] wifi: ath12k: Support arch-specific DP device allocation Add arch_init() and arch_deinit() ops to the PCI and AHB family ops to support allocation and cleanup of architecture-specific fields in ath12k_base. Define shared ath12k_wifi7_arch_init() and ath12k_wifi7_arch_deinit() functions to handle DP device allocation and cleanup for Wi-Fi 7 across both PCI and AHB. Introduce a new header file wifi7/core.h to declare functions defined in wifi7/core.c. Currently, DP device allocation and cleanup are handled via arch_init() and arch_deinit(), which can be extended to support additional architecture-specific initialization in the future. Define common ath12k_wifi7_arch_init() and ath12k_wifi7_arch_deinit() functions to handle allocation and cleanup for Wi-Fi 7. Add a new header file wifi7/core.h to declare common Wi-Fi 7 functions. Add ath12k_wifi7_dp_device_alloc() and ath12k_wifi7_dp_device_free() to handle allocation and deallocation of the DP device object for Wi-Fi 7. Add ath12k_dp_cmn_device_init() and ath12k_dp_cmn_device_deinit() to initialize and deinitialize common DP device fields. Introduce a new header file dp_cmn.h to declare these functions, which can also be used to expose new common DP functions that need to be invoked from non-DP code. Rename existing DP allocation and cleanup functions to ath12k_dp_setup() and ath12k_dp_cleanup() to better reflect their purpose in the updated design. Replicate device-related fields such as device and hw_params in the DP device object to align with the new design, which limits per packet data path object usage to DP specific objects. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 19 ++++++++-- drivers/net/wireless/ath/ath12k/ahb.h | 4 ++- drivers/net/wireless/ath/ath12k/core.c | 13 +++---- drivers/net/wireless/ath/ath12k/dp.c | 38 +++++++++++--------- drivers/net/wireless/ath/ath12k/dp.h | 4 +-- drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 +++++++ drivers/net/wireless/ath/ath12k/pci.c | 20 +++++++++-- drivers/net/wireless/ath/ath12k/pci.h | 4 ++- drivers/net/wireless/ath/ath12k/wifi7/ahb.c | 4 +++ drivers/net/wireless/ath/ath12k/wifi7/core.c | 24 +++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/core.h | 11 ++++++ drivers/net/wireless/ath/ath12k/wifi7/dp.c | 25 +++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp.h | 7 ++++ drivers/net/wireless/ath/ath12k/wifi7/pci.c | 4 +++ 14 files changed, 159 insertions(+), 30 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_cmn.h create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/core.h diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index f49f117b90754..5c95bdd36d6aa 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -1088,14 +1088,26 @@ static int ath12k_ahb_probe(struct platform_device *pdev) goto err_rproc_deconfigure; } + /* Invoke arch_init here so that arch-specific init operations + * can utilize already initialized ab fields, such as HAL SRNGs. + */ + ret = ab_ahb->device_family_ops->arch_init(ab); + if (ret) { + ath12k_err(ab, "AHB arch_init failed %d\n", ret); + goto err_rproc_deconfigure; + } + ret = ath12k_core_init(ab); if (ret) { ath12k_err(ab, "failed to init core: %d\n", ret); - goto err_rproc_deconfigure; + goto err_deinit_arch; } return 0; +err_deinit_arch: + ab_ahb->device_family_ops->arch_deinit(ab); + err_rproc_deconfigure: ath12k_ahb_deconfigure_rproc(ab); @@ -1134,11 +1146,13 @@ static void ath12k_ahb_remove_prepare(struct ath12k_base *ab) static void ath12k_ahb_free_resources(struct ath12k_base *ab) { struct platform_device *pdev = ab->pdev; + struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab); ath12k_hal_srng_deinit(ab); ath12k_ce_free_pipes(ab); ath12k_ahb_resource_deinit(ab); ath12k_ahb_deconfigure_rproc(ab); + ab_ahb->device_family_ops->arch_deinit(ab); ath12k_core_free(ab); platform_set_drvdata(pdev, NULL); } @@ -1167,7 +1181,8 @@ int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, if (device_id >= ATH12K_DEVICE_FAMILY_MAX) return -EINVAL; - if (!driver || !driver->ops.probe) + if (!driver || !driver->ops.probe || + !driver->ops.arch_init || !driver->ops.arch_deinit) return -EINVAL; if (ath12k_ahb_family_drivers[device_id]) { diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h index fce02e3af5fb4..8a040d03d27a3 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.h +++ b/drivers/net/wireless/ath/ath12k/ahb.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_AHB_H #define ATH12K_AHB_H @@ -46,6 +46,8 @@ struct ath12k_base; struct ath12k_ahb_device_family_ops { int (*probe)(struct platform_device *pdev); + int (*arch_init)(struct ath12k_base *ab); + void (*arch_deinit)(struct ath12k_base *ab); }; struct ath12k_ahb { diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 4b9a49eaa3396..c92990bae2ddf 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -22,6 +22,7 @@ #include "hif.h" #include "pci.h" #include "wow.h" +#include "dp_cmn.h" unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); @@ -711,7 +712,7 @@ static void ath12k_core_stop(struct ath12k_base *ab) ath12k_dp_rx_pdev_reo_cleanup(ab); ath12k_hif_stop(ab); ath12k_wmi_detach(ab); - ath12k_dp_free(ab); + ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab)); /* De-Init of components as needed */ } @@ -1289,7 +1290,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab) goto err_firmware_stop; } - ret = ath12k_dp_alloc(ab); + ret = ath12k_dp_cmn_device_init(ath12k_ab_to_dp(ab)); if (ret) { ath12k_err(ab, "failed to init DP: %d\n", ret); goto err_firmware_stop; @@ -1301,7 +1302,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab) ret = ath12k_core_start(ab); if (ret) { ath12k_err(ab, "failed to start core: %d\n", ret); - goto err_dp_free; + goto err_deinit; } mutex_unlock(&ab->core_lock); @@ -1334,8 +1335,8 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab) mutex_unlock(&ag->mutex); goto exit; -err_dp_free: - ath12k_dp_free(ab); +err_deinit: + ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab)); mutex_unlock(&ab->core_lock); mutex_unlock(&ag->mutex); @@ -1357,7 +1358,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab) ath12k_dp_rx_pdev_reo_cleanup(ab); mutex_unlock(&ab->core_lock); - ath12k_dp_free(ab); + ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab)); ath12k_hal_srng_deinit(ab); total_vdev = ab->num_radios * TARGET_NUM_VDEVS(ab); ab->free_vdev_map = (1LL << total_vdev) - 1; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 5a76bc58dab8d..9d9665ce5019f 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -13,6 +13,7 @@ #include "wifi7/dp_rx.h" #include "peer.h" #include "dp_mon.h" +#include "dp_cmn.h" enum ath12k_dp_desc_type { ATH12K_DP_TX_DESC, @@ -1130,7 +1131,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) } } -void ath12k_dp_free(struct ath12k_base *ab) +static void ath12k_dp_cleanup(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; @@ -1155,8 +1156,6 @@ void ath12k_dp_free(struct ath12k_base *ab) ath12k_dp_rx_free(ab); /* Deinit any SOC level resource */ - kfree(ab->dp); - ab->dp = NULL; } void ath12k_dp_cc_config(struct ath12k_base *ab) @@ -1564,7 +1563,7 @@ ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab) } } -int ath12k_dp_alloc(struct ath12k_base *ab) +static int ath12k_dp_setup(struct ath12k_base *ab) { struct ath12k_dp *dp; struct hal_srng *srng = NULL; @@ -1573,12 +1572,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) int ret; int i; - /* TODO: align dp later if cache alignment becomes a bottleneck */ - dp = kzalloc(sizeof(*dp), GFP_KERNEL); - if (!dp) - return -ENOMEM; - - ab->dp = dp; + dp = ath12k_ab_to_dp(ab); dp->ab = ab; INIT_LIST_HEAD(&dp->reo_cmd_list); @@ -1593,7 +1587,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret); - goto fail_dp_free; + return ret; } srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id]; @@ -1602,7 +1596,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) HAL_WBM_IDLE_LINK, srng, n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup link desc: %d\n", ret); - goto fail_dp_free; + return ret; } ret = ath12k_dp_cc_init(ab); @@ -1675,9 +1669,21 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); -fail_dp_free: - kfree(ab->dp); - ab->dp = NULL; - return ret; } + +void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp) +{ + ath12k_dp_cleanup(dp->ab); +} + +int ath12k_dp_cmn_device_init(struct ath12k_dp *dp) +{ + int ret; + + ret = ath12k_dp_setup(dp->ab); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 5c8e6089f9e94..938a7ebfe55f4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -428,6 +428,8 @@ struct ath12k_dp { struct dp_rxdma_mon_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV]; struct ath12k_reo_q_addr_lut reoq_lut; struct ath12k_reo_q_addr_lut ml_reoq_lut; + const struct ath12k_hw_params *hw_params; + struct device *dev; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -437,8 +439,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) } void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); -void ath12k_dp_free(struct ath12k_base *ab); -int ath12k_dp_alloc(struct ath12k_base *ab); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); int ath12k_dp_pdev_alloc(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h new file mode 100644 index 0000000000000..acc0782ad3096 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_CMN_H +#define ATH12K_DP_CMN_H + +void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); +int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); + +#endif diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 886ecc0589100..89080d2d82408 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1638,13 +1638,25 @@ static int ath12k_pci_probe(struct pci_dev *pdev, goto err_free_irq; } + /* Invoke arch_init here so that arch-specific init operations + * can utilize already initialized ab fields, such as HAL SRNGs. + */ + ret = ab_pci->device_family_ops->arch_init(ab); + if (ret) { + ath12k_err(ab, "PCI arch_init failed %d\n", ret); + goto err_pci_msi_free; + } + ret = ath12k_core_init(ab); if (ret) { ath12k_err(ab, "failed to init core: %d\n", ret); - goto err_free_irq; + goto err_deinit_arch; } return 0; +err_deinit_arch: + ab_pci->device_family_ops->arch_deinit(ab); + err_free_irq: /* __free_irq() expects the caller to have cleared the affinity hint */ ath12k_pci_set_irq_affinity_hint(ab_pci, NULL); @@ -1703,6 +1715,9 @@ static void ath12k_pci_remove(struct pci_dev *pdev) ath12k_hal_srng_deinit(ab); ath12k_ce_free_pipes(ab); + + ab_pci->device_family_ops->arch_deinit(ab); + ath12k_core_free(ab); } @@ -1799,7 +1814,8 @@ int ath12k_pci_register_driver(const enum ath12k_device_family device_id, if (device_id >= ATH12K_DEVICE_FAMILY_MAX) return -EINVAL; - if (!driver || !driver->ops.probe) + if (!driver || !driver->ops.probe || + !driver->ops.arch_init || !driver->ops.arch_deinit) return -EINVAL; if (ath12k_pci_family_drivers[device_id]) { diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 5af33e5deacfd..2c19bb42f0f70 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_PCI_H #define ATH12K_PCI_H @@ -97,6 +97,8 @@ struct ath12k_pci_ops { struct ath12k_pci_device_family_ops { int (*probe)(struct pci_dev *pdev, const struct pci_device_id *pci_dev); + int (*arch_init)(struct ath12k_base *ab); + void (*arch_deinit)(struct ath12k_base *ab); }; struct ath12k_pci_reg_base { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c index 803e13207bc06..a6c5f7689edd1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c @@ -12,6 +12,8 @@ #include "../debug.h" #include "../hif.h" #include "hw.h" +#include "dp.h" +#include "core.h" static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", @@ -57,6 +59,8 @@ static struct ath12k_ahb_driver ath12k_wifi7_ahb_driver = { .name = "ath12k_wifi7_ahb", .id_table = ath12k_wifi7_ahb_of_match, .ops.probe = ath12k_wifi7_ahb_probe, + .ops.arch_init = ath12k_wifi7_arch_init, + .ops.arch_deinit = ath12k_wifi7_arch_deinit, }; int ath12k_wifi7_ahb_init(void) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/core.c b/drivers/net/wireless/ath/ath12k/wifi7/core.c index eb882e56e5ec2..a02c57acf1374 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/core.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/core.c @@ -9,9 +9,33 @@ #include "../pci.h" #include "pci.h" #include "ahb.h" +#include "core.h" +#include "dp.h" +#include "../debug.h" static int ahb_err, pci_err; +int ath12k_wifi7_arch_init(struct ath12k_base *ab) +{ + struct ath12k_dp *dp; + + dp = ath12k_wifi7_dp_device_alloc(ab); + if (!dp) { + ath12k_err(ab, "dp alloc failed"); + return -EINVAL; + } + + ab->dp = dp; + + return 0; +} + +void ath12k_wifi7_arch_deinit(struct ath12k_base *ab) +{ + ath12k_wifi7_dp_device_free(ab->dp); + ab->dp = NULL; +} + static int ath12k_wifi7_init(void) { ahb_err = ath12k_wifi7_ahb_init(); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/core.h b/drivers/net/wireless/ath/ath12k/wifi7/core.h new file mode 100644 index 0000000000000..7e9689d2ddd73 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/core.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_CORE_WIFI7_H +#define ATH12K_CORE_WIFI7_H + +int ath12k_wifi7_arch_init(struct ath12k_base *ab); +void ath12k_wifi7_arch_deinit(struct ath12k_base *ab); + +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 4310f06163c93..adc3480b282b3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -8,6 +8,7 @@ #include "../dp_rx.h" #include "../dp_tx.h" #include "../dp_mon.h" +#include "../dp_cmn.h" #include "dp_rx.h" #include "dp.h" #include "dp_tx.h" @@ -132,3 +133,27 @@ int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, done: return tot_work_done; } + +/* TODO: remove export once this file is built with wifi7 ko */ +struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) +{ + struct ath12k_dp *dp; + + /* TODO: align dp later if cache alignment becomes a bottleneck */ + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + if (!dp) + return NULL; + + dp->ab = ab; + dp->dev = ab->dev; + dp->hw_params = ab->hw_params; + + return dp; +} +EXPORT_SYMBOL(ath12k_wifi7_dp_device_alloc); + +void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp) +{ + kfree(dp); +} +EXPORT_SYMBOL(ath12k_wifi7_dp_device_free); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 9332b9401bbf7..2300fda657865 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -7,8 +7,15 @@ #ifndef ATH12K_DP_WIFI7_H #define ATH12K_DP_WIFI7_H +#include "../dp_cmn.h" #include "hw.h" +struct ath12k_base; +struct ath12k_dp; + int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, struct ath12k_ext_irq_grp *irq_grp, int budget); +struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); +void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); + #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index ba8c19c24ae6a..f6dfdcf95025a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -13,6 +13,8 @@ #include "../mhi.h" #include "hw.h" #include "../hal.h" +#include "dp.h" +#include "core.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 @@ -163,6 +165,8 @@ static struct ath12k_pci_driver ath12k_wifi7_pci_driver = { .id_table = ath12k_wifi7_pci_id_table, .ops.probe = ath12k_wifi7_pci_probe, .reg_base = &ath12k_wifi7_reg_base, + .ops.arch_init = ath12k_wifi7_arch_init, + .ops.arch_deinit = ath12k_wifi7_arch_deinit, }; int ath12k_wifi7_pci_init(void) From 7a20665c9d0f389f790b4ee645ff4324a3b2a314 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:02 +0530 Subject: [PATCH 410/659] wifi: ath12k: Rearrange DP fields in ath12k_hw_group struct Introduce the ath12k_dp_hw_group struct within ath12k_hw_group to encapsulate all Data Path fields, providing a baseline for future extensions. Add this struct to the top of ath12k_hw_group to allow optimal usage of cache lines for data path fields, as it is accessed in multiple tight loops in the per-packet path. Add cmn_def.h to define common macros shared between DP and other modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 13 +++++ drivers/net/wireless/ath/ath12k/core.c | 4 ++ drivers/net/wireless/ath/ath12k/core.h | 9 ++- drivers/net/wireless/ath/ath12k/dp.c | 24 ++++++++ drivers/net/wireless/ath/ath12k/dp.h | 10 ++++ drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 ++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 58 +++++++++++-------- drivers/net/wireless/ath/ath12k/wmi.h | 3 +- 8 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/cmn_defs.h diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h new file mode 100644 index 0000000000000..e1f1f50341ff0 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_CMN_DEFS_H +#define ATH12K_CMN_DEFS_H + +#define MAX_RADIOS 2 +#define ATH12K_MAX_DEVICES 3 +#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) + +#endif diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index c92990bae2ddf..c82c0746a3494 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1992,6 +1992,8 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a ag->ab[ab->device_id] = ab; ab->ag = ag; + ath12k_dp_cmn_hw_group_assign(ath12k_ab_to_dp(ab), ag); + ath12k_dbg(ab, ATH12K_DBG_BOOT, "wsi group-id %d num-devices %d index %d", ag->id, ag->num_devices, wsi->index); @@ -2019,6 +2021,8 @@ void ath12k_core_hw_group_unassign(struct ath12k_base *ab) return; } + ath12k_dp_cmn_hw_group_unassign(ath12k_ab_to_dp(ab), ag); + ag->ab[device_id] = NULL; ab->ag = NULL; ab->device_id = ATH12K_INVALID_DEVICE_ID; diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 28bf34e420195..0c84347901901 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -34,6 +34,7 @@ #include "wow.h" #include "debugfs_htt_stats.h" #include "coredump.h" +#include "cmn_defs.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -64,8 +65,6 @@ #define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) #define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ) -#define ATH12K_MAX_DEVICES 3 -#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) #define ATH12K_INVALID_GROUP_ID 0xFF #define ATH12K_INVALID_DEVICE_ID 0xFF @@ -987,6 +986,11 @@ struct ath12k_hw_link { * wiphy, protected with struct ath12k_hw_group::mutex. */ struct ath12k_hw_group { + /* Keep dp_hw_grp as the first member to allow efficient + * usage of cache lines for DP fields + */ + struct ath12k_dp_hw_group dp_hw_grp; + struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; struct list_head list; u8 id; u8 num_devices; @@ -1009,7 +1013,6 @@ struct ath12k_hw_group { bool mlo_capable; struct device_node *wsi_node[ATH12K_MAX_DEVICES]; struct ath12k_mlo_memory mlo_mem; - struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; bool hw_link_id_init_done; }; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 9d9665ce5019f..1e14f3a70904c 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1687,3 +1687,27 @@ int ath12k_dp_cmn_device_init(struct ath12k_dp *dp) return 0; } + +void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag) +{ + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; + + lockdep_assert_held(&ag->mutex); + + dp_hw_grp->dp[dp->device_id] = NULL; + + dp->ag = NULL; + dp->device_id = ATH12K_INVALID_DEVICE_ID; +} + +void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag) +{ + struct ath12k_base *ab = dp->ab; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; + + dp->ag = ag; + dp->device_id = ab->device_id; + dp_hw_grp->dp[dp->device_id] = dp; +} diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 938a7ebfe55f4..84f40a6612d31 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,6 +11,7 @@ #include "wifi7/hal_rx.h" #include "hw.h" #include "dp_htt.h" +#include "dp_cmn.h" #define MAX_RXDMA_PER_PDEV 2 @@ -430,6 +431,9 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; const struct ath12k_hw_params *hw_params; struct device *dev; + + struct ath12k_hw_group *ag; + u8 device_id; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -438,6 +442,12 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } +static inline struct ath12k_dp * +ath12k_dp_hw_grp_to_dp(struct ath12k_dp_hw_group *dp_hw_grp, u8 device_id) +{ + return dp_hw_grp->dp[device_id]; +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index acc0782ad3096..70c92f6d33d6f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -6,7 +6,19 @@ #ifndef ATH12K_DP_CMN_H #define ATH12K_DP_CMN_H +#include "cmn_defs.h" + +struct ath12k_hw_group; + +struct ath12k_dp_hw_group { + struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; +}; + void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); +void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag); +void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 6353c2f1f709e..04c64b9046938 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -558,7 +558,9 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct sk_buff_head *msdu_list, int ring_id) { - struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ieee80211_rx_status rx_status = {}; struct ath12k_skb_rxcb *rxcb; struct sk_buff *msdu; @@ -566,6 +568,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; struct hal_rx_desc_data rx_info; + struct ath12k_dp *partner_dp; u8 hw_link_id, pdev_id; int ret; @@ -580,10 +583,11 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, while ((msdu = __skb_dequeue(msdu_list))) { rxcb = ATH12K_SKB_RXCB(msdu); hw_link_id = rxcb->hw_link_id; - partner_ab = ath12k_ag_to_ab(ag, - hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, + hw_links[hw_link_id].device_id); + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); + partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_id].ar; if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { dev_kfree_skb_any(msdu); @@ -612,12 +616,13 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct napi_struct *napi, int budget) { - struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_link *hw_links = ag->hw_links; int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; struct ath12k_rx_desc_info *desc_info; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; struct ath12k_dp *partner_dp; @@ -660,8 +665,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { if (desc_info->skb) { dev_kfree_skb_any(desc_info->skb); desc_info->skb = NULL; @@ -669,6 +674,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; } + partner_ab = partner_dp->ab; /* retry manual desc retrieval */ if (!desc_info) { @@ -755,8 +761,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, @@ -1290,8 +1296,9 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { - struct ath12k_hw_group *ag = ab->ag; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; @@ -1346,8 +1353,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n hw_link_id = le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, hw_links[hw_link_id].pdev_idx); @@ -1418,8 +1425,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, @@ -1686,9 +1693,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_group *ag = ab->ag; struct ath12k *ar; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; struct dp_rxdma_ring *rx_ring; struct hal_rx_wbm_rel_info err_info; @@ -1751,8 +1759,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, desc_info->skb = NULL; device_id = desc_info->device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { dev_kfree_skb_any(msdu); /* In any case continuation bit is set @@ -1762,10 +1770,12 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } + partner_ab = partner_dp->ab; + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, + dma_unmap_single(partner_dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1839,8 +1849,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(ab, rx_ring, @@ -1854,8 +1863,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, hw_link_id = rxcb->hw_link_id; device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", hw_link_id, device_id); @@ -1863,8 +1872,9 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); + partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_id].ar; if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index b1ba1f8b6bb2d..65f0d7ed4178d 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -9,6 +9,7 @@ #include #include "htc.h" +#include "cmn_defs.h" /* Naming conventions for structures: * @@ -5151,8 +5152,6 @@ struct wmi_probe_tmpl_cmd { __le32 buf_len; } __packed; -#define MAX_RADIOS 2 - #define WMI_MLO_CMD_TIMEOUT_HZ (5 * HZ) #define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ) #define WMI_SEND_TIMEOUT_HZ (3 * HZ) From ff8d754ad2044bbfb293ba7636c64c517cd8a848 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:03 +0530 Subject: [PATCH 411/659] wifi: ath12k: Add framework for hardware specific ieee80211_ops registration Introduce a framework to register the ieee80211_ops table based on the underlying hardware architecture. This is necessary to support architecture-specific implementations of ieee80211_ops such as .tx, which will be introduced in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 5 + drivers/net/wireless/ath/ath12k/debugfs.c | 1 + drivers/net/wireless/ath/ath12k/debugfs_sta.c | 3 +- drivers/net/wireless/ath/ath12k/mac.c | 308 +++++++++--------- drivers/net/wireless/ath/ath12k/mac.h | 126 +++++++ drivers/net/wireless/ath/ath12k/testmode.c | 3 +- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 62 ++++ drivers/net/wireless/ath/ath12k/wow.c | 5 +- 8 files changed, 348 insertions(+), 165 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 0c84347901901..1ec6f57bbe699 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1249,6 +1249,11 @@ struct ath12k_base { const struct ath12k_mem_profile_based_param *profile_param; enum ath12k_qmi_mem_mode target_mem_mode; + /* FIXME: Define this field in a ag equivalent object available + * during the initial phase of probe later. + */ + const struct ieee80211_ops *ath12k_ops; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index d6a86f075d73b..f25af9adeac82 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1020,6 +1020,7 @@ void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw, debugfs_create_file("link_stats", 0400, vif->debugfs_dir, ahvif, &ath12k_fops_link_stats); } +EXPORT_SYMBOL(ath12k_debugfs_op_vif_add); static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, char __user *user_buf, diff --git a/drivers/net/wireless/ath/ath12k/debugfs_sta.c b/drivers/net/wireless/ath/ath12k/debugfs_sta.c index 5bd2bf4c9dac3..e6665fd521db8 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_sta.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* - * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -335,3 +335,4 @@ void ath12k_debugfs_link_sta_op_add(struct ieee80211_hw *hw, &fops_reset_rx_stats); } } +EXPORT_SYMBOL(ath12k_debugfs_link_sta_op_add); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 90d45f11deba6..15ee26d92fbf4 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1459,10 +1459,11 @@ int ath12k_mac_vdev_stop(struct ath12k_link_vif *arvif) return ret; } -static int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) +int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) { return 0; } +EXPORT_SYMBOL(ath12k_mac_op_config); static int ath12k_mac_setup_bcn_p2p_ie(struct ath12k_link_vif *arvif, struct sk_buff *bcn) @@ -4139,7 +4140,7 @@ static void ath12k_mac_unassign_link_vif(struct ath12k_link_vif *arvif) memset(arvif, 0, sizeof(*arvif)); } -static int +int ath12k_mac_op_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 old_links, u16 new_links, @@ -4188,6 +4189,7 @@ ath12k_mac_op_change_vif_links(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_change_vif_links); static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif, struct ieee80211_bss_conf *info) @@ -4236,9 +4238,9 @@ static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif, return ret; } -static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u64 changed) +void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u64 changed) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); unsigned long links = ahvif->links_map; @@ -4306,6 +4308,7 @@ static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, } } } +EXPORT_SYMBOL(ath12k_mac_op_vif_cfg_changed); static void ath12k_mac_vif_setup_ps(struct ath12k_link_vif *arvif) { @@ -4781,10 +4784,10 @@ static void ath12k_ahvif_put_link_cache(struct ath12k_vif *ahvif, u8 link_id) ahvif->cache[link_id] = NULL; } -static void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u64 changed) +void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed) { struct ath12k *ar; struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -4814,6 +4817,7 @@ static void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, ath12k_mac_bss_info_changed(ar, arvif, info, changed); } +EXPORT_SYMBOL(ath12k_mac_op_link_info_changed); static struct ath12k* ath12k_mac_select_scan_device(struct ieee80211_hw *hw, @@ -5115,10 +5119,10 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar, return 0; } -static int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - unsigned int link_id, - int *dbm) +int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, + int *dbm) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_fw_stats_req_params params = {}; @@ -5192,6 +5196,7 @@ static int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, *dbm); return 0; } +EXPORT_SYMBOL(ath12k_mac_op_get_txpower); static u8 ath12k_mac_find_link_id_by_ar(struct ath12k_vif *ahvif, struct ath12k *ar) @@ -5403,9 +5408,9 @@ static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw, return ret; } -static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_scan_request *hw_req) +int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ieee80211_channel **chan_list, *chan; @@ -5483,9 +5488,10 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, kfree(chan_list); return ret; } +EXPORT_SYMBOL(ath12k_mac_op_hw_scan); -static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); unsigned long link_id, links_map = ahvif->links_map; @@ -5507,6 +5513,7 @@ static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, cancel_delayed_work_sync(&ar->scan.timeout); } } +EXPORT_SYMBOL(ath12k_mac_op_cancel_hw_scan); static int ath12k_install_key(struct ath12k_link_vif *arvif, struct ieee80211_key_conf *key, @@ -5844,9 +5851,9 @@ static int ath12k_mac_update_key_cache(struct ath12k_vif_cache *cache, return 0; } -static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -5933,6 +5940,7 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_set_key); static int ath12k_mac_bitrate_mask_num_vht_rates(struct ath12k *ar, @@ -7269,11 +7277,11 @@ static int ath12k_mac_select_links(struct ath12k_base *ab, return 0; } -static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - enum ieee80211_sta_state old_state, - enum ieee80211_sta_state new_state) +int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); @@ -7431,10 +7439,11 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_sta_state); -static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); struct ath12k *ar; @@ -7481,11 +7490,12 @@ static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, out: return ret; } +EXPORT_SYMBOL(ath12k_mac_op_sta_set_txpwr); -static void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_link_sta *link_sta, - u32 changed) +void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed) { struct ieee80211_sta *sta = link_sta->sta; struct ath12k *ar; @@ -7589,6 +7599,7 @@ static void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, rcu_read_unlock(); } +EXPORT_SYMBOL(ath12k_mac_op_link_sta_rc_update); static struct ath12k_link_sta *ath12k_mac_alloc_assign_link_sta(struct ath12k_hw *ah, struct ath12k_sta *ahsta, @@ -7620,10 +7631,10 @@ static struct ath12k_link_sta *ath12k_mac_alloc_assign_link_sta(struct ath12k_hw return arsta; } -static int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - u16 old_links, u16 new_links) +int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); @@ -7684,15 +7695,17 @@ static int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_change_sta_links); -static bool ath12k_mac_op_can_activate_links(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u16 active_links) +bool ath12k_mac_op_can_activate_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 active_links) { /* TODO: Handle recovery case */ return true; } +EXPORT_SYMBOL(ath12k_mac_op_can_activate_links); static int ath12k_conf_tx_uapsd(struct ath12k_link_vif *arvif, u16 ac, bool enable) @@ -7804,10 +7817,10 @@ static int ath12k_mac_conf_tx(struct ath12k_link_vif *arvif, u16 ac, return ret; } -static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - unsigned int link_id, u16 ac, - const struct ieee80211_tx_queue_params *params) +int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, + const struct ieee80211_tx_queue_params *params) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -7836,6 +7849,7 @@ static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_conf_tx); static struct ieee80211_sta_ht_cap ath12k_create_ht_cap(struct ath12k *ar, u32 ar_ht_cap, u32 rate_cap_rx_chainmask) @@ -9126,9 +9140,9 @@ static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif } /* Note: called under rcu_read_lock() */ -static void ath12k_mac_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +void ath12k_mac_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) { struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -9311,6 +9325,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, ieee80211_free_txskb(ar->ah->hw, skb); } } +EXPORT_SYMBOL(ath12k_mac_op_tx); void ath12k_mac_drain_tx(struct ath12k *ar) { @@ -9485,7 +9500,7 @@ static void ath12k_drain_tx(struct ath12k_hw *ah) ath12k_mac_drain_tx(ar); } -static int ath12k_mac_op_start(struct ieee80211_hw *hw) +int ath12k_mac_op_start(struct ieee80211_hw *hw) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -9538,6 +9553,7 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw) return ret; } +EXPORT_SYMBOL(ath12k_mac_op_start); int ath12k_mac_rfkill_config(struct ath12k *ar) { @@ -9644,7 +9660,7 @@ static void ath12k_mac_stop(struct ath12k *ar) atomic_set(&ar->num_pending_mgmt_tx, 0); } -static void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend) +void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -9663,6 +9679,7 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend) mutex_unlock(&ah->hw_mutex); } +EXPORT_SYMBOL(ath12k_mac_op_stop); static u8 ath12k_mac_get_vdev_stats_id(struct ath12k_link_vif *arvif) @@ -9827,8 +9844,8 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif) } } -static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -9852,6 +9869,7 @@ static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, ath12k_mac_update_vif_offload(&ahvif->deflink); } +EXPORT_SYMBOL(ath12k_mac_op_update_vif_offload); static bool ath12k_mac_vif_ap_active_any(struct ath12k_base *ab) { @@ -10407,8 +10425,8 @@ static struct ath12k *ath12k_mac_assign_vif_to_vdev(struct ieee80211_hw *hw, return arvif->ar; } -static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -10455,6 +10473,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, */ return 0; } +EXPORT_SYMBOL(ath12k_mac_op_add_interface); static void ath12k_mac_vif_unref(struct ath12k_dp *dp, struct ieee80211_vif *vif) { @@ -10543,8 +10562,8 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv return ret; } -static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -10591,6 +10610,7 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, ath12k_mac_unassign_link_vif(arvif); } } +EXPORT_SYMBOL(ath12k_mac_op_remove_interface); /* FIXME: Has to be verified. */ #define SUPPORTED_FILTERS \ @@ -10602,10 +10622,10 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, FIF_PROBE_REQ | \ FIF_FCSFAIL) -static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) +void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -10617,9 +10637,10 @@ static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, *total_flags &= SUPPORTED_FILTERS; ar->filter_flags = *total_flags; } +EXPORT_SYMBOL(ath12k_mac_op_configure_filter); -static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, - u32 *tx_ant, u32 *rx_ant) +int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 *tx_ant, u32 *rx_ant) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); int antennas_rx = 0, antennas_tx = 0; @@ -10638,9 +10659,10 @@ static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_get_antenna); -static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, - u32 tx_ant, u32 rx_ant) +int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 tx_ant, u32 rx_ant) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -10657,6 +10679,7 @@ static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_set_antenna); static int ath12k_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -10698,9 +10721,9 @@ static int ath12k_mac_ampdu_action(struct ieee80211_hw *hw, return ret; } -static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_ampdu_params *params) +int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) { struct ieee80211_sta *sta = params->sta; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); @@ -10721,9 +10744,10 @@ static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_ampdu_action); -static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx) +int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) { struct ath12k *ar; struct ath12k_base *ab; @@ -10750,9 +10774,10 @@ static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_add_chanctx); -static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx) +void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) { struct ath12k *ar; struct ath12k_base *ab; @@ -10777,6 +10802,7 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, spin_unlock_bh(&ar->data_lock); ar->chan_tx_pwr = ATH12K_PDEV_TX_POWER_INVALID; } +EXPORT_SYMBOL(ath12k_mac_op_remove_chanctx); static enum wmi_phy_mode ath12k_mac_check_down_grade_phy_mode(struct ath12k *ar, @@ -11335,9 +11361,9 @@ ath12k_mac_update_active_vif_chan(struct ath12k *ar, kfree(arg.vifs); } -static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx, - u32 changed) +void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx, + u32 changed) { struct ath12k *ar; struct ath12k_base *ab; @@ -11367,6 +11393,7 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, /* TODO: Recalc radar detection */ } +EXPORT_SYMBOL(ath12k_mac_op_change_chanctx); static int ath12k_start_vdev_delay(struct ath12k *ar, struct ath12k_link_vif *arvif) @@ -11808,7 +11835,7 @@ static void ath12k_mac_parse_tx_pwr_env(struct ath12k *ar, } } -static int +int ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf, @@ -11893,8 +11920,9 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, out: return ret; } +EXPORT_SYMBOL(ath12k_mac_op_assign_vif_chanctx); -static void +void ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf, @@ -11961,8 +11989,9 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, ar->scan.arvif = NULL; } } +EXPORT_SYMBOL(ath12k_mac_op_unassign_vif_chanctx); -static int +int ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif_chanctx_switch *vifs, int n_vifs, @@ -11987,6 +12016,7 @@ ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_switch_vif_chanctx); static int ath12k_set_vdev_param_to_all_vifs(struct ath12k *ar, int param, u32 value) @@ -12015,8 +12045,8 @@ ath12k_set_vdev_param_to_all_vifs(struct ath12k *ar, int param, u32 value) /* mac80211 stores device specific RTS/Fragmentation threshold value, * this is set interface specific to firmware from ath12k driver */ -static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, - int radio_idx, u32 value) +int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct wiphy *wiphy = hw->wiphy; @@ -12075,9 +12105,10 @@ static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_set_rts_threshold); -static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, - int radio_idx, u32 value) +int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value) { /* Even though there's a WMI vdev param for fragmentation threshold no * known firmware actually implements it. Moreover it is not possible to @@ -12094,6 +12125,7 @@ static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, return -EOPNOTSUPP; } +EXPORT_SYMBOL(ath12k_mac_op_set_frag_threshold); static int ath12k_mac_flush(struct ath12k *ar) { @@ -12131,8 +12163,8 @@ int ath12k_mac_wait_tx_complete(struct ath12k *ar) return ath12k_mac_flush(ar); } -static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u32 queues, bool drop) +void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_link_vif *arvif; @@ -12167,6 +12199,7 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v ath12k_mac_flush(arvif->ar); } } +EXPORT_SYMBOL(ath12k_mac_op_flush); static int ath12k_mac_bitrate_mask_num_ht_rates(struct ath12k *ar, @@ -12787,7 +12820,7 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban return ret; } -static int +int ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) @@ -12966,8 +12999,9 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, out: return ret; } +EXPORT_SYMBOL(ath12k_mac_op_set_bitrate_mask); -static void +void ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type) { @@ -13048,6 +13082,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, } } } +EXPORT_SYMBOL(ath12k_mac_op_reconfig_complete); static void ath12k_mac_update_bss_chan_survey(struct ath12k *ar, @@ -13081,8 +13116,8 @@ ath12k_mac_update_bss_chan_survey(struct ath12k *ar, ath12k_warn(ar->ab, "bss channel survey timed out\n"); } -static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) +int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) { struct ath12k *ar; struct ieee80211_supported_band *sband; @@ -13157,11 +13192,12 @@ static void ath12k_mac_put_chain_rssi(struct station_info *sinfo, } } } +EXPORT_SYMBOL(ath12k_mac_op_get_survey); -static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo) +void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); struct ath12k_fw_stats_req_params params = {}; @@ -13246,11 +13282,12 @@ static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } +EXPORT_SYMBOL(ath12k_mac_op_sta_statistics); -static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_link_sta *link_sta, - struct link_station_info *link_sinfo) +void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + struct link_station_info *link_sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta); struct ath12k_fw_stats_req_params params = {}; @@ -13330,9 +13367,10 @@ static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } +EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); -static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -13352,12 +13390,13 @@ static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_cancel_remain_on_channel); -static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_channel *chan, - int duration, - enum ieee80211_roc_type type) +int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel *chan, + int duration, + enum ieee80211_roc_type type) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_hw *ah = ath12k_hw_to_ah(hw); @@ -13492,10 +13531,11 @@ static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_remain_on_channel); -static void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_gtk_rekey_data *data) +void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_rekey_data *rekey_data; @@ -13528,63 +13568,7 @@ static void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, ath12k_dbg_dump(ar->ab, ATH12K_DBG_MAC, "replay ctr", NULL, &rekey_data->replay_ctr, sizeof(rekey_data->replay_ctr)); } - -static const struct ieee80211_ops ath12k_ops = { - .tx = ath12k_mac_op_tx, - .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = ath12k_mac_op_start, - .stop = ath12k_mac_op_stop, - .reconfig_complete = ath12k_mac_op_reconfig_complete, - .add_interface = ath12k_mac_op_add_interface, - .remove_interface = ath12k_mac_op_remove_interface, - .update_vif_offload = ath12k_mac_op_update_vif_offload, - .config = ath12k_mac_op_config, - .link_info_changed = ath12k_mac_op_link_info_changed, - .vif_cfg_changed = ath12k_mac_op_vif_cfg_changed, - .change_vif_links = ath12k_mac_op_change_vif_links, - .configure_filter = ath12k_mac_op_configure_filter, - .hw_scan = ath12k_mac_op_hw_scan, - .cancel_hw_scan = ath12k_mac_op_cancel_hw_scan, - .set_key = ath12k_mac_op_set_key, - .set_rekey_data = ath12k_mac_op_set_rekey_data, - .sta_state = ath12k_mac_op_sta_state, - .sta_set_txpwr = ath12k_mac_op_sta_set_txpwr, - .link_sta_rc_update = ath12k_mac_op_link_sta_rc_update, - .conf_tx = ath12k_mac_op_conf_tx, - .set_antenna = ath12k_mac_op_set_antenna, - .get_antenna = ath12k_mac_op_get_antenna, - .ampdu_action = ath12k_mac_op_ampdu_action, - .add_chanctx = ath12k_mac_op_add_chanctx, - .remove_chanctx = ath12k_mac_op_remove_chanctx, - .change_chanctx = ath12k_mac_op_change_chanctx, - .assign_vif_chanctx = ath12k_mac_op_assign_vif_chanctx, - .unassign_vif_chanctx = ath12k_mac_op_unassign_vif_chanctx, - .switch_vif_chanctx = ath12k_mac_op_switch_vif_chanctx, - .get_txpower = ath12k_mac_op_get_txpower, - .set_rts_threshold = ath12k_mac_op_set_rts_threshold, - .set_frag_threshold = ath12k_mac_op_set_frag_threshold, - .set_bitrate_mask = ath12k_mac_op_set_bitrate_mask, - .get_survey = ath12k_mac_op_get_survey, - .flush = ath12k_mac_op_flush, - .sta_statistics = ath12k_mac_op_sta_statistics, - .link_sta_statistics = ath12k_mac_op_link_sta_statistics, - .remain_on_channel = ath12k_mac_op_remain_on_channel, - .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel, - .change_sta_links = ath12k_mac_op_change_sta_links, - .can_activate_links = ath12k_mac_op_can_activate_links, -#ifdef CONFIG_PM - .suspend = ath12k_wow_op_suspend, - .resume = ath12k_wow_op_resume, - .set_wakeup = ath12k_wow_op_set_wakeup, -#endif -#ifdef CONFIG_ATH12K_DEBUGFS - .vif_add_debugfs = ath12k_debugfs_op_vif_add, -#endif - CFG80211_TESTMODE_CMD(ath12k_tm_cmd) -#ifdef CONFIG_ATH12K_DEBUGFS - .link_sta_add_debugfs = ath12k_debugfs_link_sta_op_add, -#endif -}; +EXPORT_SYMBOL(ath12k_mac_op_set_rekey_data); void ath12k_mac_update_freq_range(struct ath12k *ar, u32 freq_low, u32 freq_high) @@ -14803,7 +14787,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag, u8 pdev_idx; hw = ieee80211_alloc_hw(struct_size(ah, radio, num_pdev_map), - &ath12k_ops); + pdev_map->ab->ath12k_ops); if (!hw) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 1f689e367c8a1..2f4a174b88942 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -206,4 +206,130 @@ void ath12k_mac_update_freq_range(struct ath12k *ar, void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ieee80211_chanctx_conf *ctx); +void ath12k_mac_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb); +int ath12k_mac_op_start(struct ieee80211_hw *hw); +void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend); +void +ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type); +int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); +void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed); +void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u64 changed); +int +ath12k_mac_op_change_vif_links + (struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 old_links, u16 new_links, + struct ieee80211_bss_conf *ol[IEEE80211_MLD_MAX_NUM_LINKS]); +void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast); +int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req); +void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data); +int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state); +int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed); +int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, + const struct ieee80211_tx_queue_params *params); +int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 tx_ant, u32 rx_ant); +int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 *tx_ant, u32 *rx_ant); +int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params); +int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx); +void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx); +void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx, + u32 changed); +int +ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx); +void +ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx); +int +ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode); +int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value); +int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value); +int +ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask); +int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey); +void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop); +void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo); +void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + struct link_station_info *link_sinfo); +int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel *chan, + int duration, + enum ieee80211_roc_type type); +int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links); +bool ath12k_mac_op_can_activate_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 active_links); +int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, + int *dbm); #endif diff --git a/drivers/net/wireless/ath/ath12k/testmode.c b/drivers/net/wireless/ath/ath12k/testmode.c index fb6af7ccf71f4..05a65970c8624 100644 --- a/drivers/net/wireless/ath/ath12k/testmode.c +++ b/drivers/net/wireless/ath/ath12k/testmode.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "testmode.h" @@ -393,3 +393,4 @@ int ath12k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return -EOPNOTSUPP; } } +EXPORT_SYMBOL(ath12k_tm_cmd); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 909f7311619cd..1acf6ffaea08f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -19,6 +19,10 @@ #include "dp_rx.h" #include "../peer.h" #include "wmi.h" +#include "../wow.h" +#include "../debugfs.h" +#include "../debugfs_sta.h" +#include "../testmode.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, @@ -1042,6 +1046,63 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { }, }; +static const struct ieee80211_ops ath12k_ops_wifi7 = { + .tx = ath12k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, + .start = ath12k_mac_op_start, + .stop = ath12k_mac_op_stop, + .reconfig_complete = ath12k_mac_op_reconfig_complete, + .add_interface = ath12k_mac_op_add_interface, + .remove_interface = ath12k_mac_op_remove_interface, + .update_vif_offload = ath12k_mac_op_update_vif_offload, + .config = ath12k_mac_op_config, + .link_info_changed = ath12k_mac_op_link_info_changed, + .vif_cfg_changed = ath12k_mac_op_vif_cfg_changed, + .change_vif_links = ath12k_mac_op_change_vif_links, + .configure_filter = ath12k_mac_op_configure_filter, + .hw_scan = ath12k_mac_op_hw_scan, + .cancel_hw_scan = ath12k_mac_op_cancel_hw_scan, + .set_key = ath12k_mac_op_set_key, + .set_rekey_data = ath12k_mac_op_set_rekey_data, + .sta_state = ath12k_mac_op_sta_state, + .sta_set_txpwr = ath12k_mac_op_sta_set_txpwr, + .link_sta_rc_update = ath12k_mac_op_link_sta_rc_update, + .conf_tx = ath12k_mac_op_conf_tx, + .set_antenna = ath12k_mac_op_set_antenna, + .get_antenna = ath12k_mac_op_get_antenna, + .ampdu_action = ath12k_mac_op_ampdu_action, + .add_chanctx = ath12k_mac_op_add_chanctx, + .remove_chanctx = ath12k_mac_op_remove_chanctx, + .change_chanctx = ath12k_mac_op_change_chanctx, + .assign_vif_chanctx = ath12k_mac_op_assign_vif_chanctx, + .unassign_vif_chanctx = ath12k_mac_op_unassign_vif_chanctx, + .switch_vif_chanctx = ath12k_mac_op_switch_vif_chanctx, + .get_txpower = ath12k_mac_op_get_txpower, + .set_rts_threshold = ath12k_mac_op_set_rts_threshold, + .set_frag_threshold = ath12k_mac_op_set_frag_threshold, + .set_bitrate_mask = ath12k_mac_op_set_bitrate_mask, + .get_survey = ath12k_mac_op_get_survey, + .flush = ath12k_mac_op_flush, + .sta_statistics = ath12k_mac_op_sta_statistics, + .link_sta_statistics = ath12k_mac_op_link_sta_statistics, + .remain_on_channel = ath12k_mac_op_remain_on_channel, + .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel, + .change_sta_links = ath12k_mac_op_change_sta_links, + .can_activate_links = ath12k_mac_op_can_activate_links, +#ifdef CONFIG_PM + .suspend = ath12k_wow_op_suspend, + .resume = ath12k_wow_op_resume, + .set_wakeup = ath12k_wow_op_set_wakeup, +#endif +#ifdef CONFIG_ATH12K_DEBUGFS + .vif_add_debugfs = ath12k_debugfs_op_vif_add, +#endif + CFG80211_TESTMODE_CMD(ath12k_tm_cmd) +#ifdef CONFIG_ATH12K_DEBUGFS + .link_sta_add_debugfs = ath12k_debugfs_link_sta_op_add, +#endif +}; + int ath12k_wifi7_hw_init(struct ath12k_base *ab) { const struct ath12k_hw_params *hw_params = NULL; @@ -1061,6 +1122,7 @@ int ath12k_wifi7_hw_init(struct ath12k_base *ab) } ab->hw_params = hw_params; + ab->ath12k_ops = &ath12k_ops_wifi7; ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name); diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c index e8481626f1940..f56ec44a16361 100644 --- a/drivers/net/wireless/ath/ath12k/wow.c +++ b/drivers/net/wireless/ath/ath12k/wow.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -919,6 +919,7 @@ int ath12k_wow_op_suspend(struct ieee80211_hw *hw, exit: return ret ? 1 : 0; } +EXPORT_SYMBOL(ath12k_wow_op_suspend); void ath12k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled) { @@ -929,6 +930,7 @@ void ath12k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled) device_set_wakeup_enable(ar->ab->dev, enabled); } +EXPORT_SYMBOL(ath12k_wow_op_set_wakeup); int ath12k_wow_op_resume(struct ieee80211_hw *hw) { @@ -1001,6 +1003,7 @@ int ath12k_wow_op_resume(struct ieee80211_hw *hw) return ret; } +EXPORT_SYMBOL(ath12k_wow_op_resume); int ath12k_wow_init(struct ath12k *ar) { From b147853d3d5b00a052da85db876ec6b91fb4c035 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:04 +0530 Subject: [PATCH 412/659] wifi: ath12k: Add framework for hardware specific DP interrupt handler Currently, the DP service SRNG handler is invoked directly from the NAPI poll handler, which prevents using different handlers for different architectures. To fix this, introduce a DP architecture-ops table to invoke architecture specific handler from NAPI poll handler. Future patches will leverage this framework to invoke architecture-specific handlers from common code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 3 ++- drivers/net/wireless/ath/ath12k/dp.h | 18 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/pci.c | 3 ++- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 13 ++++++++++--- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 2 -- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 5c95bdd36d6aa..b743c05c5fb04 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -525,9 +525,10 @@ static int ath12k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) struct ath12k_ext_irq_grp, napi); struct ath12k_base *ab = irq_grp->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int work_done; - work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_dp_service_srng(dp, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); ath12k_ahb_ext_grp_enable(irq_grp); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 84f40a6612d31..6e0e247d93768 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -367,6 +367,15 @@ struct ath12k_link_stats { u32 tx_desc_type[HAL_TCL_DESC_TYPE_MAX]; }; +/* DP arch ops to communicate from common module + * to arch specific module + */ +struct ath12k_dp_arch_ops { + int (*service_srng)(struct ath12k_dp *dp, + struct ath12k_ext_irq_grp *irq_grp, + int budget); +}; + struct ath12k_dp { struct ath12k_base *ab; u32 mon_dest_ring_stuck_cnt; @@ -434,6 +443,8 @@ struct ath12k_dp { struct ath12k_hw_group *ag; u8 device_id; + + struct ath12k_dp_arch_ops *ops; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -448,6 +459,13 @@ ath12k_dp_hw_grp_to_dp(struct ath12k_dp_hw_group *dp_hw_grp, u8 device_id) return dp_hw_grp->dp[device_id]; } +static inline int +ath12k_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, + int budget) +{ + return dp->ops->service_srng(dp, irq_grp, budget); +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 89080d2d82408..6fb327157ecfe 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -497,10 +497,11 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) struct ath12k_ext_irq_grp, napi); struct ath12k_base *ab = irq_grp->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int work_done; int i; - work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_dp_service_srng(dp, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); for (i = 0; i < irq_grp->num_irq; i++) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index adc3480b282b3..4465a9e93bf85 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -13,10 +13,11 @@ #include "dp.h" #include "dp_tx.h" -int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget) +static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, + struct ath12k_ext_irq_grp *irq_grp, + int budget) { + struct ath12k_base *ab = dp->ab; struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; int work_done = 0; @@ -134,6 +135,10 @@ int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, return tot_work_done; } +static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { + .service_srng = ath12k_wifi7_dp_service_srng, +}; + /* TODO: remove export once this file is built with wifi7 ko */ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) { @@ -148,6 +153,8 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) dp->dev = ab->dev; dp->hw_params = ab->hw_params; + dp->ops = &ath12k_wifi7_dp_arch_ops; + return dp; } EXPORT_SYMBOL(ath12k_wifi7_dp_device_alloc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 2300fda657865..72fdfb368c994 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -13,8 +13,6 @@ struct ath12k_base; struct ath12k_dp; -int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, int budget); struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); From b103e0336bef5409d2bedcd4cba6a3c7d778cf8c Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Tue, 30 Sep 2025 18:40:05 +0530 Subject: [PATCH 413/659] wifi: ath12k: Refactor ath12k_vif structure Move the Data Path (DP)-specific fields from ath12k_vif into a new structure ath12k_dp_vif, embedded within ath12k_vif. This new structure contains an array of per-link DP fields represented by ath12k_dp_link_vif. Since dp_link_vif is small and frequently accessed from ahvif during Tx, it is stored as an array of structs rather than an array of pointers to avoid additional indirections and improve cache efficiency. However, this design comes with a trade-off: because the array is not pointer-based, it increases memory usage. Per packet data path makes use of ath12k_dp_vif and ath12k_dp_link_vif. Add pdev_idx and lmac_id in ath12k_dp_link_vif to avoid accessing ar in dp tx. Diagrammatic view of the new structure is below: +--------------------------------+ | struct ath12k_vif | | | | +--------------------------+ | | | struct ath12k_dp_vif | | | | | | | | +--------------------+ | | | | | ath12k_dp_link_vif | | | | | +--------------------+ | | | | | | | | +--------------------+ | | | | | ath12k_dp_link_vif | | | | | +--------------------+ | | | | | | | | +--------------------+ | | | | | ath12k_dp_link_vif | | | | | +--------------------+ | | | | | | | +--------------------------+ | | | +--------------------------------+ Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 6 ++ drivers/net/wireless/ath/ath12k/core.h | 13 +--- drivers/net/wireless/ath/ath12k/dp.c | 59 ++++++++++++------- drivers/net/wireless/ath/ath12k/dp_cmn.h | 26 ++++++++ drivers/net/wireless/ath/ath12k/mac.c | 29 ++++++--- drivers/net/wireless/ath/ath12k/mac.h | 3 - drivers/net/wireless/ath/ath12k/peer.c | 10 +++- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 25 ++++---- 8 files changed, 115 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h index e1f1f50341ff0..1a531357271bc 100644 --- a/drivers/net/wireless/ath/ath12k/cmn_defs.h +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -6,8 +6,14 @@ #ifndef ATH12K_CMN_DEFS_H #define ATH12K_CMN_DEFS_H +#include + #define MAX_RADIOS 2 #define ATH12K_MAX_DEVICES 3 #define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) +#define ATH12K_SCAN_MAX_LINKS ATH12K_GROUP_MAX_RADIO +/* Define 1 scan link for each radio for parallel scan purposes */ +#define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) + #endif diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 1ec6f57bbe699..b424ff8428861 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -35,6 +35,7 @@ #include "debugfs_htt_stats.h" #include "coredump.h" #include "cmn_defs.h" +#include "dp_cmn.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -309,16 +310,9 @@ struct ath12k_link_vif { u32 vdev_id; u32 beacon_interval; u32 dtim_period; - u16 ast_hash; - u16 ast_idx; - u16 tcl_metadata; - u8 hal_addr_search_flags; - u8 search_type; struct ath12k *ar; - int bank_id; - u8 vdev_id_check_en; bool beacon_prot; struct wmi_wmm_params_all_arg wmm_params; @@ -359,6 +353,8 @@ struct ath12k_link_vif { }; struct ath12k_vif { + struct ath12k_dp_vif dp_vif; + enum wmi_vdev_type vdev_type; enum wmi_vdev_subtype vdev_subtype; struct ieee80211_vif *vif; @@ -382,10 +378,7 @@ struct ath12k_vif { } u; u32 aid; - u32 key_cipher; - u8 tx_encap_type; bool ps; - atomic_t mcbc_gsn; struct ath12k_link_vif deflink; struct ath12k_link_vif __rcu *link[ATH12K_NUM_MAX_LINKS]; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 1e14f3a70904c..36e0dfd89bbde 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -338,18 +338,23 @@ u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, struct ath12k_link_vif *arvif) { u32 bank_config = 0; + u8 link_id = arvif->link_id; struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(dp_vif, link_id); /* Only valid for raw frames with HW crypto enabled. * With SW crypto, mac80211 sets key per packet */ - if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) bank_config |= - u32_encode_bits(ath12k_dp_tx_get_encrypt_type(ahvif->key_cipher), + u32_encode_bits(ath12k_dp_tx_get_encrypt_type(dp_vif->key_cipher), HAL_TX_BANK_CONFIG_ENCRYPT_TYPE); - bank_config |= u32_encode_bits(ahvif->tx_encap_type, + bank_config |= u32_encode_bits(dp_vif->tx_encap_type, HAL_TX_BANK_CONFIG_ENCAP_TYPE); bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_SRC_BUFFER_SWAP) | u32_encode_bits(0, HAL_TX_BANK_CONFIG_LINK_META_SWAP) | @@ -361,15 +366,16 @@ u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, else bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); - bank_config |= u32_encode_bits(arvif->hal_addr_search_flags & HAL_TX_ADDRX_EN, - HAL_TX_BANK_CONFIG_ADDRX_EN) | - u32_encode_bits(!!(arvif->hal_addr_search_flags & + bank_config |= u32_encode_bits(dp_link_vif->hal_addr_search_flags & + HAL_TX_ADDRX_EN, + HAL_TX_BANK_CONFIG_ADDRX_EN) | + u32_encode_bits(!!(dp_link_vif->hal_addr_search_flags & HAL_TX_ADDRY_EN), HAL_TX_BANK_CONFIG_ADDRY_EN); bank_config |= u32_encode_bits(ieee80211_vif_is_mesh(ahvif->vif) ? 3 : 0, HAL_TX_BANK_CONFIG_MESH_EN) | - u32_encode_bits(arvif->vdev_id_check_en, + u32_encode_bits(dp_link_vif->vdev_id_check_en, HAL_TX_BANK_CONFIG_VDEV_ID_CHECK_EN); bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID); @@ -938,15 +944,21 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif) { + u8 link_id = arvif->link_id; + struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id); + switch (arvif->ahvif->vdev_type) { case WMI_VDEV_TYPE_STA: - arvif->hal_addr_search_flags = HAL_TX_ADDRY_EN; - arvif->search_type = HAL_TX_ADDR_SEARCH_INDEX; + dp_link_vif->hal_addr_search_flags = HAL_TX_ADDRY_EN; + dp_link_vif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; break; case WMI_VDEV_TYPE_AP: case WMI_VDEV_TYPE_IBSS: - arvif->hal_addr_search_flags = HAL_TX_ADDRX_EN; - arvif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; + dp_link_vif->hal_addr_search_flags = HAL_TX_ADDRX_EN; + dp_link_vif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; break; case WMI_VDEV_TYPE_MONITOR: default: @@ -957,22 +969,29 @@ static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif) void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif) { struct ath12k_base *ab = ar->ab; + struct ath12k_vif *ahvif = arvif->ahvif; + u8 link_id = arvif->link_id; + int bank_id; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id); - arvif->tcl_metadata |= u32_encode_bits(1, HTT_TCL_META_DATA_TYPE) | - u32_encode_bits(arvif->vdev_id, - HTT_TCL_META_DATA_VDEV_ID) | - u32_encode_bits(ar->pdev->pdev_id, - HTT_TCL_META_DATA_PDEV_ID); + dp_link_vif->tcl_metadata |= u32_encode_bits(1, HTT_TCL_META_DATA_TYPE) | + u32_encode_bits(arvif->vdev_id, + HTT_TCL_META_DATA_VDEV_ID) | + u32_encode_bits(ar->pdev->pdev_id, + HTT_TCL_META_DATA_PDEV_ID); /* set HTT extension valid bit to 0 by default */ - arvif->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; + dp_link_vif->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; ath12k_dp_update_vdev_search(arvif); - arvif->vdev_id_check_en = true; - arvif->bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, ath12k_ab_to_dp(ab)); + dp_link_vif->vdev_id_check_en = true; + bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, ath12k_ab_to_dp(ab)); + dp_link_vif->bank_id = bank_id; /* TODO: error path for bank id failure */ - if (arvif->bank_id == DP_INVALID_BANK_ID) { + if (bank_id == DP_INVALID_BANK_ID) { ath12k_err(ar->ab, "Failed to initialize DP TX Banks"); return; } diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 70c92f6d33d6f..3dc61d1a41625 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -14,6 +14,32 @@ struct ath12k_dp_hw_group { struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; }; +struct ath12k_dp_link_vif { + u32 vdev_id; + u8 search_type; + u8 hal_addr_search_flags; + u8 pdev_idx; + u8 lmac_id; + u16 ast_idx; + u16 ast_hash; + u16 tcl_metadata; + u8 vdev_id_check_en; + int bank_id; +}; + +struct ath12k_dp_vif { + u8 tx_encap_type; + u32 key_cipher; + atomic_t mcbc_gsn; + struct ath12k_dp_link_vif dp_link_vif[ATH12K_NUM_MAX_LINKS]; +}; + +static inline struct ath12k_dp_link_vif * +ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) +{ + return &dp_vif->dp_link_vif[link_id]; +} + void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 15ee26d92fbf4..657632ed2a992 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -5621,7 +5621,7 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif, return -ETIMEDOUT; if (ether_addr_equal(arg.macaddr, arvif->bssid)) - ahvif->key_cipher = arg.ieee80211_key_cipher; + ahvif->dp_vif.key_cipher = arg.ieee80211_key_cipher; if (ar->install_key_status) { ret = -EINVAL; @@ -9248,7 +9248,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, return; } } else { - mcbc_gsn = atomic_inc_return(&ahvif->mcbc_gsn) & 0xfff; + mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff; links_map = ahvif->links_map; for_each_set_bit(link_id, &links_map, @@ -9272,9 +9272,10 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, skb_cb = ATH12K_SKB_CB(msdu_copied); skb_cb->link_id = link_id; + skb_cb->vif = vif; /* For open mode, skip peer find logic */ - if (unlikely(!ahvif->key_cipher)) + if (unlikely(!ahvif->dp_vif.key_cipher)) goto skip_peer_find; spin_lock_bh(&tmp_ar->ab->base_lock); @@ -9813,14 +9814,14 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif) IEEE80211_OFFLOAD_DECAP_ENABLED); if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) - ahvif->tx_encap_type = ATH12K_HW_TXRX_ETHERNET; + ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_ETHERNET; else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) - ahvif->tx_encap_type = ATH12K_HW_TXRX_RAW; + ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_RAW; else - ahvif->tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI; + ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI; ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - param_id, ahvif->tx_encap_type); + param_id, ahvif->dp_vif.tx_encap_type); if (ret) { ath12k_warn(ab, "failed to set vdev %d tx encap mode: %d\n", arvif->vdev_id, ret); @@ -10035,6 +10036,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) int i; int ret, vdev_id; u8 link_id; + struct ath12k_dp_link_vif *dp_link_vif = NULL; lockdep_assert_wiphy(hw->wiphy); @@ -10116,6 +10118,12 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) goto err_vdev_del; } + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id); + + dp_link_vif->vdev_id = arvif->vdev_id; + dp_link_vif->lmac_id = ar->lmac_id; + dp_link_vif->pdev_idx = ar->pdev_idx; + switch (ahvif->vdev_type) { case WMI_VDEV_TYPE_AP: peer_param.vdev_id = arvif->vdev_id; @@ -10504,6 +10512,7 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv { struct ath12k_vif *ahvif = arvif->ahvif; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); + struct ath12k_dp_link_vif *dp_link_vif; struct ath12k_base *ab = ar->ab; unsigned long time_left; int ret; @@ -10550,7 +10559,9 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv ath12k_mac_vif_txmgmt_idr_remove, vif); ath12k_mac_vif_unref(ath12k_ab_to_dp(ab), vif); - ath12k_dp_tx_put_bank_profile(ath12k_ab_to_dp(ab), arvif->bank_id); + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id); + ath12k_dp_tx_put_bank_profile(ath12k_ab_to_dp(ab), dp_link_vif->bank_id); /* Recalc txpower for remaining vdev */ ath12k_mac_txpower_recalc(ar); @@ -13062,7 +13073,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, ahvif = arvif->ahvif; ath12k_dbg(ab, ATH12K_DBG_BOOT, "reconfig cipher %d up %d vdev type %d\n", - ahvif->key_cipher, + ahvif->dp_vif.key_cipher, arvif->is_up, ahvif->vdev_type); diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 2f4a174b88942..ef5c3570bef10 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -54,9 +54,6 @@ struct ath12k_generic_iter { * for driver usage purpose. */ #define ATH12K_FIRST_SCAN_LINK IEEE80211_MLD_MAX_NUM_LINKS -#define ATH12K_SCAN_MAX_LINKS ATH12K_GROUP_MAX_RADIO -/* Define 1 scan link for each radio for parallel scan purposes */ -#define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) #define ATH12K_SCAN_LINKS_MASK GENMASK(ATH12K_NUM_MAX_LINKS, IEEE80211_MLD_MAX_NUM_LINKS) #define ATH12K_NUM_MAX_ACTIVE_LINKS_PER_DEVICE 2 diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index af95324f27086..ce15642986568 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "core.h" @@ -318,6 +318,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_wmi_peer_create_arg *arg) { struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); + struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_link_vif *dp_link_vif; struct ath12k_link_sta *arsta; u8 link_id = arvif->link_id; struct ath12k_peer *peer; @@ -327,6 +329,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id); + if (ar->num_peers > (ar->max_num_peers - 1)) { ath12k_warn(ar->ab, "failed to create peer due to insufficient peer entry resource in firmware\n"); @@ -384,8 +388,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, peer->sta = sta; if (vif->type == NL80211_IFTYPE_STATION) { - arvif->ast_hash = peer->ast_hash; - arvif->ast_idx = peer->hw_peer_id; + dp_link_vif->ast_hash = peer->ast_hash; + dp_link_vif->ast_idx = peer->hw_peer_id; } if (vif->type == NL80211_IFTYPE_AP) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 6a5d6f5259515..b94b14bda39bf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -70,6 +70,8 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, struct hal_srng *tcl_ring; struct ieee80211_hdr *hdr = (void *)skb->data; struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; + struct ath12k_dp_link_vif *dp_link_vif; struct dp_tx_ring *tx_ring; u8 pool_id; u8 hal_ring_id; @@ -113,10 +115,12 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, if (!tx_desc) return -ENOMEM; - ti.bank_id = arvif->bank_id; - ti.meta_data_flags = arvif->tcl_metadata; + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id); - if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + ti.bank_id = dp_link_vif->bank_id; + ti.meta_data_flags = dp_link_vif->tcl_metadata; + + if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { ti.encrypt_type = @@ -142,18 +146,18 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, } ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); - ti.addr_search_flags = arvif->hal_addr_search_flags; - ti.search_type = arvif->search_type; + ti.addr_search_flags = dp_link_vif->hal_addr_search_flags; + ti.search_type = dp_link_vif->search_type; ti.type = HAL_TCL_DESC_TYPE_BUFFER; ti.pkt_offset = 0; - ti.lmac_id = ar->lmac_id; + ti.lmac_id = dp_link_vif->lmac_id; - ti.vdev_id = arvif->vdev_id; + ti.vdev_id = dp_link_vif->vdev_id; if (gsn_valid) ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID; - ti.bss_ast_hash = arvif->ast_hash; - ti.bss_ast_idx = arvif->ast_idx; + ti.bss_ast_hash = dp_link_vif->ast_hash; + ti.bss_ast_idx = dp_link_vif->ast_idx; ti.dscp_tid_tbl_idx = 0; if (skb->ip_summed == CHECKSUM_PARTIAL && @@ -251,11 +255,10 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, } tx_desc->skb = skb; - tx_desc->mac_id = ar->pdev_idx; + tx_desc->mac_id = dp_link_vif->pdev_idx; ti.desc_id = tx_desc->desc_id; ti.data_len = skb->len; skb_cb->paddr = ti.paddr; - skb_cb->vif = ahvif->vif; skb_cb->ar = ar; if (msdu_ext_desc) { From b3c0b74afa2df682d6f2b2548798e3b1eb7f36e3 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 7 Oct 2025 16:32:02 +0530 Subject: [PATCH 414/659] wifi: ath12k: Refactor data path pdev struct Refactor struct ath12k_pdev_dp to encapsulate all DP related fields of radio (ar) and rely on this single pdev object in per packet DP operations to optimize cache usage. Introduce an array of RCU-protected ath12k_pdev_dp in DP device object to find DP pdev directly from the DP device object. RCU on dp_pdevs[] provides a teardown synchronization mechanism by ensuring all in-flight access to dp_pdev pointers complete before reclaim. Once a dp_pdev pointer is obtained, its internal fields can be accessed as follows: - Writers update internal fields using their own synchronization. - Readers may perform lockless reads if occasional inconsistency is acceptable, or use additional synchronization (e.g., spin_lock, atomic_t) for a coherent view between readers and writers. Please note that RCU is used for dp_pdevs[] at this stage to align with ab->pdevs_active[]. However, if the teardown paths ensure quiescence, both dp_pdevs[] and pdevs_active[] can be converted to plain pointers, removing RCU synchronization overhead. This will be evaluated separately. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251007110203.1541167-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 4 + drivers/net/wireless/ath/ath12k/dp.c | 23 ++ drivers/net/wireless/ath/ath12k/dp.h | 35 +++ drivers/net/wireless/ath/ath12k/dp_mon.c | 183 ++++++++------- drivers/net/wireless/ath/ath12k/dp_mon.h | 9 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 99 ++++---- drivers/net/wireless/ath/ath12k/dp_rx.h | 13 +- drivers/net/wireless/ath/ath12k/mac.c | 23 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 216 ++++++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 66 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 2 +- 11 files changed, 423 insertions(+), 250 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index b424ff8428861..d11bc1cae9863 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1532,4 +1532,8 @@ static inline struct ath12k_dp *ath12k_ab_to_dp(struct ath12k_base *ab) return ab->dp; } +static inline struct ath12k *ath12k_pdev_dp_to_ar(struct ath12k_pdev_dp *dp) +{ + return container_of(dp, struct ath12k, dp); +} #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 36e0dfd89bbde..088736bead58a 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -888,8 +888,17 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, void ath12k_dp_pdev_free(struct ath12k_base *ab) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k *ar; int i; + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + rcu_assign_pointer(dp->dp_pdevs[ar->pdev_idx], NULL); + } + + synchronize_rcu(); + for (i = 0; i < ab->num_radios; i++) ath12k_dp_rx_pdev_free(ab, i); } @@ -911,6 +920,8 @@ void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) int ath12k_dp_pdev_alloc(struct ath12k_base *ab) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_pdev_dp *dp_pdev; struct ath12k *ar; int ret; int i; @@ -922,6 +933,13 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) /* TODO: Per-pdev rx ring unlike tx ring which is mapped to different AC's */ for (i = 0; i < ab->num_radios; i++) { ar = ab->pdevs[i].ar; + + dp_pdev = &ar->dp; + + dp_pdev->hw = ar->ah->hw; + dp_pdev->dp = dp; + dp_pdev->hw_link_id = ar->hw_link_id; + ret = ath12k_dp_rx_pdev_alloc(ab, i); if (ret) { ath12k_warn(ab, "failed to allocate pdev rx for pdev_id :%d\n", @@ -935,6 +953,11 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) } } + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + rcu_assign_pointer(dp->dp_pdevs[ar->pdev_idx], &ar->dp); + } + return 0; err: ath12k_dp_pdev_free(ab); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 6e0e247d93768..30a101e797fb5 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -151,6 +151,11 @@ struct ath12k_pdev_dp { u32 mac_id; atomic_t num_tx_pending; wait_queue_head_t tx_empty_waitq; + + struct ath12k_dp *dp; + struct ieee80211_hw *hw; + u8 hw_link_id; + struct dp_srng rxdma_mon_dst_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng tx_mon_dst_ring[MAX_RXDMA_PER_PDEV]; @@ -441,6 +446,21 @@ struct ath12k_dp { const struct ath12k_hw_params *hw_params; struct device *dev; + /* RCU on dp_pdevs[] provides a teardown synchronization mechanism, + * ensuring in-flight data path readers complete before reclaim. Writers + * update internal fields under their own synchronization, while readers of + * internal fields may perform lockless read if occasional inconsistency + * is acceptable or use additional synchronization for a coherent view. + * + * RCU is used for dp_pdevs[] at this stage to align with + * ab->pdevs_active[]. However, if the teardown paths ensure quiescence, + * both dp_pdevs[] and pdevs_active[] can be converted to plain pointers, + * removing RCU synchronize overhead. + * + * TODO: evaluate removal of RCU from dp_pdevs in the future + */ + struct ath12k_pdev_dp __rcu *dp_pdevs[MAX_RADIOS]; + struct ath12k_hw_group *ag; u8 device_id; @@ -466,6 +486,21 @@ ath12k_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, return dp->ops->service_srng(dp, irq_grp, budget); } +static inline struct ieee80211_hw * +ath12k_pdev_dp_to_hw(struct ath12k_pdev_dp *pdev) +{ + return pdev->hw; +} + +static inline struct ath12k_pdev_dp * +ath12k_dp_to_pdev_dp(struct ath12k_dp *dp, u8 pdev_idx) +{ + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k dp to dp pdev called without rcu lock"); + + return rcu_dereference(dp->dp_pdevs[pdev_idx]); +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index c853c96ab220c..3f5d0d056bdde 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1485,7 +1485,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, } static enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar, +ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct hal_tlv_64_hdr *tlv) { @@ -1755,8 +1755,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar, } static void -ath12k_dp_mon_fill_rx_stats_info(struct ath12k *ar, - struct hal_rx_mon_ppdu_info *ppdu_info, +ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) { u32 center_freq = ppdu_info->freq; @@ -1901,10 +1900,12 @@ void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, } static void -ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, +ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ieee80211_supported_band *sband; enum rx_msdu_start_pkt_type pkt_type; u8 rate_mcs, nss, sgi; @@ -1920,6 +1921,8 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11B: is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B); if (rx_status->band < NUM_NL80211_BANDS) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + sband = &ar->mac.sbands[rx_status->band]; rx_status->rate_idx = ath12k_mac_hw_rate_to_idx(sband, rate_mcs, is_cck); @@ -1928,7 +1931,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11N: rx_status->encoding = RX_ENC_HT; if (rate_mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in HT mode %d\n", rate_mcs); break; @@ -1941,7 +1944,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, rx_status->encoding = RX_ENC_VHT; rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in VHT mode %d\n", rate_mcs); break; @@ -1952,7 +1955,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11AX: rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in HE mode %d\n", rate_mcs); break; @@ -1963,7 +1966,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11BE: rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in EHT mode %d\n", rate_mcs); break; @@ -1972,24 +1975,24 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); break; default: - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + ath12k_dbg(ab, ATH12K_DBG_DATA, "monitor receives invalid preamble type %d", pkt_type); break; } } -static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, +static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k_base *ab, struct sk_buff *head_msdu, struct sk_buff *tail_msdu) { u32 rx_pkt_offset, l2_hdr_offset, total_offset; - rx_pkt_offset = ar->ab->hal.hal_desc_sz; + rx_pkt_offset = ab->hal.hal_desc_sz; l2_hdr_offset = - ath12k_dp_rx_h_l3pad(ar->ab, (struct hal_rx_desc *)tail_msdu->data); + ath12k_dp_rx_h_l3pad(ab, (struct hal_rx_desc *)tail_msdu->data); - if (ar->ab->hw_params->rxdma1_enable) + if (ab->hw_params->rxdma1_enable) total_offset = ATH12K_MON_RX_PKT_OFFSET; else total_offset = rx_pkt_offset + l2_hdr_offset; @@ -1998,12 +2001,13 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, } static struct sk_buff * -ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, +ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rxs) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list; struct sk_buff *head_msdu, *tail_msdu; struct hal_rx_desc *rx_desc; @@ -2020,11 +2024,13 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, if (!head_msdu || !tail_msdu) goto err_merge_fail; - ath12k_dp_mon_fill_rx_stats_info(ar, ppdu_info, rxs); + ath12k_dp_mon_fill_rx_stats_info(ppdu_info, rxs); if (unlikely(rxs->band == NUM_NL80211_BANDS || - !ath12k_ar_to_hw(ar)->wiphy->bands[rxs->band])) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + !ath12k_pdev_dp_to_hw(dp_pdev)->wiphy->bands[rxs->band])) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + + ath12k_dbg(ab, ATH12K_DBG_DATA, "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n", rxs->band, channel_num, ppdu_info->freq, ar->pdev_idx); @@ -2042,17 +2048,17 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, rxs->freq = ieee80211_channel_to_frequency(channel_num, rxs->band); - ath12k_dp_mon_fill_rx_rate(ar, ppdu_info, rxs); + ath12k_dp_mon_fill_rx_rate(dp_pdev, ppdu_info, rxs); if (decap_format == DP_RX_DECAP_TYPE_RAW) { - ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu); + ath12k_dp_mon_rx_msdus_set_payload(ab, head_msdu, tail_msdu); prev_buf = head_msdu; msdu = head_msdu->next; head_frag_list = NULL; while (msdu) { - ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu); + ath12k_dp_mon_rx_msdus_set_payload(ab, head_msdu, tail_msdu); if (!head_frag_list) head_frag_list = msdu; @@ -2087,7 +2093,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, msdu = head_msdu; while (msdu) { - ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu); + ath12k_dp_mon_rx_msdus_set_payload(ab, head_msdu, tail_msdu); if (qos_pkt) { dest = skb_push(msdu, sizeof(__le16)); if (!dest) @@ -2171,11 +2177,12 @@ ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, rtap_buf[rtap_len] = rx_status->he_RU[3]; } -static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, +static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppduinfo, struct sk_buff *mon_skb, struct ieee80211_rx_status *rxs) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ieee80211_supported_band *sband; s32 noise_floor; u8 *ptr = NULL; @@ -2268,6 +2275,9 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, rxs->encoding = RX_ENC_HT; rxs->rate_idx = ppduinfo->rate; } else { + struct ath12k *ar; + + ar = ath12k_pdev_dp_to_ar(dp_pdev); rxs->encoding = RX_ENC_LEGACY; sband = &ar->mac.sbands[rxs->band]; rxs->rate_idx = ath12k_mac_hw_rate_to_idx(sband, ppduinfo->rate, @@ -2277,12 +2287,15 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, rxs->mactime = ppduinfo->tsft; } -static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, +static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, struct sk_buff *msdu, const struct hal_rx_mon_ppdu_info *ppduinfo, struct ieee80211_rx_status *status, u8 decap) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), @@ -2307,10 +2320,10 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find_by_id(ar->ab, ppduinfo->peer_id); + spin_lock_bh(&ab->base_lock); + peer = ath12k_dp_rx_h_find_peer(ab, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; if (pubsta->valid_links) { @@ -2319,9 +2332,9 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct } } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&ab->base_lock); - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, @@ -2345,7 +2358,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct !!(status->flag & RX_FLAG_MMIC_ERROR), !!(status->flag & RX_FLAG_AMSDU_MORE)); - ath12k_dbg_dump(ar->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", + ath12k_dbg_dump(ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", msdu->data, msdu->len); rx_status = IEEE80211_SKB_RXCB(msdu); *rx_status = *status; @@ -2361,20 +2374,19 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; - ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi); + ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, +static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppduinfo, struct napi_struct *napi) { - struct ath12k_pdev_dp *dp = &ar->dp; struct sk_buff *mon_skb, *skb_next, *header; - struct ieee80211_rx_status *rxs = &dp->rx_status; + struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; u8 decap = DP_RX_DECAP_TYPE_RAW; - mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, ppduinfo, rxs); + mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); if (!mon_skb) goto mon_deliver_fail; @@ -2402,8 +2414,8 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) decap = mon_mpdu->decap_format; - ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs); - ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, ppduinfo, rxs, decap); + ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); + ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); mon_skb = skb_next; } while (mon_skb); rxs->flag = 0; @@ -2465,12 +2477,12 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, } static int -ath12k_dp_mon_parse_status_buf(struct ath12k *ar, +ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info) { - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct dp_rxdma_mon_ring *buf_ring = &dp->rxdma_mon_buf_ring; struct sk_buff *msdu; int buf_id; @@ -2511,7 +2523,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k *ar, } static int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, enum hal_rx_mon_status hal_status, const void *tlv_data) @@ -2526,7 +2538,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, return -ENOMEM; break; case HAL_RX_MON_STATUS_BUF_ADDR: - return ath12k_dp_mon_parse_status_buf(ar, pmon, tlv_data); + return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); case HAL_RX_MON_STATUS_MPDU_END: /* If no MSDU then free empty MPDU */ if (pmon->mon_mpdu->tail) { @@ -2549,9 +2561,10 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, } static enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, +ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct hal_tlv_64_hdr *tlv; struct ath12k_skb_rxcb *rxcb; enum hal_rx_mon_status hal_status; @@ -2573,10 +2586,11 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, else tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv); + hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(ar, pmon, hal_status, tlv->value)) + ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) return HAL_RX_MON_STATUS_PPDU_DONE; ptr += sizeof(*tlv) + tlv_len; @@ -2599,7 +2613,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, } enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi) @@ -2609,7 +2623,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; enum hal_rx_mon_status hal_status; - hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); + hal_status = ath12k_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) return hal_status; @@ -2617,7 +2631,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, list_del(&mon_mpdu->list); if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(ar, mon_mpdu, ppdu_info, napi); + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); kfree(mon_mpdu); } @@ -3385,7 +3399,7 @@ ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, } static void -ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, +ath12k_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct dp_mon_tx_ppdu_info *tx_ppdu_info) { @@ -3396,7 +3410,7 @@ ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, list_del(&mon_mpdu->list); if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(ar, mon_mpdu, + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, &tx_ppdu_info->rx_status, napi); kfree(mon_mpdu); @@ -3404,13 +3418,14 @@ ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, } enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi, u32 ppdu_id) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; struct hal_tlv_hdr *tlv; u8 *ptr = skb->data; @@ -3452,8 +3467,8 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, break; } while (tlv_status != DP_MON_TX_FES_STATUS_END); - ath12k_dp_mon_tx_process_ppdu_info(ar, napi, tx_data_ppdu_info); - ath12k_dp_mon_tx_process_ppdu_info(ar, napi, tx_prot_ppdu_info); + ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); + ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); return tlv_status; } @@ -3491,8 +3506,7 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k *ar, - struct ath12k_link_sta *arsta, +static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta, struct hal_rx_mon_ppdu_info *ppdu_info) { struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats; @@ -3650,7 +3664,7 @@ void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) } static void -ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, +ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info, u32 uid) { @@ -3663,17 +3677,17 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) return; - peer = ath12k_peer_find_by_ast(ar->ab, user_stats->ast_index); + peer = ath12k_peer_find_by_ast(ab, user_stats->ast_index); if (!peer) { - ath12k_warn(ar->ab, "peer ast idx %d can't be found\n", + ath12k_warn(ab, "peer ast idx %d can't be found\n", user_stats->ast_index); return; } - arsta = ath12k_peer_get_link_sta(ar->ab, peer); + arsta = ath12k_peer_get_link_sta(ab, peer); if (!arsta) { - ath12k_warn(ar->ab, "link sta not found on peer %pM id %d\n", + ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); return; } @@ -3756,7 +3770,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, } static void -ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar, +ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info) { u32 num_users, i; @@ -3766,7 +3780,7 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar, num_users = HAL_MAX_UL_MU_USERS; for (i = 0; i < num_users; i++) - ath12k_dp_mon_rx_update_user_stats(ar, ppdu_info, i); + ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } static void @@ -3776,14 +3790,13 @@ ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } -int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, +int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, struct napi_struct *napi) { - struct ath12k_base *ab = ar->ab; - struct ath12k_pdev_dp *pdev_dp = &ar->dp; + struct ath12k_dp *dp = pdev_dp->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_mon_dest_desc *mon_dst_desc; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb; @@ -3796,7 +3809,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, u64 cookie; int num_buffs_reaped = 0, srng_id, buf_id; u32 hal_status, end_offset, info0, end_reason; - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, ar->pdev_idx); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); __skb_queue_head_init(&skb_list); srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); @@ -3894,7 +3907,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(ar, pmon, skb, napi); + hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ppdu_info->ppdu_continuation = true; dev_kfree_skb_any(skb); @@ -3915,21 +3928,21 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, } if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = ath12k_peer_get_link_sta(ar->ab, peer); + arsta = ath12k_peer_get_link_sta(ab, peer); if (!arsta) { - ath12k_warn(ar->ab, "link sta not found on peer %pM id %d\n", + ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); dev_kfree_skb_any(skb); continue; } - ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta, + ath12k_dp_mon_rx_update_peer_su_stats(arsta, ppdu_info); } else if ((ppdu_info->fc_valid) && (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { ath12k_dp_mon_rx_process_ulofdma(ppdu_info); - ath12k_dp_mon_rx_update_peer_mu_stats(ar, ppdu_info); + ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); } next_skb: @@ -4363,7 +4376,7 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, tmp_mpdu->tail = tail_msdu; tmp_mpdu->err_bitmap = pmon->err_bitmap; tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(ar, tmp_mpdu, + ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, &pmon->mon_ppdu_info, napi); rx_mon_stats->dest_mpdu_done++; kfree(tmp_mpdu); @@ -4408,7 +4421,7 @@ __ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; - hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); + hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); if (ar->monitor_started && pmon->mon_ppdu_status == DP_PPDU_STATUS_START && @@ -4430,17 +4443,33 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode) { - struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_pdev_dp *dp_pdev; + struct ath12k *ar; int num_buffs_reaped = 0; + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + return 0; + } + if (ab->hw_params->rxdma1_enable) { if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) - num_buffs_reaped = ath12k_dp_mon_srng_process(ar, &budget, napi); + num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, + napi); } else { + ar = ath12k_pdev_dp_to_ar(dp_pdev); + if (ar->monitor_started) num_buffs_reaped = __ath12k_dp_mon_process_ring(ar, mac_id, napi, &budget); } + rcu_read_unlock(); + return num_buffs_reaped; } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index e25595cbdcf37..068df74003456 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_DP_MON_H @@ -78,7 +78,7 @@ struct dp_mon_tx_ppdu_info { }; enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi); @@ -97,11 +97,12 @@ ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, struct hal_tlv_hdr *tx_tlv, u8 *num_users); enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, struct napi_struct *napi); +int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, + struct napi_struct *napi); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 8d4f0a673595f..89e12d916d829 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -870,7 +870,7 @@ struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, return NULL; } -int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype) +int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype) { switch (enctype) { case HAL_ENCRYPT_TYPE_OPEN: @@ -892,11 +892,11 @@ int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype break; } - ath12k_warn(ar->ab, "unsupported encryption type %d for mic len\n", enctype); + ath12k_warn(dp->ab, "unsupported encryption type %d for mic len\n", enctype); return 0; } -static int ath12k_dp_rx_crypto_param_len(struct ath12k *ar, +static int ath12k_dp_rx_crypto_param_len(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype) { switch (enctype) { @@ -920,11 +920,11 @@ static int ath12k_dp_rx_crypto_param_len(struct ath12k *ar, break; } - ath12k_warn(ar->ab, "unsupported encryption type %d\n", enctype); + ath12k_warn(dp_pdev->dp->ab, "unsupported encryption type %d\n", enctype); return 0; } -static int ath12k_dp_rx_crypto_icv_len(struct ath12k *ar, +static int ath12k_dp_rx_crypto_icv_len(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype) { switch (enctype) { @@ -945,15 +945,17 @@ static int ath12k_dp_rx_crypto_icv_len(struct ath12k *ar, break; } - ath12k_warn(ar->ab, "unsupported encryption type %d\n", enctype); + ath12k_warn(dp_pdev->dp->ab, "unsupported encryption type %d\n", enctype); return 0; } -static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, +static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; @@ -984,8 +986,9 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, /* Rebuild crypto header for mac80211 use */ if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { - crypto_hdr = skb_push(msdu, ath12k_dp_rx_crypto_param_len(ar, enctype)); - ath12k_dp_rx_desc_get_crypto_header(ar->ab, + crypto_hdr = skb_push(msdu, + ath12k_dp_rx_crypto_param_len(dp_pdev, enctype)); + ath12k_dp_rx_desc_get_crypto_header(ab, rxcb->rx_desc, crypto_hdr, enctype); } @@ -996,11 +999,13 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, memcpy(skb_push(msdu, hdr_len), decap_hdr, hdr_len); } -static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, +static void ath12k_dp_rx_h_undecap_raw(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, enum hal_encrypt_type enctype, struct ieee80211_rx_status *status, bool decrypted) { + struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_hdr *hdr; size_t hdr_len; @@ -1022,20 +1027,20 @@ static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, /* Tail */ if (status->flag & RX_FLAG_IV_STRIPPED) { skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_mic_len(ar, enctype)); + ath12k_dp_rx_crypto_mic_len(dp, enctype)); skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_icv_len(ar, enctype)); + ath12k_dp_rx_crypto_icv_len(dp_pdev, enctype)); } else { /* MIC */ if (status->flag & RX_FLAG_MIC_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_mic_len(ar, enctype)); + ath12k_dp_rx_crypto_mic_len(dp, enctype)); /* ICV */ if (status->flag & RX_FLAG_ICV_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_icv_len(ar, enctype)); + ath12k_dp_rx_crypto_icv_len(dp_pdev, enctype)); } /* MMIC */ @@ -1047,21 +1052,22 @@ static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, /* Head */ if (status->flag & RX_FLAG_IV_STRIPPED) { hdr_len = ieee80211_hdrlen(hdr->frame_control); - crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); + crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); memmove(msdu->data + crypto_len, msdu->data, hdr_len); skb_pull(msdu, crypto_len); } } -static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, +static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct ath12k_skb_rxcb *rxcb, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { struct hal_rx_desc *rx_desc = rxcb->rx_desc; - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; size_t hdr_len, crypto_len; struct ieee80211_hdr hdr; __le16 qos_ctl; @@ -1071,7 +1077,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, hdr_len = ieee80211_hdrlen(hdr.frame_control); if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { - crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); + crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); crypto_hdr = skb_push(msdu, crypto_len); ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); } @@ -1094,7 +1100,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, } } -static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, +static void ath12k_dp_rx_h_undecap_eth(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) @@ -1113,7 +1119,7 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, skb_pull(msdu, sizeof(*eth)); memcpy(skb_push(msdu, sizeof(rfc)), &rfc, sizeof(rfc)); - ath12k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, enctype, rx_info); + ath12k_get_dot11_hdr_from_rx_desc(dp_pdev, msdu, rxcb, enctype, rx_info); /* original 802.11 header has a different DA and in * case of 4addr it may also have different SA @@ -1123,7 +1129,7 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, ether_addr_copy(ieee80211_get_SA(hdr), sa); } -void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, bool decrypted, @@ -1133,10 +1139,10 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, switch (rx_info->decap_type) { case DP_RX_DECAP_TYPE_NATIVE_WIFI: - ath12k_dp_rx_h_undecap_nwifi(ar, msdu, enctype, rx_info); + ath12k_dp_rx_h_undecap_nwifi(dp_pdev, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_RAW: - ath12k_dp_rx_h_undecap_raw(ar, msdu, enctype, rx_info->rx_status, + ath12k_dp_rx_h_undecap_raw(dp_pdev, msdu, enctype, rx_info->rx_status, decrypted); break; case DP_RX_DECAP_TYPE_ETHERNET2_DIX: @@ -1145,7 +1151,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, /* mac80211 allows fast path only for authorized STA */ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) { ATH12K_SKB_RXCB(msdu)->is_eapol = true; - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); + ath12k_dp_rx_h_undecap_eth(dp_pdev, msdu, enctype, rx_info); break; } @@ -1153,7 +1159,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, * remove eth header and add 802.11 header. */ if (ATH12K_SKB_RXCB(msdu)->is_mcbc && decrypted) - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); + ath12k_dp_rx_h_undecap_eth(dp_pdev, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_8023: /* TODO: Handle undecap for these formats */ @@ -1182,18 +1188,22 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_info) +static void ath12k_dp_rx_h_rate(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; struct ieee80211_supported_band *sband; struct ieee80211_rx_status *rx_status = rx_info->rx_status; enum rx_msdu_start_pkt_type pkt_type = rx_info->pkt_type; u8 bw = rx_info->bw, sgi = rx_info->sgi; u8 rate_mcs = rx_info->rate_mcs, nss = rx_info->nss; bool is_cck; + struct ath12k *ar; switch (pkt_type) { case RX_MSDU_START_PKT_TYPE_11A: case RX_MSDU_START_PKT_TYPE_11B: + ar = ath12k_pdev_dp_to_ar(dp_pdev); is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B); sband = &ar->mac.sbands[rx_status->band]; rx_status->rate_idx = ath12k_mac_hw_rate_to_idx(sband, rate_mcs, @@ -1202,7 +1212,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i case RX_MSDU_START_PKT_TYPE_11N: rx_status->encoding = RX_ENC_HT; if (rate_mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in HT mode %d\n", rate_mcs); break; @@ -1216,7 +1226,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i rx_status->encoding = RX_ENC_VHT; rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in VHT mode %d\n", rate_mcs); break; @@ -1229,7 +1239,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i case RX_MSDU_START_PKT_TYPE_11AX: rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in HE mode %d\n", rate_mcs); break; @@ -1243,7 +1253,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in EHT mode %d\n", rate_mcs); break; @@ -1259,7 +1269,8 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i } } -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) +void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_desc_data *rx_info) { struct ieee80211_rx_status *rx_status = rx_info->rx_status; u8 channel_num; @@ -1293,6 +1304,8 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) if (unlikely(rx_status->band == NUM_NL80211_BANDS || !ath12k_ar_to_hw(ar)->wiphy->bands[rx_status->band])) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + ath12k_warn(ar->ab, "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n", rx_status->band, channel_num, center_freq, ar->pdev_idx); @@ -1316,14 +1329,15 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) rx_status->band); h_rate: - ath12k_dp_rx_h_rate(ar, rx_info); + ath12k_dp_rx_h_rate(dp_pdev, rx_info); } -void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, +void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; struct ath12k_peer *peer; @@ -1388,7 +1402,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; - ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi); + ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, @@ -1534,13 +1548,14 @@ int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, return ret; } -void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags) { + struct ath12k_dp *dp = dp_pdev->dp; struct ieee80211_hdr *hdr; size_t hdr_len; size_t crypto_len; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = dp->ab->hal.hal_desc_sz; if (!flags) return; @@ -1549,15 +1564,15 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, if (flags & RX_FLAG_MIC_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_mic_len(ar, enctype)); + ath12k_dp_rx_crypto_mic_len(dp, enctype)); if (flags & RX_FLAG_ICV_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_icv_len(ar, enctype)); + ath12k_dp_rx_crypto_icv_len(dp_pdev, enctype)); if (flags & RX_FLAG_IV_STRIPPED) { hdr_len = ieee80211_hdrlen(hdr->frame_control); - crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); + crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); memmove(msdu->data + hal_rx_desc_sz + crypto_len, msdu->data + hal_rx_desc_sz, hdr_len); @@ -1593,12 +1608,12 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, __skb_queue_tail(frag_list, cur_frag); } -u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) +u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) { struct ieee80211_hdr *hdr; u64 pn = 0; u8 *ehdr; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = dp->ab->hal.hal_desc_sz; hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); ehdr = skb->data + hal_rx_desc_sz + ieee80211_hdrlen(hdr->frame_control); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 1a8802c37443b..97b8f4608087f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -185,23 +185,23 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } -void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, bool decrypted, struct hal_rx_desc_data *rx_info); -void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, +void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); -u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); +u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb); void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff_head *frag_list, struct sk_buff *cur_frag); -void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags); void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc); @@ -251,14 +251,15 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype); +int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype); u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info); +void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_desc_data *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first); void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 657632ed2a992..9d14df501d65d 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -22,6 +22,7 @@ #include "hif.h" #include "wow.h" #include "debugfs_sta.h" +#include "dp.h" #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ @@ -8701,7 +8702,7 @@ static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_link_vif *arv ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { enctype = ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); - mic_len = ath12k_dp_rx_crypto_mic_len(ar, enctype); + mic_len = ath12k_dp_rx_crypto_mic_len(ab->dp, enctype); skb_put(skb, mic_len); } } @@ -9156,6 +9157,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, u32 info_flags = info->flags; struct sk_buff *msdu_copied; struct ath12k *ar, *tmp_ar; + struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; struct ath12k_peer *peer; unsigned long links_map; bool is_mcast = false; @@ -9204,6 +9206,10 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, ar = arvif->ar; skb_cb->link_id = link_id; + /* as skb_cb is common currently for dp and mgmt tx processing + * set this in the common mac op tx function. + */ + skb_cb->ar = ar; is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { @@ -9231,6 +9237,12 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP && vif->p2p) ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); + dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx); + if (!dp_pdev) { + ieee80211_free_txskb(hw, skb); + return; + } + /* Checking if it is a DVLAN frame */ if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && @@ -9241,7 +9253,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (!vif->valid_links || !is_mcast || is_dvlan || (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { - ret = ath12k_wifi7_dp_tx(ar, arvif, skb, false, 0, is_mcast); + ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast); if (unlikely(ret)) { ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); ieee80211_free_txskb(ar->ah->hw, skb); @@ -9258,6 +9270,10 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, continue; tmp_ar = tmp_arvif->ar; + tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp, + tmp_ar->pdev_idx); + if (!tmp_dp_pdev) + continue; msdu_copied = skb_copy(skb, GFP_ATOMIC); if (!msdu_copied) { ath12k_err(ar->ab, @@ -9273,6 +9289,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, skb_cb = ATH12K_SKB_CB(msdu_copied); skb_cb->link_id = link_id; skb_cb->vif = vif; + skb_cb->ar = tmp_ar; /* For open mode, skip peer find logic */ if (unlikely(!ahvif->dp_vif.key_cipher)) @@ -9303,7 +9320,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, spin_unlock_bh(&tmp_ar->ab->base_lock); skip_peer_find: - ret = ath12k_wifi7_dp_tx(tmp_ar, tmp_arvif, + ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, msdu_copied, true, mcbc_gsn, is_mcast); if (unlikely(ret)) { if (ret == -ENOMEM) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 04c64b9046938..d6ce6b9bb4d71 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -310,11 +310,13 @@ static void ath12k_wifi7_dp_rx_h_csum_offload(struct sk_buff *msdu, CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } -static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, +static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; @@ -330,8 +332,8 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, if (rxcb->is_mcbc) rxcb->peer_id = rx_info->peer_id; - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info); + spin_lock_bh(&ab->base_lock); + peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -345,7 +347,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, } else { enctype = HAL_ENCRYPT_TYPE_OPEN; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&ab->base_lock); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) is_decrypted = rx_info->is_decrypted; @@ -374,7 +376,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, } ath12k_wifi7_dp_rx_h_csum_offload(msdu, rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + ath12k_dp_rx_h_undecap(dp_pdev, msdu, rx_desc, enctype, is_decrypted, rx_info); if (!is_decrypted || rx_info->is_mcbc) @@ -386,19 +388,19 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, } } -static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_dp *dp, struct sk_buff_head *msdu_list, struct sk_buff *first, struct sk_buff *last, u8 l3pad_bytes, int msdu_len, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_base *ab = dp->ab; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); int buf_first_hdr_len, buf_first_len; struct hal_rx_desc *ldesc; int space_extra, rem_len, buf_len; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; bool is_continuation; /* As the msdu is spread across multiple rx buffers, @@ -474,19 +476,20 @@ static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k *ar, return 0; } -static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct sk_buff_head *msdu_list, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc, *lrx_desc; struct ath12k_skb_rxcb *rxcb; struct sk_buff *last_buf; u8 l3_pad_bytes; u16 msdu_len; int ret; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); if (!last_buf) { @@ -524,7 +527,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { - ret = ath12k_wifi7_dp_rx_msdu_coalesce(ar, msdu_list, + ret = ath12k_wifi7_dp_rx_msdu_coalesce(dp, msdu_list, msdu, last_buf, l3_pad_bytes, msdu_len, rx_info); @@ -541,8 +544,8 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, goto free_out; } - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, rx_desc, rx_info); rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; @@ -565,11 +568,12 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k_skb_rxcb *rxcb; struct sk_buff *msdu; struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; struct hal_rx_desc_data rx_info; struct ath12k_dp *partner_dp; - u8 hw_link_id, pdev_id; + u8 hw_link_id, pdev_idx; int ret; if (skb_queue_empty(msdu_list)) @@ -585,11 +589,11 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, hw_link_id = rxcb->hw_link_id; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, - hw_links[hw_link_id].pdev_idx); + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, + hw_links[hw_link_id].pdev_idx); partner_ab = partner_dp->ab; - ar = partner_ab->pdevs[pdev_id].ar; - if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { + ar = partner_ab->pdevs[pdev_idx].ar; + if (!rcu_dereference(partner_ab->pdevs_active[pdev_idx])) { dev_kfree_skb_any(msdu); continue; } @@ -599,7 +603,13 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, continue; } - ret = ath12k_wifi7_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); + dp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx); + if (!dp_pdev) { + dev_kfree_skb_any(msdu); + continue; + } + + ret = ath12k_wifi7_dp_rx_process_msdu(dp_pdev, msdu, msdu_list, &rx_info); if (ret) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process msdu %d", ret); @@ -607,7 +617,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, continue; } - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); + ath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, &rx_info); } rcu_read_unlock(); @@ -778,10 +788,11 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, } static bool -ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, +ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k_pdev_dp *dp_pdev, struct ath12k_dp_rx_tid *rx_tid, enum hal_encrypt_type encrypt_type) { + struct ath12k_dp *dp = dp_pdev->dp; struct sk_buff *first_frag, *skb; u64 last_pn; u64 cur_pn; @@ -794,12 +805,12 @@ ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) return true; - last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); + last_pn = ath12k_dp_rx_h_get_pn(dp, first_frag); skb_queue_walk(&rx_tid->rx_frags, skb) { if (skb == first_frag) continue; - cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); + cur_pn = ath12k_dp_rx_h_get_pn(dp, skb); if (cur_pn != last_pn + 1) return false; last_pn = cur_pn; @@ -807,12 +818,11 @@ ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, return true; } -static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff *defrag_skb) { - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; struct hal_reo_entrance_ring *reo_ent_ring; struct hal_reo_dest_ring *reo_dest_ring; @@ -953,13 +963,14 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } -static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, struct ath12k_peer *peer, enum hal_encrypt_type enctype, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); struct ieee80211_key_conf *key_conf; @@ -1014,26 +1025,28 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k *ar, rx_info))) return -EINVAL; - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); + ath12k_dp_rx_h_undecap(dp_pdev, msdu, rx_desc, HAL_ENCRYPT_TYPE_TKIP_MIC, true, rx_info); - ieee80211_rx(ath12k_ar_to_hw(ar), msdu); + ieee80211_rx(ath12k_pdev_dp_to_hw(dp_pdev), msdu); return -EINVAL; } -static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff **defrag_skb, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; bool is_decrypted = false; int msdu_len = 0; int extra_space; - u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 flags, hal_rx_desc_sz = ab->hal.hal_desc_sz; first_frag = skb_peek(&rx_tid->rx_frags); last_frag = skb_peek_tail(&rx_tid->rx_frags); @@ -1056,7 +1069,7 @@ static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, /* RX fragments are always raw packets */ if (skb != last_frag) skb_trim(skb, skb->len - FCS_LEN); - ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); + ath12k_dp_rx_h_undecap_frag(dp_pdev, skb, enctype, flags); if (skb != first_frag) skb_pull(skb, hal_rx_desc_sz + @@ -1079,19 +1092,21 @@ static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - if (ath12k_wifi7_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) + if (ath12k_wifi7_dp_rx_h_verify_tkip_mic(dp_pdev, peer, enctype, first_frag, + rx_info)) first_frag = NULL; *defrag_skb = first_frag; return 0; } -static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_reo_dest_ring *ring_desc, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; @@ -1186,17 +1201,17 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, if (!peer) goto err_frags_cleanup; - if (!ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) + if (!ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(dp_pdev, rx_tid, enctype)) goto err_frags_cleanup; - if (ath12k_wifi7_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, + if (ath12k_wifi7_dp_rx_h_defrag(dp_pdev, peer, rx_tid, &defrag_skb, enctype, rx_info)) goto err_frags_cleanup; if (!defrag_skb) goto err_frags_cleanup; - if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(dp, rx_tid, defrag_skb)) goto err_frags_cleanup; ath12k_dp_rx_frags_cleanup(rx_tid, false); @@ -1211,12 +1226,14 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, } static int -ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, +ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, struct hal_reo_dest_ring *desc, struct list_head *used_list, bool drop, u32 cookie) { - struct ath12k_base *ab = ar->ab; + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct sk_buff *msdu; struct ath12k_skb_rxcb *rxcb; struct hal_rx_desc_data rx_info; @@ -1249,7 +1266,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, list_add_tail(&desc_info->list, used_list); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ar->ab->dev, rxcb->paddr, + dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1274,8 +1291,8 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + ath12k_warn(ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, sizeof(*rx_desc)); dev_kfree_skb_any(msdu); goto exit; @@ -1283,7 +1300,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, skb_put(msdu, hal_rx_desc_sz + msdu_len); - if (ath12k_wifi7_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { + if (ath12k_wifi7_dp_rx_frag_h_mpdu(dp_pdev, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); @@ -1312,14 +1329,14 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n struct dp_srng *reo_except; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; + struct ath12k_pdev_dp *dp_pdev; u8 hw_link_id, device_id; u32 desc_bank, num_msdus; struct hal_srng *srng; - struct ath12k *ar; dma_addr_t paddr; bool is_frag; bool drop; - int pdev_id; + int pdev_idx; struct list_head *used_list; enum hal_wbm_rel_bm_act act; @@ -1356,9 +1373,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); partner_ab = partner_dp->ab; - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); link_desc_banks = partner_dp->link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + @@ -1396,10 +1412,18 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n act); } + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + continue; + } + for (i = 0; i < num_msdus; i++) { used_list = &rx_desc_used_list[device_id]; - if (!ath12k_wifi7_dp_process_rx_err_buf(ar, reo_desc, + if (!ath12k_wifi7_dp_process_rx_err_buf(dp_pdev, reo_desc, used_list, drop, msdu_cookies[i])) { @@ -1408,6 +1432,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n } } + rcu_read_unlock(); + if (tot_n_bufs_reaped >= quota) { tot_n_bufs_reaped = quota; goto exit; @@ -1438,7 +1464,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n } static void -ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, +ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k_dp *dp, int msdu_len, struct sk_buff_head *msdu_list) { struct sk_buff *skb, *tmp; @@ -1446,7 +1472,7 @@ ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, int n_buffs; n_buffs = DIV_ROUND_UP(msdu_len, - (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); + (DP_RX_BUFFER_SIZE - dp->ab->hal.hal_desc_sz)); skb_queue_walk_safe(msdu_list, skb, tmp) { rxcb = ATH12K_SKB_RXCB(skb); @@ -1461,21 +1487,23 @@ ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, } } -static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, +static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = dp->ab->hal.hal_desc_sz; if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); - ath12k_wifi7_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + ath12k_wifi7_dp_rx_null_q_desc_sg_drop(dp, msdu_len, msdu_list); return -EINVAL; } @@ -1487,7 +1515,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *m return -EINVAL; if (!rx_info->msdu_done) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "msdu_done bit not set in null_q_des processing\n"); __skb_queue_purge(msdu_list); return -EIO; @@ -1514,8 +1542,8 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *m if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return -EINVAL; - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, desc, rx_info); rxcb->tid = rx_info->tid; @@ -1526,15 +1554,17 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *m return 0; } -static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, +static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; rxcb->is_first_msdu = rx_info->is_first_msdu; rxcb->is_last_msdu = rx_info->is_last_msdu; @@ -1553,29 +1583,31 @@ static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return true; - ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | RX_FLAG_DECRYPTED); - ath12k_dp_rx_h_undecap(ar, msdu, desc, + ath12k_dp_rx_h_undecap(dp_pdev, msdu, desc, HAL_ENCRYPT_TYPE_TKIP_MIC, false, rx_info); return false; } -static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, +static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - ar->ab->device_stats.rxdma_error[rxcb->err_code]++; + dp->ab->device_stats.rxdma_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - drop = ath12k_wifi7_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + drop = ath12k_wifi7_dp_rx_h_tkip_mic_err(dp_pdev, msdu, rx_info); break; } fallthrough; @@ -1590,18 +1622,20 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *m return drop; } -static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, +static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { + struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - ar->ab->device_stats.reo_error[rxcb->err_code]++; + dp->ab->device_stats.reo_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: - if (ath12k_wifi7_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + if (ath12k_wifi7_dp_rx_h_null_q_desc(dp_pdev, msdu, rx_info, msdu_list)) drop = true; break; case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: @@ -1621,11 +1655,12 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu return drop; } -static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, +static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct sk_buff_head *msdu_list) { + struct ath12k_dp *dp = dp_pdev->dp; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status rxs = {}; @@ -1635,14 +1670,14 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(dp->ab, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: - drop = ath12k_wifi7_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + drop = ath12k_wifi7_dp_rx_h_reo_err(dp_pdev, msdu, &rx_info, msdu_list); break; case HAL_WBM_REL_SRC_MODULE_RXDMA: - drop = ath12k_wifi7_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + drop = ath12k_wifi7_dp_rx_h_rxdma_err(dp_pdev, msdu, &rx_info); break; default: /* msdu will get freed */ @@ -1656,7 +1691,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); + ath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, &rx_info); } void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, @@ -1694,6 +1729,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; @@ -1710,9 +1746,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct ath12k_rx_desc_info *desc_info; struct ath12k_device_dp_stats *device_stats = &ab->device_stats; struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; u8 hw_link_id, device_id; - int ret, pdev_id; + int ret, pdev_idx; struct hal_rx_desc *msdu_data; __skb_queue_head_init(&msdu_list); @@ -1770,8 +1805,6 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - partner_ab = partner_dp->ab; - list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); @@ -1804,7 +1837,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->ab, msdu_data); if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { dev_kfree_skb_any(msdu); @@ -1872,12 +1905,17 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, - hw_links[hw_link_id].pdev_idx); - partner_ab = partner_dp->ab; - ar = partner_ab->pdevs[pdev_id].ar; + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, + hw_links[hw_link_id].pdev_idx); + + dp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx); + if (!dp_pdev) { + dev_kfree_skb_any(msdu); + continue; + } + ar = ath12k_pdev_dp_to_ar(dp_pdev); - if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { + if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_idx])) { dev_kfree_skb_any(msdu); continue; } @@ -1892,7 +1930,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; } - ath12k_wifi7_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + ath12k_wifi7_dp_rx_wbm_err(dp_pdev, napi, msdu, &msdu_list); } rcu_read_unlock(); done: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index b94b14bda39bf..ab5824abfe758 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -54,12 +54,12 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb) return 0; } -int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, +int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast) { - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct hal_tx_info ti = {}; struct ath12k_tx_desc_info *tx_desc; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -84,7 +84,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, bool is_diff_encap = false; bool is_null_frame = false; - if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) + if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) return -ESHUTDOWN; if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && @@ -121,7 +121,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ti.meta_data_flags = dp_link_vif->tcl_metadata; if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && - test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { + test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) { if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { ti.encrypt_type = ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); @@ -231,7 +231,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, goto fail_remove_tx_buf; } - if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags) && !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && ieee80211_has_protected(hdr->frame_control)) || @@ -259,7 +259,6 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ti.desc_id = tx_desc->desc_id; ti.data_len = skb->len; skb_cb->paddr = ti.paddr; - skb_cb->ar = ar; if (msdu_ext_desc) { skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc)); @@ -349,7 +348,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", skb->data, skb->len); - atomic_inc(&ar->dp.num_tx_pending); + atomic_inc(&dp_pdev->num_tx_pending); return 0; @@ -511,10 +510,11 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, } } -static void -ath12k_wifi7_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) +static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, + struct hal_tx_status *ts) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_peer *peer; struct ieee80211_sta *sta; struct ath12k_sta *ahsta; @@ -630,13 +630,13 @@ ath12k_wifi7_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) spin_unlock_bh(&ab->base_lock); } -static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, +static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, struct ath12k_tx_desc_params *desc_params, struct hal_tx_status *ts, int ring) { - struct ath12k_base *ab = ar->ab; - struct ath12k_hw *ah = ar->ah; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ieee80211_tx_info *info; struct ath12k_link_vif *arvif; struct ath12k_skb_cb *skb_cb; @@ -668,13 +668,13 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, rcu_read_lock(); - if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { - ieee80211_free_txskb(ah->hw, msdu); + if (!rcu_dereference(ab->pdevs_active[dp_pdev->mac_id])) { + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } if (!skb_cb->vif) { - ieee80211_free_txskb(ah->hw, msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } @@ -703,6 +703,8 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ab->wmi_ab.svc_map)) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + spin_lock_bh(&ar->data_lock); noise_floor = ath12k_pdev_get_noise_floor(ar); spin_unlock_bh(&ar->data_lock); @@ -726,7 +728,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, * hence drop the frame; do not update the status of frame to * the upper layer */ - ieee80211_free_txskb(ah->hw, msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; default: ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n", @@ -739,7 +741,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, * Might end up reporting it out-of-band from HTT stats. */ - ath12k_wifi7_dp_tx_update_txcompl(ar, ts); + ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); spin_lock_bh(&ab->base_lock); peer = ath12k_peer_find_by_id(ab, ts->peer_id); @@ -748,7 +750,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); spin_unlock_bh(&ab->base_lock); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } ahsta = ath12k_sta_to_ahsta(peer->sta); @@ -766,7 +768,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, status.rates = &status_rate; status.n_rates = 1; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); + ieee80211_tx_status_ext(ath12k_pdev_dp_to_hw(dp_pdev), &status); exit: rcu_read_unlock(); @@ -811,7 +813,7 @@ ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) { - struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; @@ -820,7 +822,7 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) struct ath12k_tx_desc_params desc_params; struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; struct hal_wbm_release_ring *desc; - u8 pdev_id; + u8 pdev_idx; u64 desc_va; enum hal_wbm_rel_src_module buf_rel_source; enum hal_wbm_tqm_rel_reason rel_status; @@ -902,13 +904,21 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); - ar = ab->pdevs[pdev_id].ar; + pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + continue; + } + + if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) + wake_up(&dp_pdev->tx_empty_waitq); - ath12k_wifi7_dp_tx_complete_msdu(ar, &desc_params, &ts, + ath12k_wifi7_dp_tx_complete_msdu(dp_pdev, &desc_params, &ts, tx_ring->tcl_data_ring_id); + rcu_read_unlock(); } } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 061c4de4d4e62..524e23b8ed808 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -7,7 +7,7 @@ #ifndef ATH12K_DP_TX_WIFI7_H #define ATH12K_DP_TX_WIFI7_H -int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, +int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); From 3096647c6e0bc042aa16cd006231d3b912bfb183 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 7 Oct 2025 16:32:03 +0530 Subject: [PATCH 415/659] wifi: ath12k: Rearrange PPDU radio stats Encapsulate PPDU stats in dp_pdev as these stats are related to data path out-of-band operations. This reorganization improves the structuring of data path stats and enhances the efficiency of data path operations by consolidating both in-band (per packet) fields and out-of-band data path stats within the same ath12k_pdev_dp object. ppdu_list_lock is used to protect HTT pdev stats update. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251007110203.1541167-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 20 -------- drivers/net/wireless/ath/ath12k/dp.h | 6 +++ drivers/net/wireless/ath/ath12k/dp_cmn.h | 18 ++++++++ drivers/net/wireless/ath/ath12k/dp_htt.c | 59 ++++++++++++++---------- drivers/net/wireless/ath/ath12k/mac.c | 11 +++-- 5 files changed, 65 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index d11bc1cae9863..49637b56b8f9e 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -659,23 +659,6 @@ struct ath12k_debug { bool extd_rx_stats; }; -struct ath12k_per_peer_tx_stats { - u32 succ_bytes; - u32 retry_bytes; - u32 failed_bytes; - u32 duration; - u16 succ_pkts; - u16 retry_pkts; - u16 failed_pkts; - u16 ru_start; - u16 ru_tones; - u8 ba_fails; - u8 ppdu_type; - u32 mu_grpid; - u32 mu_pos; - bool is_ampdu; -}; - struct ath12k_pdev_rssi_offsets { s32 temp_offset; s8 min_nf_dbm; @@ -801,9 +784,6 @@ struct ath12k { struct ath12k_wow wow; struct completion target_suspend; bool target_suspend_ack; - struct ath12k_per_peer_tx_stats peer_tx_stats; - struct list_head ppdu_stats_info; - u32 ppdu_stat_list_depth; struct ath12k_per_peer_tx_stats cached_stats; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 30a101e797fb5..d592974f8e066 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -156,6 +156,12 @@ struct ath12k_pdev_dp { struct ieee80211_hw *hw; u8 hw_link_id; + /* Protects ppdu stats */ + spinlock_t ppdu_list_lock; + struct ath12k_per_peer_tx_stats peer_tx_stats; + struct list_head ppdu_stats_info; + u32 ppdu_stat_list_depth; + struct dp_srng rxdma_mon_dst_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng tx_mon_dst_ring[MAX_RXDMA_PER_PDEV]; diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 3dc61d1a41625..243fb5a680167 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -34,6 +34,24 @@ struct ath12k_dp_vif { struct ath12k_dp_link_vif dp_link_vif[ATH12K_NUM_MAX_LINKS]; }; +/* TODO: Move this to a separate dp_stats file */ +struct ath12k_per_peer_tx_stats { + u32 succ_bytes; + u32 retry_bytes; + u32 failed_bytes; + u32 duration; + u16 succ_pkts; + u16 retry_pkts; + u16 failed_pkts; + u16 ru_start; + u16 ru_tones; + u8 ba_fails; + u8 ppdu_type; + u32 mu_grpid; + u32 mu_pos; + bool is_ampdu; +}; + static inline struct ath12k_dp_link_vif * ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) { diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 267220f43fd2c..1a0d3e4ac8bb7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -183,14 +183,15 @@ int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, } static void -ath12k_update_per_peer_tx_stats(struct ath12k *ar, +ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, struct htt_ppdu_stats *ppdu_stats, u8 user) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_peer *peer; struct ath12k_link_sta *arsta; struct htt_ppdu_stats_user_rate *user_rate; - struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats; + struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats; struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; struct htt_ppdu_stats_common *common = &ppdu_stats->common; int ret; @@ -360,34 +361,34 @@ ath12k_update_per_peer_tx_stats(struct ath12k *ar, rcu_read_unlock(); } -static void ath12k_htt_update_ppdu_stats(struct ath12k *ar, +static void ath12k_htt_update_ppdu_stats(struct ath12k_pdev_dp *dp_pdev, struct htt_ppdu_stats *ppdu_stats) { u8 user; for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++) - ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user); + ath12k_update_per_peer_tx_stats(dp_pdev, ppdu_stats, user); } static -struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, +struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp *dp_pdev, u32 ppdu_id) { struct htt_ppdu_stats_info *ppdu_info; - lockdep_assert_held(&ar->data_lock); - if (!list_empty(&ar->ppdu_stats_info)) { - list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { + lockdep_assert_held(&dp_pdev->ppdu_list_lock); + if (!list_empty(&dp_pdev->ppdu_stats_info)) { + list_for_each_entry(ppdu_info, &dp_pdev->ppdu_stats_info, list) { if (ppdu_info->ppdu_id == ppdu_id) return ppdu_info; } - if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { - ppdu_info = list_first_entry(&ar->ppdu_stats_info, + if (dp_pdev->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { + ppdu_info = list_first_entry(&dp_pdev->ppdu_stats_info, typeof(*ppdu_info), list); list_del(&ppdu_info->list); - ar->ppdu_stat_list_depth--; - ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); + dp_pdev->ppdu_stat_list_depth--; + ath12k_htt_update_ppdu_stats(dp_pdev, &ppdu_info->ppdu_stats); kfree(ppdu_info); } } @@ -396,8 +397,8 @@ struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, if (!ppdu_info) return NULL; - list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); - ar->ppdu_stat_list_depth++; + list_add_tail(&ppdu_info->list, &dp_pdev->ppdu_stats_info); + dp_pdev->ppdu_stat_list_depth++; return ppdu_info; } @@ -435,14 +436,15 @@ static void ath12k_copy_to_bar(struct ath12k_peer *peer, static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, struct sk_buff *skb) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_htt_ppdu_stats_msg *msg; struct htt_ppdu_stats_info *ppdu_info; struct ath12k_peer *peer = NULL; struct htt_ppdu_user_stats *usr_stats = NULL; u32 peer_id = 0; - struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; int ret, i; - u8 pdev_id; + u8 pdev_id, pdev_idx; u32 ppdu_id, len; msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; @@ -457,17 +459,24 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); ppdu_id = le32_to_cpu(msg->ppdu_id); + pdev_idx = DP_HW2SW_MACID(pdev_id); + if (pdev_idx >= MAX_RADIOS) { + ath12k_warn(ab, "HTT PPDU STATS invalid pdev id %u", pdev_id); + return -EINVAL; + } + rcu_read_lock(); - ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { ret = -EINVAL; goto exit; } - spin_lock_bh(&ar->data_lock); - ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id); + spin_lock_bh(&dp_pdev->ppdu_list_lock); + ppdu_info = ath12k_dp_htt_get_ppdu_desc(dp_pdev, ppdu_id); if (!ppdu_info) { - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); ret = -EINVAL; goto exit; } @@ -477,13 +486,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, ath12k_htt_tlv_ppdu_stats_parse, (void *)ppdu_info); if (ret) { - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); ath12k_warn(ab, "Failed to parse tlv %d\n", ret); goto exit; } if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); ath12k_warn(ab, "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", ppdu_info->ppdu_stats.common.num_users, @@ -531,7 +540,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, } } - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); exit: rcu_read_unlock(); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 9d14df501d65d..bc0c7a6bb6b1b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9632,6 +9632,7 @@ int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable) static void ath12k_mac_stop(struct ath12k *ar) { + struct ath12k_pdev_dp *dp_pdev = &ar->dp; struct ath12k_hw *ah = ar->ah; struct htt_ppdu_stats_info *ppdu_stats, *tmp; struct ath12k_wmi_scan_chan_list_arg *arg; @@ -9656,13 +9657,14 @@ static void ath12k_mac_stop(struct ath12k *ar) ar->state_11d = ATH12K_11D_IDLE; complete(&ar->completed_11d_scan); - spin_lock_bh(&ar->data_lock); - - list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { + spin_lock_bh(&dp_pdev->ppdu_list_lock); + list_for_each_entry_safe(ppdu_stats, tmp, &dp_pdev->ppdu_stats_info, list) { list_del(&ppdu_stats->list); kfree(ppdu_stats); } + spin_unlock_bh(&dp_pdev->ppdu_list_lock); + spin_lock_bh(&ar->data_lock); while ((arg = list_first_entry_or_null(&ar->regd_channel_update_queue, struct ath12k_wmi_scan_chan_list_arg, list))) { @@ -14575,8 +14577,9 @@ static void ath12k_mac_setup(struct ath12k *ar) ar->vdev_id_11d_scan = ATH12K_11D_INVALID_VDEV_ID; spin_lock_init(&ar->data_lock); + spin_lock_init(&ar->dp.ppdu_list_lock); INIT_LIST_HEAD(&ar->arvifs); - INIT_LIST_HEAD(&ar->ppdu_stats_info); + INIT_LIST_HEAD(&ar->dp.ppdu_stats_info); init_completion(&ar->vdev_setup_done); init_completion(&ar->vdev_delete_done); From 0f335f2d823b84e932f6a47da58f7dfd2435b44f Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:28 +0530 Subject: [PATCH 416/659] wifi: ath12k: Move srng config and hal_ops to hw specific hal files Move srng config and hal_ops from common hal file to hw specific hal files, since these implementations are specific and configurable for each hardware Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 474 +----------------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 329 ++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 3 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 344 +++++++++++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 3 + 5 files changed, 681 insertions(+), 472 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index a14a7d8dc69f2..4ff906854970f 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,210 +12,7 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static const struct hal_srng_config hw_srng_config_template[] = { - /* TODO: max_rings can populated by querying HW capabilities */ - [HAL_REO_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, - .max_rings = 8, - .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_EXCEPTION] = { - /* Designating REO2SW0 ring as exception ring. - * Any of theREO2SW rings can be used as exception ring. - */ - .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, - .max_rings = 1, - .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_REINJECT] = { - .start_ring_id = HAL_SRNG_RING_ID_SW2REO, - .max_rings = 4, - .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_CMD] = { - .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, - .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_64_hdr) + - sizeof(struct hal_reo_get_queue_stats)) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_64_hdr) + - sizeof(struct hal_reo_get_queue_stats_status)) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TCL_DATA] = { - .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, - .max_rings = 6, - .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TCL_CMD] = { - .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, - .max_rings = 1, - .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TCL_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_tcl_status_ring)) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, - }, - [HAL_CE_SRC] = { - .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, - .max_rings = 16, - .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, - }, - [HAL_CE_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, - .max_rings = 16, - .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, - }, - [HAL_CE_DST_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, - .max_rings = 16, - .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, - }, - [HAL_WBM_IDLE_LINK] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, - }, - [HAL_SW2WBM_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, - .max_rings = 2, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_WBM2SW_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, - .max_rings = 8, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_RXDMA_BUF] = { - .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_DMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, - .max_rings = 0, - .entry_size = 0, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_DESC] = { 0, }, - [HAL_RXDMA_DIR_BUF] = { - .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, - .max_rings = 2, - .entry_size = 8 >> 2, /* TODO: Define the struct */ - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_PPE2TCL] = { - .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, - .max_rings = 1, - .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_PPE_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TX_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_TX_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - } -}; - -static const struct ath12k_hal_tcl_to_wbm_rbm_map +const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { { .wbm_ring_num = 0, @@ -235,7 +32,7 @@ ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { } }; -static const struct ath12k_hal_tcl_to_wbm_rbm_map +const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { { .wbm_ring_num = 0, @@ -296,273 +93,6 @@ static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); } -static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) -{ - struct ath12k_hal *hal = &ab->hal; - struct hal_srng_config *s; - - hal->srng_config = kmemdup(hw_srng_config_template, - sizeof(hw_srng_config_template), - GFP_KERNEL); - if (!hal->srng_config) - return -ENOMEM; - - s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; - - s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; - - s = &hal->srng_config[HAL_REO_REINJECT]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; - s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; - - s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; - - s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; - - s = &hal->srng_config[HAL_TCL_DATA]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; - - s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; - - s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; - - s = &hal->srng_config[HAL_CE_SRC]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - - s = &hal->srng_config[HAL_CE_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + - HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; - - s = &hal->srng_config[HAL_SW2WBM_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; - - s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; - - /* Some LMAC rings are not accessed from the host: - * RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS, - * RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC, - * RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA - */ - s = &hal->srng_config[HAL_PPE2TCL]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP; - - s = &hal->srng_config[HAL_PPE_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; - - return 0; -} - -const struct hal_ops hal_qcn9274_ops = { - .create_srng_config = ath12k_hal_srng_create_config_qcn9274, - .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, - .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, - .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, -}; -EXPORT_SYMBOL(hal_qcn9274_ops); - -static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) -{ - struct ath12k_hal *hal = &ab->hal; - struct hal_srng_config *s; - - hal->srng_config = kmemdup(hw_srng_config_template, - sizeof(hw_srng_config_template), - GFP_KERNEL); - if (!hal->srng_config) - return -ENOMEM; - - s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; - - s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; - - s = &hal->srng_config[HAL_REO_REINJECT]; - s->max_rings = 1; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; - - s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; - - s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; - - s = &hal->srng_config[HAL_TCL_DATA]; - s->max_rings = 5; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; - - s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; - - s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; - - s = &hal->srng_config[HAL_CE_SRC]; - s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - - s = &hal->srng_config[HAL_CE_DST]; - s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + - HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; - - s = &hal->srng_config[HAL_SW2WBM_RELEASE]; - s->max_rings = 1; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; - - s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; - - s = &hal->srng_config[HAL_RXDMA_BUF]; - s->max_rings = 2; - s->mac_type = ATH12K_HAL_SRNG_PMAC; - - s = &hal->srng_config[HAL_RXDMA_DST]; - s->max_rings = 1; - s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2; - - /* below rings are not used */ - s = &hal->srng_config[HAL_RXDMA_DIR_BUF]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_PPE2TCL]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_PPE_RELEASE]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_TX_MONITOR_BUF]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_TX_MONITOR_DST]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_PPE2TCL]; - s->max_rings = 0; - - return 0; -} - -const struct hal_ops hal_wcn7850_ops = { - .create_srng_config = ath12k_hal_srng_create_config_wcn7850, - .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, - .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, - .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, - .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, -}; -EXPORT_SYMBOL(hal_wcn7850_ops); - static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 2e84c830d9b2b..c98ffc991ad81 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -6,6 +6,209 @@ #include "hal_desc.h" #include "hal_qcn9274.h" +static const struct hal_srng_config hw_srng_config_template[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + [HAL_REO_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, + .max_rings = 8, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_EXCEPTION] = { + /* Designating REO2SW0 ring as exception ring. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, + .max_rings = 1, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_REINJECT] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2REO, + .max_rings = 4, + .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats_status)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_DATA] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, + .max_rings = 6, + .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_tcl_status_ring)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_SRC] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM_IDLE_LINK] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, + }, + [HAL_SW2WBM_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, + .max_rings = 2, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM2SW_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, + .max_rings = 8, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_RXDMA_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_DMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, + .max_rings = 0, + .entry_size = 0, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DESC] = { 0, }, + [HAL_RXDMA_DIR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, + .max_rings = 2, + .entry_size = 8 >> 2, /* TODO: Define the struct */ + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_PPE2TCL] = { + .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_PPE_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TX_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_TX_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + } +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { @@ -367,3 +570,129 @@ void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_da rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274(rx_desc); rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc); } + +static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + struct hal_srng_config *s; + + hal->srng_config = kmemdup(hw_srng_config_template, + sizeof(hw_srng_config_template), + GFP_KERNEL); + if (!hal->srng_config) + return -ENOMEM; + + s = &hal->srng_config[HAL_REO_DST]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; + + s = &hal->srng_config[HAL_REO_EXCEPTION]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; + + s = &hal->srng_config[HAL_REO_REINJECT]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; + s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; + + s = &hal->srng_config[HAL_REO_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; + + s = &hal->srng_config[HAL_REO_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; + + s = &hal->srng_config[HAL_TCL_DATA]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; + + s = &hal->srng_config[HAL_TCL_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; + + s = &hal->srng_config[HAL_TCL_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; + + s = &hal->srng_config[HAL_CE_SRC]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + + s = &hal->srng_config[HAL_CE_DST]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_CE_DST_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + HAL_CE_DST_STATUS_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_WBM_IDLE_LINK]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; + + s = &hal->srng_config[HAL_SW2WBM_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; + s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - + HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; + + s = &hal->srng_config[HAL_WBM2SW_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; + + /* Some LMAC rings are not accessed from the host: + * RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS, + * RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC, + * RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA + */ + s = &hal->srng_config[HAL_PPE2TCL]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP; + + s = &hal->srng_config[HAL_PPE_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; + + return 0; +} + +const struct hal_ops hal_qcn9274_ops = { + .create_srng_config = ath12k_hal_srng_create_config_qcn9274, + .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, +}; +EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 9a918824e093f..1563854b5b6a5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,6 +12,9 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; + u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 0fa1d9fad2e19..2e88ac0ae7971 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -7,6 +7,209 @@ #include "hal_desc.h" #include "hal_wcn7850.h" +static const struct hal_srng_config hw_srng_config_template[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + [HAL_REO_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, + .max_rings = 8, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_EXCEPTION] = { + /* Designating REO2SW0 ring as exception ring. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, + .max_rings = 1, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_REINJECT] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2REO, + .max_rings = 4, + .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats_status)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_DATA] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, + .max_rings = 6, + .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_tcl_status_ring)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_SRC] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM_IDLE_LINK] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, + }, + [HAL_SW2WBM_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, + .max_rings = 2, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM2SW_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, + .max_rings = 8, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_RXDMA_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_DMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, + .max_rings = 0, + .entry_size = 0, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DESC] = { 0, }, + [HAL_RXDMA_DIR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, + .max_rings = 2, + .entry_size = 8 >> 2, /* TODO: Define the struct */ + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_PPE2TCL] = { + .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_PPE_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TX_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_TX_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + } +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { @@ -362,3 +565,144 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850(rx_desc); rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); } + +static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + struct hal_srng_config *s; + + hal->srng_config = kmemdup(hw_srng_config_template, + sizeof(hw_srng_config_template), + GFP_KERNEL); + if (!hal->srng_config) + return -ENOMEM; + + s = &hal->srng_config[HAL_REO_DST]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; + + s = &hal->srng_config[HAL_REO_EXCEPTION]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; + + s = &hal->srng_config[HAL_REO_REINJECT]; + s->max_rings = 1; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; + + s = &hal->srng_config[HAL_REO_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; + + s = &hal->srng_config[HAL_REO_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; + + s = &hal->srng_config[HAL_TCL_DATA]; + s->max_rings = 5; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; + + s = &hal->srng_config[HAL_TCL_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; + + s = &hal->srng_config[HAL_TCL_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; + + s = &hal->srng_config[HAL_CE_SRC]; + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + + s = &hal->srng_config[HAL_CE_DST]; + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_CE_DST_STATUS]; + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + HAL_CE_DST_STATUS_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_WBM_IDLE_LINK]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; + + s = &hal->srng_config[HAL_SW2WBM_RELEASE]; + s->max_rings = 1; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; + + s = &hal->srng_config[HAL_WBM2SW_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; + + s = &hal->srng_config[HAL_RXDMA_BUF]; + s->max_rings = 2; + s->mac_type = ATH12K_HAL_SRNG_PMAC; + + s = &hal->srng_config[HAL_RXDMA_DST]; + s->max_rings = 1; + s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2; + + /* below rings are not used */ + s = &hal->srng_config[HAL_RXDMA_DIR_BUF]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE2TCL]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE_RELEASE]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_TX_MONITOR_BUF]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_TX_MONITOR_DST]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE2TCL]; + s->max_rings = 0; + + return 0; +} + +const struct hal_ops hal_wcn7850_ops = { + .create_srng_config = ath12k_hal_srng_create_config_wcn7850, + .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, +}; +EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index a90978b2a4543..80de7ea522b54 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,6 +10,9 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; + u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); From 917ae760aca18024855b4a532a6aa0e528df3fbb Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:29 +0530 Subject: [PATCH 417/659] wifi: ath12k: Initialize desc_size through hal_init Currently desc_size uses a dedicated hal_ops API for initialization. Combine it with other hal_params to be initialized in a single API "hal_init" during probe time using a static array. hal_init will be used as the common API to initialize all hal parameters during the probe. Add hal.c file to add hal definitions that are wifi7 specific but common between qca and wcn chipsets. Add hal.h header to add wifi7 specific prototypes/Macros etc Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/core.c | 2 -- drivers/net/wireless/ath/ath12k/dp.c | 5 --- drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 3 -- drivers/net/wireless/ath/ath12k/hal.h | 5 ++- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 36 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 12 +++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 - .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hw.c | 3 ++ 11 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index e148444021633..32a0f30faf922 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -28,6 +28,7 @@ ath12k-y += wifi7/hal_tx.o \ wifi7/dp_rx.o \ wifi7/dp_tx.o \ wifi7/dp.o \ + wifi7/hal.o \ wifi7/hal_qcn9274.o \ wifi7/hal_wcn7850.o diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index c82c0746a3494..04983074e9467 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -930,8 +930,6 @@ static int ath12k_core_start(struct ath12k_base *ab) goto err_hif_stop; } - ath12k_dp_hal_rx_desc_init(ab); - ret = ath12k_wmi_cmd_init(ab); if (ret) { ath12k_err(ab, "failed to send wmi init cmd: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 088736bead58a..1887a517161d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -913,11 +913,6 @@ void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) /* TODO: Add any RXDMA setup required per pdev */ } -void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) -{ - ab->hal.hal_desc_sz = ab->hw_params->hal_ops->rx_desc_get_desc_size(); -} - int ath12k_dp_pdev_alloc(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index d592974f8e066..f7cf83806eb07 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -530,5 +530,4 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, u32 cookie); struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, u32 desc_id); -void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 4ff906854970f..87abacc8ae8e1 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1103,11 +1103,8 @@ static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) int ath12k_hal_srng_init(struct ath12k_base *ab) { - struct ath12k_hal *hal = &ab->hal; int ret; - memset(hal, 0, sizeof(*hal)); - ret = ab->hw_params->hal_ops->create_srng_config(ab); if (ret) goto err_hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 8d539b72d6677..ee0d31b7788ab 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1579,6 +1579,10 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) return ret; } +struct ath12k_hw_version_map { + u32 hal_desc_sz; +}; + struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; @@ -1594,7 +1598,6 @@ struct hal_ops { void (*extract_rx_desc_data)(struct hal_rx_desc_data *rx_desc_data, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); - u32 (*rx_desc_get_desc_size)(void); u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c new file mode 100644 index 0000000000000..4ad3ef3ba5e0f --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include "hw.h" +#include "hal_desc.h" +#include "../hal.h" +#include "hal.h" + +static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { + [ATH12K_HW_QCN9274_HW10] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + }, + [ATH12K_HW_QCN9274_HW20] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + }, + [ATH12K_HW_WCN7850_HW20] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + }, + [ATH12K_HW_IPQ5332_HW10] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + }, +}; + +int ath12k_wifi7_hal_init(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + + memset(hal, 0, sizeof(*hal)); + + hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; + + return 0; +} +EXPORT_SYMBOL(ath12k_wifi7_hal_init); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h new file mode 100644 index 0000000000000..0dc5eaec5fb0a --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_HAL_WIFI7_H +#define ATH12K_HAL_WIFI7_H + +int ath12k_wifi7_hal_init(struct ath12k_base *ab); + +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index c98ffc991ad81..6a1c13565700b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -690,7 +690,6 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 2e88ac0ae7971..275de9c1a359d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -699,7 +699,6 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 1acf6ffaea08f..621022064962e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -23,6 +23,7 @@ #include "../debugfs.h" #include "../debugfs_sta.h" #include "../testmode.h" +#include "hal.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, @@ -1124,6 +1125,8 @@ int ath12k_wifi7_hw_init(struct ath12k_base *ab) ab->hw_params = hw_params; ab->ath12k_ops = &ath12k_ops_wifi7; + ath12k_wifi7_hal_init(ab); + ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name); return 0; From d1dd005aabcd92e18cf8bbee3f3a854341d28ad5 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:30 +0530 Subject: [PATCH 418/659] wifi: ath12k: Initialize hal_ops through hal_init Modularize the HAL layer by moving hal_ops from ab->hw_params into the ab->hal. This reduces indirection and allows data path to access HAL ops directly through the HAL context. Initialize hal_ops via hal_init using a const table ath12k_hw_version_map. This approach will be extended to register other HAL parameters during init. Remove ab->hw_params->hal_ops as it is no longer needed. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 4 ++-- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 16 ++++++++-------- drivers/net/wireless/ath/ath12k/hal.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 5 ++--- drivers/net/wireless/ath/ath12k/hw.h | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 7 +++++++ .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_wcn7850.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 8 -------- 13 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index b743c05c5fb04..c22bc7da882eb 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -563,7 +563,7 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab) u32 num_irq; ring_mask = ab->hw_params->ring_mask; - hal_ops = ab->hw_params->hal_ops; + hal_ops = ab->hal.hal_ops; for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { irq_grp = &ab->ext_irq_grp[i]; num_irq = 0; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 1887a517161d6..8926c0a5c34fe 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -142,7 +142,7 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab, grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0]; ring_num = 0; } else { - map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; for (i = 0; i < ab->hw_params->max_tx_ring; i++) { if (ring_num == map[i].wbm_ring_num) { ring_num = i; @@ -508,7 +508,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } for (i = 0; i < ab->hw_params->max_tx_ring; i++) { - map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; tx_comp_ring_num = map[i].wbm_ring_num; ret = ath12k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 3f5d0d056bdde..8c8d60b2019a4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2082,7 +2082,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)head_msdu->data; hdr_desc = - ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc); + ab->hal.hal_ops->rx_desc_get_msdu_payload(rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 97b8f4608087f..09042d41976bf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -123,27 +123,27 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hw_params->hal_ops->rx_desc_get_l3_pad_bytes(desc); + return ab->hal.hal_ops->rx_desc_get_l3_pad_bytes(desc); } static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hw_params->hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); + ab->hal.hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); } static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, struct hal_rx_desc *desc, u16 len) { - ab->hw_params->hal_ops->rx_desc_set_msdu_len(desc, len); + ab->hal.hal_ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc) { - return ab->hw_params->hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); + return ab->hal.hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, @@ -151,7 +151,7 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, { u32 tlv_tag; - tlv_tag = ab->hw_params->hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); + tlv_tag = ab->hal.hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); return tlv_tag == HAL_RX_MPDU_START; } @@ -160,7 +160,7 @@ static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hw_params->hal_ops->rx_desc_get_dot11_hdr(desc, hdr); + ab->hal.hal_ops->rx_desc_get_dot11_hdr(desc, hdr); } static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, @@ -168,13 +168,13 @@ static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hw_params->hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + ab->hal.hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hw_params->hal_ops->rx_desc_get_msdu_src_link_id(desc); + return ab->hal.hal_ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 87abacc8ae8e1..338a4e5244ddf 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1105,7 +1105,7 @@ int ath12k_hal_srng_init(struct ath12k_base *ab) { int ret; - ret = ab->hw_params->hal_ops->create_srng_config(ab); + ret = ab->hal.hal_ops->create_srng_config(ab); if (ret) goto err_hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index ee0d31b7788ab..195728d270c01 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1463,6 +1463,7 @@ struct ath12k_hal { dma_addr_t paddr; } wrp; + const struct hal_ops *hal_ops; /* Available REO blocking resources bitmap */ u8 avail_blk_resource; @@ -1580,6 +1581,7 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) } struct ath12k_hw_version_map { + const struct hal_ops *hal_ops; u32 hal_desc_sz; }; @@ -1604,9 +1606,6 @@ struct hal_ops { u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); }; -extern const struct hal_ops hal_qcn9274_ops; -extern const struct hal_ops hal_wcn7850_ops; - u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, int tid, u32 ba_window_size, diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 35d6900720fee..7e8f1f7ef5847 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -193,8 +193,6 @@ struct ath12k_hw_params { void (*wmi_init)(struct ath12k_base *ab, struct ath12k_wmi_resource_config_arg *config); - const struct hal_ops *hal_ops; - u64 qmi_cnss_feature_bitmap; u32 rfkill_pin; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 35709dfccbcf3..ece6a1311ef0c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -50,6 +50,6 @@ void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc) { - ab->hw_params->hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); + ab->hal.hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); } #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index ab5824abfe758..036bacd704e92 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -107,7 +107,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + ti.rbm_id = ab->hal.hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; tx_ring = &dp->tx_ring[ti.ring_id]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 4ad3ef3ba5e0f..0e3930c8575a2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,18 +7,24 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "hal_qcn9274.h" +#include "hal_wcn7850.h" static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { [ATH12K_HW_QCN9274_HW10] = { + .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), }, [ATH12K_HW_QCN9274_HW20] = { + .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), }, [ATH12K_HW_WCN7850_HW20] = { + .hal_ops = &hal_wcn7850_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), }, [ATH12K_HW_IPQ5332_HW10] = { + .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), }, }; @@ -29,6 +35,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) memset(hal, 0, sizeof(*hal)); + hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; return 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 1563854b5b6a5..4d08292d8a7f9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,6 +12,7 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct hal_ops hal_qcn9274_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 80de7ea522b54..8207e73602b3c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,6 +10,7 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct hal_ops hal_wcn7850_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 621022064962e..f469a829ae9a7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -758,8 +758,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_qcn9274, - .hal_ops = &hal_qcn9274_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, @@ -847,8 +845,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_wcn7850, - .hal_ops = &hal_wcn7850_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | BIT(CNSS_PCIE_PERST_NO_PULL_V01), @@ -934,8 +930,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_qcn9274, - .hal_ops = &hal_qcn9274_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, @@ -1017,8 +1011,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = &ath12k_wifi7_wmi_init_qcn9274, - .hal_ops = &hal_qcn9274_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, From 9be56c6c9baad8a9955d74cb0a02b255cb95c77b Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:31 +0530 Subject: [PATCH 419/659] wifi: ath12k: Move wbm_rbm_map to hw specific hal files Move wbm_rbm_map from common hal file to hw specific hal files, since these implementations are specific and configurable for each hardware. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 4 +-- drivers/net/wireless/ath/ath12k/dp.c | 4 +-- drivers/net/wireless/ath/ath12k/hal.c | 36 ------------------- drivers/net/wireless/ath/ath12k/hal.h | 4 ++- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 5 +++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 21 ++++++++++- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 2 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 17 ++++++++- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 2 +- 10 files changed, 50 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index c22bc7da882eb..2628d53845eb8 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -558,12 +558,10 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab) { const struct ath12k_hw_ring_mask *ring_mask; struct ath12k_ext_irq_grp *irq_grp; - const struct hal_ops *hal_ops; int i, j, irq, irq_idx, ret; u32 num_irq; ring_mask = ab->hw_params->ring_mask; - hal_ops = ab->hal.hal_ops; for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { irq_grp = &ab->ext_irq_grp[i]; num_irq = 0; @@ -583,7 +581,7 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab) * tcl_to_wbm_rbm_map point to the same ring number. */ if (ring_mask->tx[i] & - BIT(hal_ops->tcl_to_wbm_rbm_map[j].wbm_ring_num)) { + BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num)) { irq_grp->irqs[num_irq++] = wbm2host_tx_completions_ring1 - j; } diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 8926c0a5c34fe..fc4626d770e58 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -142,7 +142,7 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab, grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0]; ring_num = 0; } else { - map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.tcl_to_wbm_rbm_map; for (i = 0; i < ab->hw_params->max_tx_ring; i++) { if (ring_num == map[i].wbm_ring_num) { ring_num = i; @@ -508,7 +508,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } for (i = 0; i < ab->hw_params->max_tx_ring; i++) { - map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.tcl_to_wbm_rbm_map; tx_comp_ring_num = map[i].wbm_ring_num; ret = ath12k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 338a4e5244ddf..d1dfbe2f9a654 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,42 +12,6 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { - { - .wbm_ring_num = 0, - .rbm_id = HAL_RX_BUF_RBM_SW0_BM, - }, - { - .wbm_ring_num = 1, - .rbm_id = HAL_RX_BUF_RBM_SW1_BM, - }, - { - .wbm_ring_num = 2, - .rbm_id = HAL_RX_BUF_RBM_SW2_BM, - }, - { - .wbm_ring_num = 4, - .rbm_id = HAL_RX_BUF_RBM_SW4_BM, - } -}; - -const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { - { - .wbm_ring_num = 0, - .rbm_id = HAL_RX_BUF_RBM_SW0_BM, - }, - { - .wbm_ring_num = 2, - .rbm_id = HAL_RX_BUF_RBM_SW2_BM, - }, - { - .wbm_ring_num = 4, - .rbm_id = HAL_RX_BUF_RBM_SW4_BM, - }, -}; - static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab) { return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 195728d270c01..dc834d16bb3f2 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1474,6 +1474,8 @@ struct ath12k_hal { int num_shadow_reg_configured; u32 hal_desc_sz; + + const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; /* Maps WBM ring number and Return Buffer Manager Id per TCL ring */ @@ -1583,11 +1585,11 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) struct ath12k_hw_version_map { const struct hal_ops *hal_ops; u32 hal_desc_sz; + const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); - const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 036bacd704e92..b3c0f8a6a5ce0 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -107,7 +107,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hal.hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + ti.rbm_id = ab->hal.tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; tx_ring = &dp->tx_ring[ti.ring_id]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 0e3930c8575a2..53ea3792ef518 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -14,18 +14,22 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { [ATH12K_HW_QCN9274_HW10] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, }, [ATH12K_HW_QCN9274_HW20] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, }, [ATH12K_HW_WCN7850_HW20] = { .hal_ops = &hal_wcn7850_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, }, [ATH12K_HW_IPQ5332_HW10] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, }, }; @@ -37,6 +41,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; + hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 6a1c13565700b..fefa151efaefc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -681,9 +681,28 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return 0; } +const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX] = { + { + .wbm_ring_num = 0, + .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + }, + { + .wbm_ring_num = 1, + .rbm_id = HAL_RX_BUF_RBM_SW1_BM, + }, + { + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, + { + .wbm_ring_num = 4, + .rbm_id = HAL_RX_BUF_RBM_SW4_BM, + }, +}; + const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, - .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 4d08292d8a7f9..1b431d5b64170 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -14,7 +14,7 @@ extern const struct hal_ops hal_qcn9274_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; +ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX]; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 275de9c1a359d..3e88a1e68b87b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -690,9 +690,24 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return 0; } +const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX] = { + { + .wbm_ring_num = 0, + .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + }, + { + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, + { + .wbm_ring_num = 4, + .rbm_id = HAL_RX_BUF_RBM_SW4_BM, + }, +}; + const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, - .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 8207e73602b3c..2df4976f59aa4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -12,7 +12,7 @@ extern const struct hal_ops hal_wcn7850_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; +ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX]; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, From 993828df4e0c3fa895c3dd4f86bb3f968a2215df Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:32 +0530 Subject: [PATCH 420/659] wifi: ath12k: Move hal_params and regs to hal from hw Move hal_params and regs to hal structure from the hw structure, since these parameters are used by hal layer and make corresponding initializations in hal_init. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 2 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 211 +++++++--- drivers/net/wireless/ath/ath12k/hw.h | 90 +--- drivers/net/wireless/ath/ath12k/pci.h | 10 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 10 + drivers/net/wireless/ath/ath12k/wifi7/hal.h | 1 - .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 288 +++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 5 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 97 +++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 393 ------------------ 14 files changed, 563 insertions(+), 554 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index fc4626d770e58..3289d609fefb4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1243,7 +1243,7 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) /* Enable Cookie conversion for WBM2SW Rings */ val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | - ab->hw_params->hal_params->wbm2sw_cc_enable; + ab->hal.hal_params->wbm2sw_cc_enable; ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 8c8d60b2019a4..c380c631eb09f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2719,7 +2719,7 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, int req_entries) { enum hal_rx_buf_return_buf_manager mgr = - ab->hw_params->hal_params->rx_buf_rbm; + ab->hal.hal_params->rx_buf_rbm; int num_free, num_remain, buf_id; struct ath12k_buffer_addr *desc; struct hal_srng *srng; @@ -4076,7 +4076,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, move_next: skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, &buf_id); - hal_params = ab->hw_params->hal_params; + hal_params = ab->hal.hal_params; if (!skb) { ath12k_warn(ab, "failed to alloc buffer for status ring\n"); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 89e12d916d829..9343cea6e24d8 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -81,7 +81,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, dma_addr_t paddr; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_desc; - enum hal_rx_buf_return_buf_manager mgr = ab->hw_params->hal_params->rx_buf_rbm; + enum hal_rx_buf_return_buf_manager mgr = ab->hal.hal_params->rx_buf_rbm; req_entries = min(req_entries, rx_ring->bufs_max); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index dc834d16bb3f2..f9cd3d5011441 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -73,13 +73,13 @@ struct ath12k_base; #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce0_src_reg_base) + ((ab)->hal.regs->hal_umac_ce0_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce0_dest_reg_base) + ((ab)->hal.regs->hal_umac_ce0_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce1_src_reg_base) + ((ab)->hal.regs->hal_umac_ce1_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce1_dest_reg_base) + ((ab)->hal.regs->hal_umac_ce1_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 @@ -90,30 +90,30 @@ struct ath12k_base; #define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 #define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 #define HAL_TCL1_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_base_lsb) + ((ab)->hal.regs->hal_tcl1_ring_base_lsb) #define HAL_TCL1_RING_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(ab) ((ab)->hw_params->regs->hal_tcl1_ring_id) + ((ab)->hal.regs->hal_tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(ab) ((ab)->hal.regs->hal_tcl1_ring_id) #define HAL_TCL1_RING_MISC(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_misc) + ((ab)->hal.regs->hal_tcl1_ring_misc) #define HAL_TCL1_RING_TP_ADDR_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_tp_addr_lsb) + ((ab)->hal.regs->hal_tcl1_ring_tp_addr_lsb) #define HAL_TCL1_RING_TP_ADDR_MSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_tp_addr_msb) + ((ab)->hal.regs->hal_tcl1_ring_tp_addr_msb) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_consumer_int_setup_ix0) + ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix0) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_consumer_int_setup_ix1) + ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix1) #define HAL_TCL1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_msi1_base_lsb) + ((ab)->hal.regs->hal_tcl1_ring_msi1_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_msi1_base_msb) + ((ab)->hal.regs->hal_tcl1_ring_msi1_base_msb) #define HAL_TCL1_RING_MSI1_DATA(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_msi1_data) + ((ab)->hal.regs->hal_tcl1_ring_msi1_data) #define HAL_TCL2_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl2_ring_base_lsb) + ((ab)->hal.regs->hal_tcl2_ring_base_lsb) #define HAL_TCL_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl_ring_base_lsb) + ((ab)->hal.regs->hal_tcl_ring_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ (HAL_TCL1_RING_MSI1_BASE_LSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) @@ -147,7 +147,7 @@ struct ath12k_base; /* TCL STATUS ring address */ #define HAL_TCL_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl_status_ring_base_lsb) + ((ab)->hal.regs->hal_tcl_status_ring_base_lsb) #define HAL_TCL_STATUS_RING_HP 0x00002048 /* PPE2TCL1 Ring address */ @@ -156,41 +156,41 @@ struct ath12k_base; /* WBM PPE Release Ring address */ #define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_ppe_rel_ring_base) + ((ab)->hal.regs->hal_ppe_rel_ring_base) #define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 #define HAL_REO1_MISC_CTRL_ADDR(ab) \ - ((ab)->hw_params->regs->hal_reo1_misc_ctrl_addr) + ((ab)->hal.regs->hal_reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(ab) ((ab)->hw_params->regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(ab) ((ab)->hw_params->regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(ab) ((ab)->hw_params->regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(ab) ((ab)->hw_params->regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_QDESC_ADDR(ab) ((ab)->hal.regs->hal_reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(ab) ((ab)->hal.regs->hal_reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_msb) +#define HAL_REO1_RING_ID(ab) ((ab)->hal.regs->hal_reo1_ring_id) +#define HAL_REO1_RING_MISC(ab) ((ab)->hal.regs->hal_reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_msb) #define HAL_REO1_RING_PRODUCER_INT_SETUP(ab) \ - ((ab)->hw_params->regs->hal_reo1_ring_producer_int_setup) + ((ab)->hal.regs->hal_reo1_ring_producer_int_setup) #define HAL_REO1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo1_ring_msi1_base_lsb) + ((ab)->hal.regs->hal_reo1_ring_msi1_base_lsb) #define HAL_REO1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(ab) ((ab)->hw_params->regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(ab) ((ab)->hw_params->regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix3) + ((ab)->hal.regs->hal_reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(ab) ((ab)->hal.regs->hal_reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix3) /* REO2SW(x) R2 ring pointers (head/tail) address */ #define HAL_REO1_RING_HP 0x00003048 @@ -201,23 +201,23 @@ struct ath12k_base; /* REO2SW0 ring configuration address */ #define HAL_REO_SW0_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo2_sw0_ring_base) + ((ab)->hal.regs->hal_reo2_sw0_ring_base) /* REO2SW0 R2 ring pointer (head/tail) address */ #define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ #define HAL_REO_CMD_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo_cmd_ring_base) + ((ab)->hal.regs->hal_reo_cmd_ring_base) /* REO CMD R2 address */ #define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ #define HAL_SW2REO_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_sw2reo_ring_base) + ((ab)->hal.regs->hal_sw2reo_ring_base) #define HAL_SW2REO1_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_sw2reo1_ring_base) + ((ab)->hal.regs->hal_sw2reo1_ring_base) /* SW2REO R2 address */ #define HAL_SW2REO_RING_HP 0x00003028 @@ -235,41 +235,41 @@ struct ath12k_base; /* REO status address */ #define HAL_REO_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo_status_ring_base) + ((ab)->hal.regs->hal_reo_status_ring_base) #define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ #define HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_idle_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_idle_ring_base_lsb) #define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_idle_ring_misc_addr) + ((ab)->hal.regs->hal_wbm_idle_ring_misc_addr) #define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_r0_idle_list_cntl_addr) + ((ab)->hal.regs->hal_wbm_r0_idle_list_cntl_addr) #define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_r0_idle_list_size_addr) + ((ab)->hal.regs->hal_wbm_r0_idle_list_size_addr) #define HAL_WBM_SCATTERED_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_scattered_ring_base_lsb) #define HAL_WBM_SCATTERED_RING_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_ring_base_msb) + ((ab)->hal.regs->hal_wbm_scattered_ring_base_msb) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_head_info_ix0) + ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_head_info_ix1) + ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_tail_info_ix0) + ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_tail_info_ix1) + ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_ptr_hp_addr) + ((ab)->hal.regs->hal_wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ #define HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_sw_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_sw_release_ring_base_lsb) #define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_sw1_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ #define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 @@ -277,10 +277,10 @@ struct ath12k_base; /* WBM2SW R0 release address */ #define HAL_WBM0_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm0_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm0_release_ring_base_lsb) #define HAL_WBM1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm1_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ #define HAL_WBM0_RELEASE_RING_HP 0x000030c8 @@ -1440,6 +1440,91 @@ struct hal_reo_status { } u; }; +struct ath12k_hw_hal_params { + enum hal_rx_buf_return_buf_manager rx_buf_rbm; + u32 wbm2sw_cc_enable; +}; + +struct ath12k_hw_regs { + u32 hal_tcl1_ring_id; + u32 hal_tcl1_ring_misc; + u32 hal_tcl1_ring_tp_addr_lsb; + u32 hal_tcl1_ring_tp_addr_msb; + u32 hal_tcl1_ring_consumer_int_setup_ix0; + u32 hal_tcl1_ring_consumer_int_setup_ix1; + u32 hal_tcl1_ring_msi1_base_lsb; + u32 hal_tcl1_ring_msi1_base_msb; + u32 hal_tcl1_ring_msi1_data; + u32 hal_tcl_ring_base_lsb; + u32 hal_tcl1_ring_base_lsb; + u32 hal_tcl1_ring_base_msb; + u32 hal_tcl2_ring_base_lsb; + + u32 hal_tcl_status_ring_base_lsb; + + u32 hal_reo1_qdesc_addr; + u32 hal_reo1_qdesc_max_peerid; + + u32 hal_wbm_idle_ring_base_lsb; + u32 hal_wbm_idle_ring_misc_addr; + u32 hal_wbm_r0_idle_list_cntl_addr; + u32 hal_wbm_r0_idle_list_size_addr; + u32 hal_wbm_scattered_ring_base_lsb; + u32 hal_wbm_scattered_ring_base_msb; + u32 hal_wbm_scattered_desc_head_info_ix0; + u32 hal_wbm_scattered_desc_head_info_ix1; + u32 hal_wbm_scattered_desc_tail_info_ix0; + u32 hal_wbm_scattered_desc_tail_info_ix1; + u32 hal_wbm_scattered_desc_ptr_hp_addr; + + u32 hal_wbm_sw_release_ring_base_lsb; + u32 hal_wbm_sw1_release_ring_base_lsb; + u32 hal_wbm0_release_ring_base_lsb; + u32 hal_wbm1_release_ring_base_lsb; + + u32 pcie_qserdes_sysclk_en_sel; + u32 pcie_pcs_osc_dtct_config_base; + + u32 hal_umac_ce0_src_reg_base; + u32 hal_umac_ce0_dest_reg_base; + u32 hal_umac_ce1_src_reg_base; + u32 hal_umac_ce1_dest_reg_base; + + u32 hal_ppe_rel_ring_base; + + u32 hal_reo2_ring_base; + u32 hal_reo1_misc_ctrl_addr; + u32 hal_reo1_sw_cookie_cfg0; + u32 hal_reo1_sw_cookie_cfg1; + u32 hal_reo1_qdesc_lut_base0; + u32 hal_reo1_qdesc_lut_base1; + u32 hal_reo1_ring_base_lsb; + u32 hal_reo1_ring_base_msb; + u32 hal_reo1_ring_id; + u32 hal_reo1_ring_misc; + u32 hal_reo1_ring_hp_addr_lsb; + u32 hal_reo1_ring_hp_addr_msb; + u32 hal_reo1_ring_producer_int_setup; + u32 hal_reo1_ring_msi1_base_lsb; + u32 hal_reo1_ring_msi1_base_msb; + u32 hal_reo1_ring_msi1_data; + u32 hal_reo1_aging_thres_ix0; + u32 hal_reo1_aging_thres_ix1; + u32 hal_reo1_aging_thres_ix2; + u32 hal_reo1_aging_thres_ix3; + + u32 hal_reo2_sw0_ring_base; + + u32 hal_sw2reo_ring_base; + u32 hal_sw2reo1_ring_base; + + u32 hal_reo_cmd_ring_base; + + u32 hal_reo_status_ring_base; + + u32 gcc_gcc_pcie_hot_rst; +}; + /* HAL context to be used to access SRNG APIs (currently used by data path * and transport (CE) modules) */ @@ -1464,6 +1549,8 @@ struct ath12k_hal { } wrp; const struct hal_ops *hal_ops; + const struct ath12k_hw_regs *regs; + const struct ath12k_hw_hal_params *hal_params; /* Available REO blocking resources bitmap */ u8 avail_blk_resource; @@ -1586,6 +1673,8 @@ struct ath12k_hw_version_map { const struct hal_ops *hal_ops; u32 hal_desc_sz; const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; + const struct ath12k_hw_hal_params *hal_params; + const struct ath12k_hw_regs *hw_regs; }; struct hal_ops { diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 7e8f1f7ef5847..655753d0413ae 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_HW_H @@ -128,11 +128,6 @@ struct ath12k_hw_ring_mask { u8 tx_mon_dest[ATH12K_EXT_IRQ_GRP_NUM_MAX]; }; -struct ath12k_hw_hal_params { - enum hal_rx_buf_return_buf_manager rx_buf_rbm; - u32 wbm2sw_cc_enable; -}; - enum ath12k_m3_fw_loaders { ath12k_m3_fw_loader_driver, ath12k_m3_fw_loader_remoteproc, @@ -156,7 +151,6 @@ struct ath12k_hw_params { const struct ath12k_hw_ops *hw_ops; const struct ath12k_hw_ring_mask *ring_mask; - const struct ath12k_hw_regs *regs; const struct ce_attr *host_ce_config; u32 ce_count; @@ -165,8 +159,6 @@ struct ath12k_hw_params { const struct service_to_pipe *svc_to_ce_map; u32 svc_to_ce_map_len; - const struct ath12k_hw_hal_params *hal_params; - bool rxdma1_enable:1; int num_rxdma_per_pdev; int num_rxdma_dst_ring; @@ -283,86 +275,6 @@ enum ath12k_bd_ie_type { ATH12K_BD_IE_REGDB = 1, }; -struct ath12k_hw_regs { - u32 hal_tcl1_ring_id; - u32 hal_tcl1_ring_misc; - u32 hal_tcl1_ring_tp_addr_lsb; - u32 hal_tcl1_ring_tp_addr_msb; - u32 hal_tcl1_ring_consumer_int_setup_ix0; - u32 hal_tcl1_ring_consumer_int_setup_ix1; - u32 hal_tcl1_ring_msi1_base_lsb; - u32 hal_tcl1_ring_msi1_base_msb; - u32 hal_tcl1_ring_msi1_data; - u32 hal_tcl_ring_base_lsb; - u32 hal_tcl1_ring_base_lsb; - u32 hal_tcl1_ring_base_msb; - u32 hal_tcl2_ring_base_lsb; - - u32 hal_tcl_status_ring_base_lsb; - - u32 hal_reo1_qdesc_addr; - u32 hal_reo1_qdesc_max_peerid; - - u32 hal_wbm_idle_ring_base_lsb; - u32 hal_wbm_idle_ring_misc_addr; - u32 hal_wbm_r0_idle_list_cntl_addr; - u32 hal_wbm_r0_idle_list_size_addr; - u32 hal_wbm_scattered_ring_base_lsb; - u32 hal_wbm_scattered_ring_base_msb; - u32 hal_wbm_scattered_desc_head_info_ix0; - u32 hal_wbm_scattered_desc_head_info_ix1; - u32 hal_wbm_scattered_desc_tail_info_ix0; - u32 hal_wbm_scattered_desc_tail_info_ix1; - u32 hal_wbm_scattered_desc_ptr_hp_addr; - - u32 hal_wbm_sw_release_ring_base_lsb; - u32 hal_wbm_sw1_release_ring_base_lsb; - u32 hal_wbm0_release_ring_base_lsb; - u32 hal_wbm1_release_ring_base_lsb; - - u32 pcie_qserdes_sysclk_en_sel; - u32 pcie_pcs_osc_dtct_config_base; - - u32 hal_umac_ce0_src_reg_base; - u32 hal_umac_ce0_dest_reg_base; - u32 hal_umac_ce1_src_reg_base; - u32 hal_umac_ce1_dest_reg_base; - - u32 hal_ppe_rel_ring_base; - - u32 hal_reo2_ring_base; - u32 hal_reo1_misc_ctrl_addr; - u32 hal_reo1_sw_cookie_cfg0; - u32 hal_reo1_sw_cookie_cfg1; - u32 hal_reo1_qdesc_lut_base0; - u32 hal_reo1_qdesc_lut_base1; - u32 hal_reo1_ring_base_lsb; - u32 hal_reo1_ring_base_msb; - u32 hal_reo1_ring_id; - u32 hal_reo1_ring_misc; - u32 hal_reo1_ring_hp_addr_lsb; - u32 hal_reo1_ring_hp_addr_msb; - u32 hal_reo1_ring_producer_int_setup; - u32 hal_reo1_ring_msi1_base_lsb; - u32 hal_reo1_ring_msi1_base_msb; - u32 hal_reo1_ring_msi1_data; - u32 hal_reo1_aging_thres_ix0; - u32 hal_reo1_aging_thres_ix1; - u32 hal_reo1_aging_thres_ix2; - u32 hal_reo1_aging_thres_ix3; - - u32 hal_reo2_sw0_ring_base; - - u32 hal_sw2reo_ring_base; - u32 hal_sw2reo1_ring_base; - - u32 hal_reo_cmd_ring_base; - - u32 hal_reo_status_ring_base; - - u32 gcc_gcc_pcie_hot_rst; -}; - static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type) { switch (type) { diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 2c19bb42f0f70..1cc4f0e050f95 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -30,7 +30,7 @@ #define PARM_LTSSM_VALUE 0x111 #define GCC_GCC_PCIE_HOT_RST(ab) \ - ((ab)->hw_params->regs->gcc_gcc_pcie_hot_rst) + ((ab)->hal.regs->gcc_gcc_pcie_hot_rst) #define GCC_GCC_PCIE_HOT_RST_VAL 0x10 @@ -39,17 +39,17 @@ #define PCIE_INT_CLEAR_ALL 0xffffffff #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(ab) \ - ((ab)->hw_params->regs->pcie_qserdes_sysclk_en_sel) + ((ab)->hal.regs->pcie_qserdes_sysclk_en_sel) #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL 0x10 #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK 0xffffffff #define PCIE_PCS_OSC_DTCT_CONFIG1_REG(ab) \ - ((ab)->hw_params->regs->pcie_pcs_osc_dtct_config_base) + ((ab)->hal.regs->pcie_pcs_osc_dtct_config_base) #define PCIE_PCS_OSC_DTCT_CONFIG1_VAL 0x02 #define PCIE_PCS_OSC_DTCT_CONFIG2_REG(ab) \ - ((ab)->hw_params->regs->pcie_pcs_osc_dtct_config_base + 0x4) + ((ab)->hal.regs->pcie_pcs_osc_dtct_config_base + 0x4) #define PCIE_PCS_OSC_DTCT_CONFIG2_VAL 0x52 #define PCIE_PCS_OSC_DTCT_CONFIG4_REG(ab) \ - ((ab)->hw_params->regs->pcie_pcs_osc_dtct_config_base + 0xc) + ((ab)->hal.regs->pcie_pcs_osc_dtct_config_base + 0xc) #define PCIE_PCS_OSC_DTCT_CONFIG4_VAL 0xff #define PCIE_PCS_OSC_DTCT_CONFIG_MSK 0x000000ff diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d6ce6b9bb4d71..eef8d25584946 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1383,7 +1383,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n msdu_cookies, &rbm); if (rbm != partner_dp->idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && - rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + rbm != partner_ab->hal.hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; ab->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 53ea3792ef518..25963ac18cb9b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -15,21 +15,29 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, + .hal_params = &ath12k_hw_hal_params_qcn9274, + .hw_regs = &qcn9274_v1_regs, }, [ATH12K_HW_QCN9274_HW20] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, + .hal_params = &ath12k_hw_hal_params_qcn9274, + .hw_regs = &qcn9274_v2_regs, }, [ATH12K_HW_WCN7850_HW20] = { .hal_ops = &hal_wcn7850_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, + .hal_params = &ath12k_hw_hal_params_wcn7850, + .hw_regs = &wcn7850_regs, }, [ATH12K_HW_IPQ5332_HW10] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, + .hal_params = &ath12k_hw_hal_params_ipq5332, + .hw_regs = &ipq5332_regs, }, }; @@ -42,6 +50,8 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; + hal->regs = ath12k_wifi7_hw_ver_map[ab->hw_rev].hw_regs; + hal->hal_params = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_params; return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 0dc5eaec5fb0a..1a8a720c49236 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -8,5 +8,4 @@ #define ATH12K_HAL_WIFI7_H int ath12k_wifi7_hal_init(struct ath12k_base *ab); - #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index fefa151efaefc..265e9f3688587 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -5,6 +5,8 @@ */ #include "hal_desc.h" #include "hal_qcn9274.h" +#include "hw.h" +#include "hal.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -209,6 +211,274 @@ static const struct hal_srng_config hw_srng_config_template[] = { } }; +const struct ath12k_hw_regs qcn9274_v1_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, + .hal_tcl1_ring_base_lsb = 0x00000900, + .hal_tcl1_ring_base_msb = 0x00000904, + .hal_tcl2_ring_base_lsb = 0x00000978, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d38, + + .hal_wbm_idle_ring_base_lsb = 0x00000d0c, + .hal_wbm_idle_ring_misc_addr = 0x00000d1c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, + .hal_wbm_r0_idle_list_size_addr = 0x00000214, + .hal_wbm_scattered_ring_base_lsb = 0x00000220, + .hal_wbm_scattered_ring_base_msb = 0x00000224, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, + + .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, + .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, + .hal_wbm0_release_ring_base_lsb = 0x00000dd8, + .hal_wbm1_release_ring_base_lsb = 0x00000e50, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, + .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000043c, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x0000055c, + .hal_reo1_misc_ctrl_addr = 0x00000b7c, + .hal_reo1_sw_cookie_cfg0 = 0x00000050, + .hal_reo1_sw_cookie_cfg1 = 0x00000054, + .hal_reo1_qdesc_lut_base0 = 0x00000058, + .hal_reo1_qdesc_lut_base1 = 0x0000005c, + .hal_reo1_ring_base_lsb = 0x000004e4, + .hal_reo1_ring_base_msb = 0x000004e8, + .hal_reo1_ring_id = 0x000004ec, + .hal_reo1_ring_misc = 0x000004f4, + .hal_reo1_ring_hp_addr_lsb = 0x000004f8, + .hal_reo1_ring_hp_addr_msb = 0x000004fc, + .hal_reo1_ring_producer_int_setup = 0x00000508, + .hal_reo1_ring_msi1_base_lsb = 0x0000052C, + .hal_reo1_ring_msi1_base_msb = 0x00000530, + .hal_reo1_ring_msi1_data = 0x00000534, + .hal_reo1_aging_thres_ix0 = 0x00000b08, + .hal_reo1_aging_thres_ix1 = 0x00000b0c, + .hal_reo1_aging_thres_ix2 = 0x00000b10, + .hal_reo1_aging_thres_ix3 = 0x00000b14, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008a4, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000304, + .hal_sw2reo1_ring_base = 0x0000037c, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x0000028c, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000a84, + + /* CE base address */ + .hal_umac_ce0_src_reg_base = 0x01b80000, + .hal_umac_ce0_dest_reg_base = 0x01b81000, + .hal_umac_ce1_src_reg_base = 0x01b82000, + .hal_umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e38338, +}; + +const struct ath12k_hw_regs qcn9274_v2_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, + .hal_tcl1_ring_base_lsb = 0x00000900, + .hal_tcl1_ring_base_msb = 0x00000904, + .hal_tcl2_ring_base_lsb = 0x00000978, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d38, + + /* WBM idle link ring address */ + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + + /* SW2WBM release ring address */ + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, + + /* WBM2SW release ring address */ + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, + .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000046c, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x00000578, + .hal_reo1_misc_ctrl_addr = 0x00000b9c, + .hal_reo1_sw_cookie_cfg0 = 0x0000006c, + .hal_reo1_sw_cookie_cfg1 = 0x00000070, + .hal_reo1_qdesc_lut_base0 = 0x00000074, + .hal_reo1_qdesc_lut_base1 = 0x00000078, + .hal_reo1_qdesc_addr = 0x0000007c, + .hal_reo1_qdesc_max_peerid = 0x00000088, + .hal_reo1_ring_base_lsb = 0x00000500, + .hal_reo1_ring_base_msb = 0x00000504, + .hal_reo1_ring_id = 0x00000508, + .hal_reo1_ring_misc = 0x00000510, + .hal_reo1_ring_hp_addr_lsb = 0x00000514, + .hal_reo1_ring_hp_addr_msb = 0x00000518, + .hal_reo1_ring_producer_int_setup = 0x00000524, + .hal_reo1_ring_msi1_base_lsb = 0x00000548, + .hal_reo1_ring_msi1_base_msb = 0x0000054C, + .hal_reo1_ring_msi1_data = 0x00000550, + .hal_reo1_aging_thres_ix0 = 0x00000B28, + .hal_reo1_aging_thres_ix1 = 0x00000B2C, + .hal_reo1_aging_thres_ix2 = 0x00000B30, + .hal_reo1_aging_thres_ix3 = 0x00000B34, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008c0, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000320, + .hal_sw2reo1_ring_base = 0x00000398, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x000002A8, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000aa0, + + /* CE base address */ + .hal_umac_ce0_src_reg_base = 0x01b80000, + .hal_umac_ce0_dest_reg_base = 0x01b81000, + .hal_umac_ce1_src_reg_base = 0x01b82000, + .hal_umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e38338, +}; + +const struct ath12k_hw_regs ipq5332_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000918, + .hal_tcl1_ring_misc = 0x00000920, + .hal_tcl1_ring_tp_addr_lsb = 0x0000092c, + .hal_tcl1_ring_tp_addr_msb = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000940, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000944, + .hal_tcl1_ring_msi1_base_lsb = 0x00000958, + .hal_tcl1_ring_msi1_base_msb = 0x0000095c, + .hal_tcl1_ring_base_lsb = 0x00000910, + .hal_tcl1_ring_base_msb = 0x00000914, + .hal_tcl1_ring_msi1_data = 0x00000960, + .hal_tcl2_ring_base_lsb = 0x00000988, + .hal_tcl_ring_base_lsb = 0x00000b68, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d48, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x00000578, + .hal_reo1_misc_ctrl_addr = 0x00000b9c, + .hal_reo1_sw_cookie_cfg0 = 0x0000006c, + .hal_reo1_sw_cookie_cfg1 = 0x00000070, + .hal_reo1_qdesc_lut_base0 = 0x00000074, + .hal_reo1_qdesc_lut_base1 = 0x00000078, + .hal_reo1_ring_base_lsb = 0x00000500, + .hal_reo1_ring_base_msb = 0x00000504, + .hal_reo1_ring_id = 0x00000508, + .hal_reo1_ring_misc = 0x00000510, + .hal_reo1_ring_hp_addr_lsb = 0x00000514, + .hal_reo1_ring_hp_addr_msb = 0x00000518, + .hal_reo1_ring_producer_int_setup = 0x00000524, + .hal_reo1_ring_msi1_base_lsb = 0x00000548, + .hal_reo1_ring_msi1_base_msb = 0x0000054C, + .hal_reo1_ring_msi1_data = 0x00000550, + .hal_reo1_aging_thres_ix0 = 0x00000B28, + .hal_reo1_aging_thres_ix1 = 0x00000B2C, + .hal_reo1_aging_thres_ix2 = 0x00000B30, + .hal_reo1_aging_thres_ix3 = 0x00000B34, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008c0, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000320, + .hal_sw2reo1_ring_base = 0x00000398, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x000002A8, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000aa0, + + /* WBM idle link ring address */ + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + + /* SW2WBM release ring address */ + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + + /* WBM2SW release ring address */ + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000046c, + + /* CE address */ + .hal_umac_ce0_src_reg_base = 0x00740000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, + .hal_umac_ce0_dest_reg_base = 0x00741000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, + .hal_umac_ce1_src_reg_base = 0x00742000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, + .hal_umac_ce1_dest_reg_base = 0x00743000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { @@ -571,6 +841,24 @@ void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_da rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc); } +const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, +}; + +const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, +}; + static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 1b431d5b64170..c48dd029f52ee 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -13,8 +13,13 @@ #include "hal_rx.h" extern const struct hal_ops hal_qcn9274_ops; +extern const struct ath12k_hw_regs qcn9274_v1_regs; +extern const struct ath12k_hw_regs qcn9274_v2_regs; +extern const struct ath12k_hw_regs ipq5332_regs; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX]; +extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274; +extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 3e88a1e68b87b..b3ed7c8d738d8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -6,6 +6,8 @@ #include "hal_desc.h" #include "hal_wcn7850.h" +#include "hw.h" +#include "hal.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -210,6 +212,93 @@ static const struct hal_srng_config hw_srng_config_template[] = { } }; +const struct ath12k_hw_regs wcn7850_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, + .hal_tcl1_ring_base_lsb = 0x00000900, + .hal_tcl1_ring_base_msb = 0x00000904, + .hal_tcl2_ring_base_lsb = 0x00000978, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d38, + + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, + + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, + .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000043c, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x0000055c, + .hal_reo1_misc_ctrl_addr = 0x00000b7c, + .hal_reo1_sw_cookie_cfg0 = 0x00000050, + .hal_reo1_sw_cookie_cfg1 = 0x00000054, + .hal_reo1_qdesc_lut_base0 = 0x00000058, + .hal_reo1_qdesc_lut_base1 = 0x0000005c, + .hal_reo1_ring_base_lsb = 0x000004e4, + .hal_reo1_ring_base_msb = 0x000004e8, + .hal_reo1_ring_id = 0x000004ec, + .hal_reo1_ring_misc = 0x000004f4, + .hal_reo1_ring_hp_addr_lsb = 0x000004f8, + .hal_reo1_ring_hp_addr_msb = 0x000004fc, + .hal_reo1_ring_producer_int_setup = 0x00000508, + .hal_reo1_ring_msi1_base_lsb = 0x0000052C, + .hal_reo1_ring_msi1_base_msb = 0x00000530, + .hal_reo1_ring_msi1_data = 0x00000534, + .hal_reo1_aging_thres_ix0 = 0x00000b08, + .hal_reo1_aging_thres_ix1 = 0x00000b0c, + .hal_reo1_aging_thres_ix2 = 0x00000b10, + .hal_reo1_aging_thres_ix3 = 0x00000b14, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008a4, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000304, + .hal_sw2reo1_ring_base = 0x0000037c, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x0000028c, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000a84, + + /* CE base address */ + .hal_umac_ce0_src_reg_base = 0x01b80000, + .hal_umac_ce0_dest_reg_base = 0x01b81000, + .hal_umac_ce1_src_reg_base = 0x01b82000, + .hal_umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e40304, +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { @@ -706,6 +795,14 @@ ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX] = { }, }; +const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, +}; + const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 2df4976f59aa4..7d0b0c9854468 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -11,8 +11,10 @@ #include "hal_rx.h" extern const struct hal_ops hal_wcn7850_ops; +extern const struct ath12k_hw_regs wcn7850_regs; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX]; +extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index f469a829ae9a7..01c859f35a937 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -310,387 +310,6 @@ static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = { }, }; -static const struct ath12k_hw_regs qcn9274_v1_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d0c, - .hal_wbm_idle_ring_misc_addr = 0x00000d1c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, - .hal_wbm_r0_idle_list_size_addr = 0x00000214, - .hal_wbm_scattered_ring_base_lsb = 0x00000220, - .hal_wbm_scattered_ring_base_msb = 0x00000224, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, - .hal_wbm0_release_ring_base_lsb = 0x00000dd8, - .hal_wbm1_release_ring_base_lsb = 0x00000e50, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, - .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, - - /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, - - .gcc_gcc_pcie_hot_rst = 0x1e38338, -}; - -static const struct ath12k_hw_regs qcn9274_v2_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, - - /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, - - /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, - .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_qdesc_addr = 0x0000007c, - .hal_reo1_qdesc_max_peerid = 0x00000088, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, - - /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, - - .gcc_gcc_pcie_hot_rst = 0x1e38338, -}; - -static const struct ath12k_hw_regs ipq5332_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000918, - .hal_tcl1_ring_misc = 0x00000920, - .hal_tcl1_ring_tp_addr_lsb = 0x0000092c, - .hal_tcl1_ring_tp_addr_msb = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000940, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000944, - .hal_tcl1_ring_msi1_base_lsb = 0x00000958, - .hal_tcl1_ring_msi1_base_msb = 0x0000095c, - .hal_tcl1_ring_base_lsb = 0x00000910, - .hal_tcl1_ring_base_msb = 0x00000914, - .hal_tcl1_ring_msi1_data = 0x00000960, - .hal_tcl2_ring_base_lsb = 0x00000988, - .hal_tcl_ring_base_lsb = 0x00000b68, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d48, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, - - /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, - - /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - - /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, - - /* CE address */ - .hal_umac_ce0_src_reg_base = 0x00740000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce0_dest_reg_base = 0x00741000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_src_reg_base = 0x00742000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_dest_reg_base = 0x00743000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, -}; - -static const struct ath12k_hw_regs wcn7850_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, - .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, - - /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, - - .gcc_gcc_pcie_hot_rst = 0x1e40304, -}; - -static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_qcn9274 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, - .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, -}; - -static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_wcn7850 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, - .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, -}; - -static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_ipq5332 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, - .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, -}; - static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = { .ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, .ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, @@ -720,7 +339,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .hw_ops = &qcn9274_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, - .regs = &qcn9274_v1_regs, .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, @@ -730,8 +348,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, - .rxdma1_enable = false, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, @@ -806,7 +422,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .hw_ops = &wcn7850_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, - .regs = &wcn7850_regs, .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, .ce_count = 9, @@ -816,8 +431,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850, .svc_to_ce_map_len = 14, - .hal_params = &ath12k_wifi7_hw_hal_params_wcn7850, - .rxdma1_enable = false, .num_rxdma_per_pdev = 2, .num_rxdma_dst_ring = 1, @@ -892,7 +505,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .hw_ops = &qcn9274_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, - .regs = &qcn9274_v2_regs, .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, @@ -902,8 +514,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, - .rxdma1_enable = true, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, @@ -975,7 +585,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, - .regs = &ipq5332_regs, .ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332, .host_ce_config = ath12k_wifi7_host_ce_config_ipq5332, @@ -986,8 +595,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_wifi7_hw_hal_params_ipq5332, - .rxdma1_enable = false, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, From 4fedc45cc62ba493c43d7a642799f91f5b5e187c Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:33 +0530 Subject: [PATCH 421/659] wifi: ath12k: Add direct HAL pointer in ath12k_dp Add a direct pointer to the HAL context in ath12k_dp. Since ath12k_dp is frequenctly used in the per-packet data path, this avoids the need to access the HAL handle through the ab pointer, reducing indirection in the per-packet data path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index f7cf83806eb07..d0efe5b2de6ce 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -451,6 +451,7 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; const struct ath12k_hw_params *hw_params; struct device *dev; + struct ath12k_hal *hal; /* RCU on dp_pdevs[] provides a teardown synchronization mechanism, * ensuring in-flight data path readers complete before reclaim. Writers diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 4465a9e93bf85..e691d0ca0d75c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -152,6 +152,7 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) dp->ab = ab; dp->dev = ab->dev; dp->hw_params = ab->hw_params; + dp->hal = &ab->hal; dp->ops = &ath12k_wifi7_dp_arch_ops; From dcf4c7b5fc3f52b5a5e866973f77bc0bdd541bd5 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:34 +0530 Subject: [PATCH 422/659] wifi: ath12k: Use hal handle instead of ab handle Use hal handle instead of ab handle in hal config APIs and register access APIs, as this reduces the indirection. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 22 +- drivers/net/wireless/ath/ath12k/hal.c | 143 +++++----- drivers/net/wireless/ath/ath12k/hal.h | 252 +++++++++--------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 78 +++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 21 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 70 ++--- 6 files changed, 296 insertions(+), 290 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 3289d609fefb4..3550c88c34bb9 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1150,7 +1150,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) if (dp->reoq_lut.vaddr_unaligned) { ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE0(ab), 0); + HAL_REO1_QDESC_LUT_BASE0(dp->hal), 0); dma_free_coherent(ab->dev, dp->reoq_lut.size, dp->reoq_lut.vaddr_unaligned, dp->reoq_lut.paddr_unaligned); @@ -1160,7 +1160,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) if (dp->ml_reoq_lut.vaddr_unaligned) { ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE1(ab), 0); + HAL_REO1_QDESC_LUT_BASE1(dp->hal), 0); dma_free_coherent(ab->dev, dp->ml_reoq_lut.size, dp->ml_reoq_lut.vaddr_unaligned, dp->ml_reoq_lut.paddr_unaligned); @@ -1201,11 +1201,12 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; u32 val = 0; + struct ath12k_hal *hal = &ab->hal; if (ath12k_ftm_mode) return; - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(ab), cmem_base); + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(hal), cmem_base); val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | @@ -1217,7 +1218,7 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ENABLE) | u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE); - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(ab), val); + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(hal), val); /* Enable HW CC for WBM */ ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG0, cmem_base); @@ -1243,7 +1244,7 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) /* Enable Cookie conversion for WBM2SW Rings */ val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | - ab->hal.hal_params->wbm2sw_cc_enable; + hal->hal_params->wbm2sw_cc_enable; ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); } @@ -1537,6 +1538,7 @@ static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab, static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hal *hal = dp->hal; u32 val; int ret; @@ -1565,18 +1567,18 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) * register only */ - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(hal), dp->reoq_lut.paddr >> 8); - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(hal), dp->ml_reoq_lut.paddr >> 8); - val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(ab)); + val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal)); - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal), val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE); - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(hal), HAL_REO_QDESC_MAX_PEERID); return 0; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index d1dfbe2f9a654..fb369f464b2df 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,58 +12,57 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MSI1_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MSI1_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MSI1_DATA(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_PRODUCER_INT_SETUP(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_HP_ADDR_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_HP_ADDR_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) +static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; - hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr, + hal->rdp.vaddr = dma_alloc_coherent(hal->dev, size, &hal->rdp.paddr, GFP_KERNEL); if (!hal->rdp.vaddr) return -ENOMEM; @@ -71,27 +70,25 @@ static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) return 0; } -static void ath12k_hal_free_cont_rdp(struct ath12k_base *ab) +static void ath12k_hal_free_cont_rdp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; if (!hal->rdp.vaddr) return; size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; - dma_free_coherent(ab->dev, size, + dma_free_coherent(hal->dev, size, hal->rdp.vaddr, hal->rdp.paddr); hal->rdp.vaddr = NULL; } -static int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab) +static int ath12k_hal_alloc_cont_wrp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); - hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr, + hal->wrp.vaddr = dma_alloc_coherent(hal->dev, size, &hal->wrp.paddr, GFP_KERNEL); if (!hal->wrp.vaddr) return -ENOMEM; @@ -99,16 +96,15 @@ static int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab) return 0; } -static void ath12k_hal_free_cont_wrp(struct ath12k_base *ab) +static void ath12k_hal_free_cont_wrp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; if (!hal->wrp.vaddr) return; size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); - dma_free_coherent(ab->dev, size, + dma_free_coherent(hal->dev, size, hal->wrp.vaddr, hal->wrp.paddr); hal->wrp.vaddr = NULL; } @@ -143,17 +139,17 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_lsb_offset(ab), + ath12k_hal_reo1_ring_msi1_base_lsb_offset(hal), srng->msi_addr); val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_msb_offset(ab), val); + ath12k_hal_reo1_ring_msi1_base_msb_offset(hal), val); ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_msi1_data_offset(ab), + reg_base + ath12k_hal_reo1_ring_msi1_data_offset(hal), srng->msi_data); } @@ -163,11 +159,11 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | u32_encode_bits((srng->entry_size * srng->num_entries), HAL_REO1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(ab), val); + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(hal), val); val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(ab), val); + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(hal), val); /* interrupt setup */ val = u32_encode_bits((srng->intr_timer_thres_us >> 3), @@ -177,15 +173,15 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(ab), + reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(hal), val); hp_addr = hal->rdp.paddr + ((unsigned long)srng->u.dst_ring.hp_addr - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(ab), + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(hal), hp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(ab), + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(hal), hp_addr >> HAL_ADDR_MSB_REG_SHIFT); /* Initialize head and tail pointers to indicate ring is empty */ @@ -204,7 +200,7 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, val |= HAL_REO1_RING_MISC_MSI_SWAP; val |= HAL_REO1_RING_MISC_SRNG_ENABLE; - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(ab), val); + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(hal), val); } static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, @@ -219,18 +215,18 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab), + HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), srng->msi_addr); val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab), + HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), val); ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_DATA_OFFSET(ab), + HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), srng->msi_data); } @@ -240,10 +236,10 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | u32_encode_bits((srng->entry_size * srng->num_entries), HAL_TCL1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(ab), val); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); val = u32_encode_bits(srng->intr_timer_thres_us, HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); @@ -252,7 +248,7 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab), + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), val); val = 0; @@ -261,7 +257,7 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); } ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab), + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), val); if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { @@ -269,10 +265,10 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, ((unsigned long)srng->u.src_ring.tp_addr - (unsigned long)hal->rdp.vaddr); ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab), + reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), tp_addr & HAL_ADDR_LSB_REG_MASK); ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab), + reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), tp_addr >> HAL_ADDR_MSB_REG_SHIFT); } @@ -299,7 +295,7 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); } static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, @@ -719,6 +715,7 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32 nsbufs, u32 tot_link_desc, u32 end_offset) { + struct ath12k_hal *hal = &ab->hal; struct ath12k_buffer_addr *link_addr; int i; u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; @@ -744,20 +741,21 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab), + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal), val); val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab), + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal), val); val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_LSB(ab), + HAL_WBM_SCATTERED_RING_BASE_LSB(hal), val); val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, @@ -766,14 +764,14 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_MSB(ab), + HAL_WBM_SCATTERED_RING_BASE_MSB(hal), val); /* Setup head and tail pointers for the idle list */ val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab), + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), val); val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), @@ -782,19 +780,19 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab), + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal), val); val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab), + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), val); val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab), + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal), val); val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), @@ -802,13 +800,13 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab), + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal), val); val = 2 * tot_link_desc; ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab), + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal), val); /* Enable the SRNG */ @@ -816,7 +814,7 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab), + HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal), val); } @@ -1047,18 +1045,16 @@ void ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab, ath12k_hal_srng_access_end(ab, srng); } -static void ath12k_hal_register_srng_lock_keys(struct ath12k_base *ab) +static void ath12k_hal_register_srng_lock_keys(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; u32 ring_id; for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) lockdep_register_key(&hal->srng_list[ring_id].lock_key); } -static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) +static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; u32 ring_id; for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) @@ -1067,26 +1063,29 @@ static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) int ath12k_hal_srng_init(struct ath12k_base *ab) { + struct ath12k_hal *hal = &ab->hal; int ret; - ret = ab->hal.hal_ops->create_srng_config(ab); + ret = hal->hal_ops->create_srng_config(hal); if (ret) goto err_hal; - ret = ath12k_hal_alloc_cont_rdp(ab); + hal->dev = ab->dev; + + ret = ath12k_hal_alloc_cont_rdp(hal); if (ret) goto err_hal; - ret = ath12k_hal_alloc_cont_wrp(ab); + ret = ath12k_hal_alloc_cont_wrp(hal); if (ret) goto err_free_cont_rdp; - ath12k_hal_register_srng_lock_keys(ab); + ath12k_hal_register_srng_lock_keys(hal); return 0; err_free_cont_rdp: - ath12k_hal_free_cont_rdp(ab); + ath12k_hal_free_cont_rdp(hal); err_hal: return ret; @@ -1096,9 +1095,9 @@ void ath12k_hal_srng_deinit(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; - ath12k_hal_unregister_srng_lock_keys(ab); - ath12k_hal_free_cont_rdp(ab); - ath12k_hal_free_cont_wrp(ab); + ath12k_hal_unregister_srng_lock_keys(hal); + ath12k_hal_free_cont_rdp(hal); + ath12k_hal_free_cont_wrp(hal); kfree(hal->srng_config); hal->srng_config = NULL; } diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index f9cd3d5011441..db284c58be99b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -72,14 +72,14 @@ struct ath12k_base; #define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 -#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce0_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce0_dest_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce1_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce1_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce0_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce0_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce1_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce1_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 @@ -89,52 +89,53 @@ struct ath12k_base; /* SW2TCL(x) R0 ring configuration address */ #define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 #define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 -#define HAL_TCL1_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_base_lsb) -#define HAL_TCL1_RING_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(ab) ((ab)->hal.regs->hal_tcl1_ring_id) -#define HAL_TCL1_RING_MISC(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_misc) -#define HAL_TCL1_RING_TP_ADDR_LSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_tp_addr_lsb) -#define HAL_TCL1_RING_TP_ADDR_MSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_tp_addr_msb) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix0) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix1) -#define HAL_TCL1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_msi1_base_lsb) -#define HAL_TCL1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_msi1_base_msb) -#define HAL_TCL1_RING_MSI1_DATA(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_msi1_data) -#define HAL_TCL2_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl2_ring_base_lsb) -#define HAL_TCL_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl_ring_base_lsb) - -#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MSI1_BASE_LSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MSI1_BASE_MSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_MSI1_DATA_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MSI1_DATA(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_BASE_MSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_BASE_MSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_ID_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_ID(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_TP_ADDR_LSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_TP_ADDR_MSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_MISC_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MISC(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) + +#define HAL_TCL1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_lsb) +#define HAL_TCL1_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) +#define HAL_TCL1_RING_MISC(hal) \ + ((hal)->regs->hal_tcl1_ring_misc) +#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) +#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_msb) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) +#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) +#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_msb) +#define HAL_TCL1_RING_MSI1_DATA(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_data) +#define HAL_TCL2_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl2_ring_base_lsb) +#define HAL_TCL_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_ring_base_lsb) + +#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_DATA_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_DATA(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_ID_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_ID(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MISC_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MISC(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) /* SW2TCL(x) R2 ring pointers (head/tail) address */ #define HAL_TCL1_RING_HP 0x00002000 @@ -146,8 +147,8 @@ struct ath12k_base; (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) /* TCL STATUS ring address */ -#define HAL_TCL_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl_status_ring_base_lsb) +#define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_status_ring_base_lsb) #define HAL_TCL_STATUS_RING_HP 0x00002048 /* PPE2TCL1 Ring address */ @@ -155,42 +156,42 @@ struct ath12k_base; #define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 /* WBM PPE Release Ring address */ -#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_ppe_rel_ring_base) +#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_ppe_rel_ring_base) #define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 -#define HAL_REO1_MISC_CTRL_ADDR(ab) \ - ((ab)->hal.regs->hal_reo1_misc_ctrl_addr) +#define HAL_REO1_MISC_CTRL_ADDR(hal) \ + ((hal)->regs->hal_reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(ab) ((ab)->hal.regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(ab) ((ab)->hal.regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(ab) ((ab)->hal.regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(ab) ((ab)->hal.regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_msb) -#define HAL_REO1_RING_PRODUCER_INT_SETUP(ab) \ - ((ab)->hal.regs->hal_reo1_ring_producer_int_setup) -#define HAL_REO1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo1_ring_msi1_base_lsb) -#define HAL_REO1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(ab) ((ab)->hal.regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix3) +#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) +#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) +#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ + ((hal)->regs->hal_reo1_ring_producer_int_setup) +#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_lsb) +#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) /* REO2SW(x) R2 ring pointers (head/tail) address */ #define HAL_REO1_RING_HP 0x00003048 @@ -200,24 +201,24 @@ struct ath12k_base; #define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) /* REO2SW0 ring configuration address */ -#define HAL_REO_SW0_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo2_sw0_ring_base) +#define HAL_REO_SW0_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo2_sw0_ring_base) /* REO2SW0 R2 ring pointer (head/tail) address */ #define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ -#define HAL_REO_CMD_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo_cmd_ring_base) +#define HAL_REO_CMD_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_cmd_ring_base) /* REO CMD R2 address */ #define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ -#define HAL_SW2REO_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_sw2reo_ring_base) -#define HAL_SW2REO1_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_sw2reo1_ring_base) +#define HAL_SW2REO_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo_ring_base) +#define HAL_SW2REO1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo1_ring_base) /* SW2REO R2 address */ #define HAL_SW2REO_RING_HP 0x00003028 @@ -234,53 +235,53 @@ struct ath12k_base; #define HAL_CE_DST_STATUS_RING_HP 0x00000408 /* REO status address */ -#define HAL_REO_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo_status_ring_base) +#define HAL_REO_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_status_ring_base) #define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ -#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_idle_ring_base_lsb) -#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_idle_ring_misc_addr) -#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_r0_idle_list_cntl_addr) -#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_r0_idle_list_size_addr) -#define HAL_WBM_SCATTERED_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_ring_base_lsb) -#define HAL_WBM_SCATTERED_RING_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_ring_base_msb) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_ptr_hp_addr) +#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_idle_ring_base_lsb) +#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ + ((hal)->regs->hal_wbm_idle_ring_misc_addr) +#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) +#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_size_addr) +#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_lsb) +#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_msb) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ -#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_sw_release_ring_base_lsb) -#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_sw1_release_ring_base_lsb) +#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) +#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ #define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 #define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 /* WBM2SW R0 release address */ -#define HAL_WBM0_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm0_release_ring_base_lsb) +#define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm0_release_ring_base_lsb) -#define HAL_WBM1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm1_release_ring_base_lsb) +#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ #define HAL_WBM0_RELEASE_RING_HP 0x000030c8 @@ -1548,6 +1549,7 @@ struct ath12k_hal { dma_addr_t paddr; } wrp; + struct device *dev; const struct hal_ops *hal_ops; const struct ath12k_hw_regs *regs; const struct ath12k_hw_hal_params *hal_params; @@ -1678,7 +1680,7 @@ struct ath12k_hw_version_map { }; struct hal_ops { - int (*create_srng_config)(struct ath12k_base *ab); + int (*create_srng_config)(struct ath12k_hal *hal); void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 265e9f3688587..592007f1cad66 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -859,9 +859,8 @@ const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) +static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; struct hal_srng_config *s; hal->srng_config = kmemdup(hw_srng_config_template, @@ -871,85 +870,86 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return -ENOMEM; s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; s = &hal->srng_config[HAL_REO_REINJECT]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; - s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(hal) - HAL_SW2REO_RING_BASE_LSB(hal); s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; s = &hal->srng_config[HAL_TCL_DATA]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(hal) - HAL_TCL1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; s = &hal->srng_config[HAL_CE_SRC]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); s = &hal->srng_config[HAL_CE_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[0] = + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; s = &hal->srng_config[HAL_SW2WBM_RELEASE]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) - + HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal); s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(hal) - + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; /* Some LMAC rings are not accessed from the host: @@ -963,7 +963,7 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) s = &hal->srng_config[HAL_PPE_RELEASE]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); + HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; return 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index dc3447b74d791..0c00793bbfbb4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -912,6 +912,8 @@ void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { + struct ath12k_hal *hal = &ab->hal; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 val; @@ -921,7 +923,7 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) u32_encode_bits(1, HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE); ath12k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); - val = ath12k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(ab)); + val = ath12k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(hal)); val &= ~(HAL_REO1_MISC_CTL_FRAG_DST_RING | HAL_REO1_MISC_CTL_BAR_DST_RING); @@ -929,15 +931,15 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) HAL_REO1_MISC_CTL_FRAG_DST_RING); val |= u32_encode_bits(HAL_SRNG_RING_ID_REO2SW0, HAL_REO1_MISC_CTL_BAR_DST_RING); - ath12k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(ab), val); + ath12k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(hal), val); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(hal), HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(hal), HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(hal), HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(hal), HAL_DEFAULT_VO_REO_TIMEOUT_USEC); ath12k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, @@ -949,16 +951,17 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) { u32 val; + struct ath12k_hal *hal = &ab->hal; lockdep_assert_held(&ab->base_lock); val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_ADDR(ab)); + HAL_REO1_QDESC_ADDR(hal)); val |= u32_encode_bits(1, HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_ADDR(ab), val); + HAL_REO1_QDESC_ADDR(hal), val); val &= ~HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY; ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_ADDR(ab), val); + HAL_REO1_QDESC_ADDR(hal), val); } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index b3ed7c8d738d8..8949b6fc833a4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -655,9 +655,8 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); } -static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) +static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; struct hal_srng_config *s; hal->srng_config = kmemdup(hw_srng_config_template, @@ -667,86 +666,87 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return -ENOMEM; s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; s = &hal->srng_config[HAL_REO_REINJECT]; s->max_rings = 1; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; s = &hal->srng_config[HAL_TCL_DATA]; s->max_rings = 5; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(hal) - HAL_TCL1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; s = &hal->srng_config[HAL_CE_SRC]; s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); s = &hal->srng_config[HAL_CE_DST]; s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_CE_DST_STATUS]; s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[0] = + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; s = &hal->srng_config[HAL_SW2WBM_RELEASE]; s->max_rings = 1; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(hal) - + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; s = &hal->srng_config[HAL_RXDMA_BUF]; From f561398ed403e0badaf300c2e6f305e48ea8074a Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:35 +0530 Subject: [PATCH 423/659] wifi: ath12k: Move HAL CE setup and SRNG related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_dst_setup ath12k_wifi7_hal_srng_src_hw_init ath12k_wifi7_hal_srng_dst_hw_init ath12k_wifi7_hal_set_umac_srng_ptr_addr Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 260 +--------------- drivers/net/wireless/ath/ath12k/hal.h | 6 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 277 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 8 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 4 + 6 files changed, 313 insertions(+), 246 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index fb369f464b2df..67a7285dc7697 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,49 +12,28 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) +static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num) { - return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->ce_dst_setup(ab, srng, ring_num); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) +static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->srng_src_hw_init(ab, srng); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) +static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->srng_dst_hw_init(ab, srng); } -static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) +static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); } static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) @@ -109,195 +88,6 @@ static void ath12k_hal_free_cont_wrp(struct ath12k_hal *hal) hal->wrp.vaddr = NULL; } -static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, - struct hal_srng *srng, int ring_num) -{ - struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; - u32 addr; - u32 val; - - addr = HAL_CE_DST_RING_CTRL + - srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + - ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; - - val = ath12k_hif_read32(ab, addr); - val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; - val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, - HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); - ath12k_hif_write32(ab, addr, val); -} - -static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, - struct hal_srng *srng) -{ - struct ath12k_hal *hal = &ab->hal; - u32 val; - u64 hp_addr; - u32 reg_base; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - - if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_lsb_offset(hal), - srng->msi_addr); - - val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | - HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_msb_offset(hal), val); - - ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_msi1_data_offset(hal), - srng->msi_data); - } - - ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); - - val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | - u32_encode_bits((srng->entry_size * srng->num_entries), - HAL_REO1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(hal), val); - - val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | - u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(hal), val); - - /* interrupt setup */ - val = u32_encode_bits((srng->intr_timer_thres_us >> 3), - HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); - - val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), - HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); - - ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(hal), - val); - - hp_addr = hal->rdp.paddr + - ((unsigned long)srng->u.dst_ring.hp_addr - - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(hal), - hp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(hal), - hp_addr >> HAL_ADDR_MSB_REG_SHIFT); - - /* Initialize head and tail pointers to indicate ring is empty */ - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath12k_hif_write32(ab, reg_base, 0); - ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); - *srng->u.dst_ring.hp_addr = 0; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) - val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) - val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) - val |= HAL_REO1_RING_MISC_MSI_SWAP; - val |= HAL_REO1_RING_MISC_SRNG_ENABLE; - - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(hal), val); -} - -static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, - struct hal_srng *srng) -{ - struct ath12k_hal *hal = &ab->hal; - u32 val; - u64 tp_addr; - u32 reg_base; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - - if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), - srng->msi_addr); - - val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | - HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), - val); - - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), - srng->msi_data); - } - - ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); - - val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | - u32_encode_bits((srng->entry_size * srng->num_entries), - HAL_TCL1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); - - val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); - - val = u32_encode_bits(srng->intr_timer_thres_us, - HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); - - val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), - HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); - - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), - val); - - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { - val |= u32_encode_bits(srng->u.src_ring.low_threshold, - HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); - } - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), - val); - - if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { - tp_addr = hal->rdp.paddr + - ((unsigned long)srng->u.src_ring.tp_addr - - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), - tp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), - tp_addr >> HAL_ADDR_MSB_REG_SHIFT); - } - - /* Initialize head and tail pointers to indicate ring is empty */ - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath12k_hif_write32(ab, reg_base, 0); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); - *srng->u.src_ring.tp_addr = 0; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) - val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) - val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) - val |= HAL_TCL1_RING_MISC_MSI_SWAP; - - /* Loop count is not used for SRC rings */ - val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; - - val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; - - if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) - val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; - - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); -} - static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { @@ -828,7 +618,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_id; u32 idx; int i; - u32 reg_base; ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); if (ring_id < 0) @@ -863,8 +652,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, memset(srng->ring_base_vaddr, 0, (srng->entry_size * srng->num_entries) << 2); - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - if (srng->ring_dir == HAL_SRNG_DIR_SRC) { srng->u.src_ring.hp = 0; srng->u.src_ring.cached_tp = 0; @@ -873,16 +660,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, srng->u.src_ring.low_threshold = params->low_threshold * srng->entry_size; if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { - if (!ab->hw_params->supports_shadow_regs) - srng->u.src_ring.hp_addr = - (u32 *)((unsigned long)ab->mem + reg_base); - else - ath12k_dbg(ab, ATH12K_DBG_HAL, - "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n", - type, ring_num, - reg_base, - (unsigned long)srng->u.src_ring.hp_addr - - (unsigned long)ab->mem); + ath12k_hal_set_umac_srng_ptr_addr(ab, srng); } else { idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + @@ -903,17 +681,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, srng->u.dst_ring.cached_hp = 0; srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id); if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { - if (!ab->hw_params->supports_shadow_regs) - srng->u.dst_ring.tp_addr = - (u32 *)((unsigned long)ab->mem + reg_base + - (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); - else - ath12k_dbg(ab, ATH12K_DBG_HAL, - "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n", - type, ring_num, - reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, - (unsigned long)srng->u.dst_ring.tp_addr - - (unsigned long)ab->mem); + ath12k_hal_set_umac_srng_ptr_addr(ab, srng); } else { /* For PMAC & DMAC rings, tail pointer updates will be done * through FW by writing to a shared memory location diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index db284c58be99b..9d94bad6ef73a 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1697,6 +1697,12 @@ struct hal_ops { u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); + void (*ce_dst_setup)(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num); + void (*set_umac_srng_ptr_addr)(struct ath12k_base *ab, + struct hal_srng *srng); + void (*srng_src_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); + void (*srng_dst_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 25963ac18cb9b..2b81d70e60df8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,6 +7,8 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "../debug.h" +#include "../hif.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" @@ -56,3 +58,278 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) return 0; } EXPORT_SYMBOL(ath12k_wifi7_hal_init); + +static unsigned int ath12k_wifi7_hal_reo1_ring_id_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num) +{ + struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; + u32 addr; + u32 val; + + addr = HAL_CE_DST_RING_CTRL + + srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + + ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; + + val = ath12k_hif_read32(ab, addr); + val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; + val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, + HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); + ath12k_hif_write32(ab, addr, val); +} + +void ath12k_wifi7_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct ath12k_hal *hal = &ab->hal; + u32 val; + u64 hp_addr; + u32 reg_base; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + + if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_base_lsb_offset(hal), + srng->msi_addr); + + val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | + HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_base_msb_offset(hal), + val); + + ath12k_hif_write32(ab, + reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_data_offset(hal), + srng->msi_data); + } + + ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); + + val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | + u32_encode_bits((srng->entry_size * srng->num_entries), + HAL_REO1_RING_BASE_MSB_RING_SIZE); + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_base_msb_offset(hal), + val); + + val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | + u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_id_offset(hal), val); + + /* interrupt setup */ + val = u32_encode_bits((srng->intr_timer_thres_us >> 3), + HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); + + val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), + HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); + + ath12k_hif_write32(ab, + reg_base + + ath12k_wifi7_hal_reo1_ring_producer_int_setup_offset(hal), + val); + + hp_addr = hal->rdp.paddr + + ((unsigned long)srng->u.dst_ring.hp_addr - + (unsigned long)hal->rdp.vaddr); + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_hp_addr_lsb_offset(hal), + hp_addr & HAL_ADDR_LSB_REG_MASK); + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_hp_addr_msb_offset(hal), + hp_addr >> HAL_ADDR_MSB_REG_SHIFT); + + /* Initialize head and tail pointers to indicate ring is empty */ + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + ath12k_hif_write32(ab, reg_base, 0); + ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); + *srng->u.dst_ring.hp_addr = 0; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) + val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) + val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) + val |= HAL_REO1_RING_MISC_MSI_SWAP; + val |= HAL_REO1_RING_MISC_SRNG_ENABLE; + + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_misc_offset(hal), + val); +} + +void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct ath12k_hal *hal = &ab->hal; + u32 val; + u64 tp_addr; + u32 reg_base; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + + if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), + srng->msi_addr); + + val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | + HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), + val); + + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), + srng->msi_data); + } + + ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); + + val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | + u32_encode_bits((srng->entry_size * srng->num_entries), + HAL_TCL1_RING_BASE_MSB_RING_SIZE); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); + + val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); + + val = u32_encode_bits(srng->intr_timer_thres_us, + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); + + val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); + + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), + val); + + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { + val |= u32_encode_bits(srng->u.src_ring.low_threshold, + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); + } + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), + val); + + if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { + tp_addr = hal->rdp.paddr + + ((unsigned long)srng->u.src_ring.tp_addr - + (unsigned long)hal->rdp.vaddr); + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), + tp_addr & HAL_ADDR_LSB_REG_MASK); + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), + tp_addr >> HAL_ADDR_MSB_REG_SHIFT); + } + + /* Initialize head and tail pointers to indicate ring is empty */ + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + ath12k_hif_write32(ab, reg_base, 0); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); + *srng->u.src_ring.tp_addr = 0; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) + val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) + val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) + val |= HAL_TCL1_RING_MISC_MSI_SWAP; + + /* Loop count is not used for SRC rings */ + val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; + + val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; + + if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) + val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; + + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); +} + +void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng) +{ + u32 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + if (!ab->hw_params->supports_shadow_regs) { + srng->u.src_ring.hp_addr = + (u32 *)((unsigned long)ab->mem + reg_base); + } else { + ath12k_dbg(ab, ATH12K_DBG_HAL, + "hal reg_base 0x%x shadow 0x%lx\n", + reg_base, + (unsigned long)srng->u.src_ring.hp_addr - + (unsigned long)ab->mem); + } + } else { + if (!ab->hw_params->supports_shadow_regs) { + srng->u.dst_ring.tp_addr = + (u32 *)((unsigned long)ab->mem + reg_base + + (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); + } else { + ath12k_dbg(ab, ATH12K_DBG_HAL, + "target_reg 0x%x shadow 0x%lx\n", + reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, + (unsigned long)srng->u.dst_ring.tp_addr - + (unsigned long)ab->mem); + } + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 1a8a720c49236..044ed1dce323f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -8,4 +8,12 @@ #define ATH12K_HAL_WIFI7_H int ath12k_wifi7_hal_init(struct ath12k_base *ab); +void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num); +void ath12k_wifi7_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 592007f1cad66..070e28a38a70e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1000,5 +1000,9 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8949b6fc833a4..9d1f94db60bd4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -815,5 +815,9 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 963ec18a603aef891e04e4585a68cb0fd2a57c0e Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:36 +0530 Subject: [PATCH 424/659] wifi: ath12k: Move HAL SRNG shadow config and get ring id APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_srng_update_shadow_config ath12k_wifi7_hal_srng_get_ring_id Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 101 +++--------------- drivers/net/wireless/ath/ath12k/hal.h | 5 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 86 +++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 6 ++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 + 6 files changed, 117 insertions(+), 85 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 67a7285dc7697..d4dd83d9e67f6 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -36,6 +36,21 @@ static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); } +static int ath12k_hal_srng_get_ring_id(struct ath12k_hal *hal, + enum hal_ring_type type, + int ring_num, int mac_id) +{ + return hal->hal_ops->srng_get_ring_id(hal, type, ring_num, mac_id); +} + +int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num) +{ + return ab->hal.hal_ops->srng_update_shadow_config(ab, ring_type, + ring_num); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; @@ -97,28 +112,6 @@ static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, ath12k_hal_srng_dst_hw_init(ab, srng); } -static int ath12k_hal_srng_get_ring_id(struct ath12k_base *ab, - enum hal_ring_type type, - int ring_num, int mac_id) -{ - struct hal_srng_config *srng_config = &ab->hal.srng_config[type]; - int ring_id; - - if (ring_num >= srng_config->max_rings) { - ath12k_warn(ab, "invalid ring number :%d\n", ring_num); - return -EINVAL; - } - - ring_id = srng_config->start_ring_id + ring_num; - if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) - ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC; - - if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX)) - return -EINVAL; - - return ring_id; -} - int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type) { struct hal_srng_config *srng_config; @@ -619,7 +612,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, u32 idx; int i; - ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); + ring_id = ath12k_hal_srng_get_ring_id(hal, type, ring_num, mac_id); if (ring_id < 0) return ring_id; @@ -706,68 +699,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, return ring_id; } -static void ath12k_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, - int shadow_cfg_idx, - enum hal_ring_type ring_type, - int ring_num) -{ - struct hal_srng *srng; - struct ath12k_hal *hal = &ab->hal; - int ring_id; - struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; - - ring_id = ath12k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0); - if (ring_id < 0) - return; - - srng = &hal->srng_list[ring_id]; - - if (srng_config->ring_dir == HAL_SRNG_DIR_DST) - srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + - (unsigned long)ab->mem); - else - srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + - (unsigned long)ab->mem); -} - -int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, - enum hal_ring_type ring_type, - int ring_num) -{ - struct ath12k_hal *hal = &ab->hal; - struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; - int shadow_cfg_idx = hal->num_shadow_reg_configured; - u32 target_reg; - - if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) - return -EINVAL; - - hal->num_shadow_reg_configured++; - - target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START]; - target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] * - ring_num; - - /* For destination ring, shadow the TP */ - if (srng_config->ring_dir == HAL_SRNG_DIR_DST) - target_reg += HAL_OFFSET_FROM_HP_TO_TP; - - hal->shadow_reg_addr[shadow_cfg_idx] = target_reg; - - /* update hp/tp addr to hal structure*/ - ath12k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type, - ring_num); - - ath12k_dbg(ab, ATH12K_DBG_HAL, - "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", - target_reg, - HAL_SHADOW_REG(shadow_cfg_idx), - shadow_cfg_idx, - ring_type, ring_num); - - return 0; -} - void ath12k_hal_srng_shadow_config(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 9d94bad6ef73a..8e7e64be970c4 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1703,6 +1703,11 @@ struct hal_ops { struct hal_srng *srng); void (*srng_src_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); void (*srng_dst_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); + int (*srng_update_shadow_config)(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num); + int (*srng_get_ring_id)(struct ath12k_hal *hal, enum hal_ring_type type, + int ring_num, int mac_id); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 2b81d70e60df8..565f43a30deb9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -333,3 +333,89 @@ void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, } } } + +int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, + enum hal_ring_type type, + int ring_num, int mac_id) +{ + struct hal_srng_config *srng_config = &hal->srng_config[type]; + int ring_id; + + if (ring_num >= srng_config->max_rings) { + ath12k_warn(hal, "invalid ring number :%d\n", ring_num); + return -EINVAL; + } + + ring_id = srng_config->start_ring_id + ring_num; + if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) + ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC; + + if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX)) + return -EINVAL; + + return ring_id; +} + +static +void ath12k_wifi7_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, + int shadow_cfg_idx, + enum hal_ring_type ring_type, + int ring_num) +{ + struct hal_srng *srng; + struct ath12k_hal *hal = &ab->hal; + int ring_id; + struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; + + ring_id = ath12k_wifi7_hal_srng_get_ring_id(hal, ring_type, ring_num, + 0); + if (ring_id < 0) + return; + + srng = &hal->srng_list[ring_id]; + + if (srng_config->ring_dir == HAL_SRNG_DIR_DST) + srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + + (unsigned long)ab->mem); + else + srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + + (unsigned long)ab->mem); +} + +int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num) +{ + struct ath12k_hal *hal = &ab->hal; + struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; + int shadow_cfg_idx = hal->num_shadow_reg_configured; + u32 target_reg; + + if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) + return -EINVAL; + + hal->num_shadow_reg_configured++; + + target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START]; + target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] * + ring_num; + + /* For destination ring, shadow the TP */ + if (srng_config->ring_dir == HAL_SRNG_DIR_DST) + target_reg += HAL_OFFSET_FROM_HP_TO_TP; + + hal->shadow_reg_addr[shadow_cfg_idx] = target_reg; + + /* update hp/tp addr to hal structure*/ + ath12k_wifi7_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type, + ring_num); + + ath12k_dbg(ab, ATH12K_DBG_HAL, + "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", + target_reg, + HAL_SHADOW_REG(shadow_cfg_idx), + shadow_cfg_idx, + ring_type, ring_num); + + return 0; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 044ed1dce323f..1ea7b025ed713 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -16,4 +16,10 @@ void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, struct hal_srng *srng); +int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num); +int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, + enum hal_ring_type type, + int ring_num, int mac_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 070e28a38a70e..92769a525c6d2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1004,5 +1004,7 @@ const struct hal_ops hal_qcn9274_ops = { .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, + .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, + .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 9d1f94db60bd4..a941bb4783ae4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -819,5 +819,7 @@ const struct hal_ops hal_wcn7850_ops = { .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, + .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, + .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, }; EXPORT_SYMBOL(hal_wcn7850_ops); From e645c7d0fbd0f12d426931b71d7db8cdb11079b9 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:37 +0530 Subject: [PATCH 425/659] wifi: ath12k: Move HAL CE desc related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_get_desc_size ath12k_wifi7_hal_ce_src_set_desc ath12k_wifi7_hal_ce_dst_set_desc Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-11-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ce.c | 23 ++++++---- drivers/net/wireless/ath/ath12k/hal.c | 44 ++++++------------- drivers/net/wireless/ath/ath12k/hal.h | 18 ++++++-- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 38 ++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 6 +++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 3 ++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 3 ++ 7 files changed, 92 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index 8fcf2f91b9a46..89d1f4feeafeb 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "dp_rx.h" @@ -40,7 +40,7 @@ static int ath12k_ce_rx_buf_enqueue_pipe(struct ath12k_ce_pipe *pipe, goto exit; } - ath12k_hal_ce_dst_set_desc(desc, paddr); + ath12k_hal_ce_dst_set_desc(&ab->hal, desc, paddr); ring->skb[write_index] = skb; write_index = CE_RING_IDX_INCR(nentries_mask, write_index); @@ -365,6 +365,7 @@ ath12k_ce_alloc_ring(struct ath12k_base *ab, int nentries, int desc_sz) static int ath12k_ce_alloc_pipe(struct ath12k_base *ab, int ce_id) { + struct ath12k_hal *hal = &ab->hal; struct ath12k_ce_pipe *pipe = &ab->ce.ce_pipe[ce_id]; const struct ce_attr *attr = &ab->hw_params->host_ce_config[ce_id]; struct ath12k_ce_ring *ring; @@ -376,7 +377,7 @@ static int ath12k_ce_alloc_pipe(struct ath12k_base *ab, int ce_id) if (attr->src_nentries) { pipe->send_cb = ath12k_ce_send_done_cb; nentries = roundup_pow_of_two(attr->src_nentries); - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_SRC); + desc_sz = ath12k_hal_ce_get_desc_size(hal, HAL_CE_DESC_SRC); ring = ath12k_ce_alloc_ring(ab, nentries, desc_sz); if (IS_ERR(ring)) return PTR_ERR(ring); @@ -386,13 +387,13 @@ static int ath12k_ce_alloc_pipe(struct ath12k_base *ab, int ce_id) if (attr->dest_nentries) { pipe->recv_cb = attr->recv_cb; nentries = roundup_pow_of_two(attr->dest_nentries); - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST); + desc_sz = ath12k_hal_ce_get_desc_size(hal, HAL_CE_DESC_DST); ring = ath12k_ce_alloc_ring(ab, nentries, desc_sz); if (IS_ERR(ring)) return PTR_ERR(ring); pipe->dest_ring = ring; - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS); + desc_sz = ath12k_hal_ce_get_desc_size(hal, HAL_CE_DESC_DST_STATUS); ring = ath12k_ce_alloc_ring(ab, nentries, desc_sz); if (IS_ERR(ring)) return PTR_ERR(ring); @@ -485,7 +486,7 @@ int ath12k_ce_send(struct ath12k_base *ab, struct sk_buff *skb, u8 pipe_id, if (pipe->attr_flags & CE_ATTR_BYTE_SWAP_DATA) byte_swap_data = 1; - ath12k_hal_ce_src_set_desc(desc, ATH12K_SKB_CB(skb)->paddr, + ath12k_hal_ce_src_set_desc(&ab->hal, desc, ATH12K_SKB_CB(skb)->paddr, skb->len, transfer_id, byte_swap_data); pipe->src_ring->skb[write_index] = skb; @@ -671,6 +672,7 @@ int ath12k_ce_init_pipes(struct ath12k_base *ab) void ath12k_ce_free_pipes(struct ath12k_base *ab) { + struct ath12k_hal *hal = &ab->hal; struct ath12k_ce_pipe *pipe; int desc_sz; int i; @@ -679,7 +681,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) pipe = &ab->ce.ce_pipe[i]; if (pipe->src_ring) { - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_SRC); + desc_sz = ath12k_hal_ce_get_desc_size(hal, + HAL_CE_DESC_SRC); dma_free_coherent(ab->dev, pipe->src_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, @@ -690,7 +693,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) } if (pipe->dest_ring) { - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST); + desc_sz = ath12k_hal_ce_get_desc_size(hal, + HAL_CE_DESC_DST); dma_free_coherent(ab->dev, pipe->dest_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, @@ -702,7 +706,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) if (pipe->status_ring) { desc_sz = - ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS); + ath12k_hal_ce_get_desc_size(hal, + HAL_CE_DESC_DST_STATUS); dma_free_coherent(ab->dev, pipe->status_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index d4dd83d9e67f6..490a483b8c306 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -51,6 +51,11 @@ int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, ring_num); } +u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type) +{ + return hal->hal_ops->ce_get_desc_size(type); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; @@ -185,40 +190,19 @@ dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, (unsigned long)ab->hal.wrp.vaddr); } -u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type) -{ - switch (type) { - case HAL_CE_DESC_SRC: - return sizeof(struct hal_ce_srng_src_desc); - case HAL_CE_DESC_DST: - return sizeof(struct hal_ce_srng_dest_desc); - case HAL_CE_DESC_DST_STATUS: - return sizeof(struct hal_ce_srng_dst_status_desc); - } - - return 0; -} - -void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, - u32 len, u32 id, u8 byte_swap_data) +void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, u32 len, u32 id, + u8 byte_swap_data) { - desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); - desc->buffer_addr_info = - le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) | - le32_encode_bits(byte_swap_data, - HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) | - le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) | - le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN); - desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA); + hal->hal_ops->ce_src_set_desc(desc, paddr, len, id, byte_swap_data); } -void ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr) +void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr) { - desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); - desc->buffer_addr_info = - le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); + hal->hal_ops->ce_dst_set_desc(desc, paddr); } u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 8e7e64be970c4..651ad31b05b2b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1708,6 +1708,12 @@ struct hal_ops { int ring_num); int (*srng_get_ring_id)(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id); + u32 (*ce_get_desc_size)(enum hal_ce_desc type); + void (*ce_src_set_desc)(struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, u32 len, u32 id, + u8 byte_swap_data); + void (*ce_dst_set_desc)(struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1730,10 +1736,14 @@ dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, enum hal_rx_buf_return_buf_manager rbm); -u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type); -void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, - u32 len, u32 id, u8 byte_swap_data); -void ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr); +u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type); +void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr); +void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, u32 len, u32 id, + u8 byte_swap_data); u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type); int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 565f43a30deb9..06a6af8c9c8a7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -382,6 +382,20 @@ void ath12k_wifi7_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, (unsigned long)ab->mem); } +u32 ath12k_wifi7_hal_ce_get_desc_size(enum hal_ce_desc type) +{ + switch (type) { + case HAL_CE_DESC_SRC: + return sizeof(struct hal_ce_srng_src_desc); + case HAL_CE_DESC_DST: + return sizeof(struct hal_ce_srng_dest_desc); + case HAL_CE_DESC_DST_STATUS: + return sizeof(struct hal_ce_srng_dst_status_desc); + } + + return 0; +} + int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, enum hal_ring_type ring_type, int ring_num) @@ -419,3 +433,27 @@ int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, return 0; } + +void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, + u32 len, u32 id, u8 byte_swap_data) +{ + desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); + desc->buffer_addr_info = + le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) | + le32_encode_bits(byte_swap_data, + HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) | + le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) | + le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN); + desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA); +} + +void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr) +{ + desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); + desc->buffer_addr_info = + le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 1ea7b025ed713..b0b591eb5a0a4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -22,4 +22,10 @@ int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id); +u32 ath12k_wifi7_hal_ce_get_desc_size(enum hal_ce_desc type); +void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, + u32 len, u32 id, u8 byte_swap_data); +void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 92769a525c6d2..113a0424d5eb2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1006,5 +1006,8 @@ const struct hal_ops hal_qcn9274_ops = { .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, + .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, + .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, + .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index a941bb4783ae4..60a21137bd358 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -821,5 +821,8 @@ const struct hal_ops hal_wcn7850_ops = { .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, + .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, + .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, + .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 717344923fe2576f85fe705543b67e1d0389685f Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:38 +0530 Subject: [PATCH 426/659] wifi: ath12k: Move HAL CE status and set link desc addr APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_dst_status_get_length ath12k_wifi7_hal_set_link_desc_addr Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-12-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ce.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 5 ++-- drivers/net/wireless/ath/ath12k/hal.c | 24 ++++++------------- drivers/net/wireless/ath/ath12k/hal.h | 14 +++++++---- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 23 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 6 +++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 ++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 ++ 9 files changed, 55 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index 89d1f4feeafeb..f13b260c5c96e 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -133,7 +133,7 @@ static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe, goto err; } - *nbytes = ath12k_hal_ce_dst_status_get_length(desc); + *nbytes = ath12k_hal_ce_dst_status_get_length(&ab->hal, desc); *skb = pipe->dest_ring->skb[sw_index]; pipe->dest_ring->skb[sw_index] = NULL; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 3550c88c34bb9..6d405f4aa11a2 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -661,7 +661,7 @@ static int ath12k_dp_scatter_idle_link_desc_setup(struct ath12k_base *ab, paddr = link_desc_banks[i].paddr; while (n_entries) { cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i); - ath12k_hal_set_link_desc_addr(scatter_buf, cookie, + ath12k_hal_set_link_desc_addr(dp->hal, scatter_buf, cookie, paddr, rbm); n_entries--; paddr += HAL_LINK_DESC_SIZE; @@ -868,7 +868,8 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, while (n_entries && (desc = ath12k_hal_srng_src_get_next_entry(ab, srng))) { cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i); - ath12k_hal_set_link_desc_addr(desc, cookie, paddr, rbm); + ath12k_hal_set_link_desc_addr(dp->hal, desc, cookie, paddr, + rbm); n_entries--; paddr += HAL_LINK_DESC_SIZE; } diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 490a483b8c306..5c13eaf9c19e7 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -205,27 +205,17 @@ void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, hal->hal_ops->ce_dst_set_desc(desc, paddr); } -u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) +u32 ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, + struct hal_ce_srng_dst_status_desc *desc) { - u32 len; - - len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN); - desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); - - return len; + return hal->hal_ops->ce_dst_status_get_length(desc); } -void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, - dma_addr_t paddr, - enum hal_rx_buf_return_buf_manager rbm) +void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, + struct hal_wbm_link_desc *desc, u32 cookie, + dma_addr_t paddr, int rbm) { - desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK), - BUFFER_ADDR_INFO0_ADDR); - desc->buf_addr_info.info1 = - le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), - BUFFER_ADDR_INFO1_ADDR) | - le32_encode_bits(rbm, BUFFER_ADDR_INFO1_RET_BUF_MGR) | - le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE); + hal->hal_ops->set_link_desc_addr(desc, cookie, paddr, rbm); } void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 651ad31b05b2b..74ceb3d74eb80 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1714,6 +1714,10 @@ struct hal_ops { u8 byte_swap_data); void (*ce_dst_set_desc)(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr); + u32 (*ce_dst_status_get_length)(struct hal_ce_srng_dst_status_desc *desc); + void (*set_link_desc_addr)(struct hal_wbm_link_desc *desc, u32 cookie, + dma_addr_t paddr, + enum hal_rx_buf_return_buf_manager rbm); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1733,9 +1737,6 @@ dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, struct hal_srng *srng); -void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, - dma_addr_t paddr, - enum hal_rx_buf_return_buf_manager rbm); u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type); void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, struct hal_ce_srng_dest_desc *desc, @@ -1744,7 +1745,6 @@ void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, u32 len, u32 id, u8 byte_swap_data); -u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type); int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type); void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng, @@ -1783,4 +1783,10 @@ void ath12k_hal_srng_shadow_config(struct ath12k_base *ab); void ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); +void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, + struct hal_wbm_link_desc *desc, u32 cookie, + dma_addr_t paddr, int rbm); +u32 +ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, + struct hal_ce_srng_dst_status_desc *desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index e691d0ca0d75c..06d3690ff0c63 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -12,6 +12,7 @@ #include "dp_rx.h" #include "dp.h" #include "dp_tx.h" +#include "hal.h" static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 06a6af8c9c8a7..c9e853a32378c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -457,3 +457,26 @@ void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); } + +void ath12k_wifi7_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, + u32 cookie, dma_addr_t paddr, + enum hal_rx_buf_return_buf_manager rbm) +{ + desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK), + BUFFER_ADDR_INFO0_ADDR); + desc->buf_addr_info.info1 = + le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), + BUFFER_ADDR_INFO1_ADDR) | + le32_encode_bits(rbm, BUFFER_ADDR_INFO1_RET_BUF_MGR) | + le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE); +} + +u32 ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) +{ + u32 len; + + len = le32_get_bits(READ_ONCE(desc->flags), HAL_CE_DST_STATUS_DESC_FLAGS_LEN); + desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); + + return len; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index b0b591eb5a0a4..308f804276768 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -28,4 +28,10 @@ void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, u32 len, u32 id, u8 byte_swap_data); void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr); +void +ath12k_wifi7_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, + u32 cookie, dma_addr_t paddr, + enum hal_rx_buf_return_buf_manager rbm); +u32 +ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 113a0424d5eb2..b764d5cd8aeb6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1009,5 +1009,7 @@ const struct hal_ops hal_qcn9274_ops = { .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, + .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, + .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 60a21137bd358..0985f929a4b58 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -824,5 +824,7 @@ const struct hal_ops hal_wcn7850_ops = { .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, + .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, + .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, }; EXPORT_SYMBOL(hal_wcn7850_ops); From edaa200b52470d311ab03c3739605d9b580046cd Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:39 +0530 Subject: [PATCH 427/659] wifi: ath12k: Move HAL Tx, REO and link idle setup related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_tx_set_dscp_tid_map ath12k_wifi7_hal_tx_configure_bank_register ath12k_hal_reoq_lut_addr_read_enable ath12k_hal_reoq_lut_set_max_peerid ath12k_wifi7_hal_write_reoq_lut_addr ath12k_wifi7_hal_write_ml_reoq_lut_addr ath12k_wifi7_hal_setup_link_idle_list Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-13-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 33 ++-- drivers/net/wireless/ath/ath12k/hal.c | 148 +++++------------ drivers/net/wireless/ath/ath12k/hal.h | 30 +++- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 150 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 11 ++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 9 ++ .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 8 - .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 5 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 9 ++ 9 files changed, 255 insertions(+), 148 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 6d405f4aa11a2..19bae6a1b9339 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -425,8 +425,8 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, spin_unlock_bh(&dp->tx_bank_lock); if (configure_register) - ath12k_wifi7_hal_tx_configure_bank_register(ab, bank_config, - bank_id); + ath12k_hal_tx_configure_bank_register(ab, + bank_config, bank_id); ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt tcl bank_id %d input 0x%x match 0x%x num_users %u", bank_id, bank_config, dp->bank_profiles[bank_id].bank_config, @@ -1149,9 +1149,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) return; if (dp->reoq_lut.vaddr_unaligned) { - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE0(dp->hal), 0); + ath12k_hal_write_reoq_lut_addr(ab, 0); dma_free_coherent(ab->dev, dp->reoq_lut.size, dp->reoq_lut.vaddr_unaligned, dp->reoq_lut.paddr_unaligned); @@ -1159,9 +1157,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) } if (dp->ml_reoq_lut.vaddr_unaligned) { - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE1(dp->hal), 0); + ath12k_hal_write_ml_reoq_lut_addr(ab, 0); dma_free_coherent(ab->dev, dp->ml_reoq_lut.size, dp->ml_reoq_lut.vaddr_unaligned, dp->ml_reoq_lut.paddr_unaligned); @@ -1539,8 +1535,6 @@ static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab, static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_hal *hal = dp->hal; - u32 val; int ret; if (!ab->hw_params->reoq_lut_support) @@ -1568,19 +1562,10 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) * register only */ - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(hal), - dp->reoq_lut.paddr >> 8); - - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(hal), - dp->ml_reoq_lut.paddr >> 8); - - val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal)); - - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal), - val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE); - - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(hal), - HAL_REO_QDESC_MAX_PEERID); + ath12k_hal_write_reoq_lut_addr(ab, dp->reoq_lut.paddr >> 8); + ath12k_hal_write_ml_reoq_lut_addr(ab, dp->ml_reoq_lut.paddr >> 8); + ath12k_hal_reoq_lut_addr_read_enable(ab); + ath12k_hal_reoq_lut_set_max_peerid(ab); return 0; } @@ -1680,7 +1665,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab) } for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++) - ath12k_wifi7_hal_tx_set_dscp_tid_map(ab, i); + ath12k_hal_tx_set_dscp_tid_map(ab, i); ret = ath12k_dp_rx_alloc(ab); if (ret) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 5c13eaf9c19e7..b3010eea9afca 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -56,6 +56,46 @@ u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type) return hal->hal_ops->ce_get_desc_size(type); } +void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) +{ + ab->hal.hal_ops->tx_set_dscp_tid_map(ab, id); +} + +void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, u8 bank_id) +{ + ab->hal.hal_ops->tx_configure_bank_register(ab, bank_config, bank_id); +} + +void ath12k_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab) +{ + ab->hal.hal_ops->reoq_lut_addr_read_enable(ab); +} + +void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab) +{ + ab->hal.hal_ops->reoq_lut_set_max_peerid(ab); +} + +void ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) +{ + ab->hal.hal_ops->write_ml_reoq_lut_addr(ab, paddr); +} + +void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) +{ + ab->hal.hal_ops->write_reoq_lut_addr(ab, paddr); +} + +void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset) +{ + ab->hal.hal_ops->setup_link_idle_list(ab, sbuf, nsbufs, tot_link_desc, + end_offset); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; @@ -467,114 +507,6 @@ void ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng) srng->timestamp = jiffies; } -void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, - struct hal_wbm_idle_scatter_list *sbuf, - u32 nsbufs, u32 tot_link_desc, - u32 end_offset) -{ - struct ath12k_hal *hal = &ab->hal; - struct ath12k_buffer_addr *link_addr; - int i; - u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; - u32 val; - - link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; - - for (i = 1; i < nsbufs; i++) { - link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK); - - link_addr->info1 = - le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | - le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG); - - link_addr = (void *)sbuf[i].vaddr + - HAL_WBM_IDLE_SCATTER_BUF_SIZE; - } - - val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) | - u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE); - - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal), - val); - - val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, - HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal), - val); - - val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, - BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_LSB(hal), - val); - - val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) | - u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_MSB(hal), - val); - - /* Setup head and tail pointers for the idle list */ - val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), - val); - - val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | - u32_encode_bits((end_offset >> 2), - HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal), - val); - - val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), - val); - - val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal), - val); - - val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | - u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal), - val); - - val = 2 * tot_link_desc; - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal), - val); - - /* Enable the SRNG */ - val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) | - u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal), - val); -} - int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_num, int mac_id, struct hal_srng_params *params) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 74ceb3d74eb80..fb9aaee5c2539 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1718,6 +1718,18 @@ struct hal_ops { void (*set_link_desc_addr)(struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, enum hal_rx_buf_return_buf_manager rbm); + void (*tx_set_dscp_tid_map)(struct ath12k_base *ab, int id); + void (*tx_configure_bank_register)(struct ath12k_base *ab, + u32 bank_config, u8 bank_id); + void (*reoq_lut_addr_read_enable)(struct ath12k_base *ab); + void (*reoq_lut_set_max_peerid)(struct ath12k_base *ab); + void (*write_ml_reoq_lut_addr)(struct ath12k_base *ab, + dma_addr_t paddr); + void (*write_reoq_lut_addr)(struct ath12k_base *ab, dma_addr_t paddr); + void (*setup_link_idle_list)(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1727,12 +1739,6 @@ void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); - -void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, - struct hal_wbm_idle_scatter_list *sbuf, - u32 nsbufs, u32 tot_link_desc, - u32 end_offset); - dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1786,7 +1792,19 @@ void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, int rbm); +void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset); u32 ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, struct hal_ce_srng_dst_status_desc *desc); +void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); +void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, u8 bank_id); +void ath12k_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab); +void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab); +void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); +void +ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index c9e853a32378c..73d86dedadb1d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,6 +7,7 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "hal_tx.h" #include "../debug.h" #include "../hif.h" #include "hal_qcn9274.h" @@ -480,3 +481,152 @@ u32 ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc return len; } + +void +ath12k_wifi7_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset) +{ + struct ath12k_hal *hal = &ab->hal; + struct ath12k_buffer_addr *link_addr; + int i; + u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; + u32 val; + + link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; + + for (i = 1; i < nsbufs; i++) { + link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK); + + link_addr->info1 = + le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | + le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG); + + link_addr = (void *)sbuf[i].vaddr + + HAL_WBM_IDLE_SCATTER_BUF_SIZE; + } + + val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) | + u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE); + + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal), + val); + + val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, + HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal), + val); + + val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, + BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_RING_BASE_LSB(hal), + val); + + val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) | + u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_RING_BASE_MSB(hal), + val); + + /* Setup head and tail pointers for the idle list */ + val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), + val); + + val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | + u32_encode_bits((end_offset >> 2), + HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal), + val); + + val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), + val); + + val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal), + val); + + val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | + u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal), + val); + + val = 2 * tot_link_desc; + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal), + val); + + /* Enable the SRNG */ + val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) | + u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal), + val); +} + +void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, + u8 bank_id) +{ + ath12k_hif_write32(ab, HAL_TCL_SW_CONFIG_BANK_ADDR + 4 * bank_id, + bank_config); +} + +void ath12k_wifi7_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + + u32 val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_ADDR(hal)); + + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal), + val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE); +} + +void ath12k_wifi7_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(hal), + HAL_REO_QDESC_MAX_PEERID); +} + +void ath12k_wifi7_hal_write_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr) +{ + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_LUT_BASE0(&ab->hal), paddr); +} + +void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr) +{ + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_LUT_BASE1(&ab->hal), paddr); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 308f804276768..6e67f06ffa438 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -34,4 +34,15 @@ ath12k_wifi7_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, enum hal_rx_buf_return_buf_manager rbm); u32 ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); +void +ath12k_wifi7_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset); +void ath12k_wifi7_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab); +void ath12k_wifi7_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab); +void ath12k_wifi7_hal_write_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr); +void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index b764d5cd8aeb6..9cbae6d11dd84 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -7,6 +7,7 @@ #include "hal_qcn9274.h" #include "hw.h" #include "hal.h" +#include "hal_tx.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -1011,5 +1012,13 @@ const struct hal_ops hal_qcn9274_ops = { .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, + .tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map, + .tx_configure_bank_register = + ath12k_wifi7_hal_tx_configure_bank_register, + .reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable, + .reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid, + .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, + .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, + .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 027e02141ec2c..24f905c5b0624 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -136,11 +136,3 @@ void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) HAL_TCL1_RING_CMN_CTRL_REG, ctrl_reg_val); } - -void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, - u32 bank_config, - u8 bank_id) -{ - ath12k_hif_write32(ab, HAL_TCL_SW_CONFIG_BANK_ADDR + 4 * bank_id, - bank_config); -} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index d0f6a174f347c..07392b31d0ab9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -181,13 +181,14 @@ struct hal_tx_fes_status_end { /* STA mode will have MCAST_PKT_CTRL instead of DSCP_TID_MAP bitfield */ #define HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID GENMASK(22, 17) +void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab, struct hal_tcl_data_cmd *tcl_cmd, struct hal_tx_info *ti); -void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd); void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, - u32 bank_config, u8 bank_id); + u32 bank_config, + u8 bank_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 0985f929a4b58..2e645f8f4a144 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -8,6 +8,7 @@ #include "hal_wcn7850.h" #include "hw.h" #include "hal.h" +#include "hal_tx.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -826,5 +827,13 @@ const struct hal_ops hal_wcn7850_ops = { .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, + .tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map, + .tx_configure_bank_register = + ath12k_wifi7_hal_tx_configure_bank_register, + .reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable, + .reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid, + .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, + .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, + .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, }; EXPORT_SYMBOL(hal_wcn7850_ops); From fa3669d47772e8595f1cbd817e036da264e3c53d Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:40 +0530 Subject: [PATCH 428/659] wifi: ath12k: Move HAL REO and Rx buf related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_reo_qdesc_setup ath12k_wifi7_hal_reo_init_cmd_ring ath12k_wifi7_hal_reo_hw_setup ath12k_wifi7_hal_rx_buf_addr_info_set ath12k_wifi7_hal_rx_buf_addr_info_get Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-14-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dbring.c | 4 +-- drivers/net/wireless/ath/ath12k/dp.c | 4 +-- drivers/net/wireless/ath/ath12k/dp_rx.c | 3 ++- drivers/net/wireless/ath/ath12k/hal.c | 25 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/hal.h | 23 ++++++++++++----- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 +++ .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 6 +++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 4 +++ 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c index 093298f8acabd..a387cb9554d24 100644 --- a/drivers/net/wireless/ath/ath12k/dbring.c +++ b/drivers/net/wireless/ath/ath12k/dbring.c @@ -54,7 +54,7 @@ static int ath12k_dbring_bufs_replenish(struct ath12k *ar, cookie = u32_encode_bits(ar->pdev_idx, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, 0); ath12k_hal_srng_access_end(ab, srng); @@ -297,7 +297,7 @@ int ath12k_dbring_buffer_release_event(struct ath12k_base *ab, num_buff_reaped++; - ath12k_wifi7_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, &desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 19bae6a1b9339..2addfe46cea3e 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -562,7 +562,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } srng = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - ath12k_wifi7_hal_reo_init_cmd_ring(ab, srng); + ath12k_hal_reo_init_cmd_ring(ab, srng); ret = ath12k_dp_srng_setup(ab, &dp->reo_status_ring, HAL_REO_STATUS, 0, 0, DP_REO_STATUS_RING_SIZE); @@ -586,7 +586,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) HAL_HASH_ROUTING_RING_SW3 << 24 | HAL_HASH_ROUTING_RING_SW4 << 28; - ath12k_wifi7_hal_reo_hw_setup(ab, ring_hash_map); + ath12k_hal_reo_hw_setup(ab, ring_hash_map); return 0; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 9343cea6e24d8..13d7c241de6a9 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -148,7 +148,8 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, + mgr); } goto out; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index b3010eea9afca..00cd6dcb5bada 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -96,6 +96,31 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, end_offset); } +void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) +{ + ab->hal.hal_ops->reo_hw_setup(ab, ring_hash_map); +} + +void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng) +{ + ab->hal.hal_ops->reo_init_cmd_ring(ab, srng); +} + +void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager) +{ + hal->hal_ops->rx_buf_addr_info_set(binfo, paddr, cookie, manager); +} + +void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, u32 *msdu_cookies, + u8 *rbm) +{ + hal->hal_ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index fb9aaee5c2539..e0860b6675bd8 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1730,15 +1730,17 @@ struct hal_ops { struct hal_wbm_idle_scatter_list *sbuf, u32 nsbufs, u32 tot_link_desc, u32 end_offset); + void (*reo_init_cmd_ring)(struct ath12k_base *ab, + struct hal_srng *srng); + void (*reo_hw_setup)(struct ath12k_base *ab, u32 ring_hash_map); + void (*rx_buf_addr_info_set)(struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager); + void (*rx_buf_addr_info_get)(struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, u32 *msdu_cookies, + u8 *rbm); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); -void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, - int tid, u32 ba_window_size, - u32 start_seq, enum hal_pn_type type); -void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng); -void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1807,4 +1809,13 @@ void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab); void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); void ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); +void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); +void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); +void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager); +void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, u32 *msdu_cookies, + u8 *rbm); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 9cbae6d11dd84..fb723e971f5df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1020,5 +1020,9 @@ const struct hal_ops hal_qcn9274_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, + .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 458282343ff30..a029ea3fe93c6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -870,5 +870,11 @@ void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, struct hal_rx_msdu_link *link_desc, struct hal_rx_msdu_list *msdu_list, u16 *num_msdus); +void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); +void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 2e645f8f4a144..33f8ddcedd836 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -835,5 +835,9 @@ const struct hal_ops hal_wcn7850_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, + .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 017c2d6072feeb06e09918e6d6e61a42e01910da Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:41 +0530 Subject: [PATCH 429/659] wifi: ath12k: Move HAL Cookie Conversion and RBM related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_cc_config ath12k_wifi7_hal_get_idle_link_rbm Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-15-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 75 +------------------ drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 11 +++ drivers/net/wireless/ath/ath12k/hal.h | 6 ++ drivers/net/wireless/ath/ath12k/wifi7/hal.c | 73 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 3 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 + 9 files changed, 100 insertions(+), 75 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 04983074e9467..4bc56d5ac64fa 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -922,7 +922,7 @@ static int ath12k_core_start(struct ath12k_base *ab) goto err_hif_stop; } - ath12k_dp_cc_config(ab); + ath12k_hal_cc_config(ab); ret = ath12k_dp_rx_pdev_reo_setup(ab); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 2addfe46cea3e..f6ccd5a4493dc 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1192,60 +1192,6 @@ static void ath12k_dp_cleanup(struct ath12k_base *ab) /* Deinit any SOC level resource */ } -void ath12k_dp_cc_config(struct ath12k_base *ab) -{ - u32 cmem_base = ab->qmi.dev_mem[ATH12K_QMI_DEVMEM_CMEM_INDEX].start; - u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; - u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; - u32 val = 0; - struct ath12k_hal *hal = &ab->hal; - - if (ath12k_ftm_mode) - return; - - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(hal), cmem_base); - - val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, - HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | - u32_encode_bits(ATH12K_CC_PPT_MSB, - HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB) | - u32_encode_bits(ATH12K_CC_SPT_MSB, - HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB) | - u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ALIGN) | - u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ENABLE) | - u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE); - - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(hal), val); - - /* Enable HW CC for WBM */ - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG0, cmem_base); - - val = u32_encode_bits(ATH12K_CMEM_ADDR_MSB, - HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | - u32_encode_bits(ATH12K_CC_PPT_MSB, - HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB) | - u32_encode_bits(ATH12K_CC_SPT_MSB, - HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB) | - u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ALIGN); - - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG1, val); - - /* Enable conversion complete indication */ - val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2); - val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN) | - u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN) | - u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN); - - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2, val); - - /* Enable Cookie conversion for WBM2SW Rings */ - val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); - val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | - hal->hal_params->wbm2sw_cc_enable; - - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); -} - static u32 ath12k_dp_cc_cookie_gen(u16 ppt_idx, u16 spt_idx) { return (u32)ppt_idx << ATH12K_CC_PPT_SHIFT | spt_idx; @@ -1570,24 +1516,6 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) return 0; } -static enum hal_rx_buf_return_buf_manager -ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab) -{ - switch (ab->device_id) { - case 0: - return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; - case 1: - return HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST; - case 2: - return HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST; - default: - ath12k_warn(ab, "invalid %d device id, so choose default rbm\n", - ab->device_id); - WARN_ON(1); - return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; - } -} - static int ath12k_dp_setup(struct ath12k_base *ab) { struct ath12k_dp *dp; @@ -1607,7 +1535,8 @@ static int ath12k_dp_setup(struct ath12k_base *ab) spin_lock_init(&dp->reo_rxq_flush_lock); dp->reo_cmd_cache_flush_count = 0; - dp->idle_link_rbm = ath12k_dp_get_idle_link_rbm(ab); + dp->idle_link_rbm = + ath12k_hal_get_idle_link_rbm(&ab->hal, ab->device_id); ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index d0efe5b2de6ce..967fcd8ab9927 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -509,7 +509,6 @@ ath12k_dp_to_pdev_dp(struct ath12k_dp *dp, u8 pdev_idx) } void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); -void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); int ath12k_dp_pdev_alloc(struct ath12k_base *ab); void ath12k_dp_pdev_pre_alloc(struct ath12k *ar); diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 00cd6dcb5bada..528138a1dc181 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -121,6 +121,17 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, hal->hal_ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); } +void ath12k_hal_cc_config(struct ath12k_base *ab) +{ + ab->hal.hal_ops->cc_config(ab); +} + +enum hal_rx_buf_return_buf_manager +ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id) +{ + return hal->hal_ops->get_idle_link_rbm(hal, device_id); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index e0860b6675bd8..83834eff6cf45 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1738,6 +1738,9 @@ struct hal_ops { void (*rx_buf_addr_info_get)(struct ath12k_buffer_addr *binfo, dma_addr_t *paddr, u32 *msdu_cookies, u8 *rbm); + void (*cc_config)(struct ath12k_base *ab); + enum hal_rx_buf_return_buf_manager + (*get_idle_link_rbm)(struct ath12k_hal *hal, u8 device_id); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1818,4 +1821,7 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, struct ath12k_buffer_addr *binfo, dma_addr_t *paddr, u32 *msdu_cookies, u8 *rbm); +void ath12k_hal_cc_config(struct ath12k_base *ab); +enum hal_rx_buf_return_buf_manager +ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 73d86dedadb1d..4f9f1efbbfcf2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -630,3 +630,76 @@ void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(&ab->hal), paddr); } + +void ath12k_wifi7_hal_cc_config(struct ath12k_base *ab) +{ + u32 cmem_base = ab->qmi.dev_mem[ATH12K_QMI_DEVMEM_CMEM_INDEX].start; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; + u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; + u32 val = 0; + struct ath12k_hal *hal = &ab->hal; + + if (ath12k_ftm_mode) + return; + + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(hal), cmem_base); + + val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, + HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | + u32_encode_bits(ATH12K_CC_PPT_MSB, + HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB) | + u32_encode_bits(ATH12K_CC_SPT_MSB, + HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB) | + u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ALIGN) | + u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ENABLE) | + u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE); + + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(hal), val); + + /* Enable HW CC for WBM */ + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG0, cmem_base); + + val = u32_encode_bits(ATH12K_CMEM_ADDR_MSB, + HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | + u32_encode_bits(ATH12K_CC_PPT_MSB, + HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB) | + u32_encode_bits(ATH12K_CC_SPT_MSB, + HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB) | + u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ALIGN); + + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG1, val); + + /* Enable conversion complete indication */ + val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2); + val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN) | + u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN) | + u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN); + + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2, val); + + /* Enable Cookie conversion for WBM2SW Rings */ + val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); + val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | + hal->hal_params->wbm2sw_cc_enable; + + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); +} + +enum hal_rx_buf_return_buf_manager +ath12k_wifi7_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id) +{ + switch (device_id) { + case 0: + return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; + case 1: + return HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST; + case 2: + return HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST; + default: + ath12k_warn(hal, + "invalid %d device id, so choose default rbm\n", + device_id); + WARN_ON(1); + return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 6e67f06ffa438..b600b2e3cb78d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -23,6 +23,9 @@ int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id); u32 ath12k_wifi7_hal_ce_get_desc_size(enum hal_ce_desc type); +void ath12k_wifi7_hal_cc_config(struct ath12k_base *ab); +enum hal_rx_buf_return_buf_manager +ath12k_wifi7_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id); void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, u32 len, u32 id, u8 byte_swap_data); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index fb723e971f5df..2dc4f1539d684 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1024,5 +1024,7 @@ const struct hal_ops hal_qcn9274_ops = { .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, + .cc_config = ath12k_wifi7_hal_cc_config, + .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 33f8ddcedd836..233350ccd06e4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -839,5 +839,7 @@ const struct hal_ops hal_wcn7850_ops = { .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, + .cc_config = ath12k_wifi7_hal_cc_config, + .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 085d9ce32b9c96caa73b5a331a97d96a4deb5366 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:42 +0530 Subject: [PATCH 430/659] wifi: ath12k: Segregate the common and wifi7 specific structures Segregate the common and wifi7 specific structures in hal, and move them to corresponding header files. hal.h file in common directory is used by both common and wifi7 directory files, while hal.h and other hal headers are used only by files within the wifi7 directory since these headers contain hw specific hal data. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-16-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 1 + drivers/net/wireless/ath/ath12k/core.h | 2 +- drivers/net/wireless/ath/ath12k/dbring.c | 1 + drivers/net/wireless/ath/ath12k/debugfs.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 54 +- drivers/net/wireless/ath/ath12k/dp.h | 14 +- drivers/net/wireless/ath/ath12k/dp_mon.h | 1 + drivers/net/wireless/ath/ath12k/dp_rx.c | 2 - drivers/net/wireless/ath/ath12k/dp_rx.h | 1 - drivers/net/wireless/ath/ath12k/dp_tx.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 5 - drivers/net/wireless/ath/ath12k/hal.h | 610 +++--------------- drivers/net/wireless/ath/ath12k/pci.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 52 ++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 512 +++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 80 --- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 4 + .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 2 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/pci.c | 1 + 27 files changed, 695 insertions(+), 665 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h index 1a531357271bc..20208ffea1c9a 100644 --- a/drivers/net/wireless/ath/ath12k/cmn_defs.h +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -16,4 +16,5 @@ /* Define 1 scan link for each radio for parallel scan purposes */ #define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) +#define MAX_MU_GROUP_ID 64 #endif diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 49637b56b8f9e..1548116b0228f 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -26,7 +26,7 @@ #include "ce.h" #include "mac.h" #include "hw.h" -#include "wifi7/hal_rx.h" +#include "wifi7/hal_desc.h" #include "reg.h" #include "dbring.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c index a387cb9554d24..f71ec2a58469f 100644 --- a/drivers/net/wireless/ath/ath12k/dbring.c +++ b/drivers/net/wireless/ath/ath12k/dbring.c @@ -6,6 +6,7 @@ #include "core.h" #include "debug.h" +#include "hal.h" static int ath12k_dbring_bufs_replenish(struct ath12k *ar, struct ath12k_dbring *ring, diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index f25af9adeac82..19c4fabecff8e 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -967,7 +967,7 @@ static int ath12k_open_link_stats(struct inode *inode, struct file *file) "\nlink[%d] Tx Frame descriptor Encrypt Type = ", link_id); - for (i = 0; i < HAL_ENCRYPT_TYPE_MAX; i++) { + for (i = 0; i < DP_ENCRYPT_TYPE_MAX; i++) { len += scnprintf(buf + len, buf_len - len, " %d:%d", i, linkstat.tx_encrypt_type[i]); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index f6ccd5a4493dc..a3f97ef96686d 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -7,8 +7,8 @@ #include #include "core.h" #include "dp_tx.h" -#include "wifi7/hal_tx.h" #include "hif.h" +#include "hal.h" #include "debug.h" #include "wifi7/dp_rx.h" #include "peer.h" @@ -333,56 +333,6 @@ int ath12k_dp_srng_setup(struct ath12k_base *ab, struct dp_srng *ring, return 0; } -static -u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, - struct ath12k_link_vif *arvif) -{ - u32 bank_config = 0; - u8 link_id = arvif->link_id; - struct ath12k_vif *ahvif = arvif->ahvif; - struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; - struct ath12k_dp_link_vif *dp_link_vif; - - dp_link_vif = ath12k_dp_vif_to_dp_link_vif(dp_vif, link_id); - - /* Only valid for raw frames with HW crypto enabled. - * With SW crypto, mac80211 sets key per packet - */ - if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && - test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) - bank_config |= - u32_encode_bits(ath12k_dp_tx_get_encrypt_type(dp_vif->key_cipher), - HAL_TX_BANK_CONFIG_ENCRYPT_TYPE); - - bank_config |= u32_encode_bits(dp_vif->tx_encap_type, - HAL_TX_BANK_CONFIG_ENCAP_TYPE); - bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_SRC_BUFFER_SWAP) | - u32_encode_bits(0, HAL_TX_BANK_CONFIG_LINK_META_SWAP) | - u32_encode_bits(0, HAL_TX_BANK_CONFIG_EPD); - - /* only valid if idx_lookup_override is not set in tcl_data_cmd */ - if (ahvif->vdev_type == WMI_VDEV_TYPE_STA) - bank_config |= u32_encode_bits(1, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); - else - bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); - - bank_config |= u32_encode_bits(dp_link_vif->hal_addr_search_flags & - HAL_TX_ADDRX_EN, - HAL_TX_BANK_CONFIG_ADDRX_EN) | - u32_encode_bits(!!(dp_link_vif->hal_addr_search_flags & - HAL_TX_ADDRY_EN), - HAL_TX_BANK_CONFIG_ADDRY_EN); - - bank_config |= u32_encode_bits(ieee80211_vif_is_mesh(ahvif->vif) ? 3 : 0, - HAL_TX_BANK_CONFIG_MESH_EN) | - u32_encode_bits(dp_link_vif->vdev_id_check_en, - HAL_TX_BANK_CONFIG_VDEV_ID_CHECK_EN); - - bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID); - - return bank_config; -} - static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, struct ath12k_link_vif *arvif, struct ath12k_dp *dp) @@ -393,7 +343,7 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, bool configure_register = false; /* convert vdev params into hal_tx_bank_config */ - bank_config = ath12k_dp_tx_get_vdev_bank_config(ab, arvif); + bank_config = dp->ops->dp_tx_get_vdev_bank_config(ab, arvif); spin_lock_bh(&dp->tx_bank_lock); /* TODO: implement using idr kernel framework*/ diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 967fcd8ab9927..4318ec13cb8f1 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -7,8 +7,6 @@ #ifndef ATH12K_DP_H #define ATH12K_DP_H -#include "wifi7/hal_desc.h" -#include "wifi7/hal_rx.h" #include "hw.h" #include "dp_htt.h" #include "dp_cmn.h" @@ -26,6 +24,10 @@ struct ath12k_ext_irq_grp; #define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 +#define DP_ENCAP_TYPE_MAX 4 +#define DP_ENCRYPT_TYPE_MAX 12 +#define DP_DESC_TYPE_MAX 2 + struct dp_srng { u32 *vaddr_unaligned; u32 *vaddr; @@ -373,9 +375,9 @@ struct ath12k_link_stats { u32 tx_completed; u32 tx_bcast_mcast; u32 tx_dropped; - u32 tx_encap_type[HAL_TCL_ENCAP_TYPE_MAX]; - u32 tx_encrypt_type[HAL_ENCRYPT_TYPE_MAX]; - u32 tx_desc_type[HAL_TCL_DESC_TYPE_MAX]; + u32 tx_encap_type[DP_ENCAP_TYPE_MAX]; + u32 tx_encrypt_type[DP_ENCRYPT_TYPE_MAX]; + u32 tx_desc_type[DP_DESC_TYPE_MAX]; }; /* DP arch ops to communicate from common module @@ -385,6 +387,8 @@ struct ath12k_dp_arch_ops { int (*service_srng)(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, int budget); + u32 (*dp_tx_get_vdev_bank_config)(struct ath12k_base *ab, + struct ath12k_link_vif *arvif); }; struct ath12k_dp { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 068df74003456..6110227a40dd3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -8,6 +8,7 @@ #define ATH12K_DP_MON_H #include "core.h" +#include "wifi7/hal_desc.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 13d7c241de6a9..f27cf5c24a761 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -10,11 +10,9 @@ #include #include "core.h" #include "debug.h" -#include "wifi7/hal_desc.h" #include "hw.h" #include "dp_rx.h" #include "wifi7/dp_rx.h" -#include "wifi7/hal_rx.h" #include "dp_tx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 09042d41976bf..9b0ed9142a8be 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -8,7 +8,6 @@ #include #include "core.h" -#include "wifi7/hal_rx_desc.h" #include "debug.h" #define DP_MAX_NWIFI_HDR_LEN 30 diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 5b8fe280c32ae..147409f9ac408 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -8,7 +8,6 @@ #define ATH12K_DP_TX_H #include "core.h" -#include "wifi7/hal_tx.h" struct ath12k_dp_htt_wbm_tx_status { bool acked; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 528138a1dc181..296bd7824ae2d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -4,13 +4,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include -#include "wifi7/hal_tx.h" -#include "wifi7/hal_rx.h" #include "debug.h" -#include "wifi7/hal_desc.h" #include "hif.h" -#include "wifi7/hal_qcn9274.h" -#include "wifi7/hal_wcn7850.h" static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, struct hal_srng *srng, int ring_num) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 83834eff6cf45..63ad67318b0e5 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -7,8 +7,7 @@ #ifndef ATH12K_HAL_H #define ATH12K_HAL_H -#include "wifi7/hal_desc.h" -#include "wifi7/hal_rx_desc.h" +#include "hw.h" struct ath12k_base; @@ -26,6 +25,10 @@ struct ath12k_base; #define HAL_RX_MAX_MPDU 256 #define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) +/* TODO: 16 entries per radio times MAX_VAPS_SUPPORTED */ +#define HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX 32 +#define HAL_DSCP_TID_TBL_SIZE 24 + #define EHT_MAX_USER_INFO 4 #define HAL_RX_MON_MAX_AGGR_SIZE 128 #define HAL_MAX_UL_MU_USERS 37 @@ -48,366 +51,19 @@ struct ath12k_base; #define HAL_RING_BASE_ALIGN 8 #define HAL_REO_QLUT_ADDR_ALIGN 256 +#define HAL_ADDR_LSB_REG_MASK 0xffffffff +#define HAL_ADDR_MSB_REG_SHIFT 32 + +#define HAL_WBM2SW_REL_ERR_RING_NUM 3 + +#define HAL_SHADOW_NUM_REGS_MAX 40 + #define HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX 32704 /* TODO: Check with hw team on the supported scatter buf size */ #define HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE 8 #define HAL_WBM_IDLE_SCATTER_BUF_SIZE (HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX - \ HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE) -/* TODO: 16 entries per radio times MAX_VAPS_SUPPORTED */ -#define HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX 32 -#define HAL_DSCP_TID_TBL_SIZE 24 - -/* calculate the register address from bar0 of shadow register x */ -#define HAL_SHADOW_BASE_ADDR 0x000008fc -#define HAL_SHADOW_NUM_REGS 40 -#define HAL_HP_OFFSET_IN_REG_START 1 -#define HAL_OFFSET_FROM_HP_TO_TP 4 - -#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x))) -#define HAL_REO_QDESC_MAX_PEERID 8191 - -/* WCSS Relative address */ -#define HAL_SEQ_WCSS_CMEM_OFFSET 0x00100000 -#define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 -#define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 -#define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 -#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce0_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce0_dest_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce1_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce1_dest_reg_base) -#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 - -#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 - -#define HAL_TCL_SW_CONFIG_BANK_ADDR 0x00a4408c - -/* SW2TCL(x) R0 ring configuration address */ -#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 -#define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 - -#define HAL_TCL1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_lsb) -#define HAL_TCL1_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) -#define HAL_TCL1_RING_MISC(hal) \ - ((hal)->regs->hal_tcl1_ring_misc) -#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) -#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_msb) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) -#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) -#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_msb) -#define HAL_TCL1_RING_MSI1_DATA(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_data) -#define HAL_TCL2_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl2_ring_base_lsb) -#define HAL_TCL_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_ring_base_lsb) - -#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MSI1_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_MSI1_DATA_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MSI1_DATA(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_ID_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_ID(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_TP_ADDR_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_TP_ADDR_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_MISC_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MISC(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) - -/* SW2TCL(x) R2 ring pointers (head/tail) address */ -#define HAL_TCL1_RING_HP 0x00002000 -#define HAL_TCL1_RING_TP 0x00002004 -#define HAL_TCL2_RING_HP 0x00002008 -#define HAL_TCL_RING_HP 0x00002028 - -#define HAL_TCL1_RING_TP_OFFSET \ - (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) - -/* TCL STATUS ring address */ -#define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_status_ring_base_lsb) -#define HAL_TCL_STATUS_RING_HP 0x00002048 - -/* PPE2TCL1 Ring address */ -#define HAL_TCL_PPE2TCL1_RING_BASE_LSB 0x00000c48 -#define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 - -/* WBM PPE Release Ring address */ -#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_ppe_rel_ring_base) -#define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 - -/* REO2SW(x) R0 ring configuration address */ -#define HAL_REO1_GEN_ENABLE 0x00000000 -#define HAL_REO1_MISC_CTRL_ADDR(hal) \ - ((hal)->regs->hal_reo1_misc_ctrl_addr) -#define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 -#define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 -#define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c -#define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) -#define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ - ((hal)->regs->hal_reo1_ring_producer_int_setup) -#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_lsb) -#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) - -/* REO2SW(x) R2 ring pointers (head/tail) address */ -#define HAL_REO1_RING_HP 0x00003048 -#define HAL_REO1_RING_TP 0x0000304c -#define HAL_REO2_RING_HP 0x00003050 - -#define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) - -/* REO2SW0 ring configuration address */ -#define HAL_REO_SW0_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo2_sw0_ring_base) - -/* REO2SW0 R2 ring pointer (head/tail) address */ -#define HAL_REO_SW0_RING_HP 0x00003088 - -/* REO CMD R0 address */ -#define HAL_REO_CMD_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_cmd_ring_base) - -/* REO CMD R2 address */ -#define HAL_REO_CMD_HP 0x00003020 - -/* SW2REO R0 address */ -#define HAL_SW2REO_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo_ring_base) -#define HAL_SW2REO1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo1_ring_base) - -/* SW2REO R2 address */ -#define HAL_SW2REO_RING_HP 0x00003028 -#define HAL_SW2REO1_RING_HP 0x00003030 - -/* CE ring R0 address */ -#define HAL_CE_SRC_RING_BASE_LSB 0x00000000 -#define HAL_CE_DST_RING_BASE_LSB 0x00000000 -#define HAL_CE_DST_STATUS_RING_BASE_LSB 0x00000058 -#define HAL_CE_DST_RING_CTRL 0x000000b0 - -/* CE ring R2 address */ -#define HAL_CE_DST_RING_HP 0x00000400 -#define HAL_CE_DST_STATUS_RING_HP 0x00000408 - -/* REO status address */ -#define HAL_REO_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_status_ring_base) -#define HAL_REO_STATUS_HP 0x000030a8 - -/* WBM Idle R0 address */ -#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_idle_ring_base_lsb) -#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ - ((hal)->regs->hal_wbm_idle_ring_misc_addr) -#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) -#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_size_addr) -#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_lsb) -#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_msb) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) - -/* WBM Idle R2 address */ -#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 - -/* SW2WBM R0 release address */ -#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) -#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) - -/* SW2WBM R2 release address */ -#define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 -#define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 - -/* WBM2SW R0 release address */ -#define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm0_release_ring_base_lsb) - -#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm1_release_ring_base_lsb) - -/* WBM2SW R2 release address */ -#define HAL_WBM0_RELEASE_RING_HP 0x000030c8 -#define HAL_WBM1_RELEASE_RING_HP 0x000030d0 - -/* WBM cookie config address and mask */ -#define HAL_WBM_SW_COOKIE_CFG0 0x00000040 -#define HAL_WBM_SW_COOKIE_CFG1 0x00000044 -#define HAL_WBM_SW_COOKIE_CFG2 0x00000090 -#define HAL_WBM_SW_COOKIE_CONVERT_CFG 0x00000094 - -#define HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) -#define HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) -#define HAL_WBM_SW_COOKIE_CFG_ALIGN BIT(18) -#define HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN BIT(0) -#define HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN BIT(1) -#define HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN BIT(3) - -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN BIT(1) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN BIT(2) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN BIT(3) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN BIT(4) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN BIT(5) -#define HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN BIT(8) - -/* TCL ring field mask and offset */ -#define HAL_TCL1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) -#define HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_TCL1_RING_ID_ENTRY_SIZE GENMASK(7, 0) -#define HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE BIT(0) -#define HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE BIT(1) -#define HAL_TCL1_RING_MISC_MSI_SWAP BIT(3) -#define HAL_TCL1_RING_MISC_HOST_FW_SWAP BIT(4) -#define HAL_TCL1_RING_MISC_DATA_TLV_SWAP BIT(5) -#define HAL_TCL1_RING_MISC_SRNG_ENABLE BIT(6) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD GENMASK(31, 16) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD GENMASK(14, 0) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD GENMASK(15, 0) -#define HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) -#define HAL_TCL1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) -#define HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN BIT(23) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP GENMASK(31, 0) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP0 GENMASK(2, 0) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP1 GENMASK(5, 3) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP2 GENMASK(8, 6) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP3 GENMASK(11, 9) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP4 GENMASK(14, 12) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP5 GENMASK(17, 15) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP6 GENMASK(20, 18) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP7 GENMASK(23, 21) - -/* REO ring field mask and offset */ -#define HAL_REO1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) -#define HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_REO1_RING_ID_RING_ID GENMASK(15, 8) -#define HAL_REO1_RING_ID_ENTRY_SIZE GENMASK(7, 0) -#define HAL_REO1_RING_MISC_MSI_SWAP BIT(3) -#define HAL_REO1_RING_MISC_HOST_FW_SWAP BIT(4) -#define HAL_REO1_RING_MISC_DATA_TLV_SWAP BIT(5) -#define HAL_REO1_RING_MISC_SRNG_ENABLE BIT(6) -#define HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD GENMASK(31, 16) -#define HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD GENMASK(14, 0) -#define HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) -#define HAL_REO1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) -#define HAL_REO1_MISC_CTL_FRAG_DST_RING GENMASK(20, 17) -#define HAL_REO1_MISC_CTL_BAR_DST_RING GENMASK(24, 21) -#define HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE BIT(2) -#define HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE BIT(3) -#define HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) -#define HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) -#define HAL_REO1_SW_COOKIE_CFG_ALIGN BIT(18) -#define HAL_REO1_SW_COOKIE_CFG_ENABLE BIT(19) -#define HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE BIT(20) -#define HAL_REO_QDESC_ADDR_READ_LUT_ENABLE BIT(7) -#define HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY BIT(6) - -/* CE ring bit field mask and shift */ -#define HAL_CE_DST_R0_DEST_CTRL_MAX_LEN GENMASK(15, 0) - -#define HAL_ADDR_LSB_REG_MASK 0xffffffff - -#define HAL_ADDR_MSB_REG_SHIFT 32 - -/* WBM ring bit field mask and shift */ -#define HAL_WBM_LINK_DESC_IDLE_LIST_MODE BIT(1) -#define HAL_WBM_SCATTER_BUFFER_SIZE GENMASK(10, 2) -#define HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST GENMASK(31, 16) -#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32 GENMASK(7, 0) -#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG GENMASK(31, 8) - -#define HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1 GENMASK(20, 8) -#define HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1 GENMASK(20, 8) - -#define HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE BIT(6) -#define HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE BIT(0) - -#define BASE_ADDR_MATCH_TAG_VAL 0x5 - -#define HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_REO_CMD_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_CE_SRC_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_CE_DST_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff -#define HAL_RXDMA_RING_MAX_SIZE_BE 0x000fffff -#define HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff - -#define HAL_WBM2SW_REL_ERR_RING_NUM 3 -/* Add any other errors here and return them in - * ath12k_hal_rx_desc_get_err(). - */ - -#define HAL_IPQ5332_CE_WFSS_REG_BASE 0x740000 -#define HAL_IPQ5332_CE_SIZE 0x100000 - enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, @@ -637,11 +293,6 @@ enum hal_ring_type { HAL_MAX_RING_TYPES, }; -#define HAL_RX_MAX_BA_WINDOW 256 - -#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) -#define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000) - /** * enum hal_reo_cmd_type: Enum for REO command type * @HAL_REO_CMD_GET_QUEUE_STATS: Get REO queue status/stats @@ -1053,6 +704,90 @@ struct hal_rx_desc_data { u8 tid; }; +#define BUFFER_ADDR_INFO0_ADDR GENMASK(31, 0) + +#define BUFFER_ADDR_INFO1_ADDR GENMASK(7, 0) +#define BUFFER_ADDR_INFO1_RET_BUF_MGR GENMASK(11, 8) +#define BUFFER_ADDR_INFO1_SW_COOKIE GENMASK(31, 12) + +struct ath12k_buffer_addr { + __le32 info0; + __le32 info1; +} __packed; + +/* ath12k_buffer_addr + * + * buffer_addr_31_0 + * Address (lower 32 bits) of the MSDU buffer or MSDU_EXTENSION + * descriptor or Link descriptor + * + * buffer_addr_39_32 + * Address (upper 8 bits) of the MSDU buffer or MSDU_EXTENSION + * descriptor or Link descriptor + * + * return_buffer_manager (RBM) + * Consumer: WBM + * Producer: SW/FW + * Indicates to which buffer manager the buffer or MSDU_EXTENSION + * descriptor or link descriptor that is being pointed to shall be + * returned after the frame has been processed. It is used by WBM + * for routing purposes. + * + * Values are defined in enum %HAL_RX_BUF_RBM_ + * + * sw_buffer_cookie + * Cookie field exclusively used by SW. HW ignores the contents, + * accept that it passes the programmed value on to other + * descriptors together with the physical address. + * + * Field can be used by SW to for example associate the buffers + * physical address with the virtual address. + * + * NOTE1: + * The three most significant bits can have a special meaning + * in case this struct is embedded in a TX_MPDU_DETAILS STRUCT, + * and field transmit_bw_restriction is set + * + * In case of NON punctured transmission: + * Sw_buffer_cookie[19:17] = 3'b000: 20 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b001: 40 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b010: 80 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b011: 160 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b101: 240 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b100: 320 MHz TX only + * Sw_buffer_cookie[19:18] = 2'b11: reserved + * + * In case of punctured transmission: + * Sw_buffer_cookie[19:16] = 4'b0000: pattern 0 only + * Sw_buffer_cookie[19:16] = 4'b0001: pattern 1 only + * Sw_buffer_cookie[19:16] = 4'b0010: pattern 2 only + * Sw_buffer_cookie[19:16] = 4'b0011: pattern 3 only + * Sw_buffer_cookie[19:16] = 4'b0100: pattern 4 only + * Sw_buffer_cookie[19:16] = 4'b0101: pattern 5 only + * Sw_buffer_cookie[19:16] = 4'b0110: pattern 6 only + * Sw_buffer_cookie[19:16] = 4'b0111: pattern 7 only + * Sw_buffer_cookie[19:16] = 4'b1000: pattern 8 only + * Sw_buffer_cookie[19:16] = 4'b1001: pattern 9 only + * Sw_buffer_cookie[19:16] = 4'b1010: pattern 10 only + * Sw_buffer_cookie[19:16] = 4'b1011: pattern 11 only + * Sw_buffer_cookie[19:18] = 2'b11: reserved + * + * Note: a punctured transmission is indicated by the presence + * of TLV TX_PUNCTURE_SETUP embedded in the scheduler TLV + * + * Sw_buffer_cookie[20:17]: Tid: The TID field in the QoS control + * field + * + * Sw_buffer_cookie[16]: Mpdu_qos_control_valid: This field + * indicates MPDUs with a QoS control field. + * + */ + +struct hal_ce_srng_dest_desc; +struct hal_ce_srng_dst_status_desc; +struct hal_ce_srng_src_desc; +struct hal_wbm_link_desc; + /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 #define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010 @@ -1062,9 +797,6 @@ struct hal_rx_desc_data { #define HAL_SRNG_FLAGS_HIGH_THRESH_INTR_EN 0x00080000 #define HAL_SRNG_FLAGS_LMAC_RING 0x80000000 -#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) -#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) - /* Common SRNG ring structure for source and destination rings */ struct hal_srng { /* Unique SRNG ring ID */ @@ -1249,66 +981,6 @@ enum hal_rx_buf_return_buf_manager { HAL_RX_BUF_RBM_SW6_BM, }; -#define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 - -#define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) -#define HAL_REO_CMD_FLG_STATS_CLEAR BIT(1) -#define HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER BIT(2) -#define HAL_REO_CMD_FLG_FLUSH_RELEASE_BLOCKING BIT(3) -#define HAL_REO_CMD_FLG_FLUSH_NO_INVAL BIT(4) -#define HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS BIT(5) -#define HAL_REO_CMD_FLG_FLUSH_ALL BIT(6) -#define HAL_REO_CMD_FLG_UNBLK_RESOURCE BIT(7) -#define HAL_REO_CMD_FLG_UNBLK_CACHE BIT(8) -#define HAL_REO_CMD_FLG_FLUSH_QUEUE_1K_DESC BIT(9) - -/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO0_UPD_* fields */ -#define HAL_REO_CMD_UPD0_RX_QUEUE_NUM BIT(8) -#define HAL_REO_CMD_UPD0_VLD BIT(9) -#define HAL_REO_CMD_UPD0_ALDC BIT(10) -#define HAL_REO_CMD_UPD0_DIS_DUP_DETECTION BIT(11) -#define HAL_REO_CMD_UPD0_SOFT_REORDER_EN BIT(12) -#define HAL_REO_CMD_UPD0_AC BIT(13) -#define HAL_REO_CMD_UPD0_BAR BIT(14) -#define HAL_REO_CMD_UPD0_RETRY BIT(15) -#define HAL_REO_CMD_UPD0_CHECK_2K_MODE BIT(16) -#define HAL_REO_CMD_UPD0_OOR_MODE BIT(17) -#define HAL_REO_CMD_UPD0_BA_WINDOW_SIZE BIT(18) -#define HAL_REO_CMD_UPD0_PN_CHECK BIT(19) -#define HAL_REO_CMD_UPD0_EVEN_PN BIT(20) -#define HAL_REO_CMD_UPD0_UNEVEN_PN BIT(21) -#define HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE BIT(22) -#define HAL_REO_CMD_UPD0_PN_SIZE BIT(23) -#define HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG BIT(24) -#define HAL_REO_CMD_UPD0_SVLD BIT(25) -#define HAL_REO_CMD_UPD0_SSN BIT(26) -#define HAL_REO_CMD_UPD0_SEQ_2K_ERR BIT(27) -#define HAL_REO_CMD_UPD0_PN_ERR BIT(28) -#define HAL_REO_CMD_UPD0_PN_VALID BIT(29) -#define HAL_REO_CMD_UPD0_PN BIT(30) - -/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO1_* fields */ -#define HAL_REO_CMD_UPD1_VLD BIT(16) -#define HAL_REO_CMD_UPD1_ALDC GENMASK(18, 17) -#define HAL_REO_CMD_UPD1_DIS_DUP_DETECTION BIT(19) -#define HAL_REO_CMD_UPD1_SOFT_REORDER_EN BIT(20) -#define HAL_REO_CMD_UPD1_AC GENMASK(22, 21) -#define HAL_REO_CMD_UPD1_BAR BIT(23) -#define HAL_REO_CMD_UPD1_RETRY BIT(24) -#define HAL_REO_CMD_UPD1_CHECK_2K_MODE BIT(25) -#define HAL_REO_CMD_UPD1_OOR_MODE BIT(26) -#define HAL_REO_CMD_UPD1_PN_CHECK BIT(27) -#define HAL_REO_CMD_UPD1_EVEN_PN BIT(28) -#define HAL_REO_CMD_UPD1_UNEVEN_PN BIT(29) -#define HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE BIT(30) -#define HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG BIT(31) - -/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO2_* fields */ -#define HAL_REO_CMD_UPD2_SVLD BIT(10) -#define HAL_REO_CMD_UPD2_SSN GENMASK(22, 11) -#define HAL_REO_CMD_UPD2_SEQ_2K_ERR BIT(23) -#define HAL_REO_CMD_UPD2_PN_ERR BIT(24) - struct ath12k_hal_reo_cmd { u32 addr_lo; u32 flag; @@ -1354,93 +1026,6 @@ struct hal_reo_status_header { u32 timestamp; }; -struct hal_reo_status_queue_stats { - u16 ssn; - u16 curr_idx; - u32 pn[4]; - u32 last_rx_queue_ts; - u32 last_rx_dequeue_ts; - u32 rx_bitmap[8]; /* Bitmap from 0-255 */ - u32 curr_mpdu_cnt; - u32 curr_msdu_cnt; - u16 fwd_due_to_bar_cnt; - u16 dup_cnt; - u32 frames_in_order_cnt; - u32 num_mpdu_processed_cnt; - u32 num_msdu_processed_cnt; - u32 total_num_processed_byte_cnt; - u32 late_rx_mpdu_cnt; - u32 reorder_hole_cnt; - u8 timeout_cnt; - u8 bar_rx_cnt; - u8 num_window_2k_jump_cnt; -}; - -struct hal_reo_status_flush_queue { - bool err_detected; -}; - -enum hal_reo_status_flush_cache_err_code { - HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_SUCCESS, - HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_IN_USE, - HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_NOT_FOUND, -}; - -struct hal_reo_status_flush_cache { - bool err_detected; - enum hal_reo_status_flush_cache_err_code err_code; - bool cache_controller_flush_status_hit; - u8 cache_controller_flush_status_desc_type; - u8 cache_controller_flush_status_client_id; - u8 cache_controller_flush_status_err; - u8 cache_controller_flush_status_cnt; -}; - -enum hal_reo_status_unblock_cache_type { - HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE, - HAL_REO_STATUS_UNBLOCK_ENTIRE_CACHE_USAGE, -}; - -struct hal_reo_status_unblock_cache { - bool err_detected; - enum hal_reo_status_unblock_cache_type unblock_type; -}; - -struct hal_reo_status_flush_timeout_list { - bool err_detected; - bool list_empty; - u16 release_desc_cnt; - u16 fwd_buf_cnt; -}; - -enum hal_reo_threshold_idx { - HAL_REO_THRESHOLD_IDX_DESC_COUNTER0, - HAL_REO_THRESHOLD_IDX_DESC_COUNTER1, - HAL_REO_THRESHOLD_IDX_DESC_COUNTER2, - HAL_REO_THRESHOLD_IDX_DESC_COUNTER_SUM, -}; - -struct hal_reo_status_desc_thresh_reached { - enum hal_reo_threshold_idx threshold_idx; - u32 link_desc_counter0; - u32 link_desc_counter1; - u32 link_desc_counter2; - u32 link_desc_counter_sum; -}; - -struct hal_reo_status { - struct hal_reo_status_header uniform_hdr; - u8 loop_cnt; - union { - struct hal_reo_status_queue_stats queue_stats; - struct hal_reo_status_flush_queue flush_queue; - struct hal_reo_status_flush_cache flush_cache; - struct hal_reo_status_unblock_cache unblock_cache; - struct hal_reo_status_flush_timeout_list timeout_list; - struct hal_reo_status_desc_thresh_reached desc_thresh_reached; - } u; -}; - struct ath12k_hw_hal_params { enum hal_rx_buf_return_buf_manager rx_buf_rbm; u32 wbm2sw_cc_enable; @@ -1559,7 +1144,7 @@ struct ath12k_hal { u8 current_blk_index; /* shadow register configuration */ - u32 shadow_reg_addr[HAL_SHADOW_NUM_REGS]; + u32 shadow_reg_addr[HAL_SHADOW_NUM_REGS_MAX]; int num_shadow_reg_configured; u32 hal_desc_sz; @@ -1743,7 +1328,6 @@ struct hal_ops { (*get_idle_link_rbm)(struct ath12k_hal *hal, u8 device_id); }; -u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 6fb327157ecfe..a42c4289c6b27 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -15,7 +15,7 @@ #include "hif.h" #include "mhi.h" #include "debug.h" -#include "wifi7/dp.h" +#include "hal.h" #define ATH12K_PCI_BAR_NUM 0 #define ATH12K_PCI_DMA_MASK 36 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 06d3690ff0c63..976dfe1b90874 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -138,6 +138,7 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .service_srng = ath12k_wifi7_dp_service_srng, + .dp_tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config, }; /* TODO: remove export once this file is built with wifi7 ko */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index ece6a1311ef0c..5ecbbf548b056 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -8,6 +8,9 @@ #include "../core.h" #include "../dp_rx.h" +#include "hal_rx_desc.h" + +struct ath12k_hal_reo_cmd; int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index b3c0f8a6a5ce0..2f523ed00dedd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -9,6 +9,9 @@ #include "../dp_tx.h" #include "../peer.h" #include "dp_tx.h" +#include "hal_desc.h" +#include "hal.h" +#include "hal_tx.h" static void ath12k_wifi7_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, @@ -922,3 +925,52 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) rcu_read_unlock(); } } + +u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, + struct ath12k_link_vif *arvif) +{ + u32 bank_config = 0; + u8 link_id = arvif->link_id; + struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(dp_vif, link_id); + + /* Only valid for raw frames with HW crypto enabled. + * With SW crypto, mac80211 sets key per packet + */ + if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) + bank_config |= + u32_encode_bits(ath12k_dp_tx_get_encrypt_type(dp_vif->key_cipher), + HAL_TX_BANK_CONFIG_ENCRYPT_TYPE); + + bank_config |= u32_encode_bits(dp_vif->tx_encap_type, + HAL_TX_BANK_CONFIG_ENCAP_TYPE); + bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_SRC_BUFFER_SWAP) | + u32_encode_bits(0, HAL_TX_BANK_CONFIG_LINK_META_SWAP) | + u32_encode_bits(0, HAL_TX_BANK_CONFIG_EPD); + + /* only valid if idx_lookup_override is not set in tcl_data_cmd */ + if (ahvif->vdev_type == WMI_VDEV_TYPE_STA) + bank_config |= u32_encode_bits(1, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); + else + bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); + + bank_config |= u32_encode_bits(dp_link_vif->hal_addr_search_flags & + HAL_TX_ADDRX_EN, + HAL_TX_BANK_CONFIG_ADDRX_EN) | + u32_encode_bits(!!(dp_link_vif->hal_addr_search_flags & + HAL_TX_ADDRY_EN), + HAL_TX_BANK_CONFIG_ADDRY_EN); + + bank_config |= u32_encode_bits(ieee80211_vif_is_mesh(ahvif->vif) ? 3 : 0, + HAL_TX_BANK_CONFIG_MESH_EN) | + u32_encode_bits(dp_link_vif->vdev_id_check_en, + HAL_TX_BANK_CONFIG_VDEV_ID_CHECK_EN); + + bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID); + + return bank_config; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 524e23b8ed808..94a5c59289cca 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -11,4 +11,6 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, + struct ath12k_link_vif *arvif); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 4f9f1efbbfcf2..e42970346e3dd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -406,7 +406,7 @@ int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, int shadow_cfg_idx = hal->num_shadow_reg_configured; u32 target_reg; - if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) + if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS_MAX) return -EINVAL; hal->num_shadow_reg_configured++; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index b600b2e3cb78d..8a40b91764065 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -7,6 +7,517 @@ #ifndef ATH12K_HAL_WIFI7_H #define ATH12K_HAL_WIFI7_H +#include "../core.h" +#include "../hal.h" +#include "hal_desc.h" +#include "hal_tx.h" +#include "hal_rx.h" +#include "hal_rx_desc.h" + +/* calculate the register address from bar0 of shadow register x */ +#define HAL_SHADOW_BASE_ADDR 0x000008fc +#define HAL_SHADOW_NUM_REGS 40 +#define HAL_HP_OFFSET_IN_REG_START 1 +#define HAL_OFFSET_FROM_HP_TO_TP 4 + +#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x))) +#define HAL_REO_QDESC_MAX_PEERID 8191 + +/* WCSS Relative address */ +#define HAL_SEQ_WCSS_CMEM_OFFSET 0x00100000 +#define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 +#define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 +#define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 +#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce0_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce0_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce1_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce1_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 + +#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 + +#define HAL_TCL_SW_CONFIG_BANK_ADDR 0x00a4408c + +/* SW2TCL(x) R0 ring configuration address */ +#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 +#define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 + +#define HAL_TCL1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_lsb) +#define HAL_TCL1_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) +#define HAL_TCL1_RING_MISC(hal) \ + ((hal)->regs->hal_tcl1_ring_misc) +#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) +#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_msb) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) +#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) +#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_msb) +#define HAL_TCL1_RING_MSI1_DATA(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_data) +#define HAL_TCL2_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl2_ring_base_lsb) +#define HAL_TCL_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_ring_base_lsb) + +#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_DATA_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_DATA(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_ID_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_ID(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MISC_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MISC(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) + +/* SW2TCL(x) R2 ring pointers (head/tail) address */ +#define HAL_TCL1_RING_HP 0x00002000 +#define HAL_TCL1_RING_TP 0x00002004 +#define HAL_TCL2_RING_HP 0x00002008 +#define HAL_TCL_RING_HP 0x00002028 + +#define HAL_TCL1_RING_TP_OFFSET \ + (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) + +/* TCL STATUS ring address */ +#define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_status_ring_base_lsb) +#define HAL_TCL_STATUS_RING_HP 0x00002048 + +/* PPE2TCL1 Ring address */ +#define HAL_TCL_PPE2TCL1_RING_BASE_LSB 0x00000c48 +#define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 + +/* WBM PPE Release Ring address */ +#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_ppe_rel_ring_base) +#define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 + +/* REO2SW(x) R0 ring configuration address */ +#define HAL_REO1_GEN_ENABLE 0x00000000 +#define HAL_REO1_MISC_CTRL_ADDR(hal) \ + ((hal)->regs->hal_reo1_misc_ctrl_addr) +#define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 +#define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 +#define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c +#define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 +#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) +#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) +#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ + ((hal)->regs->hal_reo1_ring_producer_int_setup) +#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_lsb) +#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) + +/* REO2SW(x) R2 ring pointers (head/tail) address */ +#define HAL_REO1_RING_HP 0x00003048 +#define HAL_REO1_RING_TP 0x0000304c +#define HAL_REO2_RING_HP 0x00003050 + +#define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) + +/* REO2SW0 ring configuration address */ +#define HAL_REO_SW0_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo2_sw0_ring_base) + +/* REO2SW0 R2 ring pointer (head/tail) address */ +#define HAL_REO_SW0_RING_HP 0x00003088 + +/* REO CMD R0 address */ +#define HAL_REO_CMD_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_cmd_ring_base) + +/* REO CMD R2 address */ +#define HAL_REO_CMD_HP 0x00003020 + +/* SW2REO R0 address */ +#define HAL_SW2REO_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo_ring_base) +#define HAL_SW2REO1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo1_ring_base) + +/* SW2REO R2 address */ +#define HAL_SW2REO_RING_HP 0x00003028 +#define HAL_SW2REO1_RING_HP 0x00003030 + +/* CE ring R0 address */ +#define HAL_CE_SRC_RING_BASE_LSB 0x00000000 +#define HAL_CE_DST_RING_BASE_LSB 0x00000000 +#define HAL_CE_DST_STATUS_RING_BASE_LSB 0x00000058 +#define HAL_CE_DST_RING_CTRL 0x000000b0 + +/* CE ring R2 address */ +#define HAL_CE_DST_RING_HP 0x00000400 +#define HAL_CE_DST_STATUS_RING_HP 0x00000408 + +/* REO status address */ +#define HAL_REO_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_status_ring_base) +#define HAL_REO_STATUS_HP 0x000030a8 + +/* WBM Idle R0 address */ +#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_idle_ring_base_lsb) +#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ + ((hal)->regs->hal_wbm_idle_ring_misc_addr) +#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) +#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_size_addr) +#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_lsb) +#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_msb) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) + +/* WBM Idle R2 address */ +#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 + +/* SW2WBM R0 release address */ +#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) +#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) + +/* SW2WBM R2 release address */ +#define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 +#define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 + +/* WBM2SW R0 release address */ +#define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm0_release_ring_base_lsb) + +#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm1_release_ring_base_lsb) + +/* WBM2SW R2 release address */ +#define HAL_WBM0_RELEASE_RING_HP 0x000030c8 +#define HAL_WBM1_RELEASE_RING_HP 0x000030d0 + +/* WBM cookie config address and mask */ +#define HAL_WBM_SW_COOKIE_CFG0 0x00000040 +#define HAL_WBM_SW_COOKIE_CFG1 0x00000044 +#define HAL_WBM_SW_COOKIE_CFG2 0x00000090 +#define HAL_WBM_SW_COOKIE_CONVERT_CFG 0x00000094 + +#define HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) +#define HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) +#define HAL_WBM_SW_COOKIE_CFG_ALIGN BIT(18) +#define HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN BIT(0) +#define HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN BIT(1) +#define HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN BIT(3) + +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN BIT(1) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN BIT(2) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN BIT(3) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN BIT(4) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN BIT(5) +#define HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN BIT(8) + +/* TCL ring field mask and offset */ +#define HAL_TCL1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) +#define HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_TCL1_RING_ID_ENTRY_SIZE GENMASK(7, 0) +#define HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE BIT(0) +#define HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE BIT(1) +#define HAL_TCL1_RING_MISC_MSI_SWAP BIT(3) +#define HAL_TCL1_RING_MISC_HOST_FW_SWAP BIT(4) +#define HAL_TCL1_RING_MISC_DATA_TLV_SWAP BIT(5) +#define HAL_TCL1_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD GENMASK(31, 16) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD GENMASK(14, 0) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD GENMASK(15, 0) +#define HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) +#define HAL_TCL1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) +#define HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN BIT(23) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP GENMASK(31, 0) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP0 GENMASK(2, 0) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP1 GENMASK(5, 3) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP2 GENMASK(8, 6) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP3 GENMASK(11, 9) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP4 GENMASK(14, 12) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP5 GENMASK(17, 15) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP6 GENMASK(20, 18) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP7 GENMASK(23, 21) + +/* REO ring field mask and offset */ +#define HAL_REO1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) +#define HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_REO1_RING_ID_RING_ID GENMASK(15, 8) +#define HAL_REO1_RING_ID_ENTRY_SIZE GENMASK(7, 0) +#define HAL_REO1_RING_MISC_MSI_SWAP BIT(3) +#define HAL_REO1_RING_MISC_HOST_FW_SWAP BIT(4) +#define HAL_REO1_RING_MISC_DATA_TLV_SWAP BIT(5) +#define HAL_REO1_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD GENMASK(31, 16) +#define HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD GENMASK(14, 0) +#define HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) +#define HAL_REO1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) +#define HAL_REO1_MISC_CTL_FRAG_DST_RING GENMASK(20, 17) +#define HAL_REO1_MISC_CTL_BAR_DST_RING GENMASK(24, 21) +#define HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE BIT(2) +#define HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE BIT(3) +#define HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) +#define HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) +#define HAL_REO1_SW_COOKIE_CFG_ALIGN BIT(18) +#define HAL_REO1_SW_COOKIE_CFG_ENABLE BIT(19) +#define HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE BIT(20) +#define HAL_REO_QDESC_ADDR_READ_LUT_ENABLE BIT(7) +#define HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY BIT(6) + +/* CE ring bit field mask and shift */ +#define HAL_CE_DST_R0_DEST_CTRL_MAX_LEN GENMASK(15, 0) + +#define HAL_ADDR_LSB_REG_MASK 0xffffffff + +#define HAL_ADDR_MSB_REG_SHIFT 32 + +/* WBM ring bit field mask and shift */ +#define HAL_WBM_LINK_DESC_IDLE_LIST_MODE BIT(1) +#define HAL_WBM_SCATTER_BUFFER_SIZE GENMASK(10, 2) +#define HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST GENMASK(31, 16) +#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32 GENMASK(7, 0) +#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG GENMASK(31, 8) + +#define HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1 GENMASK(20, 8) +#define HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1 GENMASK(20, 8) + +#define HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE BIT(0) + +#define BASE_ADDR_MATCH_TAG_VAL 0x5 + +#define HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_REO_CMD_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_CE_SRC_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_CE_DST_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff +#define HAL_RXDMA_RING_MAX_SIZE_BE 0x000fffff +#define HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff + +#define HAL_WBM2SW_REL_ERR_RING_NUM 3 +/* Add any other errors here and return them in + * ath12k_hal_rx_desc_get_err(). + */ + +#define HAL_IPQ5332_CE_WFSS_REG_BASE 0x740000 +#define HAL_IPQ5332_CE_SIZE 0x100000 + +#define HAL_RX_MAX_BA_WINDOW 256 + +#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) +#define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000) + +#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) +#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) + +#define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 + +#define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) +#define HAL_REO_CMD_FLG_STATS_CLEAR BIT(1) +#define HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER BIT(2) +#define HAL_REO_CMD_FLG_FLUSH_RELEASE_BLOCKING BIT(3) +#define HAL_REO_CMD_FLG_FLUSH_NO_INVAL BIT(4) +#define HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS BIT(5) +#define HAL_REO_CMD_FLG_FLUSH_ALL BIT(6) +#define HAL_REO_CMD_FLG_UNBLK_RESOURCE BIT(7) +#define HAL_REO_CMD_FLG_UNBLK_CACHE BIT(8) + +/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO0_UPD_* fields */ +#define HAL_REO_CMD_UPD0_RX_QUEUE_NUM BIT(8) +#define HAL_REO_CMD_UPD0_VLD BIT(9) +#define HAL_REO_CMD_UPD0_ALDC BIT(10) +#define HAL_REO_CMD_UPD0_DIS_DUP_DETECTION BIT(11) +#define HAL_REO_CMD_UPD0_SOFT_REORDER_EN BIT(12) +#define HAL_REO_CMD_UPD0_AC BIT(13) +#define HAL_REO_CMD_UPD0_BAR BIT(14) +#define HAL_REO_CMD_UPD0_RETRY BIT(15) +#define HAL_REO_CMD_UPD0_CHECK_2K_MODE BIT(16) +#define HAL_REO_CMD_UPD0_OOR_MODE BIT(17) +#define HAL_REO_CMD_UPD0_BA_WINDOW_SIZE BIT(18) +#define HAL_REO_CMD_UPD0_PN_CHECK BIT(19) +#define HAL_REO_CMD_UPD0_EVEN_PN BIT(20) +#define HAL_REO_CMD_UPD0_UNEVEN_PN BIT(21) +#define HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE BIT(22) +#define HAL_REO_CMD_UPD0_PN_SIZE BIT(23) +#define HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG BIT(24) +#define HAL_REO_CMD_UPD0_SVLD BIT(25) +#define HAL_REO_CMD_UPD0_SSN BIT(26) +#define HAL_REO_CMD_UPD0_SEQ_2K_ERR BIT(27) +#define HAL_REO_CMD_UPD0_PN_ERR BIT(28) +#define HAL_REO_CMD_UPD0_PN_VALID BIT(29) +#define HAL_REO_CMD_UPD0_PN BIT(30) + +/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO1_* fields */ +#define HAL_REO_CMD_UPD1_VLD BIT(16) +#define HAL_REO_CMD_UPD1_ALDC GENMASK(18, 17) +#define HAL_REO_CMD_UPD1_DIS_DUP_DETECTION BIT(19) +#define HAL_REO_CMD_UPD1_SOFT_REORDER_EN BIT(20) +#define HAL_REO_CMD_UPD1_AC GENMASK(22, 21) +#define HAL_REO_CMD_UPD1_BAR BIT(23) +#define HAL_REO_CMD_UPD1_RETRY BIT(24) +#define HAL_REO_CMD_UPD1_CHECK_2K_MODE BIT(25) +#define HAL_REO_CMD_UPD1_OOR_MODE BIT(26) +#define HAL_REO_CMD_UPD1_PN_CHECK BIT(27) +#define HAL_REO_CMD_UPD1_EVEN_PN BIT(28) +#define HAL_REO_CMD_UPD1_UNEVEN_PN BIT(29) +#define HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE BIT(30) +#define HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG BIT(31) + +/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO2_* fields */ +#define HAL_REO_CMD_UPD2_SVLD BIT(10) +#define HAL_REO_CMD_UPD2_SSN GENMASK(22, 11) +#define HAL_REO_CMD_UPD2_SEQ_2K_ERR BIT(23) +#define HAL_REO_CMD_UPD2_PN_ERR BIT(24) + +struct hal_reo_status_queue_stats { + u16 ssn; + u16 curr_idx; + u32 pn[4]; + u32 last_rx_queue_ts; + u32 last_rx_dequeue_ts; + u32 rx_bitmap[8]; /* Bitmap from 0-255 */ + u32 curr_mpdu_cnt; + u32 curr_msdu_cnt; + u16 fwd_due_to_bar_cnt; + u16 dup_cnt; + u32 frames_in_order_cnt; + u32 num_mpdu_processed_cnt; + u32 num_msdu_processed_cnt; + u32 total_num_processed_byte_cnt; + u32 late_rx_mpdu_cnt; + u32 reorder_hole_cnt; + u8 timeout_cnt; + u8 bar_rx_cnt; + u8 num_window_2k_jump_cnt; +}; + +struct hal_reo_status_flush_queue { + bool err_detected; +}; + +enum hal_reo_status_flush_cache_err_code { + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_SUCCESS, + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_IN_USE, + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_NOT_FOUND, +}; + +struct hal_reo_status_flush_cache { + bool err_detected; + enum hal_reo_status_flush_cache_err_code err_code; + bool cache_controller_flush_status_hit; + u8 cache_controller_flush_status_desc_type; + u8 cache_controller_flush_status_client_id; + u8 cache_controller_flush_status_err; + u8 cache_controller_flush_status_cnt; +}; + +enum hal_reo_status_unblock_cache_type { + HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE, + HAL_REO_STATUS_UNBLOCK_ENTIRE_CACHE_USAGE, +}; + +struct hal_reo_status_unblock_cache { + bool err_detected; + enum hal_reo_status_unblock_cache_type unblock_type; +}; + +struct hal_reo_status_flush_timeout_list { + bool err_detected; + bool list_empty; + u16 release_desc_cnt; + u16 fwd_buf_cnt; +}; + +enum hal_reo_threshold_idx { + HAL_REO_THRESHOLD_IDX_DESC_COUNTER0, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER1, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER2, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER_SUM, +}; + +struct hal_reo_status_desc_thresh_reached { + enum hal_reo_threshold_idx threshold_idx; + u32 link_desc_counter0; + u32 link_desc_counter1; + u32 link_desc_counter2; + u32 link_desc_counter_sum; +}; + +struct hal_reo_status { + struct hal_reo_status_header uniform_hdr; + u8 loop_cnt; + union { + struct hal_reo_status_queue_stats queue_stats; + struct hal_reo_status_flush_queue flush_queue; + struct hal_reo_status_flush_cache flush_cache; + struct hal_reo_status_unblock_cache unblock_cache; + struct hal_reo_status_flush_timeout_list timeout_list; + struct hal_reo_status_desc_thresh_reached desc_thresh_reached; + } u; +}; + int ath12k_wifi7_hal_init(struct ath12k_base *ab); void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, struct hal_srng *srng, int ring_num); @@ -48,4 +559,5 @@ void ath12k_wifi7_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); +u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index b884f4f089387..57940d7ffba48 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -8,85 +8,6 @@ #ifndef ATH12K_HAL_DESC_H #define ATH12K_HAL_DESC_H -#define BUFFER_ADDR_INFO0_ADDR GENMASK(31, 0) - -#define BUFFER_ADDR_INFO1_ADDR GENMASK(7, 0) -#define BUFFER_ADDR_INFO1_RET_BUF_MGR GENMASK(11, 8) -#define BUFFER_ADDR_INFO1_SW_COOKIE GENMASK(31, 12) - -struct ath12k_buffer_addr { - __le32 info0; - __le32 info1; -} __packed; - -/* ath12k_buffer_addr - * - * buffer_addr_31_0 - * Address (lower 32 bits) of the MSDU buffer or MSDU_EXTENSION - * descriptor or Link descriptor - * - * buffer_addr_39_32 - * Address (upper 8 bits) of the MSDU buffer or MSDU_EXTENSION - * descriptor or Link descriptor - * - * return_buffer_manager (RBM) - * Consumer: WBM - * Producer: SW/FW - * Indicates to which buffer manager the buffer or MSDU_EXTENSION - * descriptor or link descriptor that is being pointed to shall be - * returned after the frame has been processed. It is used by WBM - * for routing purposes. - * - * Values are defined in enum %HAL_RX_BUF_RBM_ - * - * sw_buffer_cookie - * Cookie field exclusively used by SW. HW ignores the contents, - * accept that it passes the programmed value on to other - * descriptors together with the physical address. - * - * Field can be used by SW to for example associate the buffers - * physical address with the virtual address. - * - * NOTE1: - * The three most significant bits can have a special meaning - * in case this struct is embedded in a TX_MPDU_DETAILS STRUCT, - * and field transmit_bw_restriction is set - * - * In case of NON punctured transmission: - * Sw_buffer_cookie[19:17] = 3'b000: 20 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b001: 40 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b010: 80 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b011: 160 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b101: 240 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b100: 320 MHz TX only - * Sw_buffer_cookie[19:18] = 2'b11: reserved - * - * In case of punctured transmission: - * Sw_buffer_cookie[19:16] = 4'b0000: pattern 0 only - * Sw_buffer_cookie[19:16] = 4'b0001: pattern 1 only - * Sw_buffer_cookie[19:16] = 4'b0010: pattern 2 only - * Sw_buffer_cookie[19:16] = 4'b0011: pattern 3 only - * Sw_buffer_cookie[19:16] = 4'b0100: pattern 4 only - * Sw_buffer_cookie[19:16] = 4'b0101: pattern 5 only - * Sw_buffer_cookie[19:16] = 4'b0110: pattern 6 only - * Sw_buffer_cookie[19:16] = 4'b0111: pattern 7 only - * Sw_buffer_cookie[19:16] = 4'b1000: pattern 8 only - * Sw_buffer_cookie[19:16] = 4'b1001: pattern 9 only - * Sw_buffer_cookie[19:16] = 4'b1010: pattern 10 only - * Sw_buffer_cookie[19:16] = 4'b1011: pattern 11 only - * Sw_buffer_cookie[19:18] = 2'b11: reserved - * - * Note: a punctured transmission is indicated by the presence - * of TLV TX_PUNCTURE_SETUP embedded in the scheduler TLV - * - * Sw_buffer_cookie[20:17]: Tid: The TID field in the QoS control - * field - * - * Sw_buffer_cookie[16]: Mpdu_qos_control_valid: This field - * indicates MPDUs with a QoS control field. - * - */ - enum hal_tlv_tag { HAL_MACTX_CBF_START = 0 /* 0x0 */, HAL_PHYRX_DATA = 1 /* 0x1 */, @@ -1863,7 +1784,6 @@ struct hal_wbm_release_ring_cc_rx { #define HAL_WBM_RELEASE_INFO3_CONTINUATION BIT(2) #define HAL_WBM_RELEASE_INFO5_LOOPING_COUNT GENMASK(31, 28) -#define HAL_ENCRYPT_TYPE_MAX 12 struct hal_wbm_release_ring { struct ath12k_buffer_addr buf_addr_info; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index c48dd029f52ee..08c0a04694741 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -11,6 +11,7 @@ #include #include "../hal.h" #include "hal_rx.h" +#include "hal.h" extern const struct hal_ops hal_qcn9274_ops; extern const struct ath12k_hw_regs qcn9274_v1_regs; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 0c00793bbfbb4..d9eaf9f66634d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -10,6 +10,7 @@ #include "hal_tx.h" #include "hal_rx.h" #include "hal_desc.h" +#include "hal.h" static void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index a029ea3fe93c6..d6f33fcd2e961 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -7,6 +7,10 @@ #ifndef ATH12K_HAL_RX_H #define ATH12K_HAL_RX_H +#include "hal_desc.h" + +struct hal_reo_status; + struct hal_rx_wbm_rel_info { u32 cookie; enum hal_wbm_rel_src_module err_rel_src; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 24f905c5b0624..02d3cadf03fea 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -4,10 +4,10 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "hal_desc.h" #include "../hal.h" #include "hal_tx.h" #include "../hif.h" +#include "hal.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index 07392b31d0ab9..9d2b1552c2f51 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -7,8 +7,8 @@ #ifndef ATH12K_HAL_TX_H #define ATH12K_HAL_TX_H +#include "../mac.h" #include "hal_desc.h" -#include "../core.h" /* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */ struct hal_tx_info { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 7d0b0c9854468..46047fd6a3127 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -9,6 +9,7 @@ #include "../hal.h" #include "hal_rx.h" +#include "hal.h" extern const struct hal_ops hal_wcn7850_ops; extern const struct ath12k_hw_regs wcn7850_regs; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index f6dfdcf95025a..dedc88858bb0f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -15,6 +15,7 @@ #include "../hal.h" #include "dp.h" #include "core.h" +#include "hal.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 From 66485758f021573fc97beaf3dc08c3f991d0fbe0 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:43 +0530 Subject: [PATCH 431/659] wifi: ath12k: Remove the unused ring inits in wcn Remove the initialization for the following rings in wcn as these rings are not used for wcn chips. HAL_RXDMA_MONITOR_BUF HAL_PPE2TCL HAL_PPE_RELEASE HAL_TX_MONITOR_BUF HAL_RXDMA_MONITOR_DST HAL_TX_MONITOR_DST Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-17-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 54 +++---------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 233350ccd06e4..8151c216a5e1b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -146,14 +146,7 @@ static const struct hal_srng_config hw_srng_config_template[] = { .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - [HAL_RXDMA_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, + [HAL_RXDMA_MONITOR_BUF] = {}, [HAL_RXDMA_MONITOR_STATUS] = { .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, .max_rings = 1, @@ -171,46 +164,11 @@ static const struct hal_srng_config hw_srng_config_template[] = { .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - [HAL_PPE2TCL] = { - .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, - .max_rings = 1, - .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_PPE_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TX_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_TX_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - } + [HAL_PPE2TCL] = {}, + [HAL_PPE_RELEASE] = {}, + [HAL_TX_MONITOR_BUF] = {}, + [HAL_RXDMA_MONITOR_DST] = {}, + [HAL_TX_MONITOR_DST] = {} }; const struct ath12k_hw_regs wcn7850_regs = { From e7f1a28af4b984df76838b1341b6d32952b83907 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Thu, 9 Oct 2025 16:40:44 +0530 Subject: [PATCH 432/659] wifi: ath12k: Rename hal_ops to ops Rename the hal_ops member in the HAL context to ops. The prefix is dropped to avoid redundancy, as the structure already resides within the HAL context. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-18-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 16 +++--- drivers/net/wireless/ath/ath12k/hal.c | 50 +++++++++---------- drivers/net/wireless/ath/ath12k/hal.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 2 +- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index c380c631eb09f..8cb244de80fd4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2082,7 +2082,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)head_msdu->data; hdr_desc = - ab->hal.hal_ops->rx_desc_get_msdu_payload(rx_desc); + ab->hal.ops->rx_desc_get_msdu_payload(rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 9b0ed9142a8be..1a97264f0328f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -122,27 +122,27 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal.hal_ops->rx_desc_get_l3_pad_bytes(desc); + return ab->hal.ops->rx_desc_get_l3_pad_bytes(desc); } static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hal.hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); + ab->hal.ops->rx_desc_copy_end_tlv(fdesc, ldesc); } static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, struct hal_rx_desc *desc, u16 len) { - ab->hal.hal_ops->rx_desc_set_msdu_len(desc, len); + ab->hal.ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc) { - return ab->hal.hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); + return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, @@ -150,7 +150,7 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, { u32 tlv_tag; - tlv_tag = ab->hal.hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); return tlv_tag == HAL_RX_MPDU_START; } @@ -159,7 +159,7 @@ static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hal.hal_ops->rx_desc_get_dot11_hdr(desc, hdr); + ab->hal.ops->rx_desc_get_dot11_hdr(desc, hdr); } static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, @@ -167,13 +167,13 @@ static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hal.hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + ab->hal.ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal.hal_ops->rx_desc_get_msdu_src_link_id(desc); + return ab->hal.ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 296bd7824ae2d..3f9c2183c9a69 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -10,76 +10,76 @@ static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, struct hal_srng *srng, int ring_num) { - ab->hal.hal_ops->ce_dst_setup(ab, srng, ring_num); + ab->hal.ops->ce_dst_setup(ab, srng, ring_num); } static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->srng_src_hw_init(ab, srng); + ab->hal.ops->srng_src_hw_init(ab, srng); } static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->srng_dst_hw_init(ab, srng); + ab->hal.ops->srng_dst_hw_init(ab, srng); } static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); + ab->hal.ops->set_umac_srng_ptr_addr(ab, srng); } static int ath12k_hal_srng_get_ring_id(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id) { - return hal->hal_ops->srng_get_ring_id(hal, type, ring_num, mac_id); + return hal->ops->srng_get_ring_id(hal, type, ring_num, mac_id); } int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, enum hal_ring_type ring_type, int ring_num) { - return ab->hal.hal_ops->srng_update_shadow_config(ab, ring_type, + return ab->hal.ops->srng_update_shadow_config(ab, ring_type, ring_num); } u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type) { - return hal->hal_ops->ce_get_desc_size(type); + return hal->ops->ce_get_desc_size(type); } void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) { - ab->hal.hal_ops->tx_set_dscp_tid_map(ab, id); + ab->hal.ops->tx_set_dscp_tid_map(ab, id); } void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, u32 bank_config, u8 bank_id) { - ab->hal.hal_ops->tx_configure_bank_register(ab, bank_config, bank_id); + ab->hal.ops->tx_configure_bank_register(ab, bank_config, bank_id); } void ath12k_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab) { - ab->hal.hal_ops->reoq_lut_addr_read_enable(ab); + ab->hal.ops->reoq_lut_addr_read_enable(ab); } void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab) { - ab->hal.hal_ops->reoq_lut_set_max_peerid(ab); + ab->hal.ops->reoq_lut_set_max_peerid(ab); } void ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) { - ab->hal.hal_ops->write_ml_reoq_lut_addr(ab, paddr); + ab->hal.ops->write_ml_reoq_lut_addr(ab, paddr); } void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) { - ab->hal.hal_ops->write_reoq_lut_addr(ab, paddr); + ab->hal.ops->write_reoq_lut_addr(ab, paddr); } void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, @@ -87,25 +87,25 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32 nsbufs, u32 tot_link_desc, u32 end_offset) { - ab->hal.hal_ops->setup_link_idle_list(ab, sbuf, nsbufs, tot_link_desc, + ab->hal.ops->setup_link_idle_list(ab, sbuf, nsbufs, tot_link_desc, end_offset); } void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { - ab->hal.hal_ops->reo_hw_setup(ab, ring_hash_map); + ab->hal.ops->reo_hw_setup(ab, ring_hash_map); } void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->reo_init_cmd_ring(ab, srng); + ab->hal.ops->reo_init_cmd_ring(ab, srng); } void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, struct ath12k_buffer_addr *binfo, dma_addr_t paddr, u32 cookie, u8 manager) { - hal->hal_ops->rx_buf_addr_info_set(binfo, paddr, cookie, manager); + hal->ops->rx_buf_addr_info_set(binfo, paddr, cookie, manager); } void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, @@ -113,18 +113,18 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, dma_addr_t *paddr, u32 *msdu_cookies, u8 *rbm) { - hal->hal_ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); + hal->ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); } void ath12k_hal_cc_config(struct ath12k_base *ab) { - ab->hal.hal_ops->cc_config(ab); + ab->hal.ops->cc_config(ab); } enum hal_rx_buf_return_buf_manager ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id) { - return hal->hal_ops->get_idle_link_rbm(hal, device_id); + return hal->ops->get_idle_link_rbm(hal, device_id); } static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) @@ -266,27 +266,27 @@ void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, dma_addr_t paddr, u32 len, u32 id, u8 byte_swap_data) { - hal->hal_ops->ce_src_set_desc(desc, paddr, len, id, byte_swap_data); + hal->ops->ce_src_set_desc(desc, paddr, len, id, byte_swap_data); } void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr) { - hal->hal_ops->ce_dst_set_desc(desc, paddr); + hal->ops->ce_dst_set_desc(desc, paddr); } u32 ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, struct hal_ce_srng_dst_status_desc *desc) { - return hal->hal_ops->ce_dst_status_get_length(desc); + return hal->ops->ce_dst_status_get_length(desc); } void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, int rbm) { - hal->hal_ops->set_link_desc_addr(desc, cookie, paddr, rbm); + hal->ops->set_link_desc_addr(desc, cookie, paddr, rbm); } void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) @@ -702,7 +702,7 @@ int ath12k_hal_srng_init(struct ath12k_base *ab) struct ath12k_hal *hal = &ab->hal; int ret; - ret = hal->hal_ops->create_srng_config(hal); + ret = hal->ops->create_srng_config(hal); if (ret) goto err_hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 63ad67318b0e5..68c873a1f454c 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1135,7 +1135,7 @@ struct ath12k_hal { } wrp; struct device *dev; - const struct hal_ops *hal_ops; + const struct hal_ops *ops; const struct ath12k_hw_regs *regs; const struct ath12k_hw_hal_params *hal_params; /* Available REO blocking resources bitmap */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 5ecbbf548b056..df25164e08f24 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -53,6 +53,6 @@ void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc) { - ab->hal.hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); + ab->hal.ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); } #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index e42970346e3dd..84c0ba2d1fbe9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -50,7 +50,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) memset(hal, 0, sizeof(*hal)); - hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; + hal->ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; hal->regs = ath12k_wifi7_hw_ver_map[ab->hw_rev].hw_regs; From 6cc24a6dfb1d7c8f75dc70b54091a88e4fcc409f Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Thu, 9 Oct 2025 16:40:45 +0530 Subject: [PATCH 433/659] wifi: ath12k: Drop hal_ prefix from hardware register names Remove the hal_ prefix from hardware register names in ath12k_hw_regs as the registers have been moved from ab->regs to hal->regs. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-19-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.h | 142 +++---- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 122 +++--- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 360 +++++++++--------- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 122 +++--- 4 files changed, 373 insertions(+), 373 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 68c873a1f454c..dbf07c15481b8 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1032,81 +1032,81 @@ struct ath12k_hw_hal_params { }; struct ath12k_hw_regs { - u32 hal_tcl1_ring_id; - u32 hal_tcl1_ring_misc; - u32 hal_tcl1_ring_tp_addr_lsb; - u32 hal_tcl1_ring_tp_addr_msb; - u32 hal_tcl1_ring_consumer_int_setup_ix0; - u32 hal_tcl1_ring_consumer_int_setup_ix1; - u32 hal_tcl1_ring_msi1_base_lsb; - u32 hal_tcl1_ring_msi1_base_msb; - u32 hal_tcl1_ring_msi1_data; - u32 hal_tcl_ring_base_lsb; - u32 hal_tcl1_ring_base_lsb; - u32 hal_tcl1_ring_base_msb; - u32 hal_tcl2_ring_base_lsb; - - u32 hal_tcl_status_ring_base_lsb; - - u32 hal_reo1_qdesc_addr; - u32 hal_reo1_qdesc_max_peerid; - - u32 hal_wbm_idle_ring_base_lsb; - u32 hal_wbm_idle_ring_misc_addr; - u32 hal_wbm_r0_idle_list_cntl_addr; - u32 hal_wbm_r0_idle_list_size_addr; - u32 hal_wbm_scattered_ring_base_lsb; - u32 hal_wbm_scattered_ring_base_msb; - u32 hal_wbm_scattered_desc_head_info_ix0; - u32 hal_wbm_scattered_desc_head_info_ix1; - u32 hal_wbm_scattered_desc_tail_info_ix0; - u32 hal_wbm_scattered_desc_tail_info_ix1; - u32 hal_wbm_scattered_desc_ptr_hp_addr; - - u32 hal_wbm_sw_release_ring_base_lsb; - u32 hal_wbm_sw1_release_ring_base_lsb; - u32 hal_wbm0_release_ring_base_lsb; - u32 hal_wbm1_release_ring_base_lsb; + u32 tcl1_ring_id; + u32 tcl1_ring_misc; + u32 tcl1_ring_tp_addr_lsb; + u32 tcl1_ring_tp_addr_msb; + u32 tcl1_ring_consumer_int_setup_ix0; + u32 tcl1_ring_consumer_int_setup_ix1; + u32 tcl1_ring_msi1_base_lsb; + u32 tcl1_ring_msi1_base_msb; + u32 tcl1_ring_msi1_data; + u32 tcl_ring_base_lsb; + u32 tcl1_ring_base_lsb; + u32 tcl1_ring_base_msb; + u32 tcl2_ring_base_lsb; + + u32 tcl_status_ring_base_lsb; + + u32 reo1_qdesc_addr; + u32 reo1_qdesc_max_peerid; + + u32 wbm_idle_ring_base_lsb; + u32 wbm_idle_ring_misc_addr; + u32 wbm_r0_idle_list_cntl_addr; + u32 wbm_r0_idle_list_size_addr; + u32 wbm_scattered_ring_base_lsb; + u32 wbm_scattered_ring_base_msb; + u32 wbm_scattered_desc_head_info_ix0; + u32 wbm_scattered_desc_head_info_ix1; + u32 wbm_scattered_desc_tail_info_ix0; + u32 wbm_scattered_desc_tail_info_ix1; + u32 wbm_scattered_desc_ptr_hp_addr; + + u32 wbm_sw_release_ring_base_lsb; + u32 wbm_sw1_release_ring_base_lsb; + u32 wbm0_release_ring_base_lsb; + u32 wbm1_release_ring_base_lsb; u32 pcie_qserdes_sysclk_en_sel; u32 pcie_pcs_osc_dtct_config_base; - u32 hal_umac_ce0_src_reg_base; - u32 hal_umac_ce0_dest_reg_base; - u32 hal_umac_ce1_src_reg_base; - u32 hal_umac_ce1_dest_reg_base; - - u32 hal_ppe_rel_ring_base; - - u32 hal_reo2_ring_base; - u32 hal_reo1_misc_ctrl_addr; - u32 hal_reo1_sw_cookie_cfg0; - u32 hal_reo1_sw_cookie_cfg1; - u32 hal_reo1_qdesc_lut_base0; - u32 hal_reo1_qdesc_lut_base1; - u32 hal_reo1_ring_base_lsb; - u32 hal_reo1_ring_base_msb; - u32 hal_reo1_ring_id; - u32 hal_reo1_ring_misc; - u32 hal_reo1_ring_hp_addr_lsb; - u32 hal_reo1_ring_hp_addr_msb; - u32 hal_reo1_ring_producer_int_setup; - u32 hal_reo1_ring_msi1_base_lsb; - u32 hal_reo1_ring_msi1_base_msb; - u32 hal_reo1_ring_msi1_data; - u32 hal_reo1_aging_thres_ix0; - u32 hal_reo1_aging_thres_ix1; - u32 hal_reo1_aging_thres_ix2; - u32 hal_reo1_aging_thres_ix3; - - u32 hal_reo2_sw0_ring_base; - - u32 hal_sw2reo_ring_base; - u32 hal_sw2reo1_ring_base; - - u32 hal_reo_cmd_ring_base; - - u32 hal_reo_status_ring_base; + u32 umac_ce0_src_reg_base; + u32 umac_ce0_dest_reg_base; + u32 umac_ce1_src_reg_base; + u32 umac_ce1_dest_reg_base; + + u32 ppe_rel_ring_base; + + u32 reo2_ring_base; + u32 reo1_misc_ctrl_addr; + u32 reo1_sw_cookie_cfg0; + u32 reo1_sw_cookie_cfg1; + u32 reo1_qdesc_lut_base0; + u32 reo1_qdesc_lut_base1; + u32 reo1_ring_base_lsb; + u32 reo1_ring_base_msb; + u32 reo1_ring_id; + u32 reo1_ring_misc; + u32 reo1_ring_hp_addr_lsb; + u32 reo1_ring_hp_addr_msb; + u32 reo1_ring_producer_int_setup; + u32 reo1_ring_msi1_base_lsb; + u32 reo1_ring_msi1_base_msb; + u32 reo1_ring_msi1_data; + u32 reo1_aging_thres_ix0; + u32 reo1_aging_thres_ix1; + u32 reo1_aging_thres_ix2; + u32 reo1_aging_thres_ix3; + + u32 reo2_sw0_ring_base; + + u32 sw2reo_ring_base; + u32 sw2reo1_ring_base; + + u32 reo_cmd_ring_base; + + u32 reo_status_ring_base; u32 gcc_gcc_pcie_hot_rst; }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 8a40b91764065..0a39862d07c45 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -29,13 +29,13 @@ #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce0_src_reg_base) + ((hal)->regs->umac_ce0_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce0_dest_reg_base) + ((hal)->regs->umac_ce0_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce1_src_reg_base) + ((hal)->regs->umac_ce1_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce1_dest_reg_base) + ((hal)->regs->umac_ce1_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 @@ -47,30 +47,30 @@ #define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 #define HAL_TCL1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_lsb) + ((hal)->regs->tcl1_ring_base_lsb) #define HAL_TCL1_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) + ((hal)->regs->tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(hal) ((hal)->regs->tcl1_ring_id) #define HAL_TCL1_RING_MISC(hal) \ - ((hal)->regs->hal_tcl1_ring_misc) + ((hal)->regs->tcl1_ring_misc) #define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) + ((hal)->regs->tcl1_ring_tp_addr_lsb) #define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_msb) + ((hal)->regs->tcl1_ring_tp_addr_msb) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) + ((hal)->regs->tcl1_ring_consumer_int_setup_ix0) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) + ((hal)->regs->tcl1_ring_consumer_int_setup_ix1) #define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) + ((hal)->regs->tcl1_ring_msi1_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_msb) + ((hal)->regs->tcl1_ring_msi1_base_msb) #define HAL_TCL1_RING_MSI1_DATA(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_data) + ((hal)->regs->tcl1_ring_msi1_data) #define HAL_TCL2_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl2_ring_base_lsb) + ((hal)->regs->tcl2_ring_base_lsb) #define HAL_TCL_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_ring_base_lsb) + ((hal)->regs->tcl_ring_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) @@ -104,7 +104,7 @@ /* TCL STATUS ring address */ #define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_status_ring_base_lsb) + ((hal)->regs->tcl_status_ring_base_lsb) #define HAL_TCL_STATUS_RING_HP 0x00002048 /* PPE2TCL1 Ring address */ @@ -113,41 +113,41 @@ /* WBM PPE Release Ring address */ #define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_ppe_rel_ring_base) + ((hal)->regs->ppe_rel_ring_base) #define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 #define HAL_REO1_MISC_CTRL_ADDR(hal) \ - ((hal)->regs->hal_reo1_misc_ctrl_addr) + ((hal)->regs->reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->reo1_ring_base_msb) +#define HAL_REO1_RING_ID(hal) ((hal)->regs->reo1_ring_id) +#define HAL_REO1_RING_MISC(hal) ((hal)->regs->reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->reo1_ring_hp_addr_msb) #define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ - ((hal)->regs->hal_reo1_ring_producer_int_setup) + ((hal)->regs->reo1_ring_producer_int_setup) #define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_lsb) + ((hal)->regs->reo1_ring_msi1_base_lsb) #define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) + ((hal)->regs->reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->reo1_aging_thres_ix3) /* REO2SW(x) R2 ring pointers (head/tail) address */ #define HAL_REO1_RING_HP 0x00003048 @@ -158,23 +158,23 @@ /* REO2SW0 ring configuration address */ #define HAL_REO_SW0_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo2_sw0_ring_base) + ((hal)->regs->reo2_sw0_ring_base) /* REO2SW0 R2 ring pointer (head/tail) address */ #define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ #define HAL_REO_CMD_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_cmd_ring_base) + ((hal)->regs->reo_cmd_ring_base) /* REO CMD R2 address */ #define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ #define HAL_SW2REO_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo_ring_base) + ((hal)->regs->sw2reo_ring_base) #define HAL_SW2REO1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo1_ring_base) + ((hal)->regs->sw2reo1_ring_base) /* SW2REO R2 address */ #define HAL_SW2REO_RING_HP 0x00003028 @@ -192,41 +192,41 @@ /* REO status address */ #define HAL_REO_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_status_ring_base) + ((hal)->regs->reo_status_ring_base) #define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ #define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_idle_ring_base_lsb) + ((hal)->regs->wbm_idle_ring_base_lsb) #define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ - ((hal)->regs->hal_wbm_idle_ring_misc_addr) + ((hal)->regs->wbm_idle_ring_misc_addr) #define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) + ((hal)->regs->wbm_r0_idle_list_cntl_addr) #define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_size_addr) + ((hal)->regs->wbm_r0_idle_list_size_addr) #define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_lsb) + ((hal)->regs->wbm_scattered_ring_base_lsb) #define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_msb) + ((hal)->regs->wbm_scattered_ring_base_msb) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) + ((hal)->regs->wbm_scattered_desc_head_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) + ((hal)->regs->wbm_scattered_desc_head_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) + ((hal)->regs->wbm_scattered_desc_tail_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) + ((hal)->regs->wbm_scattered_desc_tail_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) + ((hal)->regs->wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ #define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) + ((hal)->regs->wbm_sw_release_ring_base_lsb) #define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) + ((hal)->regs->wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ #define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 @@ -234,10 +234,10 @@ /* WBM2SW R0 release address */ #define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm0_release_ring_base_lsb) + ((hal)->regs->wbm0_release_ring_base_lsb) #define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm1_release_ring_base_lsb) + ((hal)->regs->wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ #define HAL_WBM0_RELEASE_RING_HP 0x000030c8 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 2dc4f1539d684..3ccd689bbf1ca 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -214,269 +214,269 @@ static const struct hal_srng_config hw_srng_config_template[] = { const struct ath12k_hw_regs qcn9274_v1_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, + .tcl1_ring_id = 0x00000908, + .tcl1_ring_misc = 0x00000910, + .tcl1_ring_tp_addr_lsb = 0x0000091c, + .tcl1_ring_tp_addr_msb = 0x00000920, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .tcl1_ring_msi1_base_lsb = 0x00000948, + .tcl1_ring_msi1_base_msb = 0x0000094c, + .tcl1_ring_msi1_data = 0x00000950, + .tcl_ring_base_lsb = 0x00000b58, + .tcl1_ring_base_lsb = 0x00000900, + .tcl1_ring_base_msb = 0x00000904, + .tcl2_ring_base_lsb = 0x00000978, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d0c, - .hal_wbm_idle_ring_misc_addr = 0x00000d1c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, - .hal_wbm_r0_idle_list_size_addr = 0x00000214, - .hal_wbm_scattered_ring_base_lsb = 0x00000220, - .hal_wbm_scattered_ring_base_msb = 0x00000224, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, - .hal_wbm0_release_ring_base_lsb = 0x00000dd8, - .hal_wbm1_release_ring_base_lsb = 0x00000e50, + .tcl_status_ring_base_lsb = 0x00000d38, + + .wbm_idle_ring_base_lsb = 0x00000d0c, + .wbm_idle_ring_misc_addr = 0x00000d1c, + .wbm_r0_idle_list_cntl_addr = 0x00000210, + .wbm_r0_idle_list_size_addr = 0x00000214, + .wbm_scattered_ring_base_lsb = 0x00000220, + .wbm_scattered_ring_base_msb = 0x00000224, + .wbm_scattered_desc_head_info_ix0 = 0x00000230, + .wbm_scattered_desc_head_info_ix1 = 0x00000234, + .wbm_scattered_desc_tail_info_ix0 = 0x00000240, + .wbm_scattered_desc_tail_info_ix1 = 0x00000244, + .wbm_scattered_desc_ptr_hp_addr = 0x0000024c, + + .wbm_sw_release_ring_base_lsb = 0x0000034c, + .wbm_sw1_release_ring_base_lsb = 0x000003c4, + .wbm0_release_ring_base_lsb = 0x00000dd8, + .wbm1_release_ring_base_lsb = 0x00000e50, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, + .ppe_rel_ring_base = 0x0000043c, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, + .reo2_ring_base = 0x0000055c, + .reo1_misc_ctrl_addr = 0x00000b7c, + .reo1_sw_cookie_cfg0 = 0x00000050, + .reo1_sw_cookie_cfg1 = 0x00000054, + .reo1_qdesc_lut_base0 = 0x00000058, + .reo1_qdesc_lut_base1 = 0x0000005c, + .reo1_ring_base_lsb = 0x000004e4, + .reo1_ring_base_msb = 0x000004e8, + .reo1_ring_id = 0x000004ec, + .reo1_ring_misc = 0x000004f4, + .reo1_ring_hp_addr_lsb = 0x000004f8, + .reo1_ring_hp_addr_msb = 0x000004fc, + .reo1_ring_producer_int_setup = 0x00000508, + .reo1_ring_msi1_base_lsb = 0x0000052C, + .reo1_ring_msi1_base_msb = 0x00000530, + .reo1_ring_msi1_data = 0x00000534, + .reo1_aging_thres_ix0 = 0x00000b08, + .reo1_aging_thres_ix1 = 0x00000b0c, + .reo1_aging_thres_ix2 = 0x00000b10, + .reo1_aging_thres_ix3 = 0x00000b14, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, + .reo2_sw0_ring_base = 0x000008a4, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, + .sw2reo_ring_base = 0x00000304, + .sw2reo1_ring_base = 0x0000037c, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, + .reo_cmd_ring_base = 0x0000028c, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, + .reo_status_ring_base = 0x00000a84, /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, }; const struct ath12k_hw_regs qcn9274_v2_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, + .tcl1_ring_id = 0x00000908, + .tcl1_ring_misc = 0x00000910, + .tcl1_ring_tp_addr_lsb = 0x0000091c, + .tcl1_ring_tp_addr_msb = 0x00000920, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .tcl1_ring_msi1_base_lsb = 0x00000948, + .tcl1_ring_msi1_base_msb = 0x0000094c, + .tcl1_ring_msi1_data = 0x00000950, + .tcl_ring_base_lsb = 0x00000b58, + .tcl1_ring_base_lsb = 0x00000900, + .tcl1_ring_base_msb = 0x00000904, + .tcl2_ring_base_lsb = 0x00000978, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, + .tcl_status_ring_base_lsb = 0x00000d38, /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x0000027c, /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, + .wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw1_release_ring_base_lsb = 0x000003f4, /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, + .ppe_rel_ring_base = 0x0000046c, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_qdesc_addr = 0x0000007c, - .hal_reo1_qdesc_max_peerid = 0x00000088, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, + .reo2_ring_base = 0x00000578, + .reo1_misc_ctrl_addr = 0x00000b9c, + .reo1_sw_cookie_cfg0 = 0x0000006c, + .reo1_sw_cookie_cfg1 = 0x00000070, + .reo1_qdesc_lut_base0 = 0x00000074, + .reo1_qdesc_lut_base1 = 0x00000078, + .reo1_qdesc_addr = 0x0000007c, + .reo1_qdesc_max_peerid = 0x00000088, + .reo1_ring_base_lsb = 0x00000500, + .reo1_ring_base_msb = 0x00000504, + .reo1_ring_id = 0x00000508, + .reo1_ring_misc = 0x00000510, + .reo1_ring_hp_addr_lsb = 0x00000514, + .reo1_ring_hp_addr_msb = 0x00000518, + .reo1_ring_producer_int_setup = 0x00000524, + .reo1_ring_msi1_base_lsb = 0x00000548, + .reo1_ring_msi1_base_msb = 0x0000054C, + .reo1_ring_msi1_data = 0x00000550, + .reo1_aging_thres_ix0 = 0x00000B28, + .reo1_aging_thres_ix1 = 0x00000B2C, + .reo1_aging_thres_ix2 = 0x00000B30, + .reo1_aging_thres_ix3 = 0x00000B34, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, + .reo2_sw0_ring_base = 0x000008c0, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, + .sw2reo_ring_base = 0x00000320, + .sw2reo1_ring_base = 0x00000398, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, + .reo_cmd_ring_base = 0x000002A8, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, + .reo_status_ring_base = 0x00000aa0, /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, }; const struct ath12k_hw_regs ipq5332_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000918, - .hal_tcl1_ring_misc = 0x00000920, - .hal_tcl1_ring_tp_addr_lsb = 0x0000092c, - .hal_tcl1_ring_tp_addr_msb = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000940, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000944, - .hal_tcl1_ring_msi1_base_lsb = 0x00000958, - .hal_tcl1_ring_msi1_base_msb = 0x0000095c, - .hal_tcl1_ring_base_lsb = 0x00000910, - .hal_tcl1_ring_base_msb = 0x00000914, - .hal_tcl1_ring_msi1_data = 0x00000960, - .hal_tcl2_ring_base_lsb = 0x00000988, - .hal_tcl_ring_base_lsb = 0x00000b68, + .tcl1_ring_id = 0x00000918, + .tcl1_ring_misc = 0x00000920, + .tcl1_ring_tp_addr_lsb = 0x0000092c, + .tcl1_ring_tp_addr_msb = 0x00000930, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000940, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000944, + .tcl1_ring_msi1_base_lsb = 0x00000958, + .tcl1_ring_msi1_base_msb = 0x0000095c, + .tcl1_ring_base_lsb = 0x00000910, + .tcl1_ring_base_msb = 0x00000914, + .tcl1_ring_msi1_data = 0x00000960, + .tcl2_ring_base_lsb = 0x00000988, + .tcl_ring_base_lsb = 0x00000b68, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d48, + .tcl_status_ring_base_lsb = 0x00000d48, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, + .reo2_ring_base = 0x00000578, + .reo1_misc_ctrl_addr = 0x00000b9c, + .reo1_sw_cookie_cfg0 = 0x0000006c, + .reo1_sw_cookie_cfg1 = 0x00000070, + .reo1_qdesc_lut_base0 = 0x00000074, + .reo1_qdesc_lut_base1 = 0x00000078, + .reo1_ring_base_lsb = 0x00000500, + .reo1_ring_base_msb = 0x00000504, + .reo1_ring_id = 0x00000508, + .reo1_ring_misc = 0x00000510, + .reo1_ring_hp_addr_lsb = 0x00000514, + .reo1_ring_hp_addr_msb = 0x00000518, + .reo1_ring_producer_int_setup = 0x00000524, + .reo1_ring_msi1_base_lsb = 0x00000548, + .reo1_ring_msi1_base_msb = 0x0000054C, + .reo1_ring_msi1_data = 0x00000550, + .reo1_aging_thres_ix0 = 0x00000B28, + .reo1_aging_thres_ix1 = 0x00000B2C, + .reo1_aging_thres_ix2 = 0x00000B30, + .reo1_aging_thres_ix3 = 0x00000B34, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, + .reo2_sw0_ring_base = 0x000008c0, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, + .sw2reo_ring_base = 0x00000320, + .sw2reo1_ring_base = 0x00000398, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, + .reo_cmd_ring_base = 0x000002A8, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, + .reo_status_ring_base = 0x00000aa0, /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x0000027c, /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw_release_ring_base_lsb = 0x0000037c, /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, + .ppe_rel_ring_base = 0x0000046c, /* CE address */ - .hal_umac_ce0_src_reg_base = 0x00740000 - + .umac_ce0_src_reg_base = 0x00740000 - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce0_dest_reg_base = 0x00741000 - + .umac_ce0_dest_reg_base = 0x00741000 - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_src_reg_base = 0x00742000 - + .umac_ce1_src_reg_base = 0x00742000 - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_dest_reg_base = 0x00743000 - + .umac_ce1_dest_reg_base = 0x00743000 - HAL_IPQ5332_CE_WFSS_REG_BASE, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8151c216a5e1b..8966de3d64a41 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -173,87 +173,87 @@ static const struct hal_srng_config hw_srng_config_template[] = { const struct ath12k_hw_regs wcn7850_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, + .tcl1_ring_id = 0x00000908, + .tcl1_ring_misc = 0x00000910, + .tcl1_ring_tp_addr_lsb = 0x0000091c, + .tcl1_ring_tp_addr_msb = 0x00000920, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .tcl1_ring_msi1_base_lsb = 0x00000948, + .tcl1_ring_msi1_base_msb = 0x0000094c, + .tcl1_ring_msi1_data = 0x00000950, + .tcl_ring_base_lsb = 0x00000b58, + .tcl1_ring_base_lsb = 0x00000900, + .tcl1_ring_base_msb = 0x00000904, + .tcl2_ring_base_lsb = 0x00000978, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, + .tcl_status_ring_base_lsb = 0x00000d38, + + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x00000027c, + + .wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw1_release_ring_base_lsb = 0x00000284, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, + .ppe_rel_ring_base = 0x0000043c, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, + .reo2_ring_base = 0x0000055c, + .reo1_misc_ctrl_addr = 0x00000b7c, + .reo1_sw_cookie_cfg0 = 0x00000050, + .reo1_sw_cookie_cfg1 = 0x00000054, + .reo1_qdesc_lut_base0 = 0x00000058, + .reo1_qdesc_lut_base1 = 0x0000005c, + .reo1_ring_base_lsb = 0x000004e4, + .reo1_ring_base_msb = 0x000004e8, + .reo1_ring_id = 0x000004ec, + .reo1_ring_misc = 0x000004f4, + .reo1_ring_hp_addr_lsb = 0x000004f8, + .reo1_ring_hp_addr_msb = 0x000004fc, + .reo1_ring_producer_int_setup = 0x00000508, + .reo1_ring_msi1_base_lsb = 0x0000052C, + .reo1_ring_msi1_base_msb = 0x00000530, + .reo1_ring_msi1_data = 0x00000534, + .reo1_aging_thres_ix0 = 0x00000b08, + .reo1_aging_thres_ix1 = 0x00000b0c, + .reo1_aging_thres_ix2 = 0x00000b10, + .reo1_aging_thres_ix3 = 0x00000b14, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, + .reo2_sw0_ring_base = 0x000008a4, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, + .sw2reo_ring_base = 0x00000304, + .sw2reo1_ring_base = 0x0000037c, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, + .reo_cmd_ring_base = 0x0000028c, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, + .reo_status_ring_base = 0x00000a84, /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e40304, }; From 7df947507b8249fd2c5a9114d87ba60cbb94de21 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:40 +0530 Subject: [PATCH 434/659] wifi: ath12k: Move DP related functions from peer.c to dp_peer.c file Refactor the structures and APIs defined in files peer.h and peer.c in such a way that the APIs making use of ath12k_peer are moved to newly introduced files dp_peer.h and dp_peer.c. Have this new file dp_peer.c compiled as part of kernel module ath12k.ko. Move these APIs from peer.h and peer.c to dp_peer.h and dp_peer.c: ath12k_peer_find() ath12k_peer_find_by_pdev_idx() ath12k_peer_find_by_addr() ath12k_peer_find_by_ml_id() ath12k_peer_find_by_id() ath12k_peer_exist_by_vdev_id() ath12k_peer_find_by_ast() ath12k_peer_unmap_event() ath12k_peer_map_event() ath12k_peer_get_link_sta() Background: In current ath12k architecture, connected station is represented by struct ath12k_sta. struct ath12k_sta has an array of struct ath12k_link_sta wherein each index represents one link of the connected station. For each ath12k_link_sta, there is a corresponding data path peer which is represented by struct ath12k_peer. Diagrammatic view of the station is as below: ath12k_sta | |-> ath12k_link_sta <--> ath12k_peer | |-> ath12k_link_sta <--> ath12k_peer | |-> ath12k_link_sta <--> ath12k_peer Currently, in control path, ath12k_link_sta and ath12k_peer are used interchangeably, while the data path makes use of ath12k_peer only. For ath12k next-generation driver framework, in order to have a clean segregation between control and data path, use ath12k_link_sta only for control path operations. Station view for the data path is revamped as below: ath12k_dp_peer | |-> ath12k_dp_link_peer | |-> ath12k_dp_link_peer | |-> ath12k_dp_link_peer Introduce the structure ath12k_dp_peer to represent the data path version of corresponding ath12k_sta. This ath12k_dp_peer contains the fields used in the per packet Tx Rx paths applicable across all the links and maintains an array of ath12k_dp_link_peer. Per packet Tx and Rx path operates on ath12k_dp_peer. This ath12k_dp_peer is a standalone new object and has back pointer reference to ieee80211_sta. Rename ath12k_peer to ath12k_dp_link_peer and move the fields which are common across all the links to ath12k_dp_peer. Add the fields specific to a link which are mostly for statistics and monitor usage to ath12k_dp_link_peer. Final view of station in ath12k next-generation driver is shown as below: Control Path Data Path ------------------------------------------------------------------- ath12k_sta ath12k_dp_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer This patch and the subsequent patches in this series are meant to achieve the modularization of peer object as mentioned above. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp_peer.c | 207 ++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_peer.h | 82 +++++++++ drivers/net/wireless/ath/ath12k/peer.c | 172 ------------------ drivers/net/wireless/ath/ath12k/peer.h | 97 +--------- 5 files changed, 292 insertions(+), 267 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_peer.c create mode 100644 drivers/net/wireless/ath/ath12k/dp_peer.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 32a0f30faf922..d397bc494cf25 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -11,6 +11,7 @@ ath12k-y += core.o \ dp_tx.o \ dp_rx.o \ dp_htt.o \ + dp_peer.o \ debug.o \ ce.o \ peer.o \ diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c new file mode 100644 index 0000000000000..e32d3ea76a6f8 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "core.h" +#include "dp_peer.h" +#include "debug.h" + +struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, + const u8 *addr) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (peer->vdev_id != vdev_id) + continue; + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} + +struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, + u8 pdev_idx, const u8 *addr) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (peer->pdev_idx != pdev_idx) + continue; + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} + +struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, + const u8 *addr) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} +EXPORT_SYMBOL(ath12k_peer_find_by_addr); + +static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, + int ml_peer_id) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) + if (ml_peer_id == peer->ml_id) + return peer; + + return NULL; +} + +struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, + int peer_id) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + if (peer_id == HAL_INVALID_PEERID) + return NULL; + + if (peer_id & ATH12K_PEER_ML_ID_VALID) + return ath12k_peer_find_by_ml_id(ab, peer_id); + + list_for_each_entry(peer, &ab->peers, list) + if (peer_id == peer->peer_id) + return peer; + + return NULL; +} + +bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) +{ + struct ath12k_peer *peer; + + spin_lock_bh(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (vdev_id == peer->vdev_id) { + spin_unlock_bh(&ab->base_lock); + return true; + } + } + spin_unlock_bh(&ab->base_lock); + return false; +} + +struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, + int ast_hash) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) + if (ast_hash == peer->ast_hash) + return peer; + + return NULL; +} + +void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) +{ + struct ath12k_peer *peer; + + spin_lock_bh(&ab->base_lock); + + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", + peer_id); + goto exit; + } + + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", + peer->vdev_id, peer->addr, peer_id); + + list_del(&peer->list); + kfree(peer); + wake_up(&ab->peer_mapping_wq); + +exit: + spin_unlock_bh(&ab->base_lock); +} + +void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) +{ + struct ath12k_peer *peer; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find(ab, vdev_id, mac_addr); + if (!peer) { + peer = kzalloc(sizeof(*peer), GFP_ATOMIC); + if (!peer) + goto exit; + + peer->vdev_id = vdev_id; + peer->peer_id = peer_id; + peer->ast_hash = ast_hash; + peer->hw_peer_id = hw_peer_id; + ether_addr_copy(peer->addr, mac_addr); + list_add(&peer->list, &ab->peers); + wake_up(&ab->peer_mapping_wq); + } + + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", + vdev_id, mac_addr, peer_id); + +exit: + spin_unlock_bh(&ab->base_lock); +} + +struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, + struct ath12k_peer *peer) +{ + struct ath12k_sta *ahsta; + struct ath12k_link_sta *arsta; + + if (!peer->sta) + return NULL; + + ahsta = ath12k_sta_to_ahsta(peer->sta); + if (peer->ml_id & ATH12K_PEER_ML_ID_VALID) { + if (!(ahsta->links_map & BIT(peer->link_id))) { + ath12k_warn(ab, "peer %pM id %d link_id %d can't found in STA link_map 0x%x\n", + peer->addr, peer->peer_id, peer->link_id, + ahsta->links_map); + return NULL; + } + arsta = rcu_dereference(ahsta->link[peer->link_id]); + if (!arsta) + return NULL; + } else { + arsta = &ahsta->deflink; + } + return arsta; +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h new file mode 100644 index 0000000000000..19f01d69e5d3c --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_PEER_H +#define ATH12K_DP_PEER_H + +#include "dp_rx.h" + +struct ppdu_user_delayba { + u16 sw_peer_id; + u32 info0; + u16 ru_end; + u16 ru_start; + u32 info1; + u32 rate_flags; + u32 resp_rate_flags; +}; + +#define ATH12K_PEER_ML_ID_VALID BIT(13) + +struct ath12k_peer { + struct list_head list; + struct ieee80211_sta *sta; + int vdev_id; + u8 addr[ETH_ALEN]; + int peer_id; + u16 ast_hash; + u8 pdev_idx; + u16 hw_peer_id; + + /* protected by ab->data_lock */ + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; + + /* Info used in MMIC verification of + * RX fragments + */ + struct crypto_shash *tfm_mmic; + u8 mcast_keyidx; + u8 ucast_keyidx; + u16 sec_type; + u16 sec_type_grp; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; + bool is_authorized; + bool mlo; + /* protected by ab->data_lock */ + bool dp_setup_done; + + u16 ml_id; + + /* any other ML info common for all partners can be added + * here and would be same for all partner peers. + */ + u8 ml_addr[ETH_ALEN]; + + /* To ensure only certain work related to dp is done once */ + bool primary_link; + + /* for reference to ath12k_link_sta */ + u8 link_id; + bool ucast_ra_only; +}; + +void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); +void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); +struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, + const u8 *addr); +struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, + const u8 *addr); +struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, int peer_id); +bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); +struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); +struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, + u8 pdev_idx, const u8 *addr); +struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, + struct ath12k_peer *peer); +#endif diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index ce15642986568..1e2526bb11865 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -25,178 +25,6 @@ struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) } EXPORT_SYMBOL(ath12k_peer_ml_find); -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (peer->vdev_id != vdev_id) - continue; - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; -} - -static struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, - u8 pdev_idx, const u8 *addr) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (peer->pdev_idx != pdev_idx) - continue; - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; -} - -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; -} -EXPORT_SYMBOL(ath12k_peer_find_by_addr); - -static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, - int ml_peer_id) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) - if (ml_peer_id == peer->ml_id) - return peer; - - return NULL; -} - -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, - int peer_id) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - if (peer_id == HAL_INVALID_PEERID) - return NULL; - - if (peer_id & ATH12K_PEER_ML_ID_VALID) - return ath12k_peer_find_by_ml_id(ab, peer_id); - - list_for_each_entry(peer, &ab->peers, list) - if (peer_id == peer->peer_id) - return peer; - - return NULL; -} - -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) -{ - struct ath12k_peer *peer; - - spin_lock_bh(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (vdev_id == peer->vdev_id) { - spin_unlock_bh(&ab->base_lock); - return true; - } - } - spin_unlock_bh(&ab->base_lock); - return false; -} - -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, - int ast_hash) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) - if (ast_hash == peer->ast_hash) - return peer; - - return NULL; -} - -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) -{ - struct ath12k_peer *peer; - - spin_lock_bh(&ab->base_lock); - - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", - peer_id); - goto exit; - } - - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", - peer->vdev_id, peer->addr, peer_id); - - list_del(&peer->list); - kfree(peer); - wake_up(&ab->peer_mapping_wq); - -exit: - spin_unlock_bh(&ab->base_lock); -} - -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) -{ - struct ath12k_peer *peer; - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, mac_addr); - if (!peer) { - peer = kzalloc(sizeof(*peer), GFP_ATOMIC); - if (!peer) - goto exit; - - peer->vdev_id = vdev_id; - peer->peer_id = peer_id; - peer->ast_hash = ast_hash; - peer->hw_peer_id = hw_peer_id; - ether_addr_copy(peer->addr, mac_addr); - list_add(&peer->list, &ab->peers); - wake_up(&ab->peer_mapping_wq); - } - - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", - vdev_id, mac_addr, peer_id); - -exit: - spin_unlock_bh(&ab->base_lock); -} - static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, const u8 *addr, bool expect_mapped) { diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h index 44afc0b7dd53e..81e9bcc067ff4 100644 --- a/drivers/net/wireless/ath/ath12k/peer.h +++ b/drivers/net/wireless/ath/ath12k/peer.h @@ -1,69 +1,13 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_PEER_H #define ATH12K_PEER_H -#include "dp_rx.h" - -struct ppdu_user_delayba { - u16 sw_peer_id; - u32 info0; - u16 ru_end; - u16 ru_start; - u32 info1; - u32 rate_flags; - u32 resp_rate_flags; -}; - -#define ATH12K_PEER_ML_ID_VALID BIT(13) - -struct ath12k_peer { - struct list_head list; - struct ieee80211_sta *sta; - int vdev_id; - u8 addr[ETH_ALEN]; - int peer_id; - u16 ast_hash; - u8 pdev_idx; - u16 hw_peer_id; - - /* protected by ab->data_lock */ - struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; - struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; - - /* Info used in MMIC verification of - * RX fragments - */ - struct crypto_shash *tfm_mmic; - u8 mcast_keyidx; - u8 ucast_keyidx; - u16 sec_type; - u16 sec_type_grp; - struct ppdu_user_delayba ppdu_stats_delayba; - bool delayba_flag; - bool is_authorized; - bool mlo; - /* protected by ab->data_lock */ - bool dp_setup_done; - - u16 ml_id; - - /* any other ML info common for all partners can be added - * here and would be same for all partner peers. - */ - u8 ml_addr[ETH_ALEN]; - - /* To ensure only certain work related to dp is done once */ - bool primary_link; - - /* for reference to ath12k_link_sta */ - u8 link_id; - bool ucast_ra_only; -}; +#include "dp_peer.h" struct ath12k_ml_peer { struct list_head list; @@ -71,14 +15,6 @@ struct ath12k_ml_peer { u16 id; }; -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, int peer_id); void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id); int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr); int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, @@ -86,38 +22,9 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_wmi_peer_create_arg *arg); int ath12k_wait_for_peer_delete_done(struct ath12k *ar, u32 vdev_id, const u8 *addr); -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta); struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr); -static inline -struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, - struct ath12k_peer *peer) -{ - struct ath12k_sta *ahsta; - struct ath12k_link_sta *arsta; - - if (!peer->sta) - return NULL; - - ahsta = ath12k_sta_to_ahsta(peer->sta); - if (peer->ml_id & ATH12K_PEER_ML_ID_VALID) { - if (!(ahsta->links_map & BIT(peer->link_id))) { - ath12k_warn(ab, "peer %pM id %d link_id %d can't found in STA link_map 0x%x\n", - peer->addr, peer->peer_id, peer->link_id, - ahsta->links_map); - return NULL; - } - arsta = rcu_dereference(ahsta->link[peer->link_id]); - if (!arsta) - return NULL; - } else { - arsta = &ahsta->deflink; - } - return arsta; -} - #endif /* _PEER_H_ */ From 34baefea5f21aba46004df9d16b04d52241c7f6c Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:41 +0530 Subject: [PATCH 435/659] wifi: ath12k: Rename ath12k_peer to ath12k_dp_link_peer Rename ath12k_peer to ath12k_dp_link_peer for all instances and rename the following find APIs accordingly to reflect the API names as per the structural name change. APIs renamed: ath12k_peer_find() ath12k_peer_find_by_pdev_idx() ath12k_peer_find_by_addr() ath12k_peer_find_by_ml_id() ath12k_peer_find_by_id() ath12k_peer_find_by_ast() ath12k_peer_exist_by_vdev_id() ath12k_peer_get_link_sta() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 8 +-- drivers/net/wireless/ath/ath12k/dp.h | 2 +- drivers/net/wireless/ath/ath12k/dp_htt.c | 28 ++++---- drivers/net/wireless/ath/ath12k/dp_mon.c | 16 ++--- drivers/net/wireless/ath/ath12k/dp_peer.c | 64 ++++++++++--------- drivers/net/wireless/ath/ath12k/dp_peer.h | 34 +++++----- drivers/net/wireless/ath/ath12k/dp_rx.c | 35 +++++----- drivers/net/wireless/ath/ath12k/dp_rx.h | 10 +-- drivers/net/wireless/ath/ath12k/mac.c | 48 ++++++++------ drivers/net/wireless/ath/ath12k/peer.c | 22 ++++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 18 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 4 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 12 ++-- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 2 +- drivers/net/wireless/ath/ath12k/wmi.c | 4 +- 15 files changed, 163 insertions(+), 144 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index a3f97ef96686d..afad0c2cb6b9b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -23,12 +23,12 @@ enum ath12k_dp_desc_type { void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; /* TODO: Any other peer specific DP cleanup */ spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n", addr, vdev_id); @@ -50,7 +50,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; u32 reo_dest; int ret = 0, tid; @@ -89,7 +89,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) peer_clean: spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to find the peer to del rx tid\n"); spin_unlock_bh(&ab->base_lock); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 4318ec13cb8f1..43a05c6f78ecd 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -14,7 +14,7 @@ #define MAX_RXDMA_PER_PDEV 2 struct ath12k_base; -struct ath12k_peer; +struct ath12k_dp_link_peer; struct ath12k_dp; struct ath12k_vif; struct ath12k_link_vif; diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 1a0d3e4ac8bb7..cae5a90c1c659 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -188,7 +188,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; struct htt_ppdu_stats_user_rate *user_rate; struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats; @@ -273,7 +273,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, rcu_read_lock(); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, usr_stats->peer_id); if (!peer || !peer->sta) { spin_unlock_bh(&ab->base_lock); @@ -281,7 +281,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, return; } - arsta = ath12k_peer_get_link_sta(ab, peer); + arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); @@ -403,7 +403,7 @@ struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp *d return ppdu_info; } -static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, +static void ath12k_copy_to_delay_stats(struct ath12k_dp_link_peer *peer, struct htt_ppdu_user_stats *usr_stats) { peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id); @@ -418,7 +418,7 @@ static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, peer->delayba_flag = true; } -static void ath12k_copy_to_bar(struct ath12k_peer *peer, +static void ath12k_copy_to_bar(struct ath12k_dp_link_peer *peer, struct htt_ppdu_user_stats *usr_stats) { usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id); @@ -439,7 +439,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_htt_ppdu_stats_msg *msg; struct htt_ppdu_stats_info *ppdu_info; - struct ath12k_peer *peer = NULL; + struct ath12k_dp_link_peer *peer = NULL; struct htt_ppdu_user_stats *usr_stats = NULL; u32 peer_id = 0; struct ath12k_pdev_dp *dp_pdev; @@ -508,7 +508,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { spin_unlock_bh(&ab->base_lock); continue; @@ -527,7 +527,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, for (i = 0; i < ppdu_info->bar_num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { spin_unlock_bh(&ab->base_lock); continue; @@ -623,7 +623,7 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), peer_mac_h16, mac_addr); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); + ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); break; case HTT_T2H_MSG_TYPE_PEER_MAP2: vdev_id = le32_get_bits(resp->peer_map_ev.info, @@ -638,8 +638,8 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL); hw_peer_id = le32_get_bits(resp->peer_map_ev.info1, HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); + ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); break; case HTT_T2H_MSG_TYPE_PEER_MAP3: vdev_id = le32_get_bits(resp->peer_map_ev.info, @@ -654,14 +654,14 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL); hw_peer_id = le32_get_bits(resp->peer_map_ev.info2, HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); + ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); break; case HTT_T2H_MSG_TYPE_PEER_UNMAP: case HTT_T2H_MSG_TYPE_PEER_UNMAP2: peer_id = le32_get_bits(resp->peer_unmap_ev.info, HTT_T2H_PEER_UNMAP_INFO_PEER_ID); - ath12k_peer_unmap_event(ab, peer_id); + ath12k_dp_link_peer_unmap_event(ab, peer_id); break; case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: ath12k_htt_pull_ppdu_stats(ab, skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 8cb244de80fd4..d93a12d10b6fa 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2304,7 +2304,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct ieee80211_rx_status *rx_status; struct ieee80211_radiotap_he *he = NULL; struct ieee80211_sta *pubsta = NULL; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct hal_rx_desc_data rx_info; bool is_mcbc = rxcb->is_mcbc; @@ -2323,7 +2323,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ab, msdu, &rx_info); + peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; if (pubsta->valid_links) { @@ -3671,13 +3671,13 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct ath12k_link_sta *arsta; struct ath12k_rx_peer_stats *rx_stats = NULL; struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; u32 num_msdu; if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) return; - peer = ath12k_peer_find_by_ast(ab, user_stats->ast_index); + peer = ath12k_dp_link_peer_find_by_ast(ab, user_stats->ast_index); if (!peer) { ath12k_warn(ab, "peer ast idx %d can't be found\n", @@ -3685,7 +3685,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, return; } - arsta = ath12k_peer_get_link_sta(ab, peer); + arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); @@ -3804,7 +3804,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, struct hal_srng *srng; struct dp_rxdma_mon_ring *buf_ring; struct ath12k_link_sta *arsta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct sk_buff_head skb_list; u64 cookie; int num_buffs_reaped = 0, srng_id, buf_id; @@ -3919,7 +3919,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, rcu_read_lock(); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, ppdu_info->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "failed to find the peer with monitor peer_id %d\n", @@ -3928,7 +3928,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = ath12k_peer_get_link_sta(ab, peer); + arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index e32d3ea76a6f8..843369a00d3e4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -8,10 +8,11 @@ #include "dp_peer.h" #include "debug.h" -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, + int vdev_id, const u8 *addr) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -27,10 +28,11 @@ struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, return NULL; } -struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, - u8 pdev_idx, const u8 *addr) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, + const u8 *addr) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -46,10 +48,10 @@ struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, return NULL; } -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -62,12 +64,12 @@ struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, return NULL; } -EXPORT_SYMBOL(ath12k_peer_find_by_addr); +EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_addr); -static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, - int ml_peer_id) +static struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -78,10 +80,10 @@ static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, return NULL; } -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, - int peer_id) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -89,7 +91,7 @@ struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, return NULL; if (peer_id & ATH12K_PEER_ML_ID_VALID) - return ath12k_peer_find_by_ml_id(ab, peer_id); + return ath12k_dp_link_peer_find_by_ml_id(ab, peer_id); list_for_each_entry(peer, &ab->peers, list) if (peer_id == peer->peer_id) @@ -98,9 +100,9 @@ struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, return NULL; } -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; spin_lock_bh(&ab->base_lock); @@ -114,10 +116,10 @@ bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) return false; } -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, - int ast_hash) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -128,13 +130,13 @@ struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, return NULL; } -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) +void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -152,13 +154,13 @@ void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) spin_unlock_bh(&ab->base_lock); } -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) +void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, mac_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, mac_addr); if (!peer) { peer = kzalloc(sizeof(*peer), GFP_ATOMIC); if (!peer) @@ -180,8 +182,8 @@ void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, spin_unlock_bh(&ab->base_lock); } -struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, - struct ath12k_peer *peer) +struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, + struct ath12k_dp_link_peer *peer) { struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index 19f01d69e5d3c..aec73d8e35ce6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -21,7 +21,7 @@ struct ppdu_user_delayba { #define ATH12K_PEER_ML_ID_VALID BIT(13) -struct ath12k_peer { +struct ath12k_dp_link_peer { struct list_head list; struct ieee80211_sta *sta; int vdev_id; @@ -65,18 +65,22 @@ struct ath12k_peer { bool ucast_ra_only; }; -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, int peer_id); -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); -struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, - u8 pdev_idx, const u8 *addr); -struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, - struct ath12k_peer *peer); +void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); +void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, + int vdev_id, const u8 *addr); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id); +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, + const u8 *addr); +struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, + struct ath12k_dp_link_peer *peer); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index f27cf5c24a761..c2b0bce618dd2 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -560,7 +560,7 @@ void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, __skb_queue_purge(&rx_tid->rx_frags); } -void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) +void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer) { struct ath12k_dp_rx_tid *rx_tid; int i; @@ -610,7 +610,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ { struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta; struct ath12k_dp_rx_tid *rx_tid; dma_addr_t paddr_aligned; @@ -618,7 +618,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); if (!peer) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to find the peer to set up rx tid\n"); @@ -753,7 +753,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, u8 link_id) { struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(params->sta); struct ath12k_link_sta *arsta; int vdev_id; @@ -771,7 +771,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, arsta->addr); if (!peer) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n"); @@ -804,7 +804,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; struct ath12k_hal_reo_cmd cmd = {}; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct ath12k_dp_rx_tid_rxq rx_tid_rxq; u8 tid; @@ -819,7 +819,8 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer_addr); if (!peer) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n", @@ -1166,23 +1167,23 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu } } -struct ath12k_peer * -ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +struct ath12k_dp_link_peer * +ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct ath12k_peer *peer = NULL; + struct ath12k_dp_link_peer *peer = NULL; lockdep_assert_held(&ab->base_lock); if (rxcb->peer_id) - peer = ath12k_peer_find_by_id(ab, rxcb->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, rxcb->peer_id); if (peer) return peer; if (rx_info->addr2_present) - peer = ath12k_peer_find_by_addr(ab, rx_info->addr2); + peer = ath12k_dp_link_peer_find_by_addr(ab, rx_info->addr2); return peer; } @@ -1339,7 +1340,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status *status = rx_info->rx_status; u8 decap = rx_info->decap_type; @@ -1347,7 +1348,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc bool is_eapol = rxcb->is_eapol; spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info); + peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); pubsta = peer ? peer->sta : NULL; @@ -1468,7 +1469,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev { struct ath12k_base *ab = ar->ab; struct crypto_shash *tfm; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; int i; @@ -1478,7 +1479,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); if (!peer) { spin_unlock_bh(&ab->base_lock); crypto_free_shash(tfm); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 1a97264f0328f..ff568254b686f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -220,9 +220,9 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, const u8 *peer_addr, enum set_key_cmd key_cmd, struct ieee80211_key_conf *key); -void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer); +void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer); void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid); + struct ath12k_dp_link_peer *peer, u8 tid); int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type); @@ -243,9 +243,9 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); -struct ath12k_peer * -ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info); +struct ath12k_dp_link_peer * +ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index bc0c7a6bb6b1b..47326a30c556f 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1171,7 +1171,7 @@ static int ath12k_mac_set_kickout(struct ath12k_link_vif *arvif) void ath12k_mac_peer_cleanup_all(struct ath12k *ar) { - struct ath12k_peer *peer, *tmp; + struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -3731,7 +3731,7 @@ static void ath12k_bss_assoc(struct ath12k *ar, struct ath12k_link_sta *arsta; struct ieee80211_sta *ap_sta; struct ath12k_sta *ahsta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; bool is_auth = false; u32 hemode = 0; int ret; @@ -3848,7 +3848,8 @@ static void ath12k_bss_assoc(struct ath12k *ar, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arvif->bssid); if (peer && peer->is_authorized) is_auth = true; @@ -5665,7 +5666,7 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, { struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; int first_errno = 0; int ret; int i; @@ -5674,7 +5675,7 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, addr); spin_unlock_bh(&ab->base_lock); if (!peer) @@ -5709,7 +5710,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, { struct ieee80211_sta *sta = NULL; struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta; const u8 *peer_addr; int ret; @@ -5734,7 +5735,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, * we already hold wiphy lock. we just make sure its there now. */ spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer_addr); spin_unlock_bh(&ab->base_lock); if (!peer) { @@ -5768,7 +5770,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, } spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer_addr); if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { @@ -6567,7 +6570,7 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, { struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -6575,7 +6578,8 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (peer && peer->sta == sta) { ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", vif->addr, arvif->vdev_id); @@ -6595,14 +6599,15 @@ static int ath12k_mac_station_unauthorize(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_link_sta *arsta) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; int ret; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (peer) peer->is_authorized = false; @@ -6628,7 +6633,7 @@ static int ath12k_mac_station_authorize(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_link_sta *arsta) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); int ret; @@ -6636,7 +6641,8 @@ static int ath12k_mac_station_authorize(struct ath12k *ar, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (peer) peer->is_authorized = true; @@ -7505,7 +7511,7 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_link_sta *arsta; struct ath12k_link_vif *arvif; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; u32 bw, smps; rcu_read_lock(); @@ -7528,7 +7534,8 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, } spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (!peer) { spin_unlock_bh(&ar->ab->base_lock); rcu_read_unlock(); @@ -9158,7 +9165,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, struct sk_buff *msdu_copied; struct ath12k *ar, *tmp_ar; struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; unsigned long links_map; bool is_mcast = false; bool is_dvlan = false; @@ -9296,7 +9303,8 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, goto skip_peer_find; spin_lock_bh(&tmp_ar->ab->base_lock); - peer = ath12k_peer_find_by_addr(tmp_ar->ab, tmp_arvif->bssid); + peer = ath12k_dp_link_peer_find_by_addr(tmp_ar->ab, + tmp_arvif->bssid); if (!peer) { spin_unlock_bh(&tmp_ar->ab->base_lock); ath12k_warn(tmp_ar->ab, @@ -11914,7 +11922,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (ab->hw_params->vdev_start_delay && ahvif->vdev_type != WMI_VDEV_TYPE_AP && ahvif->vdev_type != WMI_VDEV_TYPE_MONITOR && - !ath12k_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { + !ath12k_dp_link_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { ret = 0; goto out; } @@ -12793,7 +12801,7 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban bool eht_fixed_rate = false, he_fixed_rate = false, vht_fixed_rate = false; const u16 *vht_mcs_mask, *he_mcs_mask, *eht_mcs_mask; struct ieee80211_link_sta *link_sta; - struct ath12k_peer *peer, *tmp; + struct ath12k_dp_link_peer *peer, *tmp; u8 vht_nss, he_nss, eht_nss; int ret = true; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 1e2526bb11865..16f4a74712d81 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -25,8 +25,8 @@ struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) } EXPORT_SYMBOL(ath12k_peer_ml_find); -static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, - const u8 *addr, bool expect_mapped) +static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id, + const u8 *addr, bool expect_mapped) { int ret; @@ -34,7 +34,9 @@ static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, bool mapped; spin_lock_bh(&ab->base_lock); - mapped = !!ath12k_peer_find(ab, vdev_id, addr); + mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(ab, + vdev_id, + addr); spin_unlock_bh(&ab->base_lock); (mapped == expect_mapped || @@ -49,7 +51,7 @@ static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) { - struct ath12k_peer *peer, *tmp; + struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -72,7 +74,7 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) static int ath12k_wait_for_peer_deleted(struct ath12k *ar, int vdev_id, const u8 *addr) { - return ath12k_wait_for_peer_common(ar->ab, vdev_id, addr, false); + return ath12k_wait_for_dp_link_peer_common(ar->ab, vdev_id, addr, false); } int ath12k_wait_for_peer_delete_done(struct ath12k *ar, u32 vdev_id, @@ -138,7 +140,7 @@ int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr) static int ath12k_wait_for_peer_created(struct ath12k *ar, int vdev_id, const u8 *addr) { - return ath12k_wait_for_peer_common(ar->ab, vdev_id, addr, true); + return ath12k_wait_for_dp_link_peer_common(ar->ab, vdev_id, addr, true); } int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, @@ -150,7 +152,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_dp_link_vif *dp_link_vif; struct ath12k_link_sta *arsta; u8 link_id = arvif->link_id; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta; u16 ml_peer_id; int ret; @@ -166,7 +168,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, } spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, arg->peer_addr); + peer = ath12k_dp_link_peer_find_by_pdev_and_addr(ar->ab, ar->pdev_idx, + arg->peer_addr); if (peer) { spin_unlock_bh(&ar->ab->base_lock); return -EINVAL; @@ -188,7 +191,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arg->vdev_id, arg->peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arg->vdev_id, + arg->peer_addr); if (!peer) { spin_unlock_bh(&ar->ab->base_lock); ath12k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index eef8d25584946..4180db504c312 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -68,7 +68,7 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, } void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid) + struct ath12k_dp_link_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; @@ -179,7 +179,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, } int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn) @@ -321,7 +321,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype; bool is_decrypted = false; struct ieee80211_hdr *hdr; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ieee80211_rx_status *rx_status = rx_info->rx_status; u32 err_bitmap = rx_info->err_bitmap; @@ -333,7 +333,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, rxcb->peer_id = rx_info->peer_id; spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info); + peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -964,7 +964,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, } static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, enum hal_encrypt_type enctype, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) @@ -1033,7 +1033,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, } static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff **defrag_skb, enum hal_encrypt_type enctype, @@ -1107,7 +1107,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; u32 peer_id = rx_info->peer_id; @@ -1134,7 +1134,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, return -EINVAL; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", peer_id); @@ -1197,7 +1197,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, timer_delete_sync(&rx_tid->frag_timer); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) goto err_frags_cleanup; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index df25164e08f24..f75588519cfff 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -34,7 +34,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid); + struct ath12k_dp_link_peer *peer, u8 tid); int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, @@ -43,7 +43,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid); int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 2f523ed00dedd..3d06987cfc0e6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -395,7 +395,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, struct sk_buff *msdu = desc_params->skb; s32 noise_floor; struct ieee80211_tx_status status = {}; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); @@ -449,7 +449,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, } rcu_read_lock(); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); @@ -518,7 +518,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ieee80211_sta *sta; struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; @@ -528,7 +528,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, int ret; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); @@ -649,7 +649,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ieee80211_rate_status status_rate = {}; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; struct ath12k_sta *ahsta; struct rate_info rate; @@ -747,7 +747,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 01c859f35a937..a3ea42fc09331 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -119,7 +119,7 @@ ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, __le16 fc = mgmt->frame_control; spin_lock_bh(&ab->base_lock); - if (!ath12k_peer_find_by_addr(ab, mgmt->da) && + if (!ath12k_dp_link_peer_find_by_addr(ab, mgmt->da) && !ath12k_peer_ml_find(ah, mgmt->da)) { spin_unlock_bh(&ab->base_lock); return false; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 743e56020906c..70d92c321fe72 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -7276,7 +7276,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff struct wmi_peer_sta_kickout_arg arg = {}; struct ath12k_link_vif *arvif; struct ieee80211_sta *sta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; unsigned int link_id; struct ath12k *ar; @@ -7289,7 +7289,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_addr(ab, arg.mac_addr); + peer = ath12k_dp_link_peer_find_by_addr(ab, arg.mac_addr); if (!peer) { ath12k_warn(ab, "peer not found %pM\n", From ed6c3220e2c71ac81b387279b091548e377a0274 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:42 +0530 Subject: [PATCH 436/659] wifi: ath12k: Add hash table for ath12k_link_sta in ath12k_base Currently ath12k_base maintains a linked list of ath12k_dp_link_peer as "peers". This linked list is used for all kinds of peer search operations. In the control path, if there is a requirement to search for ath12k_link_sta using mac address, then below sequence is to be followed: 1. Find ath12k_dp_link_peer in the linked list using mac address 2. Fetch ieee80211_sta from ath12k_dp_link_peer 3. Fetch ath12k_sta from ieee80211_sta 4. Finally fetch ath12k_link_sta from ath12k_sta using link_id In the above sequence, there are too many indirections involved. In order to simplify this, add hash table for ath12k_link_sta in ath12k_base. This hash table is lock protected by existing spinlock "base_lock" in ath12k_base as this table can be concurrently accessed in different contexts. Use this table for ath12k_link_sta search operations using mac address in the control path. Ex: For WMI interface and mac80211_ops interface in the control path, sta mac address is received and this hash table can be used to search for ath12k_link_sta directly instead of following the longer route mentioned above. Helper APIs added: - ath12k_link_sta_rhash_add() - To add arsta entry to hash table - ath12k_link_sta_rhash_delete() - To remove arsta entry from hash table - ath12k_link_sta_find_by_addr() - To find arsta from hash table using mac address Make changes in API ath12k_peer_sta_kickout_event() to find arsta using above mechanism. ath11k driver has been taken as reference for implementation of hash table. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 10 +++ drivers/net/wireless/ath/ath12k/core.h | 7 ++ drivers/net/wireless/ath/ath12k/mac.c | 72 +++++++++++++++ drivers/net/wireless/ath/ath12k/peer.c | 116 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/peer.h | 6 ++ drivers/net/wireless/ath/ath12k/wmi.c | 14 +-- 6 files changed, 218 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 4bc56d5ac64fa..d58b164886645 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -23,6 +23,7 @@ #include "pci.h" #include "wow.h" #include "dp_cmn.h" +#include "peer.h" unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); @@ -702,6 +703,8 @@ void ath12k_core_to_group_ref_put(struct ath12k_base *ab) static void ath12k_core_stop(struct ath12k_base *ab) { + ath12k_link_sta_rhash_tbl_destroy(ab); + ath12k_core_to_group_ref_put(ab); if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) @@ -964,6 +967,12 @@ static int ath12k_core_start(struct ath12k_base *ab) /* Indicate the core start in the appropriate group */ ath12k_core_to_group_ref_get(ab); + ret = ath12k_link_sta_rhash_tbl_init(ab); + if (ret) { + ath12k_warn(ab, "failed to init peer addr rhash table %d\n", ret); + goto err_reo_cleanup; + } + return 0; err_reo_cleanup: @@ -1350,6 +1359,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab) int ret, total_vdev; mutex_lock(&ab->core_lock); + ath12k_link_sta_rhash_tbl_destroy(ab); ath12k_dp_pdev_free(ab); ath12k_ce_cleanup_pipes(ab); ath12k_wmi_detach(ab); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 1548116b0228f..5565cd5e0cd8a 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "qmi.h" #include "htc.h" #include "wmi.h" @@ -566,6 +567,9 @@ struct ath12k_link_sta { u8 link_idx; u32 tx_retry_failed; u32 tx_retry_count; + + /* peer addr based rhashtable list pointer */ + struct rhash_head rhash_addr; }; struct ath12k_reoq_buf { @@ -1227,6 +1231,9 @@ struct ath12k_base { */ const struct ieee80211_ops *ath12k_ops; + struct rhashtable *rhead_sta_addr; + struct rhashtable_params rhash_sta_addr_param; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 47326a30c556f..dbbe866f01e2d 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1169,6 +1169,35 @@ static int ath12k_mac_set_kickout(struct ath12k_link_vif *arvif) return 0; } +static void ath12k_mac_link_sta_rhash_cleanup(void *data, struct ieee80211_sta *sta) +{ + u8 link_id; + unsigned long links_map; + struct ath12k_sta *ahsta; + struct ath12k *ar = data; + struct ath12k_link_sta *arsta; + struct ath12k_link_vif *arvif; + struct ath12k_base *ab = ar->ab; + + ahsta = ath12k_sta_to_ahsta(sta); + links_map = ahsta->links_map; + + rcu_read_lock(); + for_each_set_bit(link_id, &links_map, IEEE80211_MLD_MAX_NUM_LINKS) { + arsta = rcu_dereference(ahsta->link[link_id]); + if (!arsta) + continue; + arvif = arsta->arvif; + if (!(arvif->ar == ar)) + continue; + + spin_lock_bh(&ab->base_lock); + ath12k_link_sta_rhash_delete(ab, arsta); + spin_unlock_bh(&ab->base_lock); + } + rcu_read_unlock(); +} + void ath12k_mac_peer_cleanup_all(struct ath12k *ar) { struct ath12k_dp_link_peer *peer, *tmp; @@ -1189,6 +1218,10 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) ar->num_peers = 0; ar->num_stations = 0; + + /* Cleanup rhash table maintained for arsta by iterating over sta */ + ieee80211_iterate_stations_mtx(ar->ah->hw, ath12k_mac_link_sta_rhash_cleanup, + ar); } static int ath12k_mac_vdev_setup_sync(struct ath12k *ar) @@ -6670,6 +6703,7 @@ static int ath12k_mac_station_remove(struct ath12k *ar, struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ath12k_vif *ahvif = arvif->ahvif; int ret = 0; + struct ath12k_link_sta *temp_arsta; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -6698,6 +6732,15 @@ static int ath12k_mac_station_remove(struct ath12k *ar, ath12k_mac_station_post_remove(ar, arvif, arsta); + spin_lock_bh(&ar->ab->base_lock); + + /* To handle roaming and split phy scenario */ + temp_arsta = ath12k_link_sta_find_by_addr(ar->ab, arsta->addr); + if (temp_arsta && temp_arsta->arvif->ar == ar) + ath12k_link_sta_rhash_delete(ar->ab, arsta); + + spin_unlock_bh(&ar->ab->base_lock); + if (sta->valid_links) ath12k_mac_free_unassign_link_sta(ahvif->ah, arsta->ahsta, arsta->link_id); @@ -6714,6 +6757,7 @@ static int ath12k_mac_station_add(struct ath12k *ar, struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ath12k_wmi_peer_create_arg peer_param = {}; int ret; + struct ath12k_link_sta *temp_arsta; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -6732,6 +6776,26 @@ static int ath12k_mac_station_add(struct ath12k *ar, } } + spin_lock_bh(&ab->base_lock); + + /* + * In case of Split PHY and roaming scenario, pdev idx + * might differ but both the pdev will share same rhash + * table. In that case update the rhash table if link_sta is + * already present + */ + temp_arsta = ath12k_link_sta_find_by_addr(ab, arsta->addr); + if (temp_arsta && temp_arsta->arvif->ar != ar) + ath12k_link_sta_rhash_delete(ab, temp_arsta); + + ret = ath12k_link_sta_rhash_add(ab, arsta); + spin_unlock_bh(&ab->base_lock); + if (ret) { + ath12k_warn(ab, "Failed to add arsta: %pM to hash table, ret: %d", + arsta->addr, ret); + goto free_rx_stats; + } + peer_param.vdev_id = arvif->vdev_id; peer_param.peer_addr = arsta->addr; peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; @@ -6780,6 +6844,10 @@ static int ath12k_mac_station_add(struct ath12k *ar, free_peer: ath12k_peer_delete(ar, arvif->vdev_id, arsta->addr); + spin_lock_bh(&ab->base_lock); + ath12k_link_sta_rhash_delete(ab, arsta); + spin_unlock_bh(&ab->base_lock); +free_rx_stats: kfree(arsta->rx_stats); arsta->rx_stats = NULL; dec_num_station: @@ -6858,6 +6926,10 @@ static void ath12k_mac_ml_station_remove(struct ath12k_vif *ahvif, ath12k_mac_station_post_remove(ar, arvif, arsta); + spin_lock_bh(&ar->ab->base_lock); + ath12k_link_sta_rhash_delete(ar->ab, arsta); + spin_unlock_bh(&ar->ab->base_lock); + ath12k_mac_free_unassign_link_sta(ah, ahsta, link_id); } diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 16f4a74712d81..28801d87e6ed2 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -406,3 +406,119 @@ int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_st return err_ret; } + +static int ath12k_link_sta_rhash_insert(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + struct ath12k_link_sta *tmp; + + lockdep_assert_held(&ab->base_lock); + + tmp = rhashtable_lookup_get_insert_fast(ab->rhead_sta_addr, &arsta->rhash_addr, + ab->rhash_sta_addr_param); + if (!tmp) + return 0; + else if (IS_ERR(tmp)) + return PTR_ERR(tmp); + else + return -EEXIST; +} + +static int ath12k_link_sta_rhash_remove(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + int ret; + + lockdep_assert_held(&ab->base_lock); + + ret = rhashtable_remove_fast(ab->rhead_sta_addr, &arsta->rhash_addr, + ab->rhash_sta_addr_param); + if (ret && ret != -ENOENT) + return ret; + + return 0; +} + +int ath12k_link_sta_rhash_add(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + int ret; + + lockdep_assert_held(&ab->base_lock); + + ret = ath12k_link_sta_rhash_insert(ab, arsta); + if (ret) + ath12k_warn(ab, "failed to add arsta %pM in rhash_addr ret %d\n", + arsta->addr, ret); + + return ret; +} + +void ath12k_link_sta_rhash_delete(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + /* + * Return type of this function is void since there is nothing to be + * done in failure case + */ + int ret; + + lockdep_assert_held(&ab->base_lock); + + ret = ath12k_link_sta_rhash_remove(ab, arsta); + if (ret) + ath12k_warn(ab, + "failed to remove arsta %pM in rhash_addr ret %d\n", + arsta->addr, ret); +} + +int ath12k_link_sta_rhash_tbl_init(struct ath12k_base *ab) +{ + struct rhashtable_params *param; + struct rhashtable *rhash_addr_tbl; + int ret; + + rhash_addr_tbl = kzalloc(sizeof(*ab->rhead_sta_addr), GFP_KERNEL); + if (!rhash_addr_tbl) + return -ENOMEM; + + param = &ab->rhash_sta_addr_param; + + param->key_offset = offsetof(struct ath12k_link_sta, addr); + param->head_offset = offsetof(struct ath12k_link_sta, rhash_addr); + param->key_len = sizeof_field(struct ath12k_link_sta, addr); + param->automatic_shrinking = true; + param->nelem_hint = ab->num_radios * ath12k_core_get_max_peers_per_radio(ab); + + ret = rhashtable_init(rhash_addr_tbl, param); + if (ret) { + ath12k_warn(ab, "failed to init peer addr rhash table %d\n", + ret); + goto err_free; + } + + ab->rhead_sta_addr = rhash_addr_tbl; + + return 0; + +err_free: + kfree(rhash_addr_tbl); + + return ret; +} + +void ath12k_link_sta_rhash_tbl_destroy(struct ath12k_base *ab) +{ + rhashtable_destroy(ab->rhead_sta_addr); + kfree(ab->rhead_sta_addr); + ab->rhead_sta_addr = NULL; +} + +struct ath12k_link_sta *ath12k_link_sta_find_by_addr(struct ath12k_base *ab, + const u8 *addr) +{ + lockdep_assert_held(&ab->base_lock); + + return rhashtable_lookup_fast(ab->rhead_sta_addr, addr, + ab->rhash_sta_addr_param); +} diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h index 81e9bcc067ff4..cf8a463d4c371 100644 --- a/drivers/net/wireless/ath/ath12k/peer.h +++ b/drivers/net/wireless/ath/ath12k/peer.h @@ -27,4 +27,10 @@ int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta); struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr); +int ath12k_link_sta_rhash_tbl_init(struct ath12k_base *ab); +void ath12k_link_sta_rhash_tbl_destroy(struct ath12k_base *ab); +void ath12k_link_sta_rhash_delete(struct ath12k_base *ab, struct ath12k_link_sta *arsta); +int ath12k_link_sta_rhash_add(struct ath12k_base *ab, struct ath12k_link_sta *arsta); +struct ath12k_link_sta *ath12k_link_sta_find_by_addr(struct ath12k_base *ab, + const u8 *addr); #endif /* _PEER_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 70d92c321fe72..158466680b521 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -7276,7 +7276,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff struct wmi_peer_sta_kickout_arg arg = {}; struct ath12k_link_vif *arvif; struct ieee80211_sta *sta; - struct ath12k_dp_link_peer *peer; + struct ath12k_link_sta *arsta; unsigned int link_id; struct ath12k *ar; @@ -7289,10 +7289,10 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_addr(ab, arg.mac_addr); + arsta = ath12k_link_sta_find_by_addr(ab, arg.mac_addr); - if (!peer) { - ath12k_warn(ab, "peer not found %pM\n", + if (!arsta) { + ath12k_warn(ab, "arsta not found %pM\n", arg.mac_addr); goto exit; } @@ -7421,10 +7421,10 @@ static void ath12k_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb) } rcu_read_lock(); - ar = ath12k_mac_get_ar_by_vdev_id(ab, le32_to_cpu(ch_info_ev.vdev_id)); + ar = arsta->arvif->ar; if (!ar) { - ath12k_warn(ab, "invalid vdev id in chan info ev %d", - ch_info_ev.vdev_id); + ath12k_warn(ab, "invalid ar in peer sta kickout ev for STA %pM\n", + arg.mac_addr); rcu_read_unlock(); return; } From 3440f97418a445b89ca3afcf688d2bf0dd40e95d Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:43 +0530 Subject: [PATCH 437/659] wifi: ath12k: Move ath12k_dp_link_peer list from ath12k_base to ath12k_dp ath12k_base maintains a linked list of ath12k_dp_link_peer. This linked list is used for all kind of peer search operations. With the modularization of device and peer objects for ath12k next-generation driver, ath12k_dp_link_peer and ath12k_dp are exclusively meant for datapath related operations. Hence move ath12k_dp_link_peer linked list from ath12k_base to ath12k_dp. This linked list is to be lock protected by newly introduced spinlock "dp_lock" defined in ath12k_dp as this list can be concurrently accessed in different contexts for insert, delete and search operations. With the above changes, update following APIs to make use of lock "dp->dp_lock" instead of lock "ab->base_lock" and also update API signatures to pass ath12k_dp pointer instead of ath12k_base pointer as the function argument. ath12k_dp_link_peer_find_by_vdev_and_addr() ath12k_dp_link_peer_find_by_id() ath12k_dp_link_peer_find_by_ast() ath12k_dp_link_peer_find_by_pdev__and_addr() ath12k_dp_link_peer_find_by_ml_id() ath12k_dp_link_peer_find_by_addr() ath12k_dp_rx_h_find_link_peer() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 - drivers/net/wireless/ath/ath12k/core.h | 1 - drivers/net/wireless/ath/ath12k/dp.c | 23 +++-- drivers/net/wireless/ath/ath12k/dp.h | 6 ++ drivers/net/wireless/ath/ath12k/dp_htt.c | 26 ++--- drivers/net/wireless/ath/ath12k/dp_mon.c | 17 ++-- drivers/net/wireless/ath/ath12k/dp_peer.c | 64 ++++++------ drivers/net/wireless/ath/ath12k/dp_peer.h | 12 +-- drivers/net/wireless/ath/ath12k/dp_rx.c | 86 ++++++++-------- drivers/net/wireless/ath/ath12k/dp_rx.h | 4 +- drivers/net/wireless/ath/ath12k/mac.c | 99 +++++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 31 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 20 ++-- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 25 ++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 3 +- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 9 +- 16 files changed, 234 insertions(+), 193 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index d58b164886645..0bd863f83cb0e 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -2261,7 +2261,6 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, spin_lock_init(&ab->base_lock); init_completion(&ab->reset_complete); - INIT_LIST_HEAD(&ab->peers); init_waitqueue_head(&ab->peer_mapping_wq); init_waitqueue_head(&ab->wmi_ab.tx_credits_wq); INIT_WORK(&ab->restart_work, ath12k_core_restart); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 5565cd5e0cd8a..bb48e93b9b937 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1092,7 +1092,6 @@ struct ath12k_base { struct ath12k_wmi_hal_reg_capabilities_ext_arg hal_reg_cap[MAX_RADIOS]; unsigned long long free_vdev_map; unsigned long long free_vdev_stats_id_map; - struct list_head peers; wait_queue_head_t peer_mapping_wq; u8 mac_addr[ETH_ALEN]; bool wmi_ready; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index afad0c2cb6b9b..ee7244d709909 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -24,27 +24,28 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); /* TODO: Any other peer specific DP cleanup */ - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n", addr, vdev_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return; } if (!peer->primary_link) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return; } ath12k_dp_rx_peer_tid_cleanup(ar, peer); crypto_free_shash(peer->tfm_mmic); peer->dp_setup_done = false; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) @@ -53,6 +54,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) struct ath12k_dp_link_peer *peer; u32 reo_dest; int ret = 0, tid; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); /* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ reo_dest = ar->dp.mac_id + 1; @@ -87,19 +89,19 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) return 0; peer_clean: - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to find the peer to del rx tid\n"); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return -ENOENT; } for (tid--; tid >= 0; tid--) ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, tid); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } @@ -1484,6 +1486,9 @@ static int ath12k_dp_setup(struct ath12k_base *ab) spin_lock_init(&dp->reo_cmd_lock); spin_lock_init(&dp->reo_rxq_flush_lock); + spin_lock_init(&dp->dp_lock); + INIT_LIST_HEAD(&dp->peers); + dp->reo_cmd_cache_flush_count = 0; dp->idle_link_rbm = ath12k_hal_get_idle_link_rbm(&ab->hal, ab->device_id); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 43a05c6f78ecd..b2c27cb7361d3 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -475,7 +475,13 @@ struct ath12k_dp { struct ath12k_hw_group *ag; u8 device_id; + /* Lock for protection of peers */ + spinlock_t dp_lock; + struct ath12k_dp_arch_ops *ops; + + /* Linked list of struct ath12k_dp_link_peer */ + struct list_head peers; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index cae5a90c1c659..f3dca108c614e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -272,18 +272,18 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, } rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, usr_stats->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, usr_stats->peer_id); if (!peer || !peer->sta) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } @@ -357,7 +357,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); } @@ -507,17 +507,17 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, ppdu_info->delay_ba) { for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); continue; } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (usr_stats->delay_ba) ath12k_copy_to_delay_stats(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } } @@ -526,17 +526,17 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { for (i = 0; i < ppdu_info->bar_num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); continue; } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (peer->delayba_flag) ath12k_copy_to_bar(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index d93a12d10b6fa..0873f11083d0b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2322,8 +2322,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, &rx_info); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; if (pubsta->valid_links) { @@ -2332,7 +2332,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", @@ -3673,11 +3673,12 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; struct ath12k_dp_link_peer *peer; u32 num_msdu; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) return; - peer = ath12k_dp_link_peer_find_by_ast(ab, user_stats->ast_index); + peer = ath12k_dp_link_peer_find_by_ast(dp, user_stats->ast_index); if (!peer) { ath12k_warn(ab, "peer ast idx %d can't be found\n", @@ -3918,8 +3919,8 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, goto free_skb; rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, ppdu_info->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, ppdu_info->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "failed to find the peer with monitor peer_id %d\n", @@ -3932,7 +3933,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); dev_kfree_skb_any(skb); continue; @@ -3946,7 +3947,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } next_skb: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 843369a00d3e4..0267f68f85734 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -9,14 +9,14 @@ #include "debug.h" struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (peer->vdev_id != vdev_id) continue; if (!ether_addr_equal(peer->addr, addr)) @@ -29,14 +29,14 @@ ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, const u8 *addr) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (peer->pdev_idx != pdev_idx) continue; if (!ether_addr_equal(peer->addr, addr)) @@ -49,13 +49,13 @@ ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr) +ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (!ether_addr_equal(peer->addr, addr)) continue; @@ -67,13 +67,13 @@ ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr) EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_addr); static struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) +ath12k_dp_link_peer_find_by_ml_id(struct ath12k_dp *dp, int ml_peer_id) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) + list_for_each_entry(peer, &dp->peers, list) if (ml_peer_id == peer->ml_id) return peer; @@ -81,49 +81,49 @@ ath12k_dp_link_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id) +ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); if (peer_id == HAL_INVALID_PEERID) return NULL; if (peer_id & ATH12K_PEER_ML_ID_VALID) - return ath12k_dp_link_peer_find_by_ml_id(ab, peer_id); + return ath12k_dp_link_peer_find_by_ml_id(dp, peer_id); - list_for_each_entry(peer, &ab->peers, list) + list_for_each_entry(peer, &dp->peers, list) if (peer_id == peer->peer_id) return peer; return NULL; } -bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id) { struct ath12k_dp_link_peer *peer; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (vdev_id == peer->vdev_id) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return true; } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return false; } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash) +ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) + list_for_each_entry(peer, &dp->peers, list) if (ast_hash == peer->ast_hash) return peer; @@ -133,10 +133,11 @@ ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash) void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) { struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -151,16 +152,17 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) wake_up(&ab->peer_mapping_wq); exit: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) { struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, mac_addr); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); if (!peer) { peer = kzalloc(sizeof(*peer), GFP_ATOMIC); if (!peer) @@ -171,7 +173,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); - list_add(&peer->list, &ab->peers); + list_add(&peer->list, &dp->peers); wake_up(&ab->peer_mapping_wq); } @@ -179,7 +181,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ vdev_id, mac_addr, peer_id); exit: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index aec73d8e35ce6..ecc90df05b444 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -69,17 +69,17 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr); +ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id); -bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); +ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id); +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); +ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, const u8 *addr); struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c2b0bce618dd2..1df13c884225a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -539,9 +539,10 @@ void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc) { struct ath12k_buffer_addr *buf_addr_info; - struct ath12k_base *ab = rx_tid->ab; + struct ath12k_dp *dp = rx_tid->dp; + struct ath12k_base *ab = dp->ab; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); if (rx_tid->dst_ring_desc) { if (rel_link_desc) { @@ -564,8 +565,10 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer { struct ath12k_dp_rx_tid *rx_tid; int i; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - lockdep_assert_held(&ar->ab->base_lock); + lockdep_assert_held(&dp->dp_lock); for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->rx_tid[i]; @@ -573,9 +576,9 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); timer_delete_sync(&rx_tid->frag_timer); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); } } @@ -616,24 +619,24 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ dma_addr_t paddr_aligned; int ret; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to set up rx tid\n"); return -ENOENT; } if (ab->hw_params->dp_primary_link_only && !peer->primary_link) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } if (ab->hw_params->reoq_lut_support && (!dp->reoq_lut.vaddr || !dp->ml_reoq_lut.vaddr)) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "reo qref table is not setup\n"); return -EINVAL; } @@ -641,7 +644,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ if (peer->peer_id > DP_MAX_PEER_ID || tid > IEEE80211_NUM_TIDS) { ath12k_warn(ab, "peer id of peer %d or tid %d doesn't allow reoq setup\n", peer->peer_id, tid); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return -EINVAL; } @@ -650,7 +653,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ if (rx_tid->active) { ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, ba_win_sz, ssn, true); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d\n", tid); return ret; @@ -679,7 +682,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ ahsta = ath12k_sta_to_ahsta(peer->sta); ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); if (ret) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); return ret; } @@ -709,9 +712,9 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, paddr_aligned); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } else { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ret = ath12k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id, peer_mac, paddr_aligned, tid, 1, ba_win_sz); @@ -753,6 +756,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, u8 link_id) { struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(params->sta); struct ath12k_link_sta *arsta; @@ -769,11 +773,11 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, vdev_id = arsta->arvif->vdev_id; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, arsta->addr); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n"); return -ENOENT; } @@ -781,12 +785,12 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, active = peer->rx_tid[params->tid].active; if (!active) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", params->tid, ret); @@ -803,6 +807,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, { struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; @@ -817,12 +822,12 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return 0; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n", peer_addr); return -ENOENT; @@ -847,7 +852,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } @@ -1168,22 +1173,22 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu } struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ath12k_dp_link_peer *peer = NULL; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); if (rxcb->peer_id) - peer = ath12k_dp_link_peer_find_by_id(ab, rxcb->peer_id); + peer = ath12k_dp_link_peer_find_by_id(dp, rxcb->peer_id); if (peer) return peer; if (rx_info->addr2_present) - peer = ath12k_dp_link_peer_find_by_addr(ab, rx_info->addr2); + peer = ath12k_dp_link_peer_find_by_addr(dp, rx_info->addr2); return peer; } @@ -1347,8 +1352,8 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc bool is_mcbc = rxcb->is_mcbc; bool is_eapol = rxcb->is_eapol; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); pubsta = peer ? peer->sta : NULL; @@ -1357,7 +1362,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc status->link_id = peer->link_id; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", @@ -1455,14 +1460,14 @@ static void ath12k_dp_rx_frag_timer(struct timer_list *timer) struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer, frag_timer); - spin_lock_bh(&rx_tid->ab->base_lock); + spin_lock_bh(&rx_tid->dp->dp_lock); if (rx_tid->last_frag_no && rx_tid->rx_frag_bitmap == GENMASK(rx_tid->last_frag_no, 0)) { - spin_unlock_bh(&rx_tid->ab->base_lock); + spin_unlock_bh(&rx_tid->dp->dp_lock); return; } ath12k_dp_rx_frags_cleanup(rx_tid, true); - spin_unlock_bh(&rx_tid->ab->base_lock); + spin_unlock_bh(&rx_tid->dp->dp_lock); } int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id) @@ -1472,37 +1477,38 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; int i; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); tfm = crypto_alloc_shash("michael_mic", 0, 0); if (IS_ERR(tfm)) return PTR_ERR(tfm); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); crypto_free_shash(tfm); ath12k_warn(ab, "failed to find the peer to set up fragment info\n"); return -ENOENT; } if (!peer->primary_link) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); crypto_free_shash(tfm); return 0; } for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->rx_tid[i]; - rx_tid->ab = ab; + rx_tid->dp = dp; timer_setup(&rx_tid->frag_timer, ath12k_dp_rx_frag_timer, 0); skb_queue_head_init(&rx_tid->rx_frags); } peer->tfm_mmic = tfm; peer->dp_setup_done = true; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index ff568254b686f..365f2c6449e42 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -28,7 +28,7 @@ struct ath12k_dp_rx_tid { /* Timer info related to fragments */ struct timer_list frag_timer; - struct ath12k_base *ab; + struct ath12k_dp *dp; }; struct ath12k_dp_rx_tid_rxq { @@ -244,7 +244,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index dbbe866f01e2d..c1750e412c8ca 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1202,11 +1202,12 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) { struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ab->base_lock); - list_for_each_entry_safe(peer, tmp, &ab->peers, list) { + spin_lock_bh(&dp->dp_lock); + list_for_each_entry_safe(peer, tmp, &dp->peers, list) { /* Skip Rx TID cleanup for self peer */ if (peer->sta) ath12k_dp_rx_peer_tid_cleanup(ar, peer); @@ -1214,7 +1215,7 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) list_del(&peer->list); kfree(peer); } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ar->num_peers = 0; ar->num_stations = 0; @@ -3768,6 +3769,7 @@ static void ath12k_bss_assoc(struct ath12k *ar, bool is_auth = false; u32 hemode = 0; int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -3879,14 +3881,14 @@ static void ath12k_bss_assoc(struct ath12k *ar, "mac vdev %d up (associated) bssid %pM aid %d\n", arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arvif->bssid); if (peer && peer->is_authorized) is_auth = true; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); /* Authorize BSS Peer */ if (is_auth) { @@ -5704,15 +5706,18 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, int ret; int i; u32 flags = 0; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, addr); - spin_unlock_bh(&ab->base_lock); - - if (!peer) + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, addr); + if (!peer) { + spin_unlock_bh(&dp->dp_lock); return -ENOENT; + } + + spin_unlock_bh(&dp->dp_lock); for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { if (!peer->keys[i]) @@ -5728,9 +5733,9 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, ath12k_warn(ab, "failed to remove peer key %d: %d\n", i, ret); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); peer->keys[i] = NULL; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } return first_errno; @@ -5748,6 +5753,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, const u8 *peer_addr; int ret; u32 flags = 0; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -5767,12 +5773,12 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, /* the peer should not disappear in mid-way (unless FW goes awry) since * we already hold wiphy lock. we just make sure its there now. */ - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - spin_unlock_bh(&ab->base_lock); - if (!peer) { + spin_unlock_bh(&dp->dp_lock); + if (cmd == SET_KEY) { ath12k_warn(ab, "cannot install key for non-existent peer %pM\n", peer_addr); @@ -5785,6 +5791,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, return 0; } + spin_unlock_bh(&dp->dp_lock); + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) flags = WMI_KEY_PAIRWISE; else @@ -5802,8 +5810,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, return ret; } - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; @@ -5844,7 +5852,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } @@ -6604,14 +6612,15 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); ath12k_mac_dec_num_stations(arvif, arsta); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (peer && peer->sta == sta) { ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", @@ -6622,7 +6631,7 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, ar->num_peers--; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); kfree(arsta->rx_stats); arsta->rx_stats = NULL; @@ -6634,17 +6643,18 @@ static int ath12k_mac_station_unauthorize(struct ath12k *ar, { struct ath12k_dp_link_peer *peer; int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (peer) peer->is_authorized = false; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); /* Driver must clear the keys during the state change from * IEEE80211_STA_AUTHORIZED to IEEE80211_STA_ASSOC, since after @@ -6669,17 +6679,18 @@ static int ath12k_mac_station_authorize(struct ath12k *ar, struct ath12k_dp_link_peer *peer; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (peer) peer->is_authorized = true; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) { ret = ath12k_wmi_set_peer_param(ar, arsta->addr, @@ -7585,6 +7596,7 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, struct ath12k_link_vif *arvif; struct ath12k_dp_link_peer *peer; u32 bw, smps; + struct ath12k_dp *dp; rcu_read_lock(); arvif = rcu_dereference(ahvif->link[link_sta->link_id]); @@ -7596,6 +7608,7 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, } ar = arvif->ar; + dp = ath12k_ab_to_dp(ar->ab); arsta = rcu_dereference(ahsta->link[link_sta->link_id]); if (!arsta) { @@ -7604,19 +7617,19 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, link_sta->link_id, sta->addr); return; } - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (!peer) { - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); ath12k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n", arsta->addr, arvif->vdev_id); return; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (arsta->link_id >= IEEE80211_MLD_MAX_NUM_LINKS) { rcu_read_unlock(); @@ -9246,6 +9259,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, u16 mcbc_gsn; u8 link_id; int ret; + struct ath12k_dp *tmp_dp; if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { ieee80211_free_txskb(hw, skb); @@ -9374,11 +9388,12 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (unlikely(!ahvif->dp_vif.key_cipher)) goto skip_peer_find; - spin_lock_bh(&tmp_ar->ab->base_lock); - peer = ath12k_dp_link_peer_find_by_addr(tmp_ar->ab, + tmp_dp = ath12k_ab_to_dp(tmp_ar->ab); + spin_lock_bh(&tmp_dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, tmp_arvif->bssid); if (!peer) { - spin_unlock_bh(&tmp_ar->ab->base_lock); + spin_unlock_bh(&tmp_dp->dp_lock); ath12k_warn(tmp_ar->ab, "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", tmp_arvif->vdev_id, tmp_arvif->bssid, @@ -9397,7 +9412,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); } - spin_unlock_bh(&tmp_ar->ab->base_lock); + spin_unlock_bh(&tmp_dp->dp_lock); skip_peer_find: ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, @@ -11994,7 +12009,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (ab->hw_params->vdev_start_delay && ahvif->vdev_type != WMI_VDEV_TYPE_AP && ahvif->vdev_type != WMI_VDEV_TYPE_MONITOR && - !ath12k_dp_link_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { + !ath12k_dp_link_peer_exist_by_vdev_id(ath12k_ab_to_dp(ab), arvif->vdev_id)) { ret = 0; goto out; } @@ -12876,6 +12891,8 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban struct ath12k_dp_link_peer *peer, *tmp; u8 vht_nss, he_nss, eht_nss; int ret = true; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); vht_mcs_mask = mask->control[band].vht_mcs; he_mcs_mask = mask->control[band].he_mcs; @@ -12898,8 +12915,8 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban eht_nss = ath12k_mac_max_eht_nss(eht_mcs_mask); rcu_read_lock(); - spin_lock_bh(&ar->ab->base_lock); - list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) { + spin_lock_bh(&dp->dp_lock); + list_for_each_entry_safe(peer, tmp, &dp->peers, list) { if (peer->sta) { link_sta = rcu_dereference(peer->sta->link[link_id]); if (!link_sta) { @@ -12925,7 +12942,7 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban } } exit: - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 28801d87e6ed2..68eebaa24ed9c 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -29,15 +29,16 @@ static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_ const u8 *addr, bool expect_mapped) { int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); ret = wait_event_timeout(ab->peer_mapping_wq, ({ bool mapped; - spin_lock_bh(&ab->base_lock); - mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(ab, + spin_lock_bh(&dp->dp_lock); + mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); (mapped == expect_mapped || test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)); @@ -53,11 +54,12 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) { struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ab->base_lock); - list_for_each_entry_safe(peer, tmp, &ab->peers, list) { + spin_lock_bh(&dp->dp_lock); + list_for_each_entry_safe(peer, tmp, &dp->peers, list) { if (peer->vdev_id != vdev_id) continue; @@ -69,7 +71,7 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) ar->num_peers--; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } static int ath12k_wait_for_peer_deleted(struct ath12k *ar, int vdev_id, const u8 *addr) @@ -156,6 +158,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_sta *ahsta; u16 ml_peer_id; int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -167,14 +170,14 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, return -ENOBUFS; } - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_link_peer_find_by_pdev_and_addr(ar->ab, ar->pdev_idx, + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_pdev_and_addr(dp, ar->pdev_idx, arg->peer_addr); if (peer) { - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return -EINVAL; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ret = ath12k_wmi_send_peer_create_cmd(ar, arg); if (ret) { @@ -189,12 +192,12 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, if (ret) return ret; - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arg->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arg->vdev_id, arg->peer_addr); if (!peer) { - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", arg->peer_addr, arg->vdev_id); @@ -255,7 +258,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, ar->num_peers++; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 4180db504c312..da745566aca37 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -37,6 +37,7 @@ void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u1 qref->info1 = u32_encode_bits(upper_32_bits(paddr), BUFFER_ADDR_INFO1_ADDR) | u32_encode_bits(tid, DP_REO_QREF_NUM); + ath12k_hal_reo_shared_qaddr_cache_clear(ab); } @@ -316,7 +317,6 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; @@ -332,8 +332,8 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (rxcb->is_mcbc) rxcb->peer_id = rx_info->peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -347,7 +347,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, } else { enctype = HAL_ENCRYPT_TYPE_OPEN; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) is_decrypted = rx_info->is_decrypted; @@ -1133,8 +1133,8 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (WARN_ON_ONCE(!frag_no && !more_frags)) return -EINVAL; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", peer_id); @@ -1193,11 +1193,11 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, goto out_unlock; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); timer_delete_sync(&rx_tid->frag_timer); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) goto err_frags_cleanup; @@ -1221,7 +1221,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, dev_kfree_skb_any(defrag_skb); ath12k_dp_rx_frags_cleanup(rx_tid, true); out_unlock: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 3d06987cfc0e6..77de02858677a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -396,6 +396,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); @@ -448,18 +449,18 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, } } rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); goto exit; } else { status.sta = peer->sta; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); status.info = info; status.skb = msdu; @@ -527,12 +528,12 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, u8 rate_idx = 0; int ret; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return; } sta = peer->sta; @@ -546,7 +547,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, txrate.nss = arsta->last_txrate.nss; else txrate.nss = arsta->peer_nss; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); switch (ts->pkt_type) { case HAL_TX_RATE_STATS_PKT_TYPE_11A: @@ -746,20 +747,20 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } ahsta = ath12k_sta_to_ahsta(peer->sta); arsta = &ahsta->deflink; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); status.sta = peer->sta; status.info = info; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index d9eaf9f66634d..28a0564a93fd7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -953,8 +953,9 @@ void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) { u32 val; struct ath12k_hal *hal = &ab->hal; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal)); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index a3ea42fc09331..80f499b5df35c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -116,15 +116,16 @@ ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar); struct ath12k_base *ab = arvif->ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); __le16 fc = mgmt->frame_control; - spin_lock_bh(&ab->base_lock); - if (!ath12k_dp_link_peer_find_by_addr(ab, mgmt->da) && + spin_lock_bh(&dp->dp_lock); + if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da) && !ath12k_peer_ml_find(ah, mgmt->da)) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return false; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (vif->type == NL80211_IFTYPE_STATION) return arvif->is_up && From ba2a2f25923f0190a1275bd2985b3d2db20fcafd Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:44 +0530 Subject: [PATCH 438/659] wifi: ath12k: Add hash table for ath12k_dp_link_peer There is a linked list of ath12k_dp_link_peer maintained in ath12k_dp. For link peer search based on mac address, there is iteration over the list wherein the mac address are compared for each entry in the list. This search operation is a costly operation considering the time complexity involved. In order to reduce the complexity, add hash table for ath12k_dp_link_peer in ath12k_dp where mac address of the link peer is used to derive the hash index. This hash table is lock protected by spinlock "dp_lock" present in ath12k_dp. This hash table is currently used for search of link peer using mac address for any interaction between control path and data path, per packet Rx monitor path and regular multicast Tx path. Update API ath12k_dp_link_peer_find_by_addr() to make use of the hash table for search operation using mac address, while other search APIs still rely on linked list. ath11k driver has been taken as reference for implementation of hash table. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 14 ++- drivers/net/wireless/ath/ath12k/dp.h | 10 +- drivers/net/wireless/ath/ath12k/dp_peer.c | 138 ++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/dp_peer.h | 9 ++ drivers/net/wireless/ath/ath12k/mac.c | 2 + 5 files changed, 160 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index ee7244d709909..03bcecd340134 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1122,6 +1122,8 @@ static void ath12k_dp_cleanup(struct ath12k_base *ab) struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; + ath12k_dp_link_peer_rhash_tbl_destroy(dp); + if (!dp->ab) return; @@ -1489,14 +1491,22 @@ static int ath12k_dp_setup(struct ath12k_base *ab) spin_lock_init(&dp->dp_lock); INIT_LIST_HEAD(&dp->peers); + mutex_init(&dp->link_peer_rhash_tbl_lock); + dp->reo_cmd_cache_flush_count = 0; dp->idle_link_rbm = ath12k_hal_get_idle_link_rbm(&ab->hal, ab->device_id); + ret = ath12k_dp_link_peer_rhash_tbl_init(dp); + if (ret) { + ath12k_warn(ab, "failed to init link_peer rhash table: %d\n", ret); + return ret; + } + ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret); - return ret; + goto rhash_destroy; } srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id]; @@ -1577,6 +1587,8 @@ static int ath12k_dp_setup(struct ath12k_base *ab) fail_link_desc_cleanup: ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); +rhash_destroy: + ath12k_dp_link_peer_rhash_tbl_destroy(dp); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index b2c27cb7361d3..ca4b99bad16c5 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -10,6 +10,7 @@ #include "hw.h" #include "dp_htt.h" #include "dp_cmn.h" +#include #define MAX_RXDMA_PER_PDEV 2 @@ -475,13 +476,20 @@ struct ath12k_dp { struct ath12k_hw_group *ag; u8 device_id; - /* Lock for protection of peers */ + /* Lock for protection of peers and rhead_peer_addr */ spinlock_t dp_lock; struct ath12k_dp_arch_ops *ops; /* Linked list of struct ath12k_dp_link_peer */ struct list_head peers; + + /* For rhash table init and deinit protection */ + struct mutex link_peer_rhash_tbl_lock; + + /* The rhashtable containing struct ath12k_link_peer keyed by mac addr */ + struct rhashtable *rhead_peer_addr; + struct rhashtable_params rhash_peer_addr_param; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 0267f68f85734..0cf28791568e7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -51,18 +51,10 @@ ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr) { - struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &dp->peers, list) { - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; + return rhashtable_lookup_fast(dp->rhead_peer_addr, addr, + dp->rhash_peer_addr_param); } EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_addr); @@ -147,6 +139,7 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", peer->vdev_id, peer->addr, peer_id); + ath12k_dp_link_peer_rhash_delete(dp, peer); list_del(&peer->list); kfree(peer); wake_up(&ab->peer_mapping_wq); @@ -160,6 +153,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ { struct ath12k_dp_link_peer *peer; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + int ret; spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); @@ -173,7 +167,11 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); - list_add(&peer->list, &dp->peers); + ret = ath12k_dp_link_peer_rhash_add(dp, peer); + if (!ret) + list_add(&peer->list, &dp->peers); + else + kfree(peer); wake_up(&ab->peer_mapping_wq); } @@ -209,3 +207,121 @@ struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, } return arsta; } + +static int ath12k_dp_link_peer_rhash_addr_tbl_init(struct ath12k_dp *dp) +{ + struct ath12k_base *ab = dp->ab; + struct rhashtable_params *param; + struct rhashtable *rhash_addr_tbl; + int ret; + + lockdep_assert_held(&dp->link_peer_rhash_tbl_lock); + + rhash_addr_tbl = kzalloc(sizeof(*dp->rhead_peer_addr), GFP_KERNEL); + if (!rhash_addr_tbl) + return -ENOMEM; + + param = &dp->rhash_peer_addr_param; + + param->key_offset = offsetof(struct ath12k_dp_link_peer, addr); + param->head_offset = offsetof(struct ath12k_dp_link_peer, rhash_addr); + param->key_len = sizeof_field(struct ath12k_dp_link_peer, addr); + param->automatic_shrinking = true; + param->nelem_hint = ab->num_radios * ath12k_core_get_max_peers_per_radio(ab); + + ret = rhashtable_init(rhash_addr_tbl, param); + if (ret) { + ath12k_warn(ab, "failed to init peer addr rhash table %d\n", ret); + goto err_free; + } + + dp->rhead_peer_addr = rhash_addr_tbl; + + return 0; + +err_free: + kfree(rhash_addr_tbl); + + return ret; +} + +int ath12k_dp_link_peer_rhash_tbl_init(struct ath12k_dp *dp) +{ + int ret; + + mutex_lock(&dp->link_peer_rhash_tbl_lock); + ret = ath12k_dp_link_peer_rhash_addr_tbl_init(dp); + mutex_unlock(&dp->link_peer_rhash_tbl_lock); + + return ret; +} + +void ath12k_dp_link_peer_rhash_tbl_destroy(struct ath12k_dp *dp) +{ + mutex_lock(&dp->link_peer_rhash_tbl_lock); + rhashtable_destroy(dp->rhead_peer_addr); + kfree(dp->rhead_peer_addr); + dp->rhead_peer_addr = NULL; + mutex_unlock(&dp->link_peer_rhash_tbl_lock); +} + +static int ath12k_dp_link_peer_rhash_insert(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + struct ath12k_dp_link_peer *tmp; + + lockdep_assert_held(&dp->dp_lock); + + tmp = rhashtable_lookup_get_insert_fast(dp->rhead_peer_addr, &peer->rhash_addr, + dp->rhash_peer_addr_param); + if (!tmp) + return 0; + else if (IS_ERR(tmp)) + return PTR_ERR(tmp); + else + return -EEXIST; +} + +static int ath12k_dp_link_peer_rhash_remove(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + int ret; + + lockdep_assert_held(&dp->dp_lock); + + ret = rhashtable_remove_fast(dp->rhead_peer_addr, &peer->rhash_addr, + dp->rhash_peer_addr_param); + if (ret && ret != -ENOENT) + return ret; + + return 0; +} + +int ath12k_dp_link_peer_rhash_add(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + int ret; + + lockdep_assert_held(&dp->dp_lock); + + ret = ath12k_dp_link_peer_rhash_insert(dp, peer); + if (ret) + ath12k_warn(dp, "failed to add peer %pM with id %d in rhash_addr ret %d\n", + peer->addr, peer->peer_id, ret); + + return ret; +} + +void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + /* No failure handling and hence return type is void */ + int ret; + + lockdep_assert_held(&dp->dp_lock); + + ret = ath12k_dp_link_peer_rhash_remove(dp, peer); + if (ret) + ath12k_warn(dp, "failed to remove peer %pM with id %d in rhash_addr ret %d\n", + peer->addr, peer->peer_id, ret); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index ecc90df05b444..b94a9a5cb311c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -63,6 +63,9 @@ struct ath12k_dp_link_peer { /* for reference to ath12k_link_sta */ u8 link_id; bool ucast_ra_only; + + /* peer addr based rhashtable list pointer */ + struct rhash_head rhash_addr; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); @@ -83,4 +86,10 @@ ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, const u8 *addr); struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer); +int ath12k_dp_link_peer_rhash_tbl_init(struct ath12k_dp *dp); +void ath12k_dp_link_peer_rhash_tbl_destroy(struct ath12k_dp *dp); +int ath12k_dp_link_peer_rhash_add(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer); +void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index c1750e412c8ca..15b5243fc54a6 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1212,6 +1212,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) if (peer->sta) ath12k_dp_rx_peer_tid_cleanup(ar, peer); + ath12k_dp_link_peer_rhash_delete(dp, peer); + list_del(&peer->list); kfree(peer); } From 2032d119c8028024f2671d44b86de2d30a371662 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:45 +0530 Subject: [PATCH 439/659] wifi: ath12k: Define ath12k_dp_peer structure & APIs for create & delete Define the structure of ath12k_dp_peer and also define APIs for creation and deletion of ath12k_dp_peer based on STA state, as the ath12k_dp_peer is intended to be used in the subsequent set of patches. Maintain ath12k_dp_peer in a linked list in ath12k_dp_hw (which is a datapath component of ath12k_hw) and protect this list using spinlock "peer_lock". Store peer id based table (array of RCU pointers) of ath12k_dp_peer in ath12k_dp_hw. Use this peer id table to refer in the per packet Tx and Rx paths as it provides faster access to ath12k_dp_peer in comparison to linked list iterative search using peer id or mac address. Add support to handle deletion of ath12k_dp_peer in case of core reset. This patch is adding and deleting ath12k_dp_peer created for MLO STA to the above mentioned RCU pointer table. Addition and deletion of ath12k_dp_peer for non-MLO STA to RCU pointer table is handled in the subsequent following patch. Structure ath12k_ml_peer is created and deleted for MLO peers at the time of connect and disconnect and there is no other use case of it. With the above design in place for ath12k_dp_peer, ath12k_ml_peer becomes redundant. Hence, remove the structure ath12k_ml_peer and the list "ml_peers" present in ath12k_hw maintaining linked list of ath12k_ml_peer. APIs removed: - ath12k_peer_ml_find() - ath12k_peer_ml_create() - ath12k_peer_ml_delete() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/core.h | 3 +- drivers/net/wireless/ath/ath12k/dp_cmn.h | 22 ++++ drivers/net/wireless/ath/ath12k/dp_peer.c | 126 +++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_peer.h | 24 ++++ drivers/net/wireless/ath/ath12k/mac.c | 115 +++++++++++++++++-- drivers/net/wireless/ath/ath12k/mac.h | 1 + drivers/net/wireless/ath/ath12k/peer.c | 81 +------------ drivers/net/wireless/ath/ath12k/peer.h | 9 +- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 14 ++- 10 files changed, 291 insertions(+), 105 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 0bd863f83cb0e..0ab9a09d43a89 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1575,6 +1575,7 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab) ath12k_core_halt(ar); } + ath12k_mac_dp_peer_cleanup(ah); break; case ATH12K_HW_STATE_OFF: ath12k_warn(ab, diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index bb48e93b9b937..37e3bf0678a2f 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -842,8 +842,7 @@ struct ath12k_hw { DECLARE_BITMAP(free_ml_peer_id_map, ATH12K_MAX_MLO_PEERS); - /* protected by wiphy_lock() */ - struct list_head ml_peers; + struct ath12k_dp_hw dp_hw; /* Keep last */ struct ath12k radio[] __aligned(sizeof(void *)); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 243fb5a680167..52b7fa2eb138b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -10,6 +10,21 @@ struct ath12k_hw_group; +/* + * ML Peer IDs start from 8192, assuming max SLO clients count 1536, + * then max peer id shall be 9728, therefore rounding the peer table size + * to the nearest next power of 2 i.e 16384. + */ +#define MAX_DP_PEER_LIST_SIZE 16384 + +struct ath12k_dp_hw { + struct ath12k_dp_peer __rcu *dp_peers[MAX_DP_PEER_LIST_SIZE]; + + /* Lock for protection of dp_peer_list and peers */ + spinlock_t peer_lock; + struct list_head dp_peers_list; +}; + struct ath12k_dp_hw_group { struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; }; @@ -52,6 +67,13 @@ struct ath12k_per_peer_tx_stats { bool is_ampdu; }; +struct ath12k_dp_peer_create_params { + struct ieee80211_sta *sta; + bool is_mlo; + u16 peer_id; + bool ucast_ra_only; +}; + static inline struct ath12k_dp_link_vif * ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) { diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 0cf28791568e7..a2834d043dd52 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -325,3 +325,129 @@ void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, ath12k_warn(dp, "failed to remove peer %pM with id %d in rhash_addr ret %d\n", peer->addr, peer->peer_id, ret); } + +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr(struct ath12k_dp_hw *dp_hw, u8 *addr) +{ + struct ath12k_dp_peer *peer; + + lockdep_assert_held(&dp_hw->peer_lock); + + list_for_each_entry(peer, &dp_hw->dp_peers_list, list) { + if (ether_addr_equal(peer->addr, addr)) + return peer; + } + + return NULL; +} +EXPORT_SYMBOL(ath12k_dp_peer_find_by_addr); + +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw *dp_hw, + u8 *addr, + struct ieee80211_sta *sta) +{ + struct ath12k_dp_peer *dp_peer; + + lockdep_assert_held(&dp_hw->peer_lock); + + list_for_each_entry(dp_peer, &dp_hw->dp_peers_list, list) { + if (ether_addr_equal(dp_peer->addr, addr) && (dp_peer->sta == sta)) + return dp_peer; + } + + return NULL; +} + +static struct ath12k_dp_peer *ath12k_dp_peer_create_find(struct ath12k_dp_hw *dp_hw, + u8 *addr, + struct ieee80211_sta *sta, + bool mlo_peer) +{ + struct ath12k_dp_peer *dp_peer; + + lockdep_assert_held(&dp_hw->peer_lock); + + list_for_each_entry(dp_peer, &dp_hw->dp_peers_list, list) { + if (ether_addr_equal(dp_peer->addr, addr)) { + if (!sta || mlo_peer || dp_peer->is_mlo || + dp_peer->sta == sta) + return dp_peer; + } + } + + return NULL; +} + +int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ath12k_dp_peer_create_params *params) +{ + struct ath12k_dp_peer *dp_peer; + + spin_lock_bh(&dp_hw->peer_lock); + dp_peer = ath12k_dp_peer_create_find(dp_hw, addr, params->sta, params->is_mlo); + if (dp_peer) { + spin_unlock_bh(&dp_hw->peer_lock); + return -EEXIST; + } + spin_unlock_bh(&dp_hw->peer_lock); + + dp_peer = kzalloc(sizeof(*dp_peer), GFP_ATOMIC); + if (!dp_peer) + return -ENOMEM; + + ether_addr_copy(dp_peer->addr, addr); + dp_peer->sta = params->sta; + dp_peer->is_mlo = params->is_mlo; + + /* + * For MLO client, the host assigns the ML peer ID, so set peer_id in dp_peer + * For non-MLO client, host gets link peer ID from firmware and will be + * assigned at the time of link peer creation + */ + dp_peer->peer_id = params->is_mlo ? params->peer_id : ATH12K_DP_PEER_ID_INVALID; + dp_peer->ucast_ra_only = params->ucast_ra_only; + + dp_peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + dp_peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + + spin_lock_bh(&dp_hw->peer_lock); + + list_add(&dp_peer->list, &dp_hw->dp_peers_list); + + /* + * For MLO client, the peer_id for ath12k_dp_peer is allocated by host + * and that peer_id is known at this point, and hence this ath12k_dp_peer + * can be added to the RCU table using the peer_id. + * For non-MLO client, this addition to RCU table shall be done at the + * time of assignment of ath12k_dp_link_peer to ath12k_dp_peer. + */ + if (dp_peer->is_mlo) + rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], dp_peer); + + spin_unlock_bh(&dp_hw->peer_lock); + + return 0; +} + +void ath12k_dp_peer_delete(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ieee80211_sta *sta) +{ + struct ath12k_dp_peer *dp_peer; + + spin_lock_bh(&dp_hw->peer_lock); + + dp_peer = ath12k_dp_peer_find_by_addr_and_sta(dp_hw, addr, sta); + if (!dp_peer) { + spin_unlock_bh(&dp_hw->peer_lock); + return; + } + + if (dp_peer->is_mlo) + rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], NULL); + + list_del(&dp_peer->list); + + spin_unlock_bh(&dp_hw->peer_lock); + + synchronize_rcu(); + kfree(dp_peer); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index b94a9a5cb311c..b4aa4f09337e0 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -9,6 +9,8 @@ #include "dp_rx.h" +#define ATH12K_DP_PEER_ID_INVALID 0x3FFF + struct ppdu_user_delayba { u16 sw_peer_id; u32 info0; @@ -71,6 +73,20 @@ struct ath12k_dp_link_peer { void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); + +struct ath12k_dp_peer { + struct list_head list; + struct ieee80211_sta *sta; + int peer_id; + u8 addr[ETH_ALEN]; + bool is_mlo; + + u16 sec_type; + u16 sec_type_grp; + + bool ucast_ra_only; +}; + struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr); @@ -92,4 +108,12 @@ int ath12k_dp_link_peer_rhash_add(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer); void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer); +int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ath12k_dp_peer_create_params *params); +void ath12k_dp_peer_delete(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ieee80211_sta *sta); +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr(struct ath12k_dp_hw *dp_hw, u8 *addr); +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw *dp_hw, + u8 *addr, + struct ieee80211_sta *sta); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 15b5243fc54a6..1253a4b734b0c 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1203,6 +1203,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_link_vif *arvif, *tmp_vif; + struct ath12k_dp_hw *dp_hw = &ar->ah->dp_hw; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -1225,6 +1227,42 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) /* Cleanup rhash table maintained for arsta by iterating over sta */ ieee80211_iterate_stations_mtx(ar->ah->hw, ath12k_mac_link_sta_rhash_cleanup, ar); + + /* Delete all the self dp_peers on asserted radio */ + list_for_each_entry_safe_reverse(arvif, tmp_vif, &ar->arvifs, list) { + if (arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) { + ath12k_dp_peer_delete(dp_hw, arvif->bssid, NULL); + arvif->num_stations = 0; + } + } +} + +void ath12k_mac_dp_peer_cleanup(struct ath12k_hw *ah) +{ + struct list_head peers; + struct ath12k_dp_peer *dp_peer, *tmp; + struct ath12k_dp_hw *dp_hw = &ah->dp_hw; + + INIT_LIST_HEAD(&peers); + + spin_lock_bh(&dp_hw->peer_lock); + list_for_each_entry_safe(dp_peer, tmp, &dp_hw->dp_peers_list, list) { + if (dp_peer->is_mlo) { + rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], NULL); + clear_bit(dp_peer->peer_id, ah->free_ml_peer_id_map); + } + + list_move(&dp_peer->list, &peers); + } + + spin_unlock_bh(&dp_hw->peer_lock); + + synchronize_rcu(); + + list_for_each_entry_safe(dp_peer, tmp, &peers, list) { + list_del(&dp_peer->list); + kfree(dp_peer); + } } static int ath12k_mac_vdev_setup_sync(struct ath12k *ar) @@ -4126,6 +4164,8 @@ static void ath12k_mac_remove_link_interface(struct ieee80211_hw *hw, if (ret) ath12k_warn(ar->ab, "failed to submit AP self-peer removal on vdev %d link id %d: %d", arvif->vdev_id, arvif->link_id, ret); + + ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); } ath12k_mac_vdev_delete(ar, arvif); } @@ -6946,7 +6986,10 @@ static void ath12k_mac_ml_station_remove(struct ath12k_vif *ahvif, ath12k_mac_free_unassign_link_sta(ah, ahsta, link_id); } - ath12k_peer_ml_delete(ah, sta); + if (sta->mlo) { + clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map); + ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID; + } } static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw, @@ -7385,7 +7428,8 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, u16 selected_links = 0; u8 link_id = 0, i; struct ath12k *ar; - int ret; + int ret = -EINVAL; + struct ath12k_dp_peer_create_params dp_params = {}; lockdep_assert_wiphy(hw->wiphy); @@ -7408,12 +7452,28 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, /* ML sta */ if (sta->mlo && !ahsta->links_map && (hweight16(sta->valid_links) == 1)) { - ret = ath12k_peer_ml_create(ah, sta); - if (ret) { - ath12k_hw_warn(ah, "unable to create ML peer for sta %pM", + ahsta->ml_peer_id = ath12k_peer_ml_alloc(ah); + if (ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID) { + ath12k_hw_warn(ah, "unable to allocate ML peer id for sta %pM", sta->addr); goto exit; } + + dp_params.is_mlo = true; + dp_params.peer_id = ahsta->ml_peer_id | ATH12K_PEER_ML_ID_VALID; + } + + dp_params.sta = sta; + + if (vif->type == NL80211_IFTYPE_AP) + dp_params.ucast_ra_only = true; + + ret = ath12k_dp_peer_create(&ah->dp_hw, sta->addr, &dp_params); + if (ret) { + ath12k_hw_warn(ah, "unable to create ath12k_dp_peer for sta %pM, ret: %d", + sta->addr, ret); + + goto ml_peer_id_clear; } ret = ath12k_mac_assign_link_sta(ah, ahsta, arsta, ahvif, @@ -7421,7 +7481,7 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, if (ret) { ath12k_hw_warn(ah, "unable assign link %d for sta %pM", link_id, sta->addr); - goto exit; + goto peer_delete; } /* above arsta will get memset, hence do this after assign @@ -7491,7 +7551,12 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, if (ret) { ath12k_hw_warn(ah, "unable to move link sta %d of sta %pM from state %d to %d", link_id, arsta->addr, old_state, new_state); - goto exit; + + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + goto peer_delete; + else + goto exit; } } @@ -7519,11 +7584,23 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, * handler below */ if (old_state == IEEE80211_STA_NONE && - new_state == IEEE80211_STA_NOTEXIST && sta->mlo) - ath12k_mac_ml_station_remove(ahvif, ahsta); + new_state == IEEE80211_STA_NOTEXIST) { + if (sta->mlo) + ath12k_mac_ml_station_remove(ahvif, ahsta); + + ath12k_dp_peer_delete(&ah->dp_hw, sta->addr, sta); + } ret = 0; + goto exit; +peer_delete: + ath12k_dp_peer_delete(&ah->dp_hw, sta->addr, sta); +ml_peer_id_clear: + if (sta->mlo) { + clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map); + ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID; + } exit: /* update the state if everything went well */ if (!ret) @@ -10153,6 +10230,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) int ret, vdev_id; u8 link_id; struct ath12k_dp_link_vif *dp_link_vif = NULL; + struct ath12k_dp_peer_create_params params = {}; lockdep_assert_wiphy(hw->wiphy); @@ -10242,6 +10320,15 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) switch (ahvif->vdev_type) { case WMI_VDEV_TYPE_AP: + params.ucast_ra_only = true; + + ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, ¶ms); + if (ret) { + ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n", + arvif->vdev_id, ret); + goto err_vdev_del; + } + peer_param.vdev_id = arvif->vdev_id; peer_param.peer_addr = arvif->bssid; peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; @@ -10249,7 +10336,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) if (ret) { ath12k_warn(ab, "failed to vdev %d create peer for AP: %d\n", arvif->vdev_id, ret); - goto err_vdev_del; + goto err_dp_peer_del; } ret = ath12k_mac_set_kickout(arvif); @@ -10355,6 +10442,10 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) ar->num_peers--; } +err_dp_peer_del: + if (ahvif->vdev_type == WMI_VDEV_TYPE_AP) + ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); + err_vdev_del: if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { ar->monitor_vdev_id = -1; @@ -14926,7 +15017,9 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag, ah->num_radio = num_pdev_map; mutex_init(&ah->hw_mutex); - INIT_LIST_HEAD(&ah->ml_peers); + + spin_lock_init(&ah->dp_hw.peer_lock); + INIT_LIST_HEAD(&ah->dp_hw.dp_peers_list); for (i = 0; i < num_pdev_map; i++) { ab = pdev_map[i].ab; diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index ef5c3570bef10..ed7ad3ca4f407 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -169,6 +169,7 @@ struct ath12k *ath12k_mac_get_ar_by_pdev_id(struct ath12k_base *ab, u32 pdev_id) void ath12k_mac_drain_tx(struct ath12k *ar); void ath12k_mac_peer_cleanup_all(struct ath12k *ar); +void ath12k_mac_dp_peer_cleanup(struct ath12k_hw *ah); int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw); enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw); diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 68eebaa24ed9c..691314efe23f6 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -8,23 +8,6 @@ #include "peer.h" #include "debug.h" -struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) -{ - struct ath12k_ml_peer *ml_peer; - - lockdep_assert_wiphy(ah->hw->wiphy); - - list_for_each_entry(ml_peer, &ah->ml_peers, list) { - if (!ether_addr_equal(ml_peer->addr, addr)) - continue; - - return ml_peer; - } - - return NULL; -} -EXPORT_SYMBOL(ath12k_peer_ml_find); - static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id, const u8 *addr, bool expect_mapped) { @@ -263,7 +246,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, return 0; } -static u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) +u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) { u16 ml_peer_id; @@ -283,68 +266,6 @@ static u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) return ml_peer_id; } -int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta) -{ - struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); - struct ath12k_ml_peer *ml_peer; - - lockdep_assert_wiphy(ah->hw->wiphy); - - if (!sta->mlo) - return -EINVAL; - - ml_peer = ath12k_peer_ml_find(ah, sta->addr); - if (ml_peer) { - ath12k_hw_warn(ah, "ML peer %d exists already, unable to add new entry for %pM", - ml_peer->id, sta->addr); - return -EEXIST; - } - - ml_peer = kzalloc(sizeof(*ml_peer), GFP_ATOMIC); - if (!ml_peer) - return -ENOMEM; - - ahsta->ml_peer_id = ath12k_peer_ml_alloc(ah); - - if (ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID) { - ath12k_hw_warn(ah, "unable to allocate ML peer id for sta %pM", - sta->addr); - kfree(ml_peer); - return -ENOMEM; - } - - ether_addr_copy(ml_peer->addr, sta->addr); - ml_peer->id = ahsta->ml_peer_id; - list_add(&ml_peer->list, &ah->ml_peers); - - return 0; -} - -int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta) -{ - struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); - struct ath12k_ml_peer *ml_peer; - - lockdep_assert_wiphy(ah->hw->wiphy); - - if (!sta->mlo) - return -EINVAL; - - clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map); - ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID; - - ml_peer = ath12k_peer_ml_find(ah, sta->addr); - if (!ml_peer) { - ath12k_hw_warn(ah, "ML peer for %pM not found", sta->addr); - return -EINVAL; - } - - list_del(&ml_peer->list); - kfree(ml_peer); - - return 0; -} - int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta) { struct ieee80211_sta *sta = ath12k_ahsta_to_sta(ahsta); diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h index cf8a463d4c371..49d89796bc46e 100644 --- a/drivers/net/wireless/ath/ath12k/peer.h +++ b/drivers/net/wireless/ath/ath12k/peer.h @@ -9,12 +9,6 @@ #include "dp_peer.h" -struct ath12k_ml_peer { - struct list_head list; - u8 addr[ETH_ALEN]; - u16 id; -}; - void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id); int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr); int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, @@ -22,8 +16,6 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_wmi_peer_create_arg *arg); int ath12k_wait_for_peer_delete_done(struct ath12k *ar, u32 vdev_id, const u8 *addr); -int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta); -int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta); struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr); @@ -33,4 +25,5 @@ void ath12k_link_sta_rhash_delete(struct ath12k_base *ab, struct ath12k_link_sta int ath12k_link_sta_rhash_add(struct ath12k_base *ab, struct ath12k_link_sta *arsta); struct ath12k_link_sta *ath12k_link_sta_find_by_addr(struct ath12k_base *ab, const u8 *addr); +u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah); #endif /* _PEER_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 80f499b5df35c..946771b96fb58 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -117,13 +117,19 @@ ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar); struct ath12k_base *ab = arvif->ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp_peer *peer; __le16 fc = mgmt->frame_control; spin_lock_bh(&dp->dp_lock); - if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da) && - !ath12k_peer_ml_find(ah, mgmt->da)) { - spin_unlock_bh(&dp->dp_lock); - return false; + if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da)) { + spin_lock_bh(&ah->dp_hw.peer_lock); + peer = ath12k_dp_peer_find_by_addr(&ah->dp_hw, mgmt->da); + if (!peer || (peer && !peer->is_mlo)) { + spin_unlock_bh(&ah->dp_hw.peer_lock); + spin_unlock_bh(&dp->dp_lock); + return false; + } + spin_unlock_bh(&ah->dp_hw.peer_lock); } spin_unlock_bh(&dp->dp_lock); From 1d71c59fad0e8ee76f77358834c8c152c2393024 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:46 +0530 Subject: [PATCH 440/659] wifi: ath12k: Attach and detach ath12k_dp_link_peer to ath12k_dp_peer Introduce explicit attach/detach of ath12k_dp_link_peer objects to their parent ath12k_dp_peer to formalize the data path station hierarchy: ath12k_dp_peer | |--> ath12k_dp_link_peer | |--> ath12k_dp_link_peer | |--> ath12k_dp_link_peer ath12k_dp_peer maintains an array of RCU-protected pointers "link_peers[ATH12K_NUM_MAX_LINKS]" to ath12k_dp_link_peer indexed by its protocol_link_id, and each ath12k_dp_link_peer holds a back pointer to its parent ath12k_dp_peer. Attach is performed after link peer creation, and detach occurs before link peer deletion. This ensures consistent lifetime management and safe concurrent access. ath12k_dp_peer also maintains an array "hw_links[ATH12K_GROUP_MAX_RADIO]" to store the mapping between hw_link_id and protocol_link_id for each of the ath12k_dp_link_peer. RCU locking/unlocking rules: - Readers must hold rcu_read_lock() and fetch the pointer with rcu_dereference(dp_peer->link[link_id]); drop with rcu_read_unlock() when done. - Writers publish with rcu_assign_pointer() and reclaim only after synchronize_rcu(). Handle the case of detachment of link peer from ath12k_dp_peer in case of core reset. Ensure the following order of locks to be followed for attach and detach: - Lock dp->dp_lock - Lock dp_hw->peer_lock - Unlock dp_hw->peer_lock - Unlock dp->dp_lock Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 1 + drivers/net/wireless/ath/ath12k/dp.h | 1 + drivers/net/wireless/ath/ath12k/dp_cmn.h | 6 +- drivers/net/wireless/ath/ath12k/dp_peer.c | 146 ++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/dp_peer.h | 7 ++ drivers/net/wireless/ath/ath12k/mac.c | 21 +++- drivers/net/wireless/ath/ath12k/peer.c | 17 ++- 7 files changed, 189 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 03bcecd340134..4387c1b42b88f 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -887,6 +887,7 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) dp_pdev->hw = ar->ah->hw; dp_pdev->dp = dp; dp_pdev->hw_link_id = ar->hw_link_id; + dp_pdev->dp_hw = &ar->ah->dp_hw; ret = ath12k_dp_rx_pdev_alloc(ab, i); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index ca4b99bad16c5..b4ded1e4581b0 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -158,6 +158,7 @@ struct ath12k_pdev_dp { struct ath12k_dp *dp; struct ieee80211_hw *hw; u8 hw_link_id; + struct ath12k_dp_hw *dp_hw; /* Protects ppdu stats */ spinlock_t ppdu_list_lock; diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 52b7fa2eb138b..dd10426bd12de 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -86,5 +86,9 @@ void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, struct ath12k_hw_group *ag); void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, struct ath12k_hw_group *ag); - +int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, struct ieee80211_sta *sta, u8 *addr, + u8 link_id, u32 hw_link_id); +void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, u8 *addr, u32 hw_link_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index a2834d043dd52..fe4748648a844 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -139,7 +139,6 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", peer->vdev_id, peer->addr, peer_id); - ath12k_dp_link_peer_rhash_delete(dp, peer); list_del(&peer->list); kfree(peer); wake_up(&ab->peer_mapping_wq); @@ -153,7 +152,6 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ { struct ath12k_dp_link_peer *peer; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - int ret; spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); @@ -167,11 +165,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); - ret = ath12k_dp_link_peer_rhash_add(dp, peer); - if (!ret) - list_add(&peer->list, &dp->peers); - else - kfree(peer); + list_add(&peer->list, &dp->peers); wake_up(&ab->peer_mapping_wq); } @@ -377,6 +371,23 @@ static struct ath12k_dp_peer *ath12k_dp_peer_create_find(struct ath12k_dp_hw *dp return NULL; } +/* + * Index of ath12k_dp_peer for MLO client is same as peer id of ath12k_dp_peer, + * while for ath12k_dp_link_peer(mlo and non-mlo) and ath12k_dp_peer for + * Non-MLO client it is derived as ((DEVICE_ID << 10) | (10 bits of peer id)). + * + * This is done because ml_peer_id and peer_id_table are at hw granularity, + * while link_peer_id is at device granularity, hence in order to avoid + * conflict this approach is followed. + */ +#define ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT 10 + +u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id) +{ + return (peer_id & ATH12K_PEER_ML_ID_VALID) ? peer_id : + ((dp->device_id << ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT) | peer_id); +} + int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ath12k_dp_peer_create_params *params) { @@ -451,3 +462,124 @@ void ath12k_dp_peer_delete(struct ath12k_dp_hw *dp_hw, u8 *addr, synchronize_rcu(); kfree(dp_peer); } + +int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, struct ieee80211_sta *sta, u8 *addr, + u8 link_id, u32 hw_link_id) +{ + struct ath12k_dp_peer *dp_peer; + struct ath12k_dp_link_peer *peer, *temp_peer; + u16 peerid_index; + int ret = -EINVAL; + u8 *dp_peer_mac = !sta ? addr : sta->addr; + + spin_lock_bh(&dp->dp_lock); + + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); + if (!peer) { + ath12k_warn(dp, "failed to find dp_link_peer with mac %pM on vdev %u\n", + addr, vdev_id); + ret = -ENOENT; + goto err_peer; + } + + spin_lock_bh(&dp_hw->peer_lock); + + dp_peer = ath12k_dp_peer_find_by_addr_and_sta(dp_hw, dp_peer_mac, sta); + if (!dp_peer) { + ath12k_warn(dp, "failed to find dp_peer with mac %pM\n", dp_peer_mac); + ret = -ENOENT; + goto err_dp_peer; + } + + /* + * Set peer_id in dp_peer for non-mlo client, peer_id for mlo client is + * set during dp_peer create + */ + if (!dp_peer->is_mlo) + dp_peer->peer_id = peer->peer_id; + + peer->dp_peer = dp_peer; + peer->hw_link_id = hw_link_id; + + dp_peer->hw_links[peer->hw_link_id] = link_id; + + peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id); + + rcu_assign_pointer(dp_peer->link_peers[peer->link_id], peer); + + rcu_assign_pointer(dp_hw->dp_peers[peerid_index], dp_peer); + + spin_unlock_bh(&dp_hw->peer_lock); + + /* + * In case of Split PHY and roaming scenario, pdev idx + * might differ but both the pdev will share same rhash + * table. In that case update the rhash table if link_peer is + * already present + */ + temp_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (temp_peer && temp_peer->hw_link_id != hw_link_id) + ath12k_dp_link_peer_rhash_delete(dp, temp_peer); + + ret = ath12k_dp_link_peer_rhash_add(dp, peer); + if (ret) { + /* + * If new entry addition failed, add back old entry + * If old entry addition also fails, then nothing + * can be done, simply proceed + */ + if (temp_peer) + ath12k_dp_link_peer_rhash_add(dp, temp_peer); + } + + spin_unlock_bh(&dp->dp_lock); + + return ret; + +err_dp_peer: + spin_unlock_bh(&dp_hw->peer_lock); + +err_peer: + spin_unlock_bh(&dp->dp_lock); + + return ret; +} + +void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, u8 *addr, u32 hw_link_id) +{ + struct ath12k_dp_peer *dp_peer; + struct ath12k_dp_link_peer *peer, *temp_peer; + u16 peerid_index; + + spin_lock_bh(&dp->dp_lock); + + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); + if (!peer || !peer->dp_peer) { + spin_unlock_bh(&dp->dp_lock); + return; + } + + spin_lock_bh(&dp_hw->peer_lock); + + dp_peer = peer->dp_peer; + dp_peer->hw_links[peer->hw_link_id] = 0; + + peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id); + + rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL); + + rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL); + + spin_unlock_bh(&dp_hw->peer_lock); + + /* To handle roaming and split phy scenario */ + temp_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (temp_peer && temp_peer->hw_link_id == hw_link_id) + ath12k_dp_link_peer_rhash_delete(dp, peer); + + spin_unlock_bh(&dp->dp_lock); + + synchronize_rcu(); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index b4aa4f09337e0..36cce66203104 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -26,6 +26,7 @@ struct ppdu_user_delayba { struct ath12k_dp_link_peer { struct list_head list; struct ieee80211_sta *sta; + struct ath12k_dp_peer *dp_peer; int vdev_id; u8 addr[ETH_ALEN]; int peer_id; @@ -68,6 +69,8 @@ struct ath12k_dp_link_peer { /* peer addr based rhashtable list pointer */ struct rhash_head rhash_addr; + + u8 hw_link_id; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); @@ -81,10 +84,13 @@ struct ath12k_dp_peer { u8 addr[ETH_ALEN]; bool is_mlo; + struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS]; + u16 sec_type; u16 sec_type_grp; bool ucast_ra_only; + u8 hw_links[ATH12K_GROUP_MAX_RADIO]; }; struct ath12k_dp_link_peer * @@ -116,4 +122,5 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr(struct ath12k_dp_hw *dp_hw, u struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ieee80211_sta *sta); +u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 1253a4b734b0c..59a9b125814e9 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1205,6 +1205,11 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_link_vif *arvif, *tmp_vif; struct ath12k_dp_hw *dp_hw = &ar->ah->dp_hw; + struct ath12k_dp_peer *dp_peer = NULL; + u16 peerid_index; + struct list_head peers; + + INIT_LIST_HEAD(&peers); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -1214,12 +1219,26 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) if (peer->sta) ath12k_dp_rx_peer_tid_cleanup(ar, peer); + /* cleanup dp peer */ + spin_lock_bh(&dp_hw->peer_lock); + dp_peer = peer->dp_peer; + peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id); + rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL); + rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL); + spin_unlock_bh(&dp_hw->peer_lock); + ath12k_dp_link_peer_rhash_delete(dp, peer); + list_move(&peer->list, &peers); + } + spin_unlock_bh(&dp->dp_lock); + + synchronize_rcu(); + + list_for_each_entry_safe(peer, tmp, &peers, list) { list_del(&peer->list); kfree(peer); } - spin_unlock_bh(&dp->dp_lock); ar->num_peers = 0; ar->num_stations = 0; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 691314efe23f6..8b6fea685a701 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -110,6 +110,10 @@ int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); + ath12k_dp_link_peer_unassign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), vdev_id, + addr, ar->hw_link_id); + ret = ath12k_peer_delete_send(ar, vdev_id, addr); if (ret) return ret; @@ -243,7 +247,13 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, spin_unlock_bh(&dp->dp_lock); - return 0; + ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), + arvif->vdev_id, sta, + (u8 *)arg->peer_addr, link_id, + ar->hw_link_id); + + return ret; } u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) @@ -298,6 +308,11 @@ int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_st ath12k_dp_peer_cleanup(ar, arvif->vdev_id, arsta->addr); + ath12k_dp_link_peer_unassign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), + arvif->vdev_id, arsta->addr, + ar->hw_link_id); + ret = ath12k_peer_delete_send(ar, arvif->vdev_id, arsta->addr); if (ret) { ath12k_warn(ar->ab, From fe4f5ff27d2ff6415ba2be833fc67b003e0efa3e Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:47 +0530 Subject: [PATCH 441/659] wifi: ath12k: Use ath12k_dp_peer in per packet Tx & Rx paths Move link agnostic data path parameters (keys, rx_tid, reorder buffers, MIC context etc) from ath12k_sta and ath12k_dp_link_peer into ath12k_dp_peer. These parameters are shared across MLO links and should be managed at the peer level. Configure them only when the link peer is primary to avoid redundancy and ensure consistent setup. Switch per-packet Tx/Rx paths and monitor paths to look up ath12k_dp_peer and ath12k_dp_link_peer via peer_id. Helper APIs added: - ath12k_dp_peer_find_by_peerid() - ath12k_dp_link_peer_find_by_peerid() Ensure RCU read lock is held when using these helpers APIs. With the above API ath12k_dp_link_peer_find_by_peerid() being used to find ath12k_dp_link_peer, existing API ath12k_dp_link_peer_find_by_id() is required only at the time of unmap event from firmware since it fetches the ath12k_dp_link_peer from linked list. In order to restrict the usage of API ath12k_dp_link_peer_find_by_id(), make it static and also rename it to ath12k_dp_link_peer_search_by_id(). Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 8 --- drivers/net/wireless/ath/ath12k/dp.c | 6 +- drivers/net/wireless/ath/ath12k/dp_htt.c | 22 ++----- drivers/net/wireless/ath/ath12k/dp_mon.c | 13 +++-- drivers/net/wireless/ath/ath12k/dp_peer.c | 45 +++++++++++++- drivers/net/wireless/ath/ath12k/dp_peer.h | 45 +++++++------- drivers/net/wireless/ath/ath12k/dp_rx.c | 58 +++++++++++-------- drivers/net/wireless/ath/ath12k/dp_rx.h | 9 ++- drivers/net/wireless/ath/ath12k/mac.c | 54 +++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 6 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 30 +++++----- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 23 +++----- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 1 + 15 files changed, 175 insertions(+), 149 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 37e3bf0678a2f..bb2d904dae7cd 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -572,12 +572,6 @@ struct ath12k_link_sta { struct rhash_head rhash_addr; }; -struct ath12k_reoq_buf { - void *vaddr; - dma_addr_t paddr_aligned; - u32 size; -}; - struct ath12k_sta { struct ath12k_vif *ahvif; enum hal_pn_type pn_type; @@ -590,8 +584,6 @@ struct ath12k_sta { u8 num_peer; enum ieee80211_sta_state state; - - struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1]; }; #define ATH12K_HALF_20MHZ_BW 10 diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4387c1b42b88f..8dd39eaddc6c9 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -30,7 +30,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); - if (!peer) { + if (!peer || !peer->dp_peer) { ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n", addr, vdev_id); spin_unlock_bh(&dp->dp_lock); @@ -43,8 +43,8 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) } ath12k_dp_rx_peer_tid_cleanup(ar, peer); - crypto_free_shash(peer->tfm_mmic); - peer->dp_setup_done = false; + crypto_free_shash(peer->dp_peer->tfm_mmic); + peer->dp_peer->dp_setup_done = false; spin_unlock_bh(&dp->dp_lock); } diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index f3dca108c614e..db5ac36adf3dd 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -272,18 +272,15 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, } rcu_read_lock(); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, usr_stats->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, usr_stats->peer_id); if (!peer || !peer->sta) { - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } @@ -357,7 +354,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); } - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); } @@ -507,17 +503,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, ppdu_info->delay_ba) { for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); - if (!peer) { - spin_unlock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); + if (!peer) continue; - } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (usr_stats->delay_ba) ath12k_copy_to_delay_stats(peer, usr_stats); - spin_unlock_bh(&dp->dp_lock); } } @@ -526,17 +518,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { for (i = 0; i < ppdu_info->bar_num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); - if (!peer) { - spin_unlock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); + if (!peer) continue; - } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (peer->delayba_flag) ath12k_copy_to_bar(peer, usr_stats); - spin_unlock_bh(&dp->dp_lock); } } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 0873f11083d0b..14203c3722a23 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2310,6 +2310,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, bool is_mcbc = rxcb->is_mcbc; bool is_eapol_tkip = rxcb->is_eapol; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + u8 addr[ETH_ALEN] = {}; status->link_valid = 0; @@ -2322,10 +2323,12 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + rcu_read_lock(); spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, &rx_info); + peer = ath12k_dp_rx_h_find_link_peer(dp_pdev, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; + memcpy(addr, peer->addr, ETH_ALEN); if (pubsta->valid_links) { status->link_valid = 1; status->link_id = peer->link_id; @@ -2333,12 +2336,13 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, } spin_unlock_bh(&dp->dp_lock); + rcu_read_unlock(); ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, - peer ? peer->addr : NULL, + addr, rxcb->tid, (is_mcbc) ? "mcast" : "ucast", (status->encoding == RX_ENC_LEGACY) ? "legacy" : "", @@ -3919,8 +3923,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, goto free_skb; rcu_read_lock(); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, ppdu_info->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "failed to find the peer with monitor peer_id %d\n", @@ -3933,7 +3936,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); dev_kfree_skb_any(skb); continue; @@ -3947,7 +3949,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } next_skb: - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index fe4748648a844..61478e66d9af5 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -72,8 +72,8 @@ ath12k_dp_link_peer_find_by_ml_id(struct ath12k_dp *dp, int ml_peer_id) return NULL; } -struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id) +static struct ath12k_dp_link_peer * +ath12k_dp_link_peer_search_by_id(struct ath12k_dp *dp, int peer_id) { struct ath12k_dp_link_peer *peer; @@ -129,7 +129,7 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_link_peer_search_by_id(dp, peer_id); if (!peer) { ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -388,6 +388,44 @@ u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id) ((dp->device_id << ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT) | peer_id); } +struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, + u16 peer_id) +{ + u16 index; + struct ath12k_dp *dp = dp_pdev->dp; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k dp peer find by peerid index called without rcu lock"); + + if (!peer_id || peer_id >= ATH12K_DP_PEER_ID_INVALID) + return NULL; + + index = ath12k_dp_peer_get_peerid_index(dp, peer_id); + + return rcu_dereference(dp_pdev->dp_hw->dp_peers[index]); +} + +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id) +{ + struct ath12k_dp_peer *dp_peer = NULL; + u8 link_id; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k dp link peer find by peerid index called without rcu lock"); + + if (dp_pdev->hw_link_id >= ATH12K_GROUP_MAX_RADIO) + return NULL; + + dp_peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id); + if (!dp_peer) + return NULL; + + link_id = dp_peer->hw_links[dp_pdev->hw_link_id]; + + return rcu_dereference(dp_peer->link_peers[link_id]); +} + int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ath12k_dp_peer_create_params *params) { @@ -419,6 +457,7 @@ int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, dp_peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; dp_peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + dp_peer->ucast_ra_only = params->ucast_ra_only; spin_lock_bh(&dp_hw->peer_lock); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index 36cce66203104..f7c995e8c4e32 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -34,24 +34,11 @@ struct ath12k_dp_link_peer { u8 pdev_idx; u16 hw_peer_id; - /* protected by ab->data_lock */ - struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; - struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; - - /* Info used in MMIC verification of - * RX fragments - */ - struct crypto_shash *tfm_mmic; - u8 mcast_keyidx; - u8 ucast_keyidx; - u16 sec_type; - u16 sec_type_grp; struct ppdu_user_delayba ppdu_stats_delayba; bool delayba_flag; bool is_authorized; bool mlo; /* protected by ab->data_lock */ - bool dp_setup_done; u16 ml_id; @@ -65,12 +52,12 @@ struct ath12k_dp_link_peer { /* for reference to ath12k_link_sta */ u8 link_id; - bool ucast_ra_only; /* peer addr based rhashtable list pointer */ struct rhash_head rhash_addr; u8 hw_link_id; + u32 rx_tid_active_bitmask; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); @@ -79,18 +66,28 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ struct ath12k_dp_peer { struct list_head list; - struct ieee80211_sta *sta; - int peer_id; - u8 addr[ETH_ALEN]; bool is_mlo; + bool dp_setup_done; - struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS]; - - u16 sec_type; - u16 sec_type_grp; + u8 ucast_keyidx; + u8 addr[ETH_ALEN]; + u8 mcast_keyidx; bool ucast_ra_only; + int peer_id; + struct ieee80211_sta *sta; + u8 hw_links[ATH12K_GROUP_MAX_RADIO]; + + u16 sec_type_grp; + u16 sec_type; + + /* Info used in MMIC verification of * RX fragments */ + struct crypto_shash *tfm_mmic; + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS]; + struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1]; + struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; }; struct ath12k_dp_link_peer * @@ -98,8 +95,6 @@ ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr); -struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id); bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash); @@ -123,4 +118,8 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw * u8 *addr, struct ieee80211_sta *sta); u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id); +struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, + u16 peer_id); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 1df13c884225a..8110f9473849f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -570,8 +570,11 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer lockdep_assert_held(&dp->dp_lock); + if (!peer->primary_link) + return; + for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { - rx_tid = &peer->rx_tid[i]; + rx_tid = &peer->dp_peer->rx_tid[i]; ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); @@ -614,7 +617,6 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_link_peer *peer; - struct ath12k_sta *ahsta; struct ath12k_dp_rx_tid *rx_tid; dma_addr_t paddr_aligned; int ret; @@ -622,7 +624,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to set up rx tid\n"); return -ENOENT; @@ -648,9 +650,9 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ return -EINVAL; } - rx_tid = &peer->rx_tid[tid]; + rx_tid = &peer->dp_peer->rx_tid[tid]; /* Update the tid queue if it is already setup */ - if (rx_tid->active) { + if (peer->rx_tid_active_bitmask & (1 << tid)) { ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, ba_win_sz, ssn, true); spin_unlock_bh(&dp->dp_lock); @@ -679,14 +681,15 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid->ba_win_sz = ba_win_sz; - ahsta = ath12k_sta_to_ahsta(peer->sta); - ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); + ret = ath12k_wifi7_dp_rx_assign_reoq(ab, peer->dp_peer, rx_tid, ssn, pn_type); if (ret) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); return ret; } + peer->rx_tid_active_bitmask |= (1 << tid); + /* Pre-allocate the update_rxq_list for the corresponding tid * This will be used during the tid delete. The reason we are not * allocating during tid delete is that, if any alloc fail in update_rxq_list @@ -776,20 +779,26 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, arsta->addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n"); return -ENOENT; } - active = peer->rx_tid[params->tid].active; + if (ab->hw_params->dp_primary_link_only && + !peer->primary_link) { + spin_unlock_bh(&dp->dp_lock); + return 0; + } + active = peer->rx_tid_active_bitmask & (1 << params->tid); if (!active) { spin_unlock_bh(&dp->dp_lock); return 0; } - ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); + ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->dp_peer->rx_tid, + 1, 0, false); spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", @@ -826,7 +835,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n", peer_addr); @@ -834,10 +843,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, } for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) { - rx_tid = &peer->rx_tid[tid]; - if (!rx_tid->active) + if (!(peer->rx_tid_active_bitmask & (1 << tid))) continue; + rx_tid = &peer->dp_peer->rx_tid[tid]; + ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, @@ -1173,16 +1183,17 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu } struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ath12k_dp_link_peer *peer = NULL; + struct ath12k_dp *dp = dp_pdev->dp; lockdep_assert_held(&dp->dp_lock); if (rxcb->peer_id) - peer = ath12k_dp_link_peer_find_by_id(dp, rxcb->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, rxcb->peer_id); if (peer) return peer; @@ -1345,25 +1356,22 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status *status = rx_info->rx_status; u8 decap = rx_info->decap_type; bool is_mcbc = rxcb->is_mcbc; bool is_eapol = rxcb->is_eapol; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rx_info->peer_id); pubsta = peer ? peer->sta : NULL; if (pubsta && pubsta->valid_links) { status->link_valid = 1; - status->link_id = peer->link_id; + status->link_id = peer->hw_links[rxcb->hw_link_id]; } - spin_unlock_bh(&dp->dp_lock); - ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, @@ -1486,7 +1494,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); crypto_free_shash(tfm); ath12k_warn(ab, "failed to find the peer to set up fragment info\n"); @@ -1500,14 +1508,14 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev } for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { - rx_tid = &peer->rx_tid[i]; + rx_tid = &peer->dp_peer->rx_tid[i]; rx_tid->dp = dp; timer_setup(&rx_tid->frag_timer, ath12k_dp_rx_frag_timer, 0); skb_queue_head_init(&rx_tid->rx_frags); } - peer->tfm_mmic = tfm; - peer->dp_setup_done = true; + peer->dp_peer->tfm_mmic = tfm; + peer->dp_peer->dp_setup_done = true; spin_unlock_bh(&dp->dp_lock); return 0; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 365f2c6449e42..51bc443f4c7ca 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -12,10 +12,15 @@ #define DP_MAX_NWIFI_HDR_LEN 30 +struct ath12k_reoq_buf { + void *vaddr; + dma_addr_t paddr_aligned; + u32 size; +}; + struct ath12k_dp_rx_tid { u8 tid; u32 ba_win_sz; - bool active; struct ath12k_reoq_buf qbuf; /* Info related to rx fragments */ @@ -244,7 +249,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 59a9b125814e9..8fa8ad2d50bd5 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1216,7 +1216,7 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) spin_lock_bh(&dp->dp_lock); list_for_each_entry_safe(peer, tmp, &dp->peers, list) { /* Skip Rx TID cleanup for self peer */ - if (peer->sta) + if (peer->sta && peer->dp_peer) ath12k_dp_rx_peer_tid_cleanup(ar, peer); /* cleanup dp peer */ @@ -5765,27 +5765,37 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, struct ath12k_dp_link_peer *peer; int first_errno = 0; int ret; - int i; + int i, len; u32 flags = 0; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1] = {}; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); return -ENOENT; } + len = ARRAY_SIZE(peer->dp_peer->keys); + for (i = 0; i < len; i++) { + if (!peer->dp_peer->keys[i]) + continue; + + keys[i] = peer->dp_peer->keys[i]; + peer->dp_peer->keys[i] = NULL; + } + spin_unlock_bh(&dp->dp_lock); - for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { - if (!peer->keys[i]) + for (i = 0; i < len; i++) { + if (!keys[i]) continue; /* key flags are not required to delete the key */ - ret = ath12k_install_key(arvif, peer->keys[i], + ret = ath12k_install_key(arvif, keys[i], DISABLE_KEY, addr, flags); if (ret < 0 && first_errno == 0) first_errno = ret; @@ -5793,10 +5803,6 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, if (ret < 0) ath12k_warn(ab, "failed to remove peer key %d: %d\n", i, ret); - - spin_lock_bh(&dp->dp_lock); - peer->keys[i] = NULL; - spin_unlock_bh(&dp->dp_lock); } return first_errno; @@ -5837,7 +5843,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); if (cmd == SET_KEY) { @@ -5874,21 +5880,23 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - if (peer && cmd == SET_KEY) { - peer->keys[key->keyidx] = key; + if (peer && peer->dp_peer && cmd == SET_KEY) { + peer->dp_peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { - peer->ucast_keyidx = key->keyidx; - peer->sec_type = ath12k_dp_tx_get_encrypt_type(key->cipher); + peer->dp_peer->ucast_keyidx = key->keyidx; + peer->dp_peer->sec_type = + ath12k_dp_tx_get_encrypt_type(key->cipher); } else { - peer->mcast_keyidx = key->keyidx; - peer->sec_type_grp = ath12k_dp_tx_get_encrypt_type(key->cipher); + peer->dp_peer->mcast_keyidx = key->keyidx; + peer->dp_peer->sec_type_grp = + ath12k_dp_tx_get_encrypt_type(key->cipher); } - } else if (peer && cmd == DISABLE_KEY) { - peer->keys[key->keyidx] = NULL; + } else if (peer && peer->dp_peer && cmd == DISABLE_KEY) { + peer->dp_peer->keys[key->keyidx] = NULL; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) - peer->ucast_keyidx = 0; + peer->dp_peer->ucast_keyidx = 0; else - peer->mcast_keyidx = 0; + peer->dp_peer->mcast_keyidx = 0; } else if (!peer) /* impossible unless FW goes crazy */ ath12k_warn(ab, "peer %pM disappeared!\n", peer_addr); @@ -9490,7 +9498,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, spin_lock_bh(&tmp_dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, tmp_arvif->bssid); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&tmp_dp->dp_lock); ath12k_warn(tmp_ar->ab, "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", @@ -9500,7 +9508,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, continue; } - key = peer->keys[peer->mcast_keyidx]; + key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx]; if (key) { skb_cb->cipher = key->cipher; skb_cb->flags |= ATH12K_SKB_CIPHER_SET; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 8b6fea685a701..812247decab43 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -214,9 +214,6 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, dp_link_vif->ast_idx = peer->hw_peer_id; } - if (vif->type == NL80211_IFTYPE_AP) - peer->ucast_ra_only = true; - if (sta) { ahsta = ath12k_sta_to_ahsta(sta); arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy, @@ -240,9 +237,6 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, } } - peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; - peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; - ar->num_peers++; spin_unlock_bh(&dp->dp_lock); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index da745566aca37..87875486fb4a1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -72,10 +72,10 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, struct ath12k_dp_link_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; - struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + struct ath12k_dp_rx_tid *rx_tid = &peer->dp_peer->rx_tid[tid]; int ret; - if (!rx_tid->active) + if (!(peer->rx_tid_active_bitmask & (1 << tid))) return; cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; @@ -99,7 +99,7 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, else ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); - rx_tid->active = false; + peer->rx_tid_active_bitmask &= ~(1 << tid); } int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, @@ -253,7 +253,7 @@ void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, } } -int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type) { @@ -265,7 +265,7 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ah u32 hw_desc_sz; int ret; - buf = &ahsta->reoq_bufs[tid]; + buf = &dp_peer->reoq_bufs[tid]; if (!buf->vaddr) { /* TODO: Optimize the memory allocation for qos tid based on * the actual BA window size in REO tid update path. @@ -299,7 +299,6 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ah } rx_tid->qbuf = *buf; - rx_tid->active = true; return 0; } @@ -316,12 +315,11 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc *rx_desc, struct hal_rx_desc_data *rx_info) { - struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; struct ieee80211_hdr *hdr; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ieee80211_rx_status *rx_status = rx_info->rx_status; u32 err_bitmap = rx_info->err_bitmap; @@ -332,8 +330,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (rxcb->is_mcbc) rxcb->peer_id = rx_info->peer_id; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -347,7 +344,6 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, } else { enctype = HAL_ENCRYPT_TYPE_OPEN; } - spin_unlock_bh(&dp->dp_lock); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) is_decrypted = rx_info->is_decrypted; @@ -964,7 +960,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, } static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_dp_link_peer *peer, + struct ath12k_dp_peer *peer, enum hal_encrypt_type enctype, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) @@ -1033,7 +1029,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, } static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_dp_link_peer *peer, + struct ath12k_dp_peer *peer, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff **defrag_skb, enum hal_encrypt_type enctype, @@ -1107,7 +1103,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; u32 peer_id = rx_info->peer_id; @@ -1134,7 +1130,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, return -EINVAL; spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id); if (!peer) { ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", peer_id); @@ -1197,7 +1193,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, timer_delete_sync(&rx_tid->frag_timer); spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id); if (!peer) goto err_frags_cleanup; @@ -1831,6 +1827,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, rxcb->is_last_msdu = err_info.last_msdu; rxcb->is_continuation = err_info.continuation; rxcb->rx_desc = msdu_data; + rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, + err_info.peer_metadata); if (err_info.continuation) { __skb_queue_tail(&scatter_msdu_list, msdu); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index f75588519cfff..ba319ff506f28 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -25,7 +25,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, struct ath12k_dp_rx_tid *rx_tid, u32 cipher, enum set_key_cmd key_cmd); -int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type); int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 77de02858677a..950614a217a05 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -396,12 +396,13 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ath12k_dp_link_peer *peer; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_pdev_dp *dp_pdev; skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); ar = skb_cb->ar; + dp_pdev = &ar->dp; ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; if (atomic_dec_and_test(&ar->dp.num_tx_pending)) @@ -449,18 +450,15 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, } } rcu_read_lock(); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); goto exit; } else { status.sta = peer->sta; } - spin_unlock_bh(&dp->dp_lock); status.info = info; status.skb = msdu; @@ -519,7 +517,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ieee80211_sta *sta; struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; @@ -528,12 +526,10 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, u8 rate_idx = 0; int ret; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); - spin_unlock_bh(&dp->dp_lock); return; } sta = peer->sta; @@ -547,7 +543,6 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, txrate.nss = arsta->last_txrate.nss; else txrate.nss = arsta->peer_nss; - spin_unlock_bh(&dp->dp_lock); switch (ts->pkt_type) { case HAL_TX_RATE_STATS_PKT_TYPE_11A: @@ -650,7 +645,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ieee80211_rate_status status_rate = {}; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ath12k_link_sta *arsta; struct ath12k_sta *ahsta; struct rate_info rate; @@ -747,21 +742,17 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); - spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } ahsta = ath12k_sta_to_ahsta(peer->sta); arsta = &ahsta->deflink; - spin_unlock_bh(&dp->dp_lock); - status.sta = peer->sta; status.info = info; status.skb = msdu; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 28a0564a93fd7..297f7853e1853 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -436,6 +436,8 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE); } + rel_info->peer_metadata = wbm_desc->info2; + return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index d6f33fcd2e961..5536f5bf2a2bf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -21,6 +21,7 @@ struct hal_rx_wbm_rel_info { bool continuation; void *rx_desc; bool hw_cc_done; + __le32 peer_metadata; }; #define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ From 36eec64499c9675435eac77cc8ee887684538670 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Fri, 24 Oct 2025 23:45:48 +0530 Subject: [PATCH 442/659] wifi: ath12k: Add lockdep warn for RCU Add RCU_LOCKDEP_WARN() in following functions: - ath12k_dp_link_peer_to_link_sta() - ath12k_wifi7_dp_rx_h_mpdu() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_peer.c | 3 +++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 61478e66d9af5..a06113bedf0d7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -182,6 +182,9 @@ struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k_dp_link_peer to ath12k_link_sta called without rcu lock"); + if (!peer->sta) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 87875486fb4a1..d24d0f12742eb 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -323,6 +323,9 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct ieee80211_rx_status *rx_status = rx_info->rx_status; u32 err_bitmap = rx_info->err_bitmap; + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "dp_rx_h_mpdu called without rcu lock"); + /* PN for multicast packets will be checked in mac80211 */ rxcb = ATH12K_SKB_RXCB(msdu); rxcb->is_mcbc = rx_info->is_mcbc; From 3cc3603dbb84db67a28d25df5359754686d84c9d Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:00 +0530 Subject: [PATCH 443/659] wifi: ath12k: Add callbacks in arch_ops for rx APIs Facilitate modular and architecture-agnostic access to Wi-Fi 7 Rx functionality by introducing wrapper APIs in common module for existing RX callbacks already defined in arch_ops. Also remove redundant ar usage in these APIs and registered callbacks definitions, and change the callback names of few of the APIs to remove the redundant usage of "dp". Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 5 +- drivers/net/wireless/ath/ath12k/dp.h | 102 +++++++++++++++++- drivers/net/wireless/ath/ath12k/dp_rx.c | 38 ++++--- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 10 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 19 ++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 4 +- 6 files changed, 141 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 8dd39eaddc6c9..c7f7c04877c4b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -10,7 +10,6 @@ #include "hif.h" #include "hal.h" #include "debug.h" -#include "wifi7/dp_rx.h" #include "peer.h" #include "dp_mon.h" #include "dp_cmn.h" @@ -99,7 +98,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) } for (tid--; tid >= 0; tid--) - ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, tid); + ath12k_dp_arch_rx_peer_tid_delete(dp, peer, tid); spin_unlock_bh(&dp->dp_lock); @@ -345,7 +344,7 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, bool configure_register = false; /* convert vdev params into hal_tx_bank_config */ - bank_config = dp->ops->dp_tx_get_vdev_bank_config(ab, arvif); + bank_config = ath12k_dp_arch_tx_get_vdev_bank_config(dp, arvif); spin_lock_bh(&dp->tx_bank_lock); /* TODO: implement using idr kernel framework*/ diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index b4ded1e4581b0..9c926bcbd4359 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -21,6 +21,7 @@ struct ath12k_vif; struct ath12k_link_vif; struct hal_tcl_status_ring; struct ath12k_ext_irq_grp; +struct ath12k_dp_rx_tid; #define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 @@ -389,8 +390,34 @@ struct ath12k_dp_arch_ops { int (*service_srng)(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, int budget); - u32 (*dp_tx_get_vdev_bank_config)(struct ath12k_base *ab, - struct ath12k_link_vif *arvif); + u32 (*tx_get_vdev_bank_config)(struct ath12k_base *ab, + struct ath12k_link_vif *arvif); + int (*reo_cmd_send)(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)); + void (*setup_pn_check_reo_cmd)(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd); + void (*rx_peer_tid_delete)(struct ath12k_base *ab, + struct ath12k_dp_link_peer *peer, u8 tid); + void (*reo_cache_flush)(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid); + int (*rx_link_desc_return)(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); + int (*peer_rx_tid_reo_update)(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn); + int (*rx_assign_reoq)(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type); + void (*peer_rx_tid_qref_setup)(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr); }; struct ath12k_dp { @@ -493,6 +520,77 @@ struct ath12k_dp { struct rhashtable_params rhash_peer_addr_param; }; +static inline u32 ath12k_dp_arch_tx_get_vdev_bank_config(struct ath12k_dp *dp, + struct ath12k_link_vif *arvif) +{ + return dp->ops->tx_get_vdev_bank_config(dp->ab, arvif); +} + +static inline int ath12k_dp_arch_reo_cmd_send(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)) +{ + return dp->ops->reo_cmd_send(dp->ab, rx_tid, type, cmd, cb); +} + +static inline void ath12k_dp_arch_setup_pn_check_reo_cmd(struct ath12k_dp *dp, + struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, + enum set_key_cmd key_cmd) +{ + dp->ops->setup_pn_check_reo_cmd(cmd, rx_tid, cipher, key_cmd); +} + +static inline void ath12k_dp_arch_rx_peer_tid_delete(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer, + u8 tid) +{ + dp->ops->rx_peer_tid_delete(dp->ab, peer, tid); +} + +static inline void ath12k_dp_arch_reo_cache_flush(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid *rx_tid) +{ + dp->ops->reo_cache_flush(dp->ab, rx_tid); +} + +static inline +int ath12k_dp_arch_rx_link_desc_return(struct ath12k_dp *dp, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) +{ + return dp->ops->rx_link_desc_return(dp->ab, buf_addr_info, action); +} + +static inline int ath12k_dp_arch_peer_rx_tid_reo_update(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) +{ + return dp->ops->peer_rx_tid_reo_update(dp, peer, rx_tid, + ba_win_sz, ssn, update_ssn); +} + +static inline int ath12k_dp_arch_rx_assign_reoq(struct ath12k_dp *dp, + struct ath12k_dp_peer *dp_peer, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) +{ + return dp->ops->rx_assign_reoq(dp->ab, dp_peer, rx_tid, ssn, pn_type); +} + +static inline void ath12k_dp_arch_peer_rx_tid_qref_setup(struct ath12k_dp *dp, + u16 peer_id, u16 tid, + dma_addr_t paddr) +{ + dp->ops->peer_rx_tid_qref_setup(dp->ab, peer_id, tid, paddr); +} + static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) { memcpy(addr, &addr_l32, 4); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 8110f9473849f..8ae9210d5b39a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -485,7 +485,7 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, * will be called during core destroy. */ - if (ath12k_wifi7_dp_reo_cache_flush(ab, &elem->data)) + if (ath12k_dp_arch_reo_cache_flush(dp, &elem->data)) break; list_del(&elem->list); @@ -538,18 +538,16 @@ static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc) { + enum hal_wbm_rel_bm_act act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; struct ath12k_buffer_addr *buf_addr_info; struct ath12k_dp *dp = rx_tid->dp; - struct ath12k_base *ab = dp->ab; lockdep_assert_held(&dp->dp_lock); if (rx_tid->dst_ring_desc) { if (rel_link_desc) { buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_wifi7_dp_rx_link_desc_return - (ab, buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_dp_arch_rx_link_desc_return(dp, buf_addr_info, act); } kfree(rx_tid->dst_ring_desc); rx_tid->dst_ring_desc = NULL; @@ -576,7 +574,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->dp_peer->rx_tid[i]; - ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); + ath12k_dp_arch_rx_peer_tid_delete(dp, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); spin_unlock_bh(&dp->dp_lock); @@ -653,8 +651,8 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid = &peer->dp_peer->rx_tid[tid]; /* Update the tid queue if it is already setup */ if (peer->rx_tid_active_bitmask & (1 << tid)) { - ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, - ba_win_sz, ssn, true); + ret = ath12k_dp_arch_peer_rx_tid_reo_update(dp, peer, rx_tid, + ba_win_sz, ssn, true); spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d\n", tid); @@ -681,7 +679,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid->ba_win_sz = ba_win_sz; - ret = ath12k_wifi7_dp_rx_assign_reoq(ab, peer->dp_peer, rx_tid, ssn, pn_type); + ret = ath12k_dp_arch_rx_assign_reoq(dp, peer->dp_peer, rx_tid, ssn, pn_type); if (ret) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); @@ -709,11 +707,11 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ * and tid with qaddr. */ if (peer->mlo) - ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->ml_id, tid, - paddr_aligned); + ath12k_dp_arch_peer_rx_tid_qref_setup(dp, peer->ml_id, tid, + paddr_aligned); else - ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, - paddr_aligned); + ath12k_dp_arch_peer_rx_tid_qref_setup(dp, peer->peer_id, tid, + paddr_aligned); spin_unlock_bh(&dp->dp_lock); } else { @@ -797,8 +795,8 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return 0; } - ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->dp_peer->rx_tid, - 1, 0, false); + ret = ath12k_dp_arch_peer_rx_tid_reo_update(dp, peer, peer->dp_peer->rx_tid, + 1, 0, false); spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", @@ -850,11 +848,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, - key_cmd); - ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, - &cmd, NULL); + ath12k_dp_arch_setup_pn_check_reo_cmd(dp, &cmd, rx_tid, key->cipher, + key_cmd); + ret = ath12k_dp_arch_reo_cmd_send(dp, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, + &cmd, NULL); if (ret) { ath12k_warn(ab, "failed to configure rx tid %d queue of peer %pM for pn replay detection %d\n", tid, peer_addr, ret); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 976dfe1b90874..1fd7738a39b57 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -138,7 +138,15 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .service_srng = ath12k_wifi7_dp_service_srng, - .dp_tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config, + .tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config, + .reo_cmd_send = ath12k_wifi7_dp_reo_cmd_send, + .setup_pn_check_reo_cmd = ath12k_wifi7_dp_setup_pn_check_reo_cmd, + .rx_peer_tid_delete = ath12k_wifi7_dp_rx_peer_tid_delete, + .reo_cache_flush = ath12k_wifi7_dp_reo_cache_flush, + .rx_link_desc_return = ath12k_wifi7_dp_rx_link_desc_return, + .peer_rx_tid_reo_update = ath12k_wifi7_peer_rx_tid_reo_update, + .rx_assign_reoq = ath12k_wifi7_dp_rx_assign_reoq, + .peer_rx_tid_qref_setup = ath12k_wifi7_peer_rx_tid_qref_setup, }; /* TODO: remove export once this file is built with wifi7 ko */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d24d0f12742eb..f4855b001fda6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -68,7 +68,7 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, u32_encode_bits(tid, DP_REO_QREF_NUM); } -void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; @@ -82,22 +82,22 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); cmd.upd0 = HAL_REO_CMD_UPD0_VLD; - ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, ath12k_dp_rx_tid_del_func); if (ret) { - ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", + ath12k_err(ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", tid, ret); - dma_unmap_single(ar->ab->dev, rx_tid->qbuf.paddr_aligned, + dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size, DMA_BIDIRECTIONAL); kfree(rx_tid->qbuf.vaddr); rx_tid->qbuf.vaddr = NULL; } if (peer->mlo) - ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ab, peer->ml_id, tid); else - ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ab, peer->peer_id, tid); peer->rx_tid_active_bitmask &= ~(1 << tid); } @@ -179,13 +179,14 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, return 0; } -int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn) { struct ath12k_hal_reo_cmd cmd = {}; + struct ath12k_base *ab = dp->ab; int ret; cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); @@ -199,11 +200,11 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); } - ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL); if (ret) { - ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", + ath12k_warn(ab, "failed to update rx tid queue, tid %d (%d)\n", rx_tid->tid, ret); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index ba319ff506f28..cb72b75526d4a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -33,7 +33,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, enum hal_wbm_rel_bm_act action); void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); -void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid); int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, enum hal_reo_cmd_type type, @@ -42,7 +42,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid enum hal_reo_cmd_status status)); void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid); -int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, From d9dc58d65413d185c2f6f50bf99801be2996ef7a Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:01 +0530 Subject: [PATCH 444/659] wifi: ath12k: Move DP device stats to ath12k_dp As part of data path modularization of device object framework, the per packet tx/rx operations now use ath12k_dp. Move all the device stats 'device_stats' from ath12k_base to ath12k_dp, consolidating all device stats within ath12k_dp. This would improve the performance by allowing the datapath to reach to the stats counters without to having to reach out to ath12k_base object. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 27 ------------------- drivers/net/wireless/ath/ath12k/debug.c | 3 ++- drivers/net/wireless/ath/ath12k/debugfs.c | 3 ++- drivers/net/wireless/ath/ath12k/dp.h | 27 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_rx.c | 4 +-- drivers/net/wireless/ath/ath12k/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 22 +++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 19 ++++++------- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 8 +++--- 9 files changed, 60 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index bb2d904dae7cd..faae17f321d62 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -908,32 +908,6 @@ struct ath12k_board_data { size_t len; }; -struct ath12k_device_dp_tx_err_stats { - /* TCL Ring Descriptor unavailable */ - u32 desc_na[DP_TCL_NUM_RING_MAX]; - /* Other failures during dp_tx due to mem allocation failure - * idr unavailable etc. - */ - atomic_t misc_fail; -}; - -struct ath12k_device_dp_stats { - u32 err_ring_pkts; - u32 invalid_rbm; - u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; - u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; - u32 hal_reo_error[DP_REO_DST_RING_MAX]; - struct ath12k_device_dp_tx_err_stats tx_err; - u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES]; - u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES]; - u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON]; - u32 fw_tx_status[MAX_FW_TX_STATUS]; - u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; - u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; - u32 tx_completed[DP_TCL_NUM_RING_MAX]; - u32 reo_excep_msdu_buf_type; -}; - struct ath12k_reg_freq { u32 start_freq; u32 end_freq; @@ -1112,7 +1086,6 @@ struct ath12k_base { /* Current DFS Regulatory */ enum ath12k_dfs_region dfs_region; - struct ath12k_device_dp_stats device_stats; #ifdef CONFIG_ATH12K_DEBUGFS struct dentry *debugfs_soc; #endif diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c index 9910c60f30ced..5fe9b2fbf5096 100644 --- a/drivers/net/wireless/ath/ath12k/debug.c +++ b/drivers/net/wireless/ath/ath12k/debug.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * */ #include diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index 19c4fabecff8e..64d89d82332ba 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1027,7 +1027,8 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, size_t count, loff_t *ppos) { struct ath12k_base *ab = file->private_data; - struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_device_dp_stats *device_stats = &dp->device_stats; int len = 0, i, j, ret; struct ath12k *ar; const int size = 4096; diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9c926bcbd4359..1068a130fc82c 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,6 +11,7 @@ #include "dp_htt.h" #include "dp_cmn.h" #include +#include "wifi7/hal_desc.h" #define MAX_RXDMA_PER_PDEV 2 @@ -420,6 +421,31 @@ struct ath12k_dp_arch_ops { dma_addr_t paddr); }; +struct ath12k_device_dp_tx_err_stats { + /* TCL Ring Descriptor unavailable */ + u32 desc_na[DP_TCL_NUM_RING_MAX]; + /* Other failures during dp_tx due to mem allocation failure + * idr unavailable etc. + */ + atomic_t misc_fail; +}; + +struct ath12k_device_dp_stats { + u32 err_ring_pkts; + u32 invalid_rbm; + u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; + u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; + u32 hal_reo_error[DP_REO_DST_RING_MAX]; + struct ath12k_device_dp_tx_err_stats tx_err; + u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES]; + u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES]; + u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON]; + u32 fw_tx_status[MAX_FW_TX_STATUS]; + u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; + u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; + u32 tx_completed[DP_TCL_NUM_RING_MAX]; +}; + struct ath12k_dp { struct ath12k_base *ab; u32 mon_dest_ring_stuck_cnt; @@ -518,6 +544,7 @@ struct ath12k_dp { /* The rhashtable containing struct ath12k_link_peer keyed by mac addr */ struct rhashtable *rhead_peer_addr; struct rhashtable_params rhash_peer_addr_param; + struct ath12k_device_dp_stats device_stats; }; static inline u32 ath12k_dp_arch_tx_get_vdev_bank_config(struct ath12k_dp *dp, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 8ae9210d5b39a..b0ef21dc1278d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1416,7 +1416,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct hal_rx_desc *rx_desc, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) @@ -1433,7 +1433,7 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, if ((likely(hdr_len <= DP_MAX_NWIFI_HDR_LEN))) return true; - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; WARN_ON_ONCE(1); return false; } diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 51bc443f4c7ca..4a93331dff579 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -197,7 +197,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); -bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct hal_rx_desc *rx_desc, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index f4855b001fda6..0cf8a8f7b5f6e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -538,7 +538,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, rx_desc, msdu, rx_info))) { ret = -EINVAL; goto free_out; @@ -710,14 +710,14 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, DMA_FROM_DEVICE); num_buffs_reaped[device_id]++; - ab->device_stats.reo_rx[ring_id][ab->device_id]++; + dp->device_stats.reo_rx[ring_id][ab->device_id]++; push_reason = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_PUSH_REASON); if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { dev_kfree_skb_any(msdu); - ab->device_stats.hal_reo_error[ring_id]++; + dp->device_stats.hal_reo_error[ring_id]++; continue; } @@ -1021,7 +1021,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; skb_pull(msdu, hal_rx_desc_sz); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, rx_desc, msdu, rx_info))) return -EINVAL; @@ -1357,7 +1357,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n while (budget && (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { drop = false; - ab->device_stats.err_ring_pkts++; + dp->device_stats.err_ring_pkts++; ret = ath12k_wifi7_hal_desc_reo_parse_err(ab, reo_desc, &paddr, &desc_bank); @@ -1385,7 +1385,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n rbm != HAL_RX_BUF_RBM_SW3_BM && rbm != partner_ab->hal.hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); ath12k_wifi7_dp_rx_link_desc_return(partner_ab, &reo_desc->buf_addr_info, @@ -1539,7 +1539,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev, skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, desc, msdu, rx_info))) return -EINVAL; ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); @@ -1580,7 +1580,7 @@ static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k_pdev_dp *dp_pdev, skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, desc, msdu, rx_info))) return true; ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); @@ -1601,7 +1601,7 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev, struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - dp->ab->device_stats.rxdma_error[rxcb->err_code]++; + dp->device_stats.rxdma_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: @@ -1631,7 +1631,7 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev, struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - dp->ab->device_stats.reo_error[rxcb->err_code]++; + dp->device_stats.reo_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: @@ -1744,7 +1744,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; int total_num_buffs_reaped = 0; struct ath12k_rx_desc_info *desc_info; - struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_device_dp_stats *device_stats = &dp->device_stats; struct ath12k_hw_link *hw_links = ag->hw_links; u8 hw_link_id, device_id; int ret, pdev_idx; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 950614a217a05..454d5a7532cfd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -205,7 +205,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a default: /* TODO: Take care of other encap modes as well */ ret = -EINVAL; - atomic_inc(&ab->device_stats.tx_err.misc_fail); + atomic_inc(&dp->device_stats.tx_err.misc_fail); goto fail_remove_tx_buf; } @@ -228,7 +228,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a map: ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(ab->dev, ti.paddr)) { - atomic_inc(&ab->device_stats.tx_err.misc_fail); + atomic_inc(&dp->device_stats.tx_err.misc_fail); ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); ret = -ENOMEM; goto fail_remove_tx_buf; @@ -311,7 +311,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a * desc because the desc is directly enqueued onto hw queue. */ ath12k_hal_srng_access_end(ab, tcl_ring); - ab->device_stats.tx_err.desc_na[ti.ring_id]++; + dp->device_stats.tx_err.desc_na[ti.ring_id]++; spin_unlock_bh(&tcl_ring->lock); ret = -ENOMEM; @@ -340,7 +340,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a arvif->link_stats.tx_enqueued++; spin_unlock_bh(&arvif->link_stats_lock); - ab->device_stats.tx_enqueued[ti.ring_id]++; + dp->device_stats.tx_enqueued[ti.ring_id]++; ath12k_wifi7_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); @@ -403,7 +403,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, ar = skb_cb->ar; dp_pdev = &ar->dp; - ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + ab->dp->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); @@ -475,13 +475,14 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, struct htt_tx_wbm_completion *status_desc; struct ath12k_dp_htt_wbm_tx_status ts = {}; enum hal_wbm_htt_tx_comp_status wbm_status; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u16 peer_id; status_desc = desc; wbm_status = le32_get_bits(status_desc->info0, HTT_TX_WBM_COMP_INFO0_STATUS); - ab->device_stats.fw_tx_status[wbm_status]++; + dp->device_stats.fw_tx_status[wbm_status]++; switch (wbm_status) { case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: @@ -656,7 +657,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, } skb_cb = ATH12K_SKB_CB(msdu); - ab->device_stats.tx_completed[ring]++; + dp->device_stats.tx_completed[ring]++; dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { @@ -883,11 +884,11 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */ buf_rel_source = le32_get_bits(tx_status->info0, HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); - ab->device_stats.tx_wbm_rel_source[buf_rel_source]++; + dp->device_stats.tx_wbm_rel_source[buf_rel_source]++; rel_status = le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); - ab->device_stats.tqm_rel_reason[rel_status]++; + dp->device_stats.tqm_rel_reason[rel_status]++; /* Release descriptor as soon as extracting necessary info * to reduce contention diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 297f7853e1853..590680b4f1421 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -329,13 +329,14 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, { enum hal_reo_dest_ring_push_reason push_reason; enum hal_reo_dest_ring_error_code err_code; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 cookie; push_reason = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_PUSH_REASON); err_code = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_ERROR_CODE); - ab->device_stats.reo_error[err_code]++; + dp->device_stats.reo_error[err_code]++; if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED && push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { @@ -356,6 +357,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, { struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_src_module rel_src; bool hw_cc_done; @@ -385,7 +387,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, val = le32_get_bits(wbm_desc->buf_addr_info.info1, BUFFER_ADDR_INFO1_RET_BUF_MGR); if (val != HAL_RX_BUF_RBM_SW3_BM) { - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; return -EINVAL; } @@ -397,7 +399,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, val = le32_get_bits(wbm_cc_desc->info0, HAL_WBM_RELEASE_RX_CC_INFO0_RBM); if (val != HAL_RX_BUF_RBM_SW3_BM) { - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; return -EINVAL; } From c96262ac912bc3b99987af14a29a2544df187343 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Mon, 3 Nov 2025 16:51:02 +0530 Subject: [PATCH 445/659] wifi: ath12k: Move DP specific link stats to DP link peer As part of peer modularization in the Driver Framework, the station view is as follows: Common Path Data Path ------------------------------------------------------------------- ath12k_sta ath12k_dp_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer Currently ath12k_link_sta has data path stats updated in tx_htt and rx monitor path. Move those stats from ath12_link_sta to ath12k_dp_link_peer to align with peer modularization model as shown above. This allows datapath to use only ath12k_dp_link_peer without having to reach out to other objects for updating stats, thereby improving the cache locality. Add following API to fetch rate info from DP link peer: ath12k_dp_link_peer_get_sta_rate_info_stats() This wrapper API populates link stats in 'struct ath12k_dp_link_peer_rate_info', which can be extended to support out-of-band retrieval of various rate stats. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 59 --------- drivers/net/wireless/ath/ath12k/debugfs_sta.c | 35 +++-- drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 ++ drivers/net/wireless/ath/ath12k/dp_htt.c | 63 +++++---- drivers/net/wireless/ath/ath12k/dp_mon.c | 41 ++---- drivers/net/wireless/ath/ath12k/dp_peer.c | 58 ++++++++- drivers/net/wireless/ath/ath12k/dp_peer.h | 56 ++++++++ drivers/net/wireless/ath/ath12k/hal.h | 9 ++ drivers/net/wireless/ath/ath12k/mac.c | 120 ++++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 3 + drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 33 ++--- 11 files changed, 281 insertions(+), 208 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index faae17f321d62..8a1abd5049144 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -400,51 +400,8 @@ struct ath12k_vif_iter { struct ath12k_link_vif *arvif; }; -#define HAL_AST_IDX_INVALID 0xFFFF -#define HAL_RX_MAX_MCS 12 -#define HAL_RX_MAX_MCS_HT 31 -#define HAL_RX_MAX_MCS_VHT 9 -#define HAL_RX_MAX_MCS_HE 11 -#define HAL_RX_MAX_MCS_BE 15 -#define HAL_RX_MAX_NSS 8 -#define HAL_RX_MAX_NUM_LEGACY_RATES 12 - #define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ) -struct ath12k_rx_peer_rate_stats { - u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; - u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; - u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; - u64 be_mcs_count[HAL_RX_MAX_MCS_BE + 1]; - u64 nss_count[HAL_RX_MAX_NSS]; - u64 bw_count[HAL_RX_BW_MAX]; - u64 gi_count[HAL_RX_GI_MAX]; - u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; - u64 rx_rate[HAL_RX_BW_MAX][HAL_RX_GI_MAX][HAL_RX_MAX_NSS][HAL_RX_MAX_MCS_HT + 1]; -}; - -struct ath12k_rx_peer_stats { - u64 num_msdu; - u64 num_mpdu_fcs_ok; - u64 num_mpdu_fcs_err; - u64 tcp_msdu_count; - u64 udp_msdu_count; - u64 other_msdu_count; - u64 ampdu_msdu_count; - u64 non_ampdu_msdu_count; - u64 stbc_count; - u64 beamformed_count; - u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; - u64 tid_count[IEEE80211_NUM_TIDS + 1]; - u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; - u64 reception_type[HAL_RX_RECEPTION_TYPE_MAX]; - u64 rx_duration; - u64 dcm_count; - u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; - struct ath12k_rx_peer_rate_stats pkt_stats; - struct ath12k_rx_peer_rate_stats byte_stats; -}; - #define ATH12K_HE_MCS_NUM 12 #define ATH12K_VHT_MCS_NUM 10 #define ATH12K_BW_NUM 5 @@ -526,12 +483,6 @@ struct ath12k_per_ppdu_tx_stats { u32 retry_bytes; }; -struct ath12k_wbm_tx_stats { - u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX]; -}; - -DECLARE_EWMA(avg_rssi, 10, 8) - struct ath12k_link_sta { struct ath12k_link_vif *arvif; struct ath12k_sta *ahsta; @@ -546,15 +497,7 @@ struct ath12k_link_sta { u32 smps; struct wiphy_work update_wk; - struct rate_info txrate; - struct rate_info last_txrate; - u64 rx_duration; - u64 tx_duration; - u8 rssi_comb; - struct ewma_avg_rssi avg_rssi; u8 link_id; - struct ath12k_rx_peer_stats *rx_stats; - struct ath12k_wbm_tx_stats *wbm_tx_stats; u32 bw_prev; u32 peer_nss; s8 rssi_beacon; @@ -565,8 +508,6 @@ struct ath12k_link_sta { /* for firmware use only */ u8 link_idx; - u32 tx_retry_failed; - u32 tx_retry_count; /* peer addr based rhashtable list pointer */ struct rhash_head rhash_addr; diff --git a/drivers/net/wireless/ath/ath12k/debugfs_sta.c b/drivers/net/wireless/ath/ath12k/debugfs_sta.c index e6665fd521db8..dde3efed4b60b 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_sta.c @@ -11,6 +11,7 @@ #include "debug.h" #include "debugfs_htt_stats.h" #include "debugfs.h" +#include "dp_cmn.h" static u32 ath12k_dbg_sta_dump_rate_stats(u8 *buf, u32 offset, const int size, @@ -144,9 +145,11 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, const int size = ATH12K_STA_RX_STATS_BUF_SIZE; struct ath12k_hw *ah = ahsta->ahvif->ah; struct ath12k_rx_peer_stats *rx_stats; + struct ath12k_dp_link_peer *link_peer; struct ath12k_link_sta *arsta; u8 link_id = link_sta->link_id; int len = 0, i, ret = 0; + struct ath12k_dp *dp; bool he_rates_avail; struct ath12k *ar; @@ -171,9 +174,16 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, goto out; } - spin_lock_bh(&ar->ab->base_lock); + dp = ath12k_ab_to_dp(ar->ab); + spin_lock_bh(&dp->dp_lock); - rx_stats = arsta->rx_stats; + link_peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr); + if (!link_peer) { + ret = -ENOENT; + goto unlock; + } + + rx_stats = link_peer->peer_stats.rx_stats; if (!rx_stats) { ret = -ENOENT; goto unlock; @@ -238,7 +248,7 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, &rx_stats->byte_stats); unlock: - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (len) ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -261,10 +271,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file, struct ieee80211_link_sta *link_sta = file->private_data; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta); struct ath12k_hw *ah = ahsta->ahvif->ah; - struct ath12k_rx_peer_stats *rx_stats; - struct ath12k_link_sta *arsta; u8 link_id = link_sta->link_id; - struct ath12k *ar; + struct ath12k_link_sta *arsta; + struct ath12k_dp *dp; bool reset; int ret; @@ -288,19 +297,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file, goto out; } - ar = arsta->arvif->ar; - - spin_lock_bh(&ar->ab->base_lock); - - rx_stats = arsta->rx_stats; - if (!rx_stats) { - spin_unlock_bh(&ar->ab->base_lock); - ret = -ENOENT; - goto out; - } + dp = ath12k_ab_to_dp(arsta->arvif->ar->ab); - memset(rx_stats, 0, sizeof(*rx_stats)); - spin_unlock_bh(&ar->ab->base_lock); + ath12k_dp_link_peer_reset_rx_stats(dp, arsta->addr); ret = count; out: diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index dd10426bd12de..e17f044ff8122 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -74,6 +74,14 @@ struct ath12k_dp_peer_create_params { bool ucast_ra_only; }; +struct ath12k_dp_link_peer_rate_info { + struct rate_info txrate; + u64 rx_duration; + u64 tx_duration; + u8 rssi_comb; + s8 signal_avg; +}; + static inline struct ath12k_dp_link_vif * ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) { @@ -91,4 +99,8 @@ int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, u8 link_id, u32 hw_link_id); void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, u8 vdev_id, u8 *addr, u32 hw_link_id); +void +ath12k_dp_link_peer_get_sta_rate_info_stats(struct ath12k_dp *dp, const u8 *addr, + struct ath12k_dp_link_peer_rate_info *info); +void ath12k_dp_link_peer_reset_rx_stats(struct ath12k_dp *dp, const u8 *addr); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index db5ac36adf3dd..39f42cd99835b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -189,7 +189,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; struct ath12k_dp_link_peer *peer; - struct ath12k_link_sta *arsta; struct htt_ppdu_stats_user_rate *user_rate; struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats; struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; @@ -279,66 +278,64 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, return; } - arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); - if (!arsta) { - rcu_read_unlock(); - return; - } + spin_lock_bh(&dp->dp_lock); - memset(&arsta->txrate, 0, sizeof(arsta->txrate)); + memset(&peer->txrate, 0, sizeof(peer->txrate)); - arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); + peer->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); switch (flags) { case WMI_RATE_PREAMBLE_OFDM: - arsta->txrate.legacy = rate; + peer->txrate.legacy = rate; break; case WMI_RATE_PREAMBLE_CCK: - arsta->txrate.legacy = rate; + peer->txrate.legacy = rate; break; case WMI_RATE_PREAMBLE_HT: - arsta->txrate.mcs = mcs + 8 * (nss - 1); - arsta->txrate.flags = RATE_INFO_FLAGS_MCS; + peer->txrate.mcs = mcs + 8 * (nss - 1); + peer->txrate.flags = RATE_INFO_FLAGS_MCS; if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; break; case WMI_RATE_PREAMBLE_VHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; + peer->txrate.mcs = mcs; + peer->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; break; case WMI_RATE_PREAMBLE_HE: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); + peer->txrate.mcs = mcs; + peer->txrate.flags = RATE_INFO_FLAGS_HE_MCS; + peer->txrate.he_dcm = dcm; + peer->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); tones = le16_to_cpu(user_rate->ru_end) - le16_to_cpu(user_rate->ru_start) + 1; v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones); - arsta->txrate.he_ru_alloc = v; + peer->txrate.he_ru_alloc = v; if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_HE_RU; + peer->txrate.bw = RATE_INFO_BW_HE_RU; break; case WMI_RATE_PREAMBLE_EHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); + peer->txrate.mcs = mcs; + peer->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; + peer->txrate.he_dcm = dcm; + peer->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); tones = le16_to_cpu(user_rate->ru_end) - le16_to_cpu(user_rate->ru_start) + 1; v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones); - arsta->txrate.eht_ru_alloc = v; + peer->txrate.eht_ru_alloc = v; if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_EHT_RU; + peer->txrate.bw = RATE_INFO_BW_EHT_RU; break; } - arsta->tx_retry_failed += tx_retry_failed; - arsta->tx_retry_count += tx_retry_count; - arsta->txrate.nss = nss; - arsta->tx_duration += tx_duration; - memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); + peer->tx_retry_failed += tx_retry_failed; + peer->tx_retry_count += tx_retry_count; + peer->txrate.nss = nss; + peer->tx_duration += tx_duration; + memcpy(&peer->last_txrate, &peer->txrate, sizeof(struct rate_info)); + + spin_unlock_bh(&dp->dp_lock); /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. * So skip peer stats update for mgmt packets. diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 14203c3722a23..60caf9db94c84 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -3490,6 +3490,9 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st u32 gi_idx = ppdu_info->gi; u32 len; + if (!rx_stats) + return; + if (mcs_idx > HAL_RX_MAX_MCS_HT || nss_idx >= HAL_RX_MAX_NSS || bw_idx >= HAL_RX_BW_MAX || gi_idx >= HAL_RX_GI_MAX) { return; @@ -3510,14 +3513,14 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta, +static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info) { - struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats; + struct ath12k_rx_peer_stats *rx_stats = peer->peer_stats.rx_stats; u32 num_msdu; - arsta->rssi_comb = ppdu_info->rssi_comb; - ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb); + peer->rssi_comb = ppdu_info->rssi_comb; + ewma_avg_rssi_add(&peer->avg_rssi, ppdu_info->rssi_comb); if (!rx_stats) return; @@ -3565,7 +3568,7 @@ static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta, rx_stats->dcm_count += ppdu_info->dcm; rx_stats->rx_duration += ppdu_info->rx_duration; - arsta->rx_duration = rx_stats->rx_duration; + peer->rx_duration = rx_stats->rx_duration; if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; @@ -3672,7 +3675,6 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info, u32 uid) { - struct ath12k_link_sta *arsta; struct ath12k_rx_peer_stats *rx_stats = NULL; struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; struct ath12k_dp_link_peer *peer; @@ -3690,16 +3692,9 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, return; } - arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); - if (!arsta) { - ath12k_warn(ab, "link sta not found on peer %pM id %d\n", - peer->addr, peer->peer_id); - return; - } - - arsta->rssi_comb = ppdu_info->rssi_comb; - ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb); - rx_stats = arsta->rx_stats; + peer->rssi_comb = ppdu_info->rssi_comb; + ewma_avg_rssi_add(&peer->avg_rssi, ppdu_info->rssi_comb); + rx_stats = peer->peer_stats.rx_stats; if (!rx_stats) return; @@ -3743,7 +3738,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; rx_stats->rx_duration += ppdu_info->rx_duration; - arsta->rx_duration = rx_stats->rx_duration; + peer->rx_duration = rx_stats->rx_duration; if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; @@ -3808,7 +3803,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, struct dp_srng *mon_dst_ring; struct hal_srng *srng; struct dp_rxdma_mon_ring *buf_ring; - struct ath12k_link_sta *arsta; struct ath12k_dp_link_peer *peer; struct sk_buff_head skb_list; u64 cookie; @@ -3932,16 +3926,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); - if (!arsta) { - ath12k_warn(ab, "link sta not found on peer %pM id %d\n", - peer->addr, peer->peer_id); - rcu_read_unlock(); - dev_kfree_skb_any(skb); - continue; - } - ath12k_dp_mon_rx_update_peer_su_stats(arsta, - ppdu_info); + ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); } else if ((ppdu_info->fc_valid) && (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { ath12k_dp_mon_rx_process_ulofdma(ppdu_info); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index a06113bedf0d7..8961c4635ed0b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -7,6 +7,7 @@ #include "core.h" #include "dp_peer.h" #include "debug.h" +#include "debugfs.h" struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, @@ -140,6 +141,8 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) peer->vdev_id, peer->addr, peer_id); list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); wake_up(&ab->peer_mapping_wq); @@ -152,6 +155,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ { struct ath12k_dp_link_peer *peer; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k *ar; spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); @@ -165,10 +169,20 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); + + rcu_read_lock(); + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id); + if (ar && ath12k_debugfs_is_extd_rx_stats_enabled(ar) && + !peer->peer_stats.rx_stats) { + peer->peer_stats.rx_stats = + kzalloc(sizeof(*peer->peer_stats.rx_stats), GFP_ATOMIC); + } + rcu_read_unlock(); + list_add(&peer->list, &dp->peers); wake_up(&ab->peer_mapping_wq); + ewma_avg_rssi_init(&peer->avg_rssi); } - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", vdev_id, mac_addr, peer_id); @@ -625,3 +639,45 @@ void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_ synchronize_rcu(); } + +void +ath12k_dp_link_peer_get_sta_rate_info_stats(struct ath12k_dp *dp, const u8 *addr, + struct ath12k_dp_link_peer_rate_info *info) +{ + struct ath12k_dp_link_peer *link_peer; + + guard(spinlock_bh)(&dp->dp_lock); + + link_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (!link_peer) + return; + + info->rx_duration = link_peer->rx_duration; + info->tx_duration = link_peer->tx_duration; + info->txrate.legacy = link_peer->txrate.legacy; + info->txrate.mcs = link_peer->txrate.mcs; + info->txrate.nss = link_peer->txrate.nss; + info->txrate.bw = link_peer->txrate.bw; + info->txrate.he_gi = link_peer->txrate.he_gi; + info->txrate.he_dcm = link_peer->txrate.he_dcm; + info->txrate.he_ru_alloc = link_peer->txrate.he_ru_alloc; + info->txrate.flags = link_peer->txrate.flags; + info->rssi_comb = link_peer->rssi_comb; + info->signal_avg = ewma_avg_rssi_read(&link_peer->avg_rssi); +} + +void ath12k_dp_link_peer_reset_rx_stats(struct ath12k_dp *dp, const u8 *addr) +{ + struct ath12k_rx_peer_stats *rx_stats; + struct ath12k_dp_link_peer *link_peer; + + guard(spinlock_bh)(&dp->dp_lock); + + link_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (!link_peer || !link_peer->peer_stats.rx_stats) + return; + + rx_stats = link_peer->peer_stats.rx_stats; + if (rx_stats) + memset(rx_stats, 0, sizeof(*rx_stats)); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index f7c995e8c4e32..f9be27d865453 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -23,6 +23,51 @@ struct ppdu_user_delayba { #define ATH12K_PEER_ML_ID_VALID BIT(13) +struct ath12k_rx_peer_rate_stats { + u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; + u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; + u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; + u64 be_mcs_count[HAL_RX_MAX_MCS_BE + 1]; + u64 nss_count[HAL_RX_MAX_NSS]; + u64 bw_count[HAL_RX_BW_MAX]; + u64 gi_count[HAL_RX_GI_MAX]; + u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; + u64 rx_rate[HAL_RX_BW_MAX][HAL_RX_GI_MAX][HAL_RX_MAX_NSS][HAL_RX_MAX_MCS_HT + 1]; +}; + +struct ath12k_rx_peer_stats { + u64 num_msdu; + u64 num_mpdu_fcs_ok; + u64 num_mpdu_fcs_err; + u64 tcp_msdu_count; + u64 udp_msdu_count; + u64 other_msdu_count; + u64 ampdu_msdu_count; + u64 non_ampdu_msdu_count; + u64 stbc_count; + u64 beamformed_count; + u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; + u64 tid_count[IEEE80211_NUM_TIDS + 1]; + u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; + u64 reception_type[HAL_RX_RECEPTION_TYPE_MAX]; + u64 rx_duration; + u64 dcm_count; + u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; + struct ath12k_rx_peer_rate_stats pkt_stats; + struct ath12k_rx_peer_rate_stats byte_stats; +}; + +struct ath12k_wbm_tx_stats { + u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX]; +}; + +struct ath12k_dp_peer_stats { + struct ath12k_rx_peer_stats *rx_stats; + struct ath12k_wbm_tx_stats *wbm_tx_stats; +}; + +DECLARE_EWMA(avg_rssi, 10, 8) + struct ath12k_dp_link_peer { struct list_head list; struct ieee80211_sta *sta; @@ -58,6 +103,17 @@ struct ath12k_dp_link_peer { u8 hw_link_id; u32 rx_tid_active_bitmask; + + /* link stats */ + struct rate_info txrate; + struct rate_info last_txrate; + u64 rx_duration; + u64 tx_duration; + u8 rssi_comb; + struct ewma_avg_rssi avg_rssi; + struct ath12k_dp_peer_stats peer_stats; + u32 tx_retry_failed; + u32 tx_retry_count; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index dbf07c15481b8..69c2e8b318d5b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -64,6 +64,15 @@ struct ath12k_base; #define HAL_WBM_IDLE_SCATTER_BUF_SIZE (HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX - \ HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE) +#define HAL_AST_IDX_INVALID 0xFFFF +#define HAL_RX_MAX_MCS 12 +#define HAL_RX_MAX_MCS_HT 31 +#define HAL_RX_MAX_MCS_VHT 9 +#define HAL_RX_MAX_MCS_HE 11 +#define HAL_RX_MAX_MCS_BE 15 +#define HAL_RX_MAX_NSS 8 +#define HAL_RX_MAX_NUM_LEGACY_RATES 12 + enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 8fa8ad2d50bd5..56574177be767 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -23,6 +23,7 @@ #include "wow.h" #include "debugfs_sta.h" #include "dp.h" +#include "dp_cmn.h" #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ @@ -1237,6 +1238,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) list_for_each_entry_safe(peer, tmp, &peers, list) { list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); } @@ -6696,14 +6699,13 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, vif->addr, arvif->vdev_id); peer->sta = NULL; list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); ar->num_peers--; } spin_unlock_bh(&dp->dp_lock); - - kfree(arsta->rx_stats); - arsta->rx_stats = NULL; } static int ath12k_mac_station_unauthorize(struct ath12k *ar, @@ -6848,14 +6850,6 @@ static int ath12k_mac_station_add(struct ath12k *ar, goto exit; } - if (ath12k_debugfs_is_extd_rx_stats_enabled(ar) && !arsta->rx_stats) { - arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL); - if (!arsta->rx_stats) { - ret = -ENOMEM; - goto dec_num_station; - } - } - spin_lock_bh(&ab->base_lock); /* @@ -6873,7 +6867,7 @@ static int ath12k_mac_station_add(struct ath12k *ar, if (ret) { ath12k_warn(ab, "Failed to add arsta: %pM to hash table, ret: %d", arsta->addr, ret); - goto free_rx_stats; + goto dec_num_station; } peer_param.vdev_id = arvif->vdev_id; @@ -6919,7 +6913,6 @@ static int ath12k_mac_station_add(struct ath12k *ar, } } - ewma_avg_rssi_init(&arsta->avg_rssi); return 0; free_peer: @@ -6927,9 +6920,6 @@ static int ath12k_mac_station_add(struct ath12k *ar, spin_lock_bh(&ab->base_lock); ath12k_link_sta_rhash_delete(ab, arsta); spin_unlock_bh(&ab->base_lock); -free_rx_stats: - kfree(arsta->rx_stats); - arsta->rx_stats = NULL; dec_num_station: ath12k_mac_dec_num_stations(arvif, arsta); exit: @@ -13447,9 +13437,12 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, struct station_info *sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); + struct ath12k_dp_link_peer_rate_info rate_info = {}; struct ath12k_fw_stats_req_params params = {}; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; s8 signal, noise_floor; + struct ath12k_dp *dp; struct ath12k *ar; bool db2dbm; @@ -13460,34 +13453,37 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, if (!ar) return; + dp = ath12k_ab_to_dp(ar->ab); + ath12k_dp_link_peer_get_sta_rate_info_stats(dp, arsta->addr, &rate_info); + db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - sinfo->rx_duration = arsta->rx_duration; + sinfo->rx_duration = rate_info.rx_duration; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); - sinfo->tx_duration = arsta->tx_duration; + sinfo->tx_duration = rate_info.tx_duration; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); - if (arsta->txrate.legacy || arsta->txrate.nss) { - if (arsta->txrate.legacy) { - sinfo->txrate.legacy = arsta->txrate.legacy; + if (rate_info.txrate.legacy || rate_info.txrate.nss) { + if (rate_info.txrate.legacy) { + sinfo->txrate.legacy = rate_info.txrate.legacy; } else { - sinfo->txrate.mcs = arsta->txrate.mcs; - sinfo->txrate.nss = arsta->txrate.nss; - sinfo->txrate.bw = arsta->txrate.bw; - sinfo->txrate.he_gi = arsta->txrate.he_gi; - sinfo->txrate.he_dcm = arsta->txrate.he_dcm; - sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc; - sinfo->txrate.eht_gi = arsta->txrate.eht_gi; - sinfo->txrate.eht_ru_alloc = arsta->txrate.eht_ru_alloc; - } - sinfo->txrate.flags = arsta->txrate.flags; + sinfo->txrate.mcs = rate_info.txrate.mcs; + sinfo->txrate.nss = rate_info.txrate.nss; + sinfo->txrate.bw = rate_info.txrate.bw; + sinfo->txrate.he_gi = rate_info.txrate.he_gi; + sinfo->txrate.he_dcm = rate_info.txrate.he_dcm; + sinfo->txrate.he_ru_alloc = rate_info.txrate.he_ru_alloc; + sinfo->txrate.eht_gi = rate_info.txrate.eht_gi; + sinfo->txrate.eht_ru_alloc = rate_info.txrate.eht_ru_alloc; + } + sinfo->txrate.flags = rate_info.txrate.flags; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } /* TODO: Use real NF instead of default one. */ - signal = arsta->rssi_comb; + signal = rate_info.rssi_comb; params.pdev_id = ar->pdev->pdev_id; params.vdev_id = 0; @@ -13517,17 +13513,26 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi); + sinfo->signal_avg = rate_info.signal_avg; if (!db2dbm) sinfo->signal_avg += noise_floor; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - sinfo->tx_retries = arsta->tx_retry_count; - sinfo->tx_failed = arsta->tx_retry_failed; + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr); + if (!peer) { + spin_unlock_bh(&dp->dp_lock); + return; + } + + sinfo->tx_retries = peer->tx_retry_count; + sinfo->tx_failed = peer->tx_retry_failed; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + + spin_unlock_bh(&dp->dp_lock); } EXPORT_SYMBOL(ath12k_mac_op_sta_statistics); @@ -13538,6 +13543,7 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta); struct ath12k_fw_stats_req_params params = {}; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; struct ath12k *ar; s8 signal; @@ -13557,33 +13563,40 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - link_sinfo->rx_duration = arsta->rx_duration; + spin_lock_bh(&ar->ab->dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); + if (!peer) { + spin_unlock_bh(&ar->ab->dp->dp_lock); + return; + } + + link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); - link_sinfo->tx_duration = arsta->tx_duration; + link_sinfo->tx_duration = peer->tx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); - if (arsta->txrate.legacy || arsta->txrate.nss) { - if (arsta->txrate.legacy) { - link_sinfo->txrate.legacy = arsta->txrate.legacy; + if (peer->txrate.legacy || peer->txrate.nss) { + if (peer->txrate.legacy) { + link_sinfo->txrate.legacy = peer->txrate.legacy; } else { - link_sinfo->txrate.mcs = arsta->txrate.mcs; - link_sinfo->txrate.nss = arsta->txrate.nss; - link_sinfo->txrate.bw = arsta->txrate.bw; - link_sinfo->txrate.he_gi = arsta->txrate.he_gi; - link_sinfo->txrate.he_dcm = arsta->txrate.he_dcm; + link_sinfo->txrate.mcs = peer->txrate.mcs; + link_sinfo->txrate.nss = peer->txrate.nss; + link_sinfo->txrate.bw = peer->txrate.bw; + link_sinfo->txrate.he_gi = peer->txrate.he_gi; + link_sinfo->txrate.he_dcm = peer->txrate.he_dcm; link_sinfo->txrate.he_ru_alloc = - arsta->txrate.he_ru_alloc; - link_sinfo->txrate.eht_gi = arsta->txrate.eht_gi; + peer->txrate.he_ru_alloc; + link_sinfo->txrate.eht_gi = peer->txrate.eht_gi; link_sinfo->txrate.eht_ru_alloc = - arsta->txrate.eht_ru_alloc; + peer->txrate.eht_ru_alloc; } - link_sinfo->txrate.flags = arsta->txrate.flags; + link_sinfo->txrate.flags = peer->txrate.flags; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } /* TODO: Use real NF instead of default one. */ - signal = arsta->rssi_comb; + signal = peer->rssi_comb; params.pdev_id = ar->pdev->pdev_id; params.vdev_id = 0; @@ -13602,17 +13615,18 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - link_sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi); + link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); if (!db2dbm) link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - link_sinfo->tx_retries = arsta->tx_retry_count; - link_sinfo->tx_failed = arsta->tx_retry_failed; + link_sinfo->tx_retries = peer->tx_retry_count; + link_sinfo->tx_failed = peer->tx_retry_failed; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + spin_unlock_bh(&ar->ab->dp->dp_lock); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 812247decab43..9c100ecea798e 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -7,6 +7,7 @@ #include "core.h" #include "peer.h" #include "debug.h" +#include "debugfs.h" static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id, const u8 *addr, bool expect_mapped) @@ -50,6 +51,8 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) peer->addr, vdev_id); list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); ar->num_peers--; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 454d5a7532cfd..737651341afcd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -517,31 +517,36 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, struct hal_tx_status *ts) { struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_dp_link_peer *peer; struct ath12k_base *ab = dp->ab; - struct ath12k_dp_peer *peer; - struct ieee80211_sta *sta; - struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; struct rate_info txrate = {}; + struct ieee80211_sta *sta; + struct ath12k_sta *ahsta; u16 rate, ru_tones; u8 rate_idx = 0; int ret; - peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); return; } + + spin_lock_bh(&dp->dp_lock); + sta = peer->sta; ahsta = ath12k_sta_to_ahsta(sta); arsta = &ahsta->deflink; + spin_unlock_bh(&dp->dp_lock); + /* This is to prefer choose the real NSS value arsta->last_txrate.nss, * if it is invalid, then choose the NSS value while assoc. */ - if (arsta->last_txrate.nss) - txrate.nss = arsta->last_txrate.nss; + if (peer->last_txrate.nss) + txrate.nss = peer->last_txrate.nss; else txrate.nss = arsta->peer_nss; @@ -625,9 +630,9 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones); } - spin_lock_bh(&ab->base_lock); - arsta->txrate = txrate; - spin_unlock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); + peer->txrate = txrate; + spin_unlock_bh(&dp->dp_lock); } static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, @@ -646,9 +651,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ieee80211_rate_status status_rate = {}; - struct ath12k_dp_peer *peer; - struct ath12k_link_sta *arsta; - struct ath12k_sta *ahsta; + struct ath12k_dp_link_peer *peer; struct rate_info rate; if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { @@ -743,7 +746,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); - peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", @@ -751,13 +754,11 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } - ahsta = ath12k_sta_to_ahsta(peer->sta); - arsta = &ahsta->deflink; status.sta = peer->sta; status.info = info; status.skb = msdu; - rate = arsta->last_txrate; + rate = peer->last_txrate; status_rate.rate_idx = rate; status_rate.try_count = 1; From 2cdf73ddfacf2cedef6cae6cb697760633da6f8c Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:03 +0530 Subject: [PATCH 446/659] wifi: ath12k: Add helper to free DP link peer Introduce ath12k_dp_link_peer_free() to wrap cleanup steps required before freeing a DP link peer. This avoids code duplication and ensures consistent teardown across multiple call flows. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_peer.c | 13 +++++++++---- drivers/net/wireless/ath/ath12k/dp_peer.h | 1 + drivers/net/wireless/ath/ath12k/mac.c | 9 ++------- drivers/net/wireless/ath/ath12k/peer.c | 5 +---- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 8961c4635ed0b..0ad01f7414cd6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -9,6 +9,14 @@ #include "debug.h" #include "debugfs.h" +void ath12k_dp_link_peer_free(struct ath12k_dp_link_peer *peer) +{ + list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); + kfree(peer); +} + struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr) @@ -140,10 +148,7 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", peer->vdev_id, peer->addr, peer_id); - list_del(&peer->list); - - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); wake_up(&ab->peer_mapping_wq); exit: diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index f9be27d865453..20294ff095131 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -178,4 +178,5 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_p u16 peer_id); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id); +void ath12k_dp_link_peer_free(struct ath12k_dp_link_peer *peer); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 56574177be767..3ab13969a27e4 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1237,10 +1237,7 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) synchronize_rcu(); list_for_each_entry_safe(peer, tmp, &peers, list) { - list_del(&peer->list); - - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); } ar->num_peers = 0; @@ -6698,10 +6695,8 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", vif->addr, arvif->vdev_id); peer->sta = NULL; - list_del(&peer->list); - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); ar->num_peers--; } diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 9c100ecea798e..c2fb5bbd6ceae 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -50,10 +50,7 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) ath12k_warn(ab, "removing stale peer %pM from vdev_id %d\n", peer->addr, vdev_id); - list_del(&peer->list); - - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); ar->num_peers--; } From 1088dae4ffcf8183b1b2d8bfd9b60904e9e0fd60 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Mon, 3 Nov 2025 16:51:04 +0530 Subject: [PATCH 447/659] wifi: ath12k: Move ieee80211_ops callback to the arch specific module Move the ieee80211_ops Tx callback to the architecture-specific module to avoid additional indirections caused by the common Tx function calling the architecture-specific Tx functions via ops. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/mac.c | 234 ++---------------- drivers/net/wireless/ath/ath12k/mac.h | 15 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 208 +++++++++++++++- 5 files changed, 237 insertions(+), 223 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 0ab9a09d43a89..8f6c537348736 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -28,6 +28,7 @@ unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); MODULE_PARM_DESC(debug_mask, "Debugging mask"); +EXPORT_SYMBOL(ath12k_debug_mask); bool ath12k_ftm_mode; module_param_named(ftm_mode, ath12k_ftm_mode, bool, 0444); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 3ab13969a27e4..eb6259368dc31 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9156,8 +9156,8 @@ static void ath12k_mgmt_over_wmi_tx_work(struct wiphy *wiphy, struct wiphy_work } } -static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, - bool is_prb_rsp) +int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, + bool is_prb_rsp) { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; @@ -9187,11 +9187,12 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, return 0; } +EXPORT_SYMBOL(ath12k_mac_mgmt_tx); -static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, - struct ieee80211_vif *vif, - struct sk_buff *skb, - bool is_prb_rsp) +void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, + struct ieee80211_vif *vif, + struct sk_buff *skb, + bool is_prb_rsp) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -9208,11 +9209,12 @@ static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, spin_unlock_bh(&ar->data_lock); } +EXPORT_SYMBOL(ath12k_mac_add_p2p_noa_ie); /* Note: called under rcu_read_lock() */ -static void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, - u8 link_id, struct sk_buff *skb, - u32 info_flags) +void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, + u8 link_id, struct sk_buff *skb, + u32 info_flags) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_bss_conf *bss_conf; @@ -9224,10 +9226,11 @@ static void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, if (bss_conf) ether_addr_copy(hdr->addr2, bss_conf->addr); } +EXPORT_SYMBOL(ath12k_mlo_mcast_update_tx_link_address); /* Note: called under rcu_read_lock() */ -static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif, - u8 link, struct sk_buff *skb, u32 info_flags) +u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif, + u8 link, struct sk_buff *skb, u32 info_flags) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -9322,214 +9325,7 @@ static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif return link; } - -/* Note: called under rcu_read_lock() */ -void ath12k_mac_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; - struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); - struct ath12k_link_vif *arvif = &ahvif->deflink; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_key_conf *key = info->control.hw_key; - struct ieee80211_sta *sta = control->sta; - struct ath12k_link_vif *tmp_arvif; - u32 info_flags = info->flags; - struct sk_buff *msdu_copied; - struct ath12k *ar, *tmp_ar; - struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; - struct ath12k_dp_link_peer *peer; - unsigned long links_map; - bool is_mcast = false; - bool is_dvlan = false; - struct ethhdr *eth; - bool is_prb_rsp; - u16 mcbc_gsn; - u8 link_id; - int ret; - struct ath12k_dp *tmp_dp; - - if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { - ieee80211_free_txskb(hw, skb); - return; - } - - link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK); - memset(skb_cb, 0, sizeof(*skb_cb)); - skb_cb->vif = vif; - - if (key) { - skb_cb->cipher = key->cipher; - skb_cb->flags |= ATH12K_SKB_CIPHER_SET; - } - - /* handle only for MLO case, use deflink for non MLO case */ - if (ieee80211_vif_is_mld(vif)) { - link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags); - if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) { - ieee80211_free_txskb(hw, skb); - return; - } - } else { - if (vif->type == NL80211_IFTYPE_P2P_DEVICE) - link_id = ATH12K_FIRST_SCAN_LINK; - else - link_id = 0; - } - - arvif = rcu_dereference(ahvif->link[link_id]); - if (!arvif || !arvif->ar) { - ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission", - link_id); - ieee80211_free_txskb(hw, skb); - return; - } - - ar = arvif->ar; - skb_cb->link_id = link_id; - /* as skb_cb is common currently for dp and mgmt tx processing - * set this in the common mac op tx function. - */ - skb_cb->ar = ar; - is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); - - if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { - eth = (struct ethhdr *)skb->data; - is_mcast = is_multicast_ether_addr(eth->h_dest); - - skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP; - } else if (ieee80211_is_mgmt(hdr->frame_control)) { - if (sta && sta->mlo) - skb_cb->flags |= ATH12K_SKB_MLO_STA; - - ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp); - if (ret) { - ath12k_warn(ar->ab, "failed to queue management frame %d\n", - ret); - ieee80211_free_txskb(hw, skb); - } - return; - } - - if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) - is_mcast = is_multicast_ether_addr(hdr->addr1); - - /* This is case only for P2P_GO */ - if (vif->type == NL80211_IFTYPE_AP && vif->p2p) - ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); - - dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx); - if (!dp_pdev) { - ieee80211_free_txskb(hw, skb); - return; - } - - /* Checking if it is a DVLAN frame */ - if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && - !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && - !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && - ieee80211_has_protected(hdr->frame_control)) - is_dvlan = true; - - if (!vif->valid_links || !is_mcast || is_dvlan || - (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || - test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { - ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast); - if (unlikely(ret)) { - ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); - ieee80211_free_txskb(ar->ah->hw, skb); - return; - } - } else { - mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff; - - links_map = ahvif->links_map; - for_each_set_bit(link_id, &links_map, - IEEE80211_MLD_MAX_NUM_LINKS) { - tmp_arvif = rcu_dereference(ahvif->link[link_id]); - if (!tmp_arvif || !tmp_arvif->is_up) - continue; - - tmp_ar = tmp_arvif->ar; - tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp, - tmp_ar->pdev_idx); - if (!tmp_dp_pdev) - continue; - msdu_copied = skb_copy(skb, GFP_ATOMIC); - if (!msdu_copied) { - ath12k_err(ar->ab, - "skb copy failure link_id 0x%X vdevid 0x%X\n", - link_id, tmp_arvif->vdev_id); - continue; - } - - ath12k_mlo_mcast_update_tx_link_address(vif, link_id, - msdu_copied, - info_flags); - - skb_cb = ATH12K_SKB_CB(msdu_copied); - skb_cb->link_id = link_id; - skb_cb->vif = vif; - skb_cb->ar = tmp_ar; - - /* For open mode, skip peer find logic */ - if (unlikely(!ahvif->dp_vif.key_cipher)) - goto skip_peer_find; - - tmp_dp = ath12k_ab_to_dp(tmp_ar->ab); - spin_lock_bh(&tmp_dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, - tmp_arvif->bssid); - if (!peer || !peer->dp_peer) { - spin_unlock_bh(&tmp_dp->dp_lock); - ath12k_warn(tmp_ar->ab, - "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", - tmp_arvif->vdev_id, tmp_arvif->bssid, - ahvif->links_map); - dev_kfree_skb_any(msdu_copied); - continue; - } - - key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx]; - if (key) { - skb_cb->cipher = key->cipher; - skb_cb->flags |= ATH12K_SKB_CIPHER_SET; - - hdr = (struct ieee80211_hdr *)msdu_copied->data; - if (!ieee80211_has_protected(hdr->frame_control)) - hdr->frame_control |= - cpu_to_le16(IEEE80211_FCTL_PROTECTED); - } - spin_unlock_bh(&tmp_dp->dp_lock); - -skip_peer_find: - ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, - msdu_copied, true, mcbc_gsn, is_mcast); - if (unlikely(ret)) { - if (ret == -ENOMEM) { - /* Drops are expected during heavy multicast - * frame flood. Print with debug log - * level to avoid lot of console prints - */ - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, - "failed to transmit frame %d\n", - ret); - } else { - ath12k_warn(ar->ab, - "failed to transmit frame %d\n", - ret); - } - - dev_kfree_skb_any(msdu_copied); - } - } - ieee80211_free_txskb(ar->ah->hw, skb); - } -} -EXPORT_SYMBOL(ath12k_mac_op_tx); +EXPORT_SYMBOL(ath12k_mac_get_tx_link); void ath12k_mac_drain_tx(struct ath12k *ar) { diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index ed7ad3ca4f407..422bd3b095cd2 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -204,9 +204,6 @@ void ath12k_mac_update_freq_range(struct ath12k *ar, void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ieee80211_chanctx_conf *ctx); -void ath12k_mac_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb); int ath12k_mac_op_start(struct ieee80211_hw *hw); void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend); void @@ -330,4 +327,16 @@ int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, int *dbm); +int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, + bool is_prb_rsp); +void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, + struct ieee80211_vif *vif, + struct sk_buff *skb, + bool is_prb_rsp); +u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif, + u8 link, struct sk_buff *skb, u32 info_flags); + +void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, + u8 link_id, struct sk_buff *skb, + u32 info_flags); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 737651341afcd..7e16bc12e36ac 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -57,6 +57,7 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb) return 0; } +/* TODO: Remove the export once this file is built with wifi7 ko */ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast) @@ -378,6 +379,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a return ret; } +EXPORT_SYMBOL(ath12k_wifi7_dp_tx); static void ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 946771b96fb58..1f5dda73230d0 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -24,6 +24,7 @@ #include "../debugfs_sta.h" #include "../testmode.h" #include "hal.h" +#include "dp_tx.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, @@ -653,8 +654,213 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { }, }; +/* Note: called under rcu_read_lock() */ +static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = info->control.vif; + struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); + struct ath12k_link_vif *arvif = &ahvif->deflink; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key_conf *key = info->control.hw_key; + struct ieee80211_sta *sta = control->sta; + struct ath12k_link_vif *tmp_arvif; + u32 info_flags = info->flags; + struct sk_buff *msdu_copied; + struct ath12k *ar, *tmp_ar; + struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; + struct ath12k_dp_link_peer *peer; + unsigned long links_map; + bool is_mcast = false; + bool is_dvlan = false; + struct ethhdr *eth; + bool is_prb_rsp; + u16 mcbc_gsn; + u8 link_id; + int ret; + struct ath12k_dp *tmp_dp; + + if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + ieee80211_free_txskb(hw, skb); + return; + } + + link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK); + memset(skb_cb, 0, sizeof(*skb_cb)); + skb_cb->vif = vif; + + if (key) { + skb_cb->cipher = key->cipher; + skb_cb->flags |= ATH12K_SKB_CIPHER_SET; + } + + /* handle only for MLO case, use deflink for non MLO case */ + if (ieee80211_vif_is_mld(vif)) { + link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags); + if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) { + ieee80211_free_txskb(hw, skb); + return; + } + } else { + link_id = 0; + } + + arvif = rcu_dereference(ahvif->link[link_id]); + if (!arvif || !arvif->ar) { + ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission", + link_id); + ieee80211_free_txskb(hw, skb); + return; + } + + ar = arvif->ar; + skb_cb->link_id = link_id; + /* + * as skb_cb is common currently for dp and mgmt tx processing + * set this in the common mac op tx function. + */ + skb_cb->ar = ar; + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); + + if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { + eth = (struct ethhdr *)skb->data; + is_mcast = is_multicast_ether_addr(eth->h_dest); + + skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP; + } else if (ieee80211_is_mgmt(hdr->frame_control)) { + if (sta && sta->mlo) + skb_cb->flags |= ATH12K_SKB_MLO_STA; + + ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp); + if (ret) { + ath12k_warn(ar->ab, "failed to queue management frame %d\n", + ret); + ieee80211_free_txskb(hw, skb); + } + return; + } + + if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) + is_mcast = is_multicast_ether_addr(hdr->addr1); + + /* This is case only for P2P_GO */ + if (vif->type == NL80211_IFTYPE_AP && vif->p2p) + ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); + + dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx); + if (!dp_pdev) { + ieee80211_free_txskb(hw, skb); + return; + } + + /* Checking if it is a DVLAN frame */ + if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && + !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && + ieee80211_has_protected(hdr->frame_control)) + is_dvlan = true; + + if (!vif->valid_links || !is_mcast || is_dvlan || + (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || + test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { + ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast); + if (unlikely(ret)) { + ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->ah->hw, skb); + return; + } + } else { + mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff; + + links_map = ahvif->links_map; + for_each_set_bit(link_id, &links_map, + IEEE80211_MLD_MAX_NUM_LINKS) { + tmp_arvif = rcu_dereference(ahvif->link[link_id]); + if (!tmp_arvif || !tmp_arvif->is_up) + continue; + + tmp_ar = tmp_arvif->ar; + tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp, + tmp_ar->pdev_idx); + if (!tmp_dp_pdev) + continue; + msdu_copied = skb_copy(skb, GFP_ATOMIC); + if (!msdu_copied) { + ath12k_err(ar->ab, + "skb copy failure link_id 0x%X vdevid 0x%X\n", + link_id, tmp_arvif->vdev_id); + continue; + } + + ath12k_mlo_mcast_update_tx_link_address(vif, link_id, + msdu_copied, + info_flags); + + skb_cb = ATH12K_SKB_CB(msdu_copied); + skb_cb->link_id = link_id; + skb_cb->vif = vif; + skb_cb->ar = tmp_ar; + + /* For open mode, skip peer find logic */ + if (unlikely(!ahvif->dp_vif.key_cipher)) + goto skip_peer_find; + + tmp_dp = ath12k_ab_to_dp(tmp_ar->ab); + spin_lock_bh(&tmp_dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, + tmp_arvif->bssid); + if (!peer || !peer->dp_peer) { + spin_unlock_bh(&tmp_dp->dp_lock); + ath12k_warn(tmp_ar->ab, + "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", + tmp_arvif->vdev_id, tmp_arvif->bssid, + ahvif->links_map); + dev_kfree_skb_any(msdu_copied); + continue; + } + + key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx]; + if (key) { + skb_cb->cipher = key->cipher; + skb_cb->flags |= ATH12K_SKB_CIPHER_SET; + + hdr = (struct ieee80211_hdr *)msdu_copied->data; + if (!ieee80211_has_protected(hdr->frame_control)) + hdr->frame_control |= + cpu_to_le16(IEEE80211_FCTL_PROTECTED); + } + spin_unlock_bh(&tmp_dp->dp_lock); + +skip_peer_find: + ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, + msdu_copied, true, mcbc_gsn, is_mcast); + if (unlikely(ret)) { + if (ret == -ENOMEM) { + /* Drops are expected during heavy multicast + * frame flood. Print with debug log + * level to avoid lot of console prints + */ + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "failed to transmit frame %d\n", + ret); + } else { + ath12k_warn(ar->ab, + "failed to transmit frame %d\n", + ret); + } + + dev_kfree_skb_any(msdu_copied); + } + } + ieee80211_free_txskb(ar->ah->hw, skb); + } +} + static const struct ieee80211_ops ath12k_ops_wifi7 = { - .tx = ath12k_mac_op_tx, + .tx = ath12k_wifi7_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, .start = ath12k_mac_op_start, .stop = ath12k_mac_op_stop, From 2d548a36423ea2f31e17fa23a3b52679c13e5ad9 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:05 +0530 Subject: [PATCH 448/659] wifi: ath12k: Remove the wifi7 header inclusions in common code As a precursor to the movement of wifi7 specific .c files to ath12k_wifi7.ko module, remove the wifi7 headers included in the common .c files except for dp_mon.c file, as the changes for moving the code from common to wifi7 directory for monitor will be coming incrementally. Since, dp_mon.c continues to be part of ath12k.ko module, add a few callbacks in hal_ops to facilitate calls from dp_mon.c to reach hal APIs present in ath12k_wifi7.ko module Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 1 - drivers/net/wireless/ath/ath12k/core.c | 1 - drivers/net/wireless/ath/ath12k/core.h | 1 - drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/dp_mon.c | 45 ++++++++------ drivers/net/wireless/ath/ath12k/dp_rx.c | 1 - drivers/net/wireless/ath/ath12k/dp_rx.h | 14 ----- drivers/net/wireless/ath/ath12k/hal.c | 18 ++++++ drivers/net/wireless/ath/ath12k/hal.h | 60 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/mac.c | 1 - .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 46 -------------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 19 +++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 15 ++--- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 + 15 files changed, 129 insertions(+), 98 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 2628d53845eb8..9a4d34e491044 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -15,7 +15,6 @@ #include "ahb.h" #include "debug.h" #include "hif.h" -#include "wifi7/dp.h" #define ATH12K_IRQ_CE0_OFFSET 4 #define ATH12K_MAX_UPDS 1 diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 8f6c537348736..e4c3fdb504832 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -15,7 +15,6 @@ #include "core.h" #include "dp_tx.h" #include "dp_rx.h" -#include "wifi7/dp_rx.h" #include "debug.h" #include "debugfs.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 8a1abd5049144..31d5d10beb85a 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -27,7 +27,6 @@ #include "ce.h" #include "mac.h" #include "hw.h" -#include "wifi7/hal_desc.h" #include "reg.h" #include "dbring.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 1068a130fc82c..813a9e2a47ce7 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,7 +11,6 @@ #include "dp_htt.h" #include "dp_cmn.h" #include -#include "wifi7/hal_desc.h" #define MAX_RXDMA_PER_PDEV 2 diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 60caf9db94c84..048b418a56f71 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,6 +17,16 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) +static bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} + static void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -1842,7 +1852,7 @@ ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, if (!status_desc) return DP_MON_STATUS_NO_DMA; - ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, status_desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -1886,7 +1896,8 @@ static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } static -void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, +void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, struct ath12k_buffer_addr **pp_buf_addr_info) { @@ -1894,7 +1905,7 @@ void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, buf_addr_info = &msdu_link->buf_addr_info; - ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, buf_addr_info, paddr, sw_cookie, rbm); *pp_buf_addr_info = buf_addr_info; } @@ -2780,7 +2791,7 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, mgr); } ath12k_hal_srng_access_end(ab, srng); @@ -3981,8 +3992,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, pmon->buf_state = DP_MON_STATUS_REPLINISH; break; } - ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, - &cookie, &rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, rx_mon_status_desc, &paddr, + &cookie, &rbm); if (paddr) { buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -4067,8 +4078,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, if (!skb) { ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, - hal_params->rx_buf_rbm); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, + 0, 0, hal_params->rx_buf_rbm); num_buffs_reaped++; break; } @@ -4077,9 +4088,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, - cookie, - hal_params->rx_buf_rbm); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, rxcb->paddr, + cookie, hal_params->rx_buf_rbm); ath12k_hal_srng_src_get_next_entry(ab, srng); num_buffs_reaped++; } @@ -4117,7 +4127,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, dma_addr_t paddr; u8 rbm; - ath12k_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr, + ath12k_hal_rx_reo_ent_buf_paddr_get(&ab->hal, ring_entry, &paddr, &sw_cookie, &p_last_buf_addr_info, &rbm, &msdu_cnt); @@ -4153,7 +4163,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, dp->link_desc_banks[desc_bank].vaddr + (paddr - dp->link_desc_banks[desc_bank].paddr); - ath12k_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, + ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, &num_msdus); desc_info = ath12k_dp_get_rx_desc(ar->ab, msdu_list.sw_cookie[num_msdus - 1]); @@ -4250,14 +4260,15 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, list_add_tail(&desc_info->list, used_list); } - ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, &buf_info, paddr, + sw_cookie, rbm); - ath12k_dp_mon_next_link_desc_get(msdu_link_desc, &paddr, + ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, &sw_cookie, &rbm, &p_buf_addr_info); - ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); p_last_buf_addr_info = p_buf_addr_info; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index b0ef21dc1278d..99e52a749b32b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -12,7 +12,6 @@ #include "debug.h" #include "hw.h" #include "dp_rx.h" -#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 4a93331dff579..f413834eff892 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -150,16 +150,6 @@ static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } -static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) @@ -258,10 +248,6 @@ u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype); u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc); -bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc); void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 3f9c2183c9a69..08063d1094ae1 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -116,6 +116,24 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, hal->ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); } +void ath12k_hal_rx_msdu_list_get(struct ath12k_hal *hal, struct ath12k *ar, + void *link_desc, + void *msdu_list, + u16 *num_msdus) +{ + hal->ops->rx_msdu_list_get(ar, link_desc, msdu_list, num_msdus); +} + +void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, + dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt) +{ + hal->ops->rx_reo_ent_buf_paddr_get(rx_desc, paddr, sw_cookie, + pp_buf_addr, rbm, msdu_cnt); +} + void ath12k_hal_cc_config(struct ath12k_base *ab) { ab->hal.ops->cc_config(ab); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 69c2e8b318d5b..29bcedca0a3b0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -927,6 +927,51 @@ struct hal_srng { } u; }; +/* hal_wbm_link_desc + * + * Producer: WBM + * Consumer: WBM + * + * buf_addr_info + * Details of the physical address of a buffer or MSDU + * link descriptor. + */ + +enum hal_wbm_rel_src_module { + HAL_WBM_REL_SRC_MODULE_TQM, + HAL_WBM_REL_SRC_MODULE_RXDMA, + HAL_WBM_REL_SRC_MODULE_REO, + HAL_WBM_REL_SRC_MODULE_FW, + HAL_WBM_REL_SRC_MODULE_SW, + HAL_WBM_REL_SRC_MODULE_MAX, +}; + +/* hal_wbm_rel_desc_type + * + * msdu_buffer + * The address points to an MSDU buffer + * + * msdu_link_descriptor + * The address points to an Tx MSDU link descriptor + * + * mpdu_link_descriptor + * The address points to an MPDU link descriptor + * + * msdu_ext_descriptor + * The address points to an MSDU extension descriptor + * + * queue_ext_descriptor + * The address points to an TQM queue extension descriptor. WBM should + * treat this is the same way as a link descriptor. + */ +enum hal_wbm_rel_desc_type { + HAL_WBM_REL_DESC_TYPE_REL_MSDU, + HAL_WBM_REL_DESC_TYPE_MSDU_LINK, + HAL_WBM_REL_DESC_TYPE_MPDU_LINK, + HAL_WBM_REL_DESC_TYPE_MSDU_EXT, + HAL_WBM_REL_DESC_TYPE_QUEUE_EXT, +}; + /* Interrupt mitigation - Batch threshold in terms of number of frames */ #define HAL_SRNG_INT_BATCH_THRESHOLD_TX 256 #define HAL_SRNG_INT_BATCH_THRESHOLD_RX 128 @@ -1335,6 +1380,14 @@ struct hal_ops { void (*cc_config)(struct ath12k_base *ab); enum hal_rx_buf_return_buf_manager (*get_idle_link_rbm)(struct ath12k_hal *hal, u8 device_id); + void (*rx_msdu_list_get)(struct ath12k *ar, + void *link_desc, + void *msdu_list, + u16 *num_msdus); + void (*rx_reo_ent_buf_paddr_get)(void *rx_desc, dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt); }; dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, @@ -1417,4 +1470,11 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, void ath12k_hal_cc_config(struct ath12k_base *ab); enum hal_rx_buf_return_buf_manager ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id); +void ath12k_hal_rx_msdu_list_get(struct ath12k_hal *hal, struct ath12k *ar, + void *link_desc, void *msdu_list, + u16 *num_msdus); +void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, + dma_addr_t *paddr, u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index eb6259368dc31..8635daf6e5538 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -14,7 +14,6 @@ #include "wmi.h" #include "hw.h" #include "dp_tx.h" -#include "wifi7/dp_tx.h" #include "dp_rx.h" #include "testmode.h" #include "peer.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 57940d7ffba48..63c62a6de6400 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1597,52 +1597,6 @@ struct hal_wbm_link_desc { struct ath12k_buffer_addr buf_addr_info; } __packed; -/* hal_wbm_link_desc - * - * Producer: WBM - * Consumer: WBM - * - * buf_addr_info - * Details of the physical address of a buffer or MSDU - * link descriptor. - */ - -enum hal_wbm_rel_src_module { - HAL_WBM_REL_SRC_MODULE_TQM, - HAL_WBM_REL_SRC_MODULE_RXDMA, - HAL_WBM_REL_SRC_MODULE_REO, - HAL_WBM_REL_SRC_MODULE_FW, - HAL_WBM_REL_SRC_MODULE_SW, - HAL_WBM_REL_SRC_MODULE_MAX, -}; - -enum hal_wbm_rel_desc_type { - HAL_WBM_REL_DESC_TYPE_REL_MSDU, - HAL_WBM_REL_DESC_TYPE_MSDU_LINK, - HAL_WBM_REL_DESC_TYPE_MPDU_LINK, - HAL_WBM_REL_DESC_TYPE_MSDU_EXT, - HAL_WBM_REL_DESC_TYPE_QUEUE_EXT, -}; - -/* hal_wbm_rel_desc_type - * - * msdu_buffer - * The address points to an MSDU buffer - * - * msdu_link_descriptor - * The address points to an Tx MSDU link descriptor - * - * mpdu_link_descriptor - * The address points to an MPDU link descriptor - * - * msdu_ext_descriptor - * The address points to an MSDU extension descriptor - * - * queue_ext_descriptor - * The address points to an TQM queue extension descriptor. WBM should - * treat this is the same way as a link descriptor. - */ - #define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0) #define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3) #define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 3ccd689bbf1ca..f13376b7faa1f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1026,5 +1026,7 @@ const struct hal_ops hal_qcn9274_ops = { .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, .cc_config = ath12k_wifi7_hal_cc_config, .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, + .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, + .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 590680b4f1421..c49042a34ed9d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -454,10 +454,10 @@ void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, *cookie = le32_get_bits(buff_addr->info1, BUFFER_ADDR_INFO1_SW_COOKIE); } -void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, - u32 *sw_cookie, - struct ath12k_buffer_addr **pp_buf_addr, - u8 *rbm, u32 *msdu_cnt) +void ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt) { struct hal_reo_entrance_ring *reo_ent_ring = (struct hal_reo_entrance_ring *)rx_desc; @@ -485,11 +485,14 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, *pp_buf_addr = (void *)buf_addr_info; } -void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, - struct hal_rx_msdu_link *link_desc, - struct hal_rx_msdu_list *msdu_list, - u16 *num_msdus) +void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, + void *link_desc_opaque, + void *msdu_list_opaque, u16 *num_msdus) { + struct hal_rx_msdu_link *link_desc = + (struct hal_rx_msdu_link *)link_desc_opaque; + struct hal_rx_msdu_list *msdu_list = + (struct hal_rx_msdu_list *)msdu_list_opaque; struct hal_rx_msdu_details *msdu_details = NULL; struct rx_msdu_desc *msdu_desc_info = NULL; u32 last = 0, first = 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 5536f5bf2a2bf..a2498c6257268 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -868,13 +868,14 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, struct ath12k_buffer_addr *buff_addr, dma_addr_t *paddr, u32 *cookie); -void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, - struct ath12k_buffer_addr **pp_buf_addr, - u8 *rbm, u32 *msdu_cnt); -void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, - struct hal_rx_msdu_link *link_desc, - struct hal_rx_msdu_list *msdu_list, - u16 *num_msdus); +void ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt); +void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, + void *link_desc, + void *msdu_list_opaque, + u16 *num_msdus); void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8966de3d64a41..a73e7539a27ab 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -799,5 +799,7 @@ const struct hal_ops hal_wcn7850_ops = { .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, .cc_config = ath12k_wifi7_hal_cc_config, .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, + .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, + .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 03044a61637bbabf7c264e7922e5d3dbca9b949e Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:06 +0530 Subject: [PATCH 449/659] wifi: ath12k: Move ath12k_dp_rx_frags_cleanup API to Wi-Fi 7 The API ath12k_dp_rx_frags_cleanup uses rx hw structure that is specific to Wi-Fi 7. Hence move the API to Wi-Fi 7 and use ops infra to reach it from the common code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 10 +++++++ drivers/net/wireless/ath/ath12k/dp_rx.c | 28 ++--------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 30 +++++++++++++++++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 ++ 6 files changed, 42 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 813a9e2a47ce7..2c77dc636ecfb 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -408,6 +408,8 @@ struct ath12k_dp_arch_ops { int (*rx_link_desc_return)(struct ath12k_base *ab, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); + void (*rx_frags_cleanup)(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc); int (*peer_rx_tid_reo_update)(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, @@ -592,6 +594,14 @@ int ath12k_dp_arch_rx_link_desc_return(struct ath12k_dp *dp, return dp->ops->rx_link_desc_return(dp->ab, buf_addr_info, action); } +static inline +void ath12k_dp_arch_rx_frags_cleanup(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc) +{ + dp->ops->rx_frags_cleanup(rx_tid, rel_link_desc); +} + static inline int ath12k_dp_arch_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 99e52a749b32b..66d5bec4242cc 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -534,30 +534,6 @@ static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 spin_unlock_bh(&dp->reo_rxq_flush_lock); } -void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, - bool rel_link_desc) -{ - enum hal_wbm_rel_bm_act act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; - struct ath12k_buffer_addr *buf_addr_info; - struct ath12k_dp *dp = rx_tid->dp; - - lockdep_assert_held(&dp->dp_lock); - - if (rx_tid->dst_ring_desc) { - if (rel_link_desc) { - buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_dp_arch_rx_link_desc_return(dp, buf_addr_info, act); - } - kfree(rx_tid->dst_ring_desc); - rx_tid->dst_ring_desc = NULL; - } - - rx_tid->cur_sn = 0; - rx_tid->last_frag_no = 0; - rx_tid->rx_frag_bitmap = 0; - __skb_queue_purge(&rx_tid->rx_frags); -} - void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer) { struct ath12k_dp_rx_tid *rx_tid; @@ -574,7 +550,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer rx_tid = &peer->dp_peer->rx_tid[i]; ath12k_dp_arch_rx_peer_tid_delete(dp, peer, i); - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_dp_arch_rx_frags_cleanup(dp, rx_tid, true); spin_unlock_bh(&dp->dp_lock); timer_delete_sync(&rx_tid->frag_timer); @@ -1471,7 +1447,7 @@ static void ath12k_dp_rx_frag_timer(struct timer_list *timer) spin_unlock_bh(&rx_tid->dp->dp_lock); return; } - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_dp_arch_rx_frags_cleanup(rx_tid->dp, rx_tid, true); spin_unlock_bh(&rx_tid->dp->dp_lock); } diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index f413834eff892..61d0d8568a748 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -197,8 +197,6 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff *cur_frag); void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags); -void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, - bool rel_link_desc); int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, struct ieee80211_hdr *hdr, u8 *data, size_t data_len, u8 *mic); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 1fd7738a39b57..b57e8de05c273 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -144,6 +144,7 @@ static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .rx_peer_tid_delete = ath12k_wifi7_dp_rx_peer_tid_delete, .reo_cache_flush = ath12k_wifi7_dp_reo_cache_flush, .rx_link_desc_return = ath12k_wifi7_dp_rx_link_desc_return, + .rx_frags_cleanup = ath12k_wifi7_dp_rx_frags_cleanup, .peer_rx_tid_reo_update = ath12k_wifi7_peer_rx_tid_reo_update, .rx_assign_reoq = ath12k_wifi7_dp_rx_assign_reoq, .peer_rx_tid_qref_setup = ath12k_wifi7_peer_rx_tid_qref_setup, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 0cf8a8f7b5f6e..13cd23d7c7dae 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1100,6 +1100,30 @@ static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, return 0; } +void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc) +{ + enum hal_wbm_rel_bm_act act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; + struct ath12k_buffer_addr *buf_addr_info; + struct ath12k_dp *dp = rx_tid->dp; + + lockdep_assert_held(&dp->dp_lock); + + if (rx_tid->dst_ring_desc) { + if (rel_link_desc) { + buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; + ath12k_wifi7_dp_rx_link_desc_return(dp->ab, buf_addr_info, act); + } + kfree(rx_tid->dst_ring_desc); + rx_tid->dst_ring_desc = NULL; + } + + rx_tid->cur_sn = 0; + rx_tid->last_frag_no = 0; + rx_tid->rx_frag_bitmap = 0; + __skb_queue_purge(&rx_tid->rx_frags); +} + static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_reo_dest_ring *ring_desc, @@ -1154,7 +1178,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || skb_queue_empty(&rx_tid->rx_frags)) { /* Flush stored fragments and start a new sequence */ - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_wifi7_dp_rx_frags_cleanup(rx_tid, true); rx_tid->cur_sn = seqno; } @@ -1214,12 +1238,12 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(dp, rx_tid, defrag_skb)) goto err_frags_cleanup; - ath12k_dp_rx_frags_cleanup(rx_tid, false); + ath12k_wifi7_dp_rx_frags_cleanup(rx_tid, false); goto out_unlock; err_frags_cleanup: dev_kfree_skb_any(defrag_skb); - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_wifi7_dp_rx_frags_cleanup(rx_tid, true); out_unlock: spin_unlock_bh(&dp->dp_lock); return ret; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index cb72b75526d4a..85677258b1df1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -31,6 +31,8 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); +void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc); void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, From 63faea63b3f447283b50efd1dfbe3234227dce26 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:07 +0530 Subject: [PATCH 450/659] wifi: ath12k: Move ath12k_dp_rx_get_peer_id API to Wi-Fi 7 Move ath12k_dp_rx_get_peer_id() from common to Wi-Fi 7 as it operates on arch specific peer metadata. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 23 -------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 3 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 31 ++++++++++++++++--- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 66d5bec4242cc..fda4e433ff192 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1413,29 +1413,6 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, return false; } -u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, - enum ath12k_peer_metadata_version ver, - __le32 peer_metadata) -{ - switch (ver) { - default: - ath12k_warn(ab, "Unknown peer metadata version: %d", ver); - fallthrough; - case ATH12K_PEER_METADATA_V0: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V0_PEER_ID); - case ATH12K_PEER_METADATA_V1: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V1_PEER_ID); - case ATH12K_PEER_METADATA_V1A: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V1A_PEER_ID); - case ATH12K_PEER_METADATA_V1B: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V1B_PEER_ID); - } -} - static void ath12k_dp_rx_frag_timer(struct timer_list *timer) { struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 61d0d8568a748..51e1de59208d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -200,9 +200,6 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, struct ieee80211_hdr *hdr, u8 *data, size_t data_len, u8 *mic); -u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, - enum ath12k_peer_metadata_version ver, - __le32 peer_metadata); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 13cd23d7c7dae..5eb62afde4a53 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -10,6 +10,29 @@ #include "hal_qcn9274.h" #include "hal_wcn7850.h" +static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp, + enum ath12k_peer_metadata_version ver, + __le32 peer_metadata) +{ + switch (ver) { + default: + ath12k_warn(dp->ab, "Unknown peer metadata version: %d", ver); + fallthrough; + case ATH12K_PEER_METADATA_V0: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V0_PEER_ID); + case ATH12K_PEER_METADATA_V1: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1_PEER_ID); + case ATH12K_PEER_METADATA_V1A: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1A_PEER_ID); + case ATH12K_PEER_METADATA_V1B: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1B_PEER_ID); + } +} + void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr) { @@ -731,8 +754,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); rxcb->hw_link_id = hw_link_id; - rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, - mpdu_info->peer_meta_data); + rxcb->peer_id = ath12k_wifi7_dp_rx_get_peer_id(dp, dp->peer_metadata_ver, + mpdu_info->peer_meta_data); rxcb->tid = le32_get_bits(mpdu_info->info0, RX_MPDU_DESC_INFO0_TID); @@ -1855,8 +1878,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, rxcb->is_last_msdu = err_info.last_msdu; rxcb->is_continuation = err_info.continuation; rxcb->rx_desc = msdu_data; - rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, - err_info.peer_metadata); + rxcb->peer_id = ath12k_wifi7_dp_rx_get_peer_id(dp, dp->peer_metadata_ver, + err_info.peer_metadata); if (err_info.continuation) { __skb_queue_tail(&scatter_msdu_list, msdu); From d0a61f5b5a03d2e2251c2aee0bc4d541bb50e846 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:08 +0530 Subject: [PATCH 451/659] wifi: ath12k: Remove arch-specific HAL dependencies from common DP Currently common DP includes arch-specific structs from wifi7/hal_desc.h via dp_mon.h. Store hal_wbm_release_ring_tx size in the HAL object and move hal_wbm_link_desc to common HAL for this separation. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 3 +-- drivers/net/wireless/ath/ath12k/hal.h | 6 +++++- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h | 4 ---- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index c7f7c04877c4b..6c5076261eafe 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -11,7 +11,6 @@ #include "hal.h" #include "debug.h" #include "peer.h" -#include "dp_mon.h" #include "dp_cmn.h" enum ath12k_dp_desc_type { @@ -1534,7 +1533,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab) if (ret) goto fail_dp_bank_profiles_cleanup; - size = sizeof(struct hal_wbm_release_ring_tx) * + size = ab->hal.hal_wbm_release_ring_tx_size * DP_TX_COMP_RING_SIZE(ab); ret = ath12k_dp_reoq_lut_setup(ab); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 29bcedca0a3b0..071f4897e4cd0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -795,7 +795,10 @@ struct ath12k_buffer_addr { struct hal_ce_srng_dest_desc; struct hal_ce_srng_dst_status_desc; struct hal_ce_srng_src_desc; -struct hal_wbm_link_desc; + +struct hal_wbm_link_desc { + struct ath12k_buffer_addr buf_addr_info; +} __packed; /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 @@ -1202,6 +1205,7 @@ struct ath12k_hal { int num_shadow_reg_configured; u32 hal_desc_sz; + u32 hal_wbm_release_ring_tx_size; const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index b57e8de05c273..cf7ede27623af 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -7,6 +7,7 @@ #include "../debug.h" #include "../dp_rx.h" #include "../dp_tx.h" +#include "hal_desc.h" #include "../dp_mon.h" #include "../dp_cmn.h" #include "dp_rx.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 84c0ba2d1fbe9..f48adb83599e8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -55,6 +55,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; hal->regs = ath12k_wifi7_hw_ver_map[ab->hw_rev].hw_regs; hal->hal_params = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_params; + hal->hal_wbm_release_ring_tx_size = sizeof(struct hal_wbm_release_ring_tx); return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 63c62a6de6400..4a249ba7357d1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1593,10 +1593,6 @@ struct hal_tx_rate_stats { __le32 tsf; } __packed; -struct hal_wbm_link_desc { - struct ath12k_buffer_addr buf_addr_info; -} __packed; - #define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0) #define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3) #define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6) From fd15086f48c6030e9aa84858ded0308c96b3886b Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:09 +0530 Subject: [PATCH 452/659] wifi: ath12k: Build all the files in wifi7 directory into ath12k_wifi7.ko Move files built as part of ath12k.ko from wifi7 directory to ath12k_wifi7.ko. Export necessary symbols from ath12k.ko and remove redundant exports from the wifi7 directory, as they are no longer needed. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-11-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 9 --------- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/debug.c | 1 + drivers/net/wireless/ath/ath12k/dp.c | 2 ++ drivers/net/wireless/ath/ath12k/dp_htt.c | 1 + drivers/net/wireless/ath/ath12k/dp_mon.c | 1 + drivers/net/wireless/ath/ath12k/dp_peer.c | 2 ++ drivers/net/wireless/ath/ath12k/dp_rx.c | 12 ++++++++++++ drivers/net/wireless/ath/ath12k/dp_tx.c | 9 +++++++++ drivers/net/wireless/ath/ath12k/hal.c | 8 ++++++++ drivers/net/wireless/ath/ath12k/mac.c | 5 +++++ drivers/net/wireless/ath/ath12k/wifi7/Makefile | 10 +++++++++- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hal.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 - 18 files changed, 51 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index d397bc494cf25..3ba1236956cc8 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -24,15 +24,6 @@ ath12k-y += core.o \ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o -ath12k-y += wifi7/hal_tx.o \ - wifi7/hal_rx.o \ - wifi7/dp_rx.o \ - wifi7/dp_tx.o \ - wifi7/dp.o \ - wifi7/hal.o \ - wifi7/hal_qcn9274.o \ - wifi7/hal_wcn7850.o - obj-$(CONFIG_ATH12K) += wifi7/ ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index e4c3fdb504832..9d6c50a94e642 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -32,6 +32,7 @@ EXPORT_SYMBOL(ath12k_debug_mask); bool ath12k_ftm_mode; module_param_named(ftm_mode, ath12k_ftm_mode, bool, 0444); MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode"); +EXPORT_SYMBOL(ath12k_ftm_mode); /* protected with ath12k_hw_group_mutex */ static struct list_head ath12k_hw_group_list = LIST_HEAD_INIT(ath12k_hw_group_list); diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c index 5fe9b2fbf5096..34b3b2c920dc7 100644 --- a/drivers/net/wireless/ath/ath12k/debug.c +++ b/drivers/net/wireless/ath/ath12k/debug.c @@ -105,5 +105,6 @@ void ath12k_dbg_dump(struct ath12k_base *ab, } } } +EXPORT_SYMBOL(ath12k_dbg_dump); #endif /* CONFIG_ATH12K_DEBUG */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 6c5076261eafe..36a11cb4a9c7f 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1181,6 +1181,7 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, return *desc_addr_ptr; } +EXPORT_SYMBOL(ath12k_dp_get_rx_desc); struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, u32 cookie) @@ -1204,6 +1205,7 @@ struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, return *desc_addr_ptr; } +EXPORT_SYMBOL(ath12k_dp_get_tx_desc); static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 39f42cd99835b..cc71c5c5de5a1 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -1077,6 +1077,7 @@ int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, return ret; } +EXPORT_SYMBOL(ath12k_dp_tx_htt_rx_filter_setup); int ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 048b418a56f71..230e234768b62 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -4471,3 +4471,4 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, return num_buffs_reaped; } +EXPORT_SYMBOL(ath12k_dp_mon_process_ring); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 0ad01f7414cd6..2e66872b55723 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -426,6 +426,7 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_p return rcu_dereference(dp_pdev->dp_hw->dp_peers[index]); } +EXPORT_SYMBOL(ath12k_dp_peer_find_by_peerid); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id) @@ -447,6 +448,7 @@ ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id) return rcu_dereference(dp_peer->link_peers[link_id]); } +EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_peerid); int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ath12k_dp_peer_create_params *params) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index fda4e433ff192..b10f2a67effd5 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -166,6 +166,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, return req_entries - num_remain; } +EXPORT_SYMBOL(ath12k_dp_rx_bufs_replenish); static int ath12k_dp_rxdma_mon_buf_ring_free(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring) @@ -394,6 +395,7 @@ void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab) } spin_unlock_bh(&dp->reo_cmd_lock); } +EXPORT_SYMBOL(ath12k_dp_reo_cmd_free); void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status) @@ -435,6 +437,7 @@ static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp * spin_unlock_bh(&dp->reo_rxq_flush_lock); } +EXPORT_SYMBOL(ath12k_dp_rx_tid_del_func); void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status) @@ -839,6 +842,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, return ret; } +EXPORT_SYMBOL(ath12k_dp_rx_get_msdu_last_buf); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first) @@ -1154,6 +1158,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu break; } } +EXPORT_SYMBOL(ath12k_dp_rx_h_undecap); struct ath12k_dp_link_peer * ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, @@ -1320,6 +1325,7 @@ void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, h_rate: ath12k_dp_rx_h_rate(dp_pdev, rx_info); } +EXPORT_SYMBOL(ath12k_dp_rx_h_ppdu); void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, @@ -1390,6 +1396,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } +EXPORT_SYMBOL(ath12k_dp_rx_deliver_msdu); bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct hal_rx_desc *rx_desc, @@ -1412,6 +1419,7 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, WARN_ON_ONCE(1); return false; } +EXPORT_SYMBOL(ath12k_dp_rx_check_nwifi_hdr_len_valid); static void ath12k_dp_rx_frag_timer(struct timer_list *timer) { @@ -1511,6 +1519,7 @@ int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, shash_desc_zero(desc); return ret; } +EXPORT_SYMBOL(ath12k_dp_rx_h_michael_mic); void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags) @@ -1543,6 +1552,7 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff skb_pull(msdu, crypto_len); } } +EXPORT_SYMBOL(ath12k_dp_rx_h_undecap_frag); static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, struct sk_buff *a, struct sk_buff *b) @@ -1571,6 +1581,7 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, } __skb_queue_tail(frag_list, cur_frag); } +EXPORT_SYMBOL(ath12k_dp_rx_h_sort_frags); u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) { @@ -1591,6 +1602,7 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) return pn; } +EXPORT_SYMBOL(ath12k_dp_rx_h_get_pn); static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, struct list_head *list, diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index 8d5e10781377e..bcae34f5db7d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -25,6 +25,7 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI; } +EXPORT_SYMBOL(ath12k_dp_tx_get_encap_type); void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) { @@ -42,6 +43,7 @@ void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) hdr = (void *)skb->data; hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); } +EXPORT_SYMBOL(ath12k_dp_tx_encap_nwifi); u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) { @@ -55,6 +57,7 @@ u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) else return skb->priority & IEEE80211_QOS_CTL_TID_MASK; } +EXPORT_SYMBOL(ath12k_dp_tx_get_tid); enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher) { @@ -77,6 +80,7 @@ enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher) return HAL_ENCRYPT_TYPE_OPEN; } } +EXPORT_SYMBOL(ath12k_dp_tx_get_encrypt_type); void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, struct ath12k_tx_desc_info *tx_desc, @@ -87,6 +91,7 @@ void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, list_move_tail(&tx_desc->list, &dp->tx_desc_free_list[pool_id]); spin_unlock_bh(&dp->tx_desc_lock[pool_id]); } +EXPORT_SYMBOL(ath12k_dp_tx_release_txbuf); struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, u8 pool_id) @@ -108,6 +113,7 @@ struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, return desc; } +EXPORT_SYMBOL(ath12k_dp_tx_assign_buffer); void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) { @@ -121,6 +127,7 @@ void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) memset(metadata, 0, tail_len); return metadata; } +EXPORT_SYMBOL(ath12k_dp_metadata_align_skb); static void ath12k_dp_tx_move_payload(struct sk_buff *skb, unsigned long delta, @@ -175,6 +182,7 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab, out: return ret; } +EXPORT_SYMBOL(ath12k_dp_tx_align_payload); void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, struct dp_tx_ring *tx_ring, @@ -200,3 +208,4 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); } +EXPORT_SYMBOL(ath12k_dp_tx_free_txbuf); diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 08063d1094ae1..efa039f6df924 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -217,6 +217,7 @@ int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type) return (srng_config->entry_size << 2); } +EXPORT_SYMBOL(ath12k_hal_srng_get_entrysize); int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type) { @@ -246,6 +247,7 @@ void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng, params->msi2_data = srng->msi2_data; params->flags = srng->flags; } +EXPORT_SYMBOL(ath12k_hal_srng_get_params); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, struct hal_srng *srng) @@ -316,6 +318,7 @@ void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) return NULL; } +EXPORT_SYMBOL(ath12k_hal_srng_dst_peek); void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab, struct hal_srng *srng) @@ -334,6 +337,7 @@ void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_dst_get_next_entry); int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng, bool sync_hw_ptr) @@ -356,6 +360,7 @@ int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng, else return (srng->ring_size - tp + hp) / srng->entry_size; } +EXPORT_SYMBOL(ath12k_hal_srng_dst_num_free); /* Returns number of available entries in src ring */ int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng, @@ -430,6 +435,7 @@ void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_src_get_next_entry); void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng) { @@ -500,6 +506,7 @@ void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng) } } } +EXPORT_SYMBOL(ath12k_hal_srng_access_begin); /* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin() * should have been called before this. @@ -555,6 +562,7 @@ void ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng) srng->timestamp = jiffies; } +EXPORT_SYMBOL(ath12k_hal_srng_access_end); int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_num, int mac_id, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 8635daf6e5538..f3bbd3b8a647a 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -363,6 +363,7 @@ u16 ath12k_mac_he_convert_tones_to_ru_tones(u16 tones) return RU_26; } } +EXPORT_SYMBOL(ath12k_mac_he_convert_tones_to_ru_tones); enum nl80211_eht_gi ath12k_mac_eht_gi_to_nl80211_eht_gi(u8 sgi) { @@ -377,6 +378,7 @@ enum nl80211_eht_gi ath12k_mac_eht_gi_to_nl80211_eht_gi(u8 sgi) return NL80211_RATE_INFO_EHT_GI_0_8; } } +EXPORT_SYMBOL(ath12k_mac_eht_gi_to_nl80211_eht_gi); enum nl80211_eht_ru_alloc ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(u16 ru_tones) { @@ -417,6 +419,7 @@ enum nl80211_eht_ru_alloc ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(u16 ru return NL80211_RATE_INFO_EHT_RU_ALLOC_26; } } +EXPORT_SYMBOL(ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc); enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw) @@ -443,6 +446,7 @@ ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw) return ret; } +EXPORT_SYMBOL(ath12k_mac_bw_to_mac80211_bw); enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw) { @@ -486,6 +490,7 @@ int ath12k_mac_hw_ratecode_to_legacy_rate(u8 hw_rc, u8 preamble, u8 *rateidx, return -EINVAL; } +EXPORT_SYMBOL(ath12k_mac_hw_ratecode_to_legacy_rate); u8 ath12k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband, u32 bitrate) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index 872ca620a5c50..30258a1b313de 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -5,6 +5,14 @@ ath12k_wifi7-y += core.o \ wmi.o \ mhi.o \ ce.o \ - hw.o + hw.o \ + hal_tx.o \ + hal_rx.o \ + dp_rx.o \ + dp_tx.o \ + dp.o \ + hal.o \ + hal_qcn9274.o \ + hal_wcn7850.o ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index cf7ede27623af..433ffdb552647 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -170,10 +170,8 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) return dp; } -EXPORT_SYMBOL(ath12k_wifi7_dp_device_alloc); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp) { kfree(dp); } -EXPORT_SYMBOL(ath12k_wifi7_dp_device_free); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 5eb62afde4a53..d2026082708e4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2022,7 +2022,6 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) return ret; } -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) { @@ -2065,7 +2064,6 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 7e16bc12e36ac..bb8c2384c13ea 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -379,7 +379,6 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a return ret; } -EXPORT_SYMBOL(ath12k_wifi7_dp_tx); static void ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index f48adb83599e8..03a007dd6857f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -59,7 +59,6 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) return 0; } -EXPORT_SYMBOL(ath12k_wifi7_hal_init); static unsigned int ath12k_wifi7_hal_reo1_ring_id_offset(struct ath12k_hal *hal) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index f13376b7faa1f..4b6f43389b2d9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1029,4 +1029,3 @@ const struct hal_ops hal_qcn9274_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; -EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index a73e7539a27ab..f243bc3ab4097 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -802,4 +802,3 @@ const struct hal_ops hal_wcn7850_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; -EXPORT_SYMBOL(hal_wcn7850_ops); From cd735a612bedc936ca1982a24fe079d7cd1d26b4 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:10 +0530 Subject: [PATCH 453/659] wifi: ath12k: Use dp objects in performance critical paths Use dp objects in tx and rx data paths in place of other objects to minimize pointer indirections and increase the cache efficiency in the data paths. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-12-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 25 ++- drivers/net/wireless/ath/ath12k/dp.h | 9 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 15 +- drivers/net/wireless/ath/ath12k/dp_mon.h | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 44 +++-- drivers/net/wireless/ath/ath12k/dp_rx.h | 32 ++-- drivers/net/wireless/ath/ath12k/dp_tx.c | 24 +-- drivers/net/wireless/ath/ath12k/dp_tx.h | 5 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 66 ++++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 166 +++++++++--------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 14 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 109 ++++++------ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 12 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 7 +- 15 files changed, 262 insertions(+), 270 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 36a11cb4a9c7f..9f05eea6695a5 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1150,26 +1150,23 @@ static u32 ath12k_dp_cc_cookie_gen(u16 ppt_idx, u16 spt_idx) return (u32)ppt_idx << ATH12K_CC_PPT_SHIFT | spt_idx; } -static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab, - u16 ppt_idx, u16 spt_idx) +static void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_dp *dp, + u16 ppt_idx, u16 spt_idx) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - return dp->spt_info[ppt_idx].vaddr + spt_idx; } -struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, +struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp, u32 cookie) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info **desc_addr_ptr; u16 start_ppt_idx, end_ppt_idx, ppt_idx, spt_idx; ppt_idx = u32_get_bits(cookie, ATH12K_DP_CC_COOKIE_PPT); spt_idx = u32_get_bits(cookie, ATH12K_DP_CC_COOKIE_SPT); - start_ppt_idx = dp->rx_ppt_base + ATH12K_RX_SPT_PAGE_OFFSET(ab); - end_ppt_idx = start_ppt_idx + ATH12K_NUM_RX_SPT_PAGES(ab); + start_ppt_idx = dp->rx_ppt_base + ATH12K_RX_SPT_PAGE_OFFSET(dp->ab); + end_ppt_idx = start_ppt_idx + ATH12K_NUM_RX_SPT_PAGES(dp->ab); if (ppt_idx < start_ppt_idx || ppt_idx >= end_ppt_idx || @@ -1177,13 +1174,13 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, return NULL; ppt_idx = ppt_idx - dp->rx_ppt_base; - desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, spt_idx); + desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, spt_idx); return *desc_addr_ptr; } EXPORT_SYMBOL(ath12k_dp_get_rx_desc); -struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, +struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp, u32 cookie) { struct ath12k_tx_desc_info **desc_addr_ptr; @@ -1194,14 +1191,14 @@ struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, start_ppt_idx = ATH12K_TX_SPT_PAGE_OFFSET; end_ppt_idx = start_ppt_idx + - (ATH12K_TX_SPT_PAGES_PER_POOL(ab) * ATH12K_HW_MAX_QUEUES); + (ATH12K_TX_SPT_PAGES_PER_POOL(dp->ab) * ATH12K_HW_MAX_QUEUES); if (ppt_idx < start_ppt_idx || ppt_idx >= end_ppt_idx || spt_idx > ATH12K_MAX_SPT_ENTRIES) return NULL; - desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, spt_idx); + desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, spt_idx); return *desc_addr_ptr; } @@ -1249,7 +1246,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) list_add_tail(&rx_descs[j].list, &dp->rx_desc_free_list); /* Update descriptor VA in SPT */ - rx_desc_addr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, j); + rx_desc_addr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, j); *rx_desc_addr = &rx_descs[j]; } } @@ -1288,7 +1285,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) /* Update descriptor VA in SPT */ tx_desc_addr = - ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, j); + ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, j); *tx_desc_addr = &tx_descs[j]; } } diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 2c77dc636ecfb..dc18423812ec0 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -19,7 +19,6 @@ struct ath12k_dp_link_peer; struct ath12k_dp; struct ath12k_vif; struct ath12k_link_vif; -struct hal_tcl_status_ring; struct ath12k_ext_irq_grp; struct ath12k_dp_rx_tid; @@ -405,7 +404,7 @@ struct ath12k_dp_arch_ops { struct ath12k_dp_link_peer *peer, u8 tid); void (*reo_cache_flush)(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid); - int (*rx_link_desc_return)(struct ath12k_base *ab, + int (*rx_link_desc_return)(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); void (*rx_frags_cleanup)(struct ath12k_dp_rx_tid *rx_tid, @@ -591,7 +590,7 @@ int ath12k_dp_arch_rx_link_desc_return(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action) { - return dp->ops->rx_link_desc_return(dp->ab, buf_addr_info, action); + return dp->ops->rx_link_desc_return(dp, buf_addr_info, action); } static inline @@ -679,8 +678,8 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, struct dp_link_desc_bank *link_desc_banks, u32 ring_type, struct hal_srng *srng, u32 n_link_desc); -struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, +struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp, u32 cookie); -struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, +struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp, u32 desc_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 230e234768b62..d2fc4de51eb96 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2332,7 +2332,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); rcu_read_lock(); spin_lock_bh(&dp->dp_lock); @@ -4165,7 +4165,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, &num_msdus); - desc_info = ath12k_dp_get_rx_desc(ar->ab, + desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[num_msdus - 1]); tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; @@ -4182,7 +4182,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, } desc_info = - ath12k_dp_get_rx_desc(ar->ab, msdu_list.sw_cookie[i]); + ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); msdu = desc_info->skb; if (!msdu) { @@ -4389,7 +4389,7 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, if (rx_bufs_used) { rx_mon_stats->dest_ppdu_done++; - ath12k_dp_rx_bufs_replenish(ar->ab, + ath12k_dp_rx_bufs_replenish(ar->ab->dp, &dp->rx_refill_buf_ring, &rx_desc_used_list, rx_bufs_used); @@ -4437,12 +4437,11 @@ __ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, return num_buffs_reaped; } -int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, +int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode) { - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); struct ath12k_pdev_dp *dp_pdev; struct ath12k *ar; int num_buffs_reaped = 0; @@ -4455,7 +4454,7 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, return 0; } - if (ab->hw_params->rxdma1_enable) { + if (dp->hw_params->rxdma1_enable) { if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, napi); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 6110227a40dd3..3e6ff4b0a6d9e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -89,7 +89,7 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, +int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode); struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index b10f2a67effd5..d236c0638dabf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -64,11 +64,12 @@ static void ath12k_dp_rx_enqueue_free(struct ath12k_dp *dp, } /* Returns number of Rx buffers replenished */ -int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, +int ath12k_dp_rx_bufs_replenish(struct ath12k_dp *dp, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, int req_entries) { + struct ath12k_base *ab = dp->ab; struct ath12k_buffer_addr *desc; struct hal_srng *srng; struct sk_buff *skb; @@ -76,13 +77,12 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int num_remain; u32 cookie; dma_addr_t paddr; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_desc; - enum hal_rx_buf_return_buf_manager mgr = ab->hal.hal_params->rx_buf_rbm; + enum hal_rx_buf_return_buf_manager mgr = dp->hal->hal_params->rx_buf_rbm; req_entries = min(req_entries, rx_ring->bufs_max); - srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; + srng = &dp->hal->srng_list[rx_ring->refill_buf_ring.ring_id]; spin_lock_bh(&srng->lock); @@ -121,10 +121,10 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, skb->data); } - paddr = dma_map_single(ab->dev, skb->data, + paddr = dma_map_single(dp->dev, skb->data, skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); - if (dma_mapping_error(ab->dev, paddr)) + if (dma_mapping_error(dp->dev, paddr)) goto fail_free_skb; rx_desc = list_first_entry_or_null(used_list, @@ -145,14 +145,14 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, + ath12k_hal_rx_buf_addr_info_set(dp->hal, desc, paddr, cookie, mgr); } goto out; fail_dma_unmap: - dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb), + dma_unmap_single(dp->dev, paddr, skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); fail_free_skb: dev_kfree_skb_any(skb); @@ -236,7 +236,7 @@ static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab, rx_ring->bufs_max = rx_ring->refill_buf_ring.size / ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF); - ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); + ath12k_dp_rx_bufs_replenish(ath12k_ab_to_dp(ab), rx_ring, &list, 0); return 0; } @@ -946,8 +946,6 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { - struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; @@ -980,7 +978,7 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k_pdev_dp *dp_pdev, if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_hdr = skb_push(msdu, ath12k_dp_rx_crypto_param_len(dp_pdev, enctype)); - ath12k_dp_rx_desc_get_crypto_header(ab, + ath12k_dp_rx_desc_get_crypto_header(dp_pdev->dp->hal, rxcb->rx_desc, crypto_hdr, enctype); } @@ -1059,19 +1057,20 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k_pdev_dp *dp_pdev, { struct hal_rx_desc *rx_desc = rxcb->rx_desc; struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; size_t hdr_len, crypto_len; struct ieee80211_hdr hdr; __le16 qos_ctl; u8 *crypto_hdr; - ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr); + ath12k_dp_rx_desc_get_dot11_hdr(hal, rx_desc, &hdr); hdr_len = ieee80211_hdrlen(hdr.frame_control); if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); crypto_hdr = skb_push(msdu, crypto_len); - ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); + ath12k_dp_rx_desc_get_crypto_header(dp->hal, rx_desc, crypto_hdr, + enctype); } skb_push(msdu, hdr_len); @@ -1332,7 +1331,6 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; struct ath12k_dp_peer *peer; @@ -1351,7 +1349,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc status->link_id = peer->hw_links[rxcb->hw_link_id]; } - ath12k_dbg(ab, ATH12K_DBG_DATA, + ath12k_dbg(dp->ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, @@ -1377,7 +1375,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc !!(status->flag & RX_FLAG_MMIC_ERROR), !!(status->flag & RX_FLAG_AMSDU_MORE)); - ath12k_dbg_dump(ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", + ath12k_dbg_dump(dp->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", msdu->data, msdu->len); rx_status = IEEE80211_SKB_RXCB(msdu); @@ -1554,18 +1552,18 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff } EXPORT_SYMBOL(ath12k_dp_rx_h_undecap_frag); -static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, +static int ath12k_dp_rx_h_cmp_frags(struct ath12k_hal *hal, struct sk_buff *a, struct sk_buff *b) { int frag1, frag2; - frag1 = ath12k_dp_rx_h_frag_no(ab, a); - frag2 = ath12k_dp_rx_h_frag_no(ab, b); + frag1 = ath12k_dp_rx_h_frag_no(hal, a); + frag2 = ath12k_dp_rx_h_frag_no(hal, b); return frag1 - frag2; } -void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, +void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal, struct sk_buff_head *frag_list, struct sk_buff *cur_frag) { @@ -1573,7 +1571,7 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, int cmp; skb_queue_walk(frag_list, skb) { - cmp = ath12k_dp_rx_h_cmp_frags(ab, skb, cur_frag); + cmp = ath12k_dp_rx_h_cmp_frags(hal, skb, cur_frag); if (cmp < 0) continue; __skb_queue_before(frag_list, skb, cur_frag); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 51e1de59208d6..916cf41aa5c31 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -106,21 +106,21 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) return ret; } -static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, +static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_hal *hal, struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz); return ieee80211_has_morefrags(hdr->frame_control); } -static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, +static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_hal *hal, struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz); return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; } @@ -130,18 +130,18 @@ static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, return ab->hal.ops->rx_desc_get_l3_pad_bytes(desc); } -static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, +static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_hal *hal, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hal.ops->rx_desc_copy_end_tlv(fdesc, ldesc); + hal->ops->rx_desc_copy_end_tlv(fdesc, ldesc); } -static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, +static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_hal *hal, struct hal_rx_desc *desc, u16 len) { - ab->hal.ops->rx_desc_set_msdu_len(desc, len); + hal->ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, @@ -150,25 +150,25 @@ static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } -static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, +static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_hal *hal, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hal.ops->rx_desc_get_dot11_hdr(desc, hdr); + hal->ops->rx_desc_get_dot11_hdr(desc, hdr); } -static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, +static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_hal *hal, struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hal.ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + hal->ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } -static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, +static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_hal *hal, struct hal_rx_desc *desc) { - return ab->hal.ops->rx_desc_get_msdu_src_link_id(desc); + return hal->ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) @@ -192,7 +192,7 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb); -void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, +void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal, struct sk_buff_head *frag_list, struct sk_buff *cur_frag); void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, @@ -224,7 +224,7 @@ void ath12k_dp_rx_free(struct ath12k_base *ab); int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); -int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, +int ath12k_dp_rx_bufs_replenish(struct ath12k_dp *dp, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, int req_entries); diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index bcae34f5db7d6..1d4444f3936ff 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -146,10 +146,9 @@ static void ath12k_dp_tx_move_payload(struct sk_buff *skb, } } -int ath12k_dp_tx_align_payload(struct ath12k_base *ab, - struct sk_buff **pskb) +int ath12k_dp_tx_align_payload(struct ath12k_dp *dp, struct sk_buff **pskb) { - u32 iova_mask = ab->hw_params->iova_mask; + u32 iova_mask = dp->hw_params->iova_mask; unsigned long offset, delta1, delta2; struct sk_buff *skb2, *skb = *pskb; unsigned int headroom = skb_headroom(skb); @@ -184,28 +183,29 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_tx_align_payload); -void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, +void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params) { - struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct sk_buff *msdu = desc_params->skb; struct ath12k_skb_cb *skb_cb; - u8 pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params->mac_id); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params->mac_id); skb_cb = ATH12K_SKB_CB(msdu); - ar = ab->pdevs[pdev_id].ar; - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + + dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, desc_params->skb_ext_desc->len, DMA_TO_DEVICE); dev_kfree_skb_any(desc_params->skb_ext_desc); } - ieee80211_free_txskb(ar->ah->hw, msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); + if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) + wake_up(&dp_pdev->tx_empty_waitq); } EXPORT_SYMBOL(ath12k_dp_tx_free_txbuf); diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 147409f9ac408..7cef20540179f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -20,14 +20,13 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb); void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb); u8 ath12k_dp_tx_get_tid(struct sk_buff *skb); void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len); -int ath12k_dp_tx_align_payload(struct ath12k_base *ab, - struct sk_buff **pskb); +int ath12k_dp_tx_align_payload(struct ath12k_dp *dp, struct sk_buff **pskb); void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, struct ath12k_tx_desc_info *tx_desc, u8 pool_id); struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, u8 pool_id); -void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, +void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 433ffdb552647..30c27e005ed8f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -19,7 +19,6 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, int budget) { - struct ath12k_base *ab = dp->ab; struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; int work_done = 0; @@ -28,21 +27,21 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, enum dp_monitor_mode monitor_mode; u8 ring_mask; - if (ab->hw_params->ring_mask->tx[grp_id]) { - i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; - ath12k_wifi7_dp_tx_completion_handler(ab, i); + if (dp->hw_params->ring_mask->tx[grp_id]) { + i = fls(dp->hw_params->ring_mask->tx[grp_id]) - 1; + ath12k_wifi7_dp_tx_completion_handler(dp, i); } - if (ab->hw_params->ring_mask->rx_err[grp_id]) { - work_done = ath12k_wifi7_dp_rx_process_err(ab, napi, budget); + if (dp->hw_params->ring_mask->rx_err[grp_id]) { + work_done = ath12k_wifi7_dp_rx_process_err(dp, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } - if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { - work_done = ath12k_wifi7_dp_rx_process_wbm_err(ab, napi, budget); + if (dp->hw_params->ring_mask->rx_wbm_rel[grp_id]) { + work_done = ath12k_wifi7_dp_rx_process_wbm_err(dp, napi, budget); budget -= work_done; tot_work_done += work_done; @@ -50,24 +49,24 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, goto done; } - if (ab->hw_params->ring_mask->rx[grp_id]) { - i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; - work_done = ath12k_wifi7_dp_rx_process(ab, i, napi, budget); + if (dp->hw_params->ring_mask->rx[grp_id]) { + i = fls(dp->hw_params->ring_mask->rx[grp_id]) - 1; + work_done = ath12k_wifi7_dp_rx_process(dp, i, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } - if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { - ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; + if (dp->hw_params->ring_mask->rx_mon_status[grp_id]) { + ring_mask = dp->hw_params->ring_mask->rx_mon_status[grp_id]; + for (i = 0; i < dp->ab->num_radios; i++) { + for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) { + int id = i * dp->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, + ath12k_dp_mon_process_ring(dp, id, napi, budget, 0); budget -= work_done; tot_work_done += work_done; @@ -78,16 +77,16 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, } } - if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { + if (dp->hw_params->ring_mask->rx_mon_dest[grp_id]) { monitor_mode = ATH12K_DP_RX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; + ring_mask = dp->hw_params->ring_mask->rx_mon_dest[grp_id]; + for (i = 0; i < dp->ab->num_radios; i++) { + for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) { + int id = i * dp->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, + ath12k_dp_mon_process_ring(dp, id, napi, budget, monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -99,16 +98,16 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, } } - if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { + if (dp->hw_params->ring_mask->tx_mon_dest[grp_id]) { monitor_mode = ATH12K_DP_TX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; + ring_mask = dp->hw_params->ring_mask->tx_mon_dest[grp_id]; + for (i = 0; i < dp->ab->num_radios; i++) { + for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) { + int id = i * dp->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, + ath12k_dp_mon_process_ring(dp, id, napi, budget, monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -120,15 +119,14 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, } } - if (ab->hw_params->ring_mask->reo_status[grp_id]) - ath12k_wifi7_dp_rx_process_reo_status(ab); + if (dp->hw_params->ring_mask->reo_status[grp_id]) + ath12k_wifi7_dp_rx_process_reo_status(dp); - if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + if (dp->hw_params->ring_mask->host2rxdma[grp_id]) { struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; LIST_HEAD(list); - ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); + ath12k_dp_rx_bufs_replenish(dp, rx_ring, &list, 0); } /* TODO: Implement handler for other interrupts */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d2026082708e4..2138b20a04d57 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -125,16 +125,16 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, peer->rx_tid_active_bitmask &= ~(1 << tid); } -int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action) { + struct ath12k_base *ab = dp->ab; struct hal_wbm_release_ring *desc; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_srng *srng; int ret = 0; - srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; + srng = &dp->hal->srng_list[dp->wbm_desc_rel_ring.ring_id]; spin_lock_bh(&srng->lock); @@ -411,19 +411,18 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, } } -static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_dp *dp, +static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_hal *hal, struct sk_buff_head *msdu_list, struct sk_buff *first, struct sk_buff *last, u8 l3pad_bytes, int msdu_len, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = dp->ab; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); int buf_first_hdr_len, buf_first_len; struct hal_rx_desc *ldesc; int space_extra, rem_len, buf_len; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = hal->hal_desc_sz; bool is_continuation; /* As the msdu is spread across multiple rx buffers, @@ -453,7 +452,7 @@ static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_dp *dp, /* When an MSDU spread over multiple buffers MSDU_END * tlvs are valid only in the last buffer. Copy those tlvs. */ - ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc); + ath12k_dp_rx_desc_end_tlv_copy(hal, rxcb->rx_desc, ldesc); space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); if (space_extra > 0 && @@ -505,18 +504,18 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc, *lrx_desc; struct ath12k_skb_rxcb *rxcb; struct sk_buff *last_buf; + struct ath12k_hal *hal = dp->hal; u8 l3_pad_bytes; u16 msdu_len; int ret; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = hal->hal_desc_sz; last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); if (!last_buf) { - ath12k_warn(ab, + ath12k_warn(dp->ab, "No valid Rx buffer to access MSDU_END tlv\n"); ret = -EIO; goto free_out; @@ -525,9 +524,9 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, lrx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); if (!rx_info->msdu_done) { - ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); + ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; goto free_out; } @@ -542,20 +541,20 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } else if (!rxcb->is_continuation) { if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ret = -EINVAL; - ath12k_warn(ab, "invalid msdu len %u\n", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + ath12k_warn(dp->ab, "invalid msdu len %u\n", msdu_len); + ath12k_dbg_dump(dp->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, sizeof(*rx_desc)); goto free_out; } skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { - ret = ath12k_wifi7_dp_rx_msdu_coalesce(dp, msdu_list, + ret = ath12k_wifi7_dp_rx_msdu_coalesce(hal, msdu_list, msdu, last_buf, l3_pad_bytes, msdu_len, rx_info); if (ret) { - ath12k_warn(ab, + ath12k_warn(dp->ab, "failed to coalesce msdu rx buffer%d\n", ret); goto free_out; } @@ -579,12 +578,11 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } static void -ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, +ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp, struct napi_struct *napi, struct sk_buff_head *msdu_list, int ring_id) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ieee80211_rx_status rx_status = {}; @@ -634,7 +632,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, ret = ath12k_wifi7_dp_rx_process_msdu(dp_pdev, msdu, msdu_list, &rx_info); if (ret) { - ath12k_dbg(ab, ATH12K_DBG_DATA, + ath12k_dbg(dp->ab, ATH12K_DBG_DATA, "Unable to process msdu %d", ret); dev_kfree_skb_any(msdu); continue; @@ -646,11 +644,12 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, rcu_read_unlock(); } -int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, +int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id, struct napi_struct *napi, int budget) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_link *hw_links = ag->hw_links; @@ -659,7 +658,6 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; struct ath12k_dp *partner_dp; - struct ath12k_base *partner_ab; struct sk_buff_head msdu_list; struct ath12k_skb_rxcb *rxcb; int total_msdu_reaped = 0; @@ -674,7 +672,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; + srng = &hal->srng_list[dp->reo_dst_ring[ring_id].ring_id]; spin_lock_bh(&srng->lock); @@ -707,13 +705,12 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; } - partner_ab = partner_dp->ab; /* retry manual desc retrieval */ if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie); + desc_info = ath12k_dp_get_rx_desc(partner_dp, cookie); if (!desc_info) { - ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", + ath12k_warn(partner_dp->ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", cookie); continue; } @@ -728,12 +725,12 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, + dma_unmap_single(partner_dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); num_buffs_reaped[device_id]++; - dp->device_stats.reo_rx[ring_id][ab->device_id]++; + dp->device_stats.reo_rx[ring_id][dp->device_id]++; push_reason = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_PUSH_REASON); @@ -795,15 +792,14 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + ath12k_dp_rx_bufs_replenish(partner_dp, rx_ring, &rx_desc_used_list[device_id], num_buffs_reaped[device_id]); } - ath12k_wifi7_dp_rx_process_received_packets(ab, napi, &msdu_list, + ath12k_wifi7_dp_rx_process_received_packets(dp, napi, &msdu_list, ring_id); exit: @@ -846,6 +842,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, struct sk_buff *defrag_skb) { struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; struct hal_reo_entrance_ring *reo_ent_ring; struct hal_reo_dest_ring *reo_dest_ring; @@ -861,11 +858,11 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm; u8 dst_ind; - hal_rx_desc_sz = ab->hal.hal_desc_sz; + hal_rx_desc_sz = hal->hal_desc_sz; link_desc_banks = dp->link_desc_banks; reo_dest_ring = rx_tid->dst_ring_desc; - ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, + ath12k_wifi7_hal_rx_reo_ent_paddr_get(&reo_dest_ring->buf_addr_info, &link_paddr, &cookie); desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); @@ -888,12 +885,12 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info); /* change msdu len in hal rx desc */ - ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); + ath12k_dp_rxdesc_set_msdu_len(hal, rx_desc, defrag_skb->len - hal_rx_desc_sz); - buf_paddr = dma_map_single(ab->dev, defrag_skb->data, + buf_paddr = dma_map_single(dp->dev, defrag_skb->data, defrag_skb->len + skb_tailroom(defrag_skb), DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, buf_paddr)) + if (dma_mapping_error(dp->dev, buf_paddr)) return -ENOMEM; spin_lock_bh(&dp->rx_desc_lock); @@ -920,7 +917,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, HAL_RX_BUF_RBM_SW3_BM); /* Fill mpdu details into reo entrance ring */ - srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; + srng = &hal->srng_list[dp->reo_reinject_ring.ring_id]; spin_lock_bh(&srng->lock); ath12k_hal_srng_access_begin(ab, srng); @@ -947,7 +944,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, reo_ent_ring->rx_mpdu_info.peer_meta_data = reo_dest_ring->rx_mpdu_info.peer_meta_data; - if (ab->hw_params->reoq_lut_support) { + if (dp->hw_params->reoq_lut_support) { reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; queue_addr_hi = 0; } else { @@ -981,7 +978,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, list_add_tail(&desc_info->list, &dp->rx_desc_free_list); spin_unlock_bh(&dp->rx_desc_lock); err_unmap_dma: - dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), + dma_unmap_single(dp->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), DMA_TO_DEVICE); return ret; } @@ -993,7 +990,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); struct ieee80211_key_conf *key_conf; @@ -1001,7 +998,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, u8 mic[IEEE80211_CCMP_MIC_LEN]; int head_len, tail_len, ret; size_t data_len; - u32 hdr_len, hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hdr_len, hal_rx_desc_sz = hal->hal_desc_sz; u8 *key, *data; u8 key_idx; @@ -1038,7 +1035,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; @@ -1135,7 +1132,7 @@ void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, if (rx_tid->dst_ring_desc) { if (rel_link_desc) { buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_wifi7_dp_rx_link_desc_return(dp->ab, buf_addr_info, act); + ath12k_wifi7_dp_rx_link_desc_return(dp, buf_addr_info, act); } kfree(rx_tid->dst_ring_desc); rx_tid->dst_ring_desc = NULL; @@ -1153,6 +1150,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_hal *hal = dp->hal; struct ath12k_base *ab = dp->ab; struct ath12k_dp_peer *peer; struct ath12k_dp_rx_tid *rx_tid; @@ -1164,8 +1162,8 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, bool more_frags; enum hal_encrypt_type enctype = rx_info->enctype; - frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); - more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + frag_no = ath12k_dp_rx_h_frag_no(hal, msdu); + more_frags = ath12k_dp_rx_h_more_frags(hal, msdu); seqno = rx_info->seq_no; if (!rx_info->seq_ctl_valid || !rx_info->fc_valid || @@ -1214,7 +1212,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) __skb_queue_tail(&rx_tid->rx_frags, msdu); else - ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); + ath12k_dp_rx_h_sort_frags(hal, &rx_tid->rx_frags, msdu); rx_tid->rx_frag_bitmap |= BIT(frag_no); if (!more_frags) @@ -1229,7 +1227,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, goto out_unlock; } } else { - ath12k_wifi7_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + ath12k_wifi7_dp_rx_link_desc_return(dp, &ring_desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } @@ -1280,13 +1278,13 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, { struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct sk_buff *msdu; struct ath12k_skb_rxcb *rxcb; struct hal_rx_desc_data rx_info; struct hal_rx_desc *rx_desc; u16 msdu_len; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = hal->hal_desc_sz; struct ath12k_rx_desc_info *desc_info; u64 desc_va; @@ -1296,16 +1294,17 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, /* retry manual desc retrieval */ if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, cookie); + desc_info = ath12k_dp_get_rx_desc(dp, cookie); if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", + ath12k_warn(dp->ab, + "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", cookie); return -EINVAL; } } if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, " RX Exception, Check HW CC implementation"); + ath12k_warn(dp->ab, "RX Exception, Check HW CC implementation"); msdu = desc_info->skb; desc_info->skb = NULL; @@ -1313,7 +1312,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, list_add_tail(&desc_info->list, used_list); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ab->dev, rxcb->paddr, + dma_unmap_single(dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1334,12 +1333,12 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, } rx_desc = (struct hal_rx_desc *)msdu->data; - ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + ath12k_warn(dp->ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(dp->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, sizeof(*rx_desc)); dev_kfree_skb_any(msdu); goto exit; @@ -1349,7 +1348,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, if (ath12k_wifi7_dp_rx_frag_h_mpdu(dp_pdev, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); - ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + ath12k_wifi7_dp_rx_link_desc_return(dp, &desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } exit: @@ -1357,10 +1356,11 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } -int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, +int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; @@ -1375,7 +1375,6 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n struct dp_rxdma_ring *rx_ring; struct dp_srng *reo_except; struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; struct ath12k_pdev_dp *dp_pdev; u8 hw_link_id, device_id; u32 desc_bank, num_msdus; @@ -1395,7 +1394,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n reo_except = &dp->reo_except_ring; - srng = &ab->hal.srng_list[reo_except->ring_id]; + srng = &hal->srng_list[reo_except->ring_id]; spin_lock_bh(&srng->lock); @@ -1406,7 +1405,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n drop = false; dp->device_stats.err_ring_pkts++; - ret = ath12k_wifi7_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + ret = ath12k_wifi7_hal_desc_reo_parse_err(dp, reo_desc, &paddr, &desc_bank); if (ret) { ath12k_warn(ab, "failed to parse error reo desc %d\n", @@ -1418,9 +1417,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - partner_ab = partner_dp->ab; - pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); link_desc_banks = partner_dp->link_desc_banks; @@ -1430,11 +1428,11 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n msdu_cookies, &rbm); if (rbm != partner_dp->idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && - rbm != partner_ab->hal.hal_params->rx_buf_rbm) { + rbm != partner_dp->hal->hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; dp->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); - ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + ath12k_wifi7_dp_rx_link_desc_return(partner_dp, &reo_desc->buf_addr_info, act); continue; @@ -1449,12 +1447,12 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n * partner device buffers. */ if (!is_frag || num_msdus > 1 || - partner_ab->device_id != ab->device_id) { + partner_dp->device_id != dp->device_id) { drop = true; act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; /* Return the link desc back to wbm idle list */ - ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + ath12k_wifi7_dp_rx_link_desc_return(partner_dp, &reo_desc->buf_addr_info, act); } @@ -1499,10 +1497,9 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n continue; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + ath12k_dp_rx_bufs_replenish(partner_dp, rx_ring, &rx_desc_used_list[device_id], num_buffs_reaped[device_id]); } @@ -1717,7 +1714,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(dp->ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: @@ -1771,13 +1768,14 @@ void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); } -int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct ath12k *ar; struct ath12k_pdev_dp *dp_pdev; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; @@ -1803,7 +1801,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; + srng = &hal->srng_list[dp->rx_rel_ring.ring_id]; spin_lock_bh(&srng->lock); ath12k_hal_srng_access_begin(ab, srng); @@ -1813,11 +1811,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!rx_desc) break; - ret = ath12k_wifi7_hal_wbm_desc_parse_err(ab, rx_desc, + ret = ath12k_wifi7_hal_wbm_desc_parse_err(dp, rx_desc, &err_info); if (ret) { - ath12k_warn(ab, - "failed to parse rx error in wbm_rel ring desc %d\n", + ath12k_warn(ab, "failed to parse rx error in wbm_rel ring desc %d\n", ret); continue; } @@ -1826,7 +1823,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, /* retry manual desc retrieval if hw cc is not done */ if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); + desc_info = ath12k_dp_get_rx_desc(dp, err_info.cookie); if (!desc_info) { ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", err_info.cookie); @@ -1886,7 +1883,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->ab, + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->hal, msdu_data); if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { dev_kfree_skb_any(msdu); @@ -1934,7 +1931,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); rx_ring = &partner_dp->rx_refill_buf_ring; - ath12k_dp_rx_bufs_replenish(ab, rx_ring, + ath12k_dp_rx_bufs_replenish(dp, rx_ring, &rx_desc_used_list[device_id], num_buffs_reaped[device_id]); } @@ -1975,7 +1972,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, } if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { - device_id = ar->ab->device_id; + device_id = dp_pdev->dp->device_id; device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; } @@ -2065,9 +2062,10 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } -void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct hal_tlv_64_hdr *hdr; struct hal_srng *srng; struct ath12k_dp_rx_reo_cmd *cmd, *tmp; @@ -2075,7 +2073,7 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) u16 tag; struct hal_reo_status reo_status; - srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; + srng = &hal->srng_list[dp->reo_status_ring.ring_id]; memset(&reo_status, 0, sizeof(reo_status)); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 85677258b1df1..b92f9cf173dc8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -12,14 +12,14 @@ struct ath12k_hal_reo_cmd; -int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget); -int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, +int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget); -int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int mac_id, +int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget); -void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab); +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, @@ -28,7 +28,7 @@ void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type); -int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, @@ -50,11 +50,11 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, u32 ba_win_sz, u16 ssn, bool update_ssn); static inline -void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, +void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, struct hal_rx_desc_data *rx_info, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc) { - ab->hal.ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); + hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); } #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index bb8c2384c13ea..629084aa36d85 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -63,6 +63,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a bool is_mcast) { struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_hal *hal = dp->hal; struct ath12k_base *ab = dp->ab; struct hal_tx_info ti = {}; struct ath12k_tx_desc_info *tx_desc; @@ -84,7 +85,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a bool tcl_ring_retry; bool msdu_ext_desc = false; bool add_htt_metadata = false; - u32 iova_mask = ab->hw_params->iova_mask; + u32 iova_mask = dp->hw_params->iova_mask; bool is_diff_encap = false; bool is_null_frame = false; @@ -104,14 +105,14 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a * If all rings are full, we drop the packet. * TODO: Add throttling logic when all rings are full */ - ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb); + ring_selector = dp->hw_params->hw_ops->get_ring_selector(skb); tcl_ring_sel: tcl_ring_retry = false; - ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; + ti.ring_id = ring_selector % dp->hw_params->max_tx_ring; ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hal.tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + ti.rbm_id = hal->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; tx_ring = &dp->tx_ring[ti.ring_id]; @@ -212,7 +213,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a if (iova_mask && (unsigned long)skb->data & iova_mask) { - ret = ath12k_dp_tx_align_payload(ab, &skb); + ret = ath12k_dp_tx_align_payload(dp, &skb); if (ret) { ath12k_warn(ab, "failed to align TX buffer %d\n", ret); /* don't bail out, give original buffer @@ -227,8 +228,8 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a hdr = (void *)skb->data; } map: - ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, ti.paddr)) { + ti.paddr = dma_map_single(dp->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(dp->dev, ti.paddr)) { atomic_inc(&dp->device_stats.tx_err.misc_fail); ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); ret = -ENOMEM; @@ -286,9 +287,9 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a } } - ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data, + ti.paddr = dma_map_single(dp->dev, skb_ext_desc->data, skb_ext_desc->len, DMA_TO_DEVICE); - ret = dma_mapping_error(ab->dev, ti.paddr); + ret = dma_mapping_error(dp->dev, ti.paddr); if (ret) goto fail_free_ext_skb; @@ -300,7 +301,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a } hal_ring_id = tx_ring->tcl_data_ring.ring_id; - tcl_ring = &ab->hal.srng_list[hal_ring_id]; + tcl_ring = &hal->srng_list[hal_ring_id]; spin_lock_bh(&tcl_ring->lock); @@ -321,8 +322,8 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a * checking this ring earlier for each pkt tx. * Restart ring selection if some rings are not checked yet. */ - if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) && - ab->hw_params->tcl_ring_retry) { + if (ring_map != (BIT(dp->hw_params->max_tx_ring) - 1) && + dp->hw_params->tcl_ring_retry) { tcl_ring_retry = true; ring_selector++; } @@ -358,14 +359,14 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a fail_unmap_dma_ext: if (skb_cb->paddr_ext_desc) - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, skb_ext_desc->len, DMA_TO_DEVICE); fail_free_ext_skb: kfree_skb(skb_ext_desc); fail_unmap_dma: - dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); + dma_unmap_single(dp->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); fail_remove_tx_buf: ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); @@ -381,37 +382,45 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a } static void -ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, +ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_dp *dp, struct ath12k_tx_desc_params *desc_params, struct dp_tx_ring *tx_ring, struct ath12k_dp_htt_wbm_tx_status *ts, u16 peer_id) { + struct ath12k_base *ab = dp->ab; struct ieee80211_tx_info *info; struct ath12k_link_vif *arvif; struct ath12k_skb_cb *skb_cb; struct ieee80211_vif *vif; struct ath12k_vif *ahvif; - struct ath12k *ar; struct sk_buff *msdu = desc_params->skb; s32 noise_floor; struct ieee80211_tx_status status = {}; struct ath12k_dp_link_peer *peer; struct ath12k_pdev_dp *dp_pdev; + u8 pdev_id; skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); - ar = skb_cb->ar; - dp_pdev = &ar->dp; - ab->dp->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + pdev_id = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params->mac_id); - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); + rcu_read_lock(); + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_id); + if (!dp_pdev) { + rcu_read_unlock(); + return; + } - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + dp->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + + if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) + wake_up(&dp_pdev->tx_empty_waitq); + + dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, desc_params->skb_ext_desc->len, DMA_TO_DEVICE); dev_kfree_skb_any(desc_params->skb_ext_desc); } @@ -419,14 +428,12 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, vif = skb_cb->vif; if (vif) { ahvif = ath12k_vif_to_ahvif(vif); - rcu_read_lock(); arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); if (arvif) { spin_lock_bh(&arvif->link_stats_lock); arvif->link_stats.tx_completed++; spin_unlock_bh(&arvif->link_stats_lock); } - rcu_read_unlock(); } memset(&info->status, 0, sizeof(info->status)); @@ -438,6 +445,8 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ab->wmi_ab.svc_map)) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + spin_lock_bh(&ar->data_lock); noise_floor = ath12k_pdev_get_noise_floor(ar); spin_unlock_bh(&ar->data_lock); @@ -450,12 +459,12 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; } } - rcu_read_lock(); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } else { status.sta = peer->sta; @@ -463,20 +472,19 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, status.info = info; status.skb = msdu; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); + ieee80211_tx_status_ext(ath12k_pdev_dp_to_hw(dp_pdev), &status); exit: rcu_read_unlock(); } static void -ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, +ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params) { struct htt_tx_wbm_completion *status_desc; struct ath12k_dp_htt_wbm_tx_status ts = {}; enum hal_wbm_htt_tx_comp_status wbm_status; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u16 peer_id; status_desc = desc; @@ -494,14 +502,14 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)-> info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); - ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id); + ath12k_dp_tx_htt_tx_complete_buf(dp, desc_params, tx_ring, &ts, peer_id); break; case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH: - ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params); + ath12k_dp_tx_free_txbuf(dp, tx_ring, desc_params); break; case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: /* This event is to be handled only when the driver decides to @@ -509,7 +517,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, */ break; default: - ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status); + ath12k_warn(dp->ab, "Unknown htt wbm tx status %d\n", wbm_status); break; } } @@ -519,7 +527,6 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_dp_link_peer *peer; - struct ath12k_base *ab = dp->ab; struct ath12k_link_sta *arsta; struct rate_info txrate = {}; struct ieee80211_sta *sta; @@ -530,7 +537,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DP_TX, + ath12k_dbg(dp->ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); return; } @@ -559,7 +566,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, &rate_idx, &rate); if (ret < 0) { - ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret); + ath12k_warn(dp->ab, "Invalid tx legacy rate %d\n", ret); return; } @@ -567,7 +574,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11N: if (ts->mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid HT mcs index %d\n", ts->mcs); return; } @@ -581,7 +588,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11AC: if (ts->mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid VHT mcs index %d\n", ts->mcs); return; } @@ -593,7 +600,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11AX: if (ts->mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid HE mcs index %d\n", ts->mcs); return; } @@ -603,7 +610,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11BE: if (ts->mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid EHT mcs index %d\n", ts->mcs); return; } @@ -612,7 +619,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi); break; default: - ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type); + ath12k_warn(dp->ab, "Invalid tx pkt type: %d\n", ts->pkt_type); return; } @@ -663,9 +670,9 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, skb_cb = ATH12K_SKB_CB(msdu); dp->device_stats.tx_completed[ring]++; - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, desc_params->skb_ext_desc->len, DMA_TO_DEVICE); dev_kfree_skb_any(desc_params->skb_ext_desc); } @@ -773,7 +780,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, } static void -ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, +ath12k_wifi7_dp_tx_status_parse(struct ath12k_dp *dp, struct hal_wbm_completion_ring_tx *desc, struct hal_tx_status *ts) { @@ -809,12 +816,12 @@ ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, } } -void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id) { + struct ath12k_base *ab = dp->ab; struct ath12k_pdev_dp *dp_pdev; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; - struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; + struct hal_srng *status_ring = &dp->hal->srng_list[hal_ring_id]; struct ath12k_tx_desc_info *tx_desc = NULL; struct hal_tx_status ts = {}; struct ath12k_tx_desc_params desc_params; @@ -860,7 +867,7 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) tx_ring->tx_status_tail = ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; - ath12k_wifi7_dp_tx_status_parse(ab, tx_status, &ts); + ath12k_wifi7_dp_tx_status_parse(dp, tx_status, &ts); if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { /* HW done cookie conversion */ @@ -872,7 +879,7 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) desc_id = le32_get_bits(tx_status->buf_va_hi, BUFFER_ADDR_INFO1_SW_COOKIE); - tx_desc = ath12k_dp_get_tx_desc(ab, desc_id); + tx_desc = ath12k_dp_get_tx_desc(dp, desc_id); } if (!tx_desc) { ath12k_warn(ab, "unable to retrieve tx_desc!"); @@ -897,12 +904,12 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) */ ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id); if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) { - ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, + ath12k_dp_tx_process_htt_tx_complete(dp, (void *)tx_status, tx_ring, &desc_params); continue; } - pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); + pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params.mac_id); rcu_read_lock(); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 94a5c59289cca..24cf7972d41ba 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -10,7 +10,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); -void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id); u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, struct ath12k_link_vif *arvif); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index c49042a34ed9d..241fa0d9a2842 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -323,13 +323,13 @@ ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, } } -int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp, struct hal_reo_dest_ring *desc, dma_addr_t *paddr, u32 *desc_bank) { + struct ath12k_base *ab = dp->ab; enum hal_reo_dest_ring_push_reason push_reason; enum hal_reo_dest_ring_error_code err_code; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 cookie; push_reason = le32_get_bits(desc->info0, @@ -345,19 +345,18 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, return -EINVAL; } - ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, + ath12k_wifi7_hal_rx_reo_ent_paddr_get(&desc->buf_addr_info, paddr, &cookie); *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); return 0; } -int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_dp *dp, void *desc, struct hal_rx_wbm_rel_info *rel_info) { struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_src_module rel_src; bool hw_cc_done; @@ -443,8 +442,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, return 0; } -void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_buffer_addr *buff_addr, dma_addr_t *paddr, u32 *cookie) { *paddr = ((u64)(le32_get_bits(buff_addr->info1, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index a2498c6257268..c0d57d9b1009d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -860,13 +860,12 @@ void ath12k_wifi7_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, void ath12k_wifi7_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, dma_addr_t *paddr, u32 *cookie, u8 *rbm); -int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp, struct hal_reo_dest_ring *desc, dma_addr_t *paddr, u32 *desc_bank); -int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_dp *dp, void *desc, struct hal_rx_wbm_rel_info *rel_info); -void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_buffer_addr *buff_addr, dma_addr_t *paddr, u32 *cookie); void ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, From d6782a0592957509939fff4e0b0f45d2d2f69c17 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Mon, 3 Nov 2025 16:51:11 +0530 Subject: [PATCH 454/659] wifi: ath12k: Replace lock/unlock with guard() Use guard(wiphy)(...) and guard(spinlock_bh)(...) in: ath12k_dbg_sta_dump_rx_stats() ath12k_mac_op_link_sta_statistics() The guard() API ensures locks are automatically released when the scope exits, reducing the risk of missing unlocks in error paths and improving code readability. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-13-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/debugfs_sta.c | 36 ++++++------------- drivers/net/wireless/ath/ath12k/mac.c | 7 ++-- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs_sta.c b/drivers/net/wireless/ath/ath12k/debugfs_sta.c index dde3efed4b60b..585c40bd29517 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_sta.c @@ -153,41 +153,32 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, bool he_rates_avail; struct ath12k *ar; - wiphy_lock(ah->hw->wiphy); + guard(wiphy)(ah->hw->wiphy); - if (!(BIT(link_id) & ahsta->links_map)) { - wiphy_unlock(ah->hw->wiphy); + if (!(BIT(link_id) & ahsta->links_map)) return -ENOENT; - } arsta = wiphy_dereference(ah->hw->wiphy, ahsta->link[link_id]); - if (!arsta || !arsta->arvif->ar) { - wiphy_unlock(ah->hw->wiphy); + if (!arsta || !arsta->arvif->ar) return -ENOENT; - } ar = arsta->arvif->ar; u8 *buf __free(kfree) = kzalloc(size, GFP_KERNEL); - if (!buf) { - ret = -ENOENT; - goto out; - } + if (!buf) + return -ENOMEM; dp = ath12k_ab_to_dp(ar->ab); - spin_lock_bh(&dp->dp_lock); + + guard(spinlock_bh)(&dp->dp_lock); link_peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr); - if (!link_peer) { - ret = -ENOENT; - goto unlock; - } + if (!link_peer) + return -ENOENT; rx_stats = link_peer->peer_stats.rx_stats; - if (!rx_stats) { - ret = -ENOENT; - goto unlock; - } + if (!rx_stats) + return -ENOENT; len += scnprintf(buf + len, size - len, "RX peer stats:\n\n"); len += scnprintf(buf + len, size - len, "Num of MSDUs: %llu\n", @@ -247,13 +238,8 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, len += ath12k_dbg_sta_dump_rate_stats(buf, len, size, he_rates_avail, &rx_stats->byte_stats); -unlock: - spin_unlock_bh(&dp->dp_lock); - if (len) ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -out: - wiphy_unlock(ah->hw->wiphy); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index f3bbd3b8a647a..b1bf9434dd6f5 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13358,12 +13358,10 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - spin_lock_bh(&ar->ab->dp->dp_lock); + guard(spinlock_bh)(&ar->ab->dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); - if (!peer) { - spin_unlock_bh(&ar->ab->dp->dp_lock); + if (!peer) return; - } link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); @@ -13421,7 +13419,6 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->tx_failed = peer->tx_retry_failed; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); - spin_unlock_bh(&ar->ab->dp->dp_lock); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); From 5c13b47d1593d0dfbd8fed0810627b8b01ec530e Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:02 +0530 Subject: [PATCH 455/659] wifi: ath12k: Move monitor ring processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor-mode processing from common ath12k data path code to improve modularity. Move monitor status ring processing to wifi7/dp_mon.c: - ath12k_dp_mon_srng_process() - __ath12k_dp_mon_process_ring() - ath12k_dp_mon_process_ring() Rename the above to use the ath12k_wifi7_ prefix and export helper functions required by the ath12k_wifi7 module. Update the Wi-Fi 7 module Makefile to build dp_mon.o. No functional changes are intended; this is preparatory refactoring to isolate Wi-Fi 7 monitor-mode code from shared ath12k code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-2-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 256 ++---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 19 +- .../net/wireless/ath/ath12k/wifi7/Makefile | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 16 +- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 1 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 244 +++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.h | 17 ++ 7 files changed, 305 insertions(+), 249 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index d2fc4de51eb96..861137f59cd82 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2575,7 +2575,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } -static enum hal_rx_mon_status +enum hal_rx_mon_status ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb) { @@ -2626,6 +2626,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_da return hal_status; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest); enum hal_rx_mon_status ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, @@ -2653,6 +2654,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, return hal_status; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_mon_status); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, @@ -2728,6 +2730,7 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, spin_unlock_bh(&srng->lock); return -ENOMEM; } +EXPORT_SYMBOL(ath12k_dp_mon_buf_replenish); int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, @@ -3524,8 +3527,8 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, + struct hal_rx_mon_ppdu_info *ppdu_info) { struct ath12k_rx_peer_stats *rx_stats = peer->peer_stats.rx_stats; u32 num_msdu; @@ -3632,6 +3635,7 @@ static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *pe ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_su_stats); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -3680,6 +3684,7 @@ void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) } ppdu_info->ldpc = 1; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_process_ulofdma); static void ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, @@ -3780,7 +3785,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, user_stats, num_msdu); } -static void +void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -3793,169 +3798,18 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, for (i = 0; i < num_users; i++) ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); -static void +void ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) { memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_memset_ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, - struct napi_struct *napi) -{ - struct ath12k_dp *dp = pdev_dp->dp; - struct ath12k_base *ab = dp->ab; - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct hal_mon_dest_desc *mon_dst_desc; - struct sk_buff *skb; - struct ath12k_skb_rxcb *rxcb; - struct dp_srng *mon_dst_ring; - struct hal_srng *srng; - struct dp_rxdma_mon_ring *buf_ring; - struct ath12k_dp_link_peer *peer; - struct sk_buff_head skb_list; - u64 cookie; - int num_buffs_reaped = 0, srng_id, buf_id; - u32 hal_status, end_offset, info0, end_reason; - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); - - __skb_queue_head_init(&skb_list); - srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); - mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; - buf_ring = &dp->rxdma_mon_buf_ring; - - srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; - spin_lock_bh(&srng->lock); - ath12k_hal_srng_access_begin(ab, srng); - - while (likely(*budget)) { - mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); - if (unlikely(!mon_dst_desc)) - break; - - /* In case of empty descriptor, the cookie in the ring descriptor - * is invalid. Therefore, this entry is skipped, and ring processing - * continues. - */ - info0 = le32_to_cpu(mon_dst_desc->info0); - if (u32_get_bits(info0, HAL_MON_DEST_INFO0_EMPTY_DESC)) - goto move_next; - - cookie = le32_to_cpu(mon_dst_desc->cookie); - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&buf_ring->idr_lock); - skb = idr_remove(&buf_ring->bufs_idr, buf_id); - spin_unlock_bh(&buf_ring->idr_lock); - - if (unlikely(!skb)) { - ath12k_warn(ab, "monitor destination with invalid buf_id %d\n", - buf_id); - goto move_next; - } - - rxcb = ATH12K_SKB_RXCB(skb); - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); - - /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of - * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got - * truncated due to a system level error. In both the cases, buffer data - * can be discarded - */ - if ((end_reason == HAL_MON_FLUSH_DETECTED) || - (end_reason == HAL_MON_PPDU_TRUNCATED)) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Monitor dest descriptor end reason %d", end_reason); - dev_kfree_skb_any(skb); - goto move_next; - } - - /* Calculate the budget when the ring descriptor with the - * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always - * reaped. This helps to efficiently utilize the NAPI budget. - */ - if (end_reason == HAL_MON_END_OF_PPDU) { - *budget -= 1; - rxcb->is_end_of_ppdu = true; - } - - end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); - if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { - skb_put(skb, end_offset); - } else { - ath12k_warn(ab, - "invalid offset on mon stats destination %u\n", - end_offset); - skb_put(skb, DP_RX_BUFFER_SIZE); - } - - __skb_queue_tail(&skb_list, skb); - -move_next: - ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); - ath12k_hal_srng_dst_get_next_entry(ab, srng); - num_buffs_reaped++; - } - - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - if (!num_buffs_reaped) - return 0; - - /* In some cases, one PPDU worth of data can be spread across multiple NAPI - * schedules, To avoid losing existing parsed ppdu_info information, skip - * the memset of the ppdu_info structure and continue processing it. - */ - if (!ppdu_info->ppdu_continuation) - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); - - while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); - if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { - ppdu_info->ppdu_continuation = true; - dev_kfree_skb_any(skb); - continue; - } - - if (ppdu_info->peer_id == HAL_INVALID_PEERID) - goto free_skb; - - rcu_read_lock(); - peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "failed to find the peer with monitor peer_id %d\n", - ppdu_info->peer_id); - goto next_skb; - } - - if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); - } else if ((ppdu_info->fc_valid) && - (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { - ath12k_dp_mon_rx_process_ulofdma(ppdu_info); - ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); - } - -next_skb: - rcu_read_unlock(); -free_skb: - dev_kfree_skb_any(skb); - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); - } - - return num_buffs_reaped; -} - -static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list) +int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) { const struct ath12k_hw_hal_params *hal_params; int buf_id, srng_id, num_buffs_reaped = 0; @@ -4098,6 +3952,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, return num_buffs_reaped; } +EXPORT_SYMBOL(ath12k_dp_rx_reap_mon_status_ring); static u32 ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, @@ -4293,8 +4148,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, */ #define MON_DEST_RING_STUCK_MAX_CNT 16 -static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi) +void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi) { struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; struct ath12k_pdev_mon_stats *rx_mon_stats; @@ -4395,79 +4250,4 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, rx_bufs_used); } } - -static int -__ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, - struct napi_struct *napi, int *budget) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats; - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - enum hal_rx_mon_status hal_status; - struct sk_buff_head skb_list; - int num_buffs_reaped; - struct sk_buff *skb; - - __skb_queue_head_init(&skb_list); - - num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, - budget, &skb_list); - if (!num_buffs_reaped) - goto exit; - - while ((skb = __skb_dequeue(&skb_list))) { - memset(ppdu_info, 0, sizeof(*ppdu_info)); - ppdu_info->peer_id = HAL_INVALID_PEERID; - - hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); - - if (ar->monitor_started && - pmon->mon_ppdu_status == DP_PPDU_STATUS_START && - hal_status == HAL_TLV_STATUS_PPDU_DONE) { - rx_mon_stats->status_ppdu_done++; - pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; - ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); - pmon->mon_ppdu_status = DP_PPDU_STATUS_START; - } - - dev_kfree_skb_any(skb); - } - -exit: - return num_buffs_reaped; -} - -int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, - struct napi_struct *napi, int budget, - enum dp_monitor_mode monitor_mode) -{ - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); - struct ath12k_pdev_dp *dp_pdev; - struct ath12k *ar; - int num_buffs_reaped = 0; - - rcu_read_lock(); - - dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); - if (!dp_pdev) { - rcu_read_unlock(); - return 0; - } - - if (dp->hw_params->rxdma1_enable) { - if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) - num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, - napi); - } else { - ar = ath12k_pdev_dp_to_ar(dp_pdev); - - if (ar->monitor_started) - num_buffs_reaped = - __ath12k_dp_mon_process_ring(ar, mac_id, napi, &budget); - } - - rcu_read_unlock(); - - return num_buffs_reaped; -} -EXPORT_SYMBOL(ath12k_dp_mon_process_ring); +EXPORT_SYMBOL(ath12k_dp_rx_mon_dest_process); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 3e6ff4b0a6d9e..689d7a0fff5c1 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -89,9 +89,6 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, - struct napi_struct *napi, int budget, - enum dp_monitor_mode monitor_mode); struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); enum dp_mon_tx_tlv_status ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, @@ -104,6 +101,18 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, - struct napi_struct *napi); +enum hal_rx_mon_status +ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, + struct sk_buff *skb); +int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list); +void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi); +void +ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index 30258a1b313de..dcfa732bb95bc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -11,6 +11,7 @@ ath12k_wifi7-y += core.o \ dp_rx.o \ dp_tx.o \ dp.o \ + dp_mon.o \ hal.o \ hal_qcn9274.o \ hal_wcn7850.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 30c27e005ed8f..0b2c7f37c7566 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -9,6 +9,7 @@ #include "../dp_tx.h" #include "hal_desc.h" #include "../dp_mon.h" +#include "dp_mon.h" #include "../dp_cmn.h" #include "dp_rx.h" #include "dp.h" @@ -66,8 +67,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - 0); + ath12k_wifi7_dp_mon_process_ring(dp, id, napi, + budget, + 0); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -86,8 +88,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - monitor_mode); + ath12k_wifi7_dp_mon_process_ring(dp, id, napi, + budget, + monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -107,8 +110,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - monitor_mode); + ath12k_wifi7_dp_mon_process_ring(dp, id, + napi, budget, + monitor_mode); budget -= work_done; tot_work_done += work_done; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 72fdfb368c994..a5f0941d34e2f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -12,6 +12,7 @@ struct ath12k_base; struct ath12k_dp; +enum dp_monitor_mode; struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c new file mode 100644 index 0000000000000..4135ff5e87590 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_desc.h" +#include "../dp_mon.h" +#include "dp_mon.h" +#include "../debug.h" +#include "hal_qcn9274.h" +#include "dp_rx.h" +#include "../peer.h" + +static int +__ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, + struct napi_struct *napi, int *budget) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats; + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + enum hal_rx_mon_status hal_status; + struct sk_buff_head skb_list; + int num_buffs_reaped; + struct sk_buff *skb; + + __skb_queue_head_init(&skb_list); + + num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, + budget, &skb_list); + if (!num_buffs_reaped) + goto exit; + + while ((skb = __skb_dequeue(&skb_list))) { + memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; + + hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); + + if (ar->monitor_started && + pmon->mon_ppdu_status == DP_PPDU_STATUS_START && + hal_status == HAL_TLV_STATUS_PPDU_DONE) { + rx_mon_stats->status_ppdu_done++; + pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; + ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + } + + dev_kfree_skb_any(skb); + } + +exit: + return num_buffs_reaped; +} + +static int +ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, + struct napi_struct *napi) +{ + struct ath12k_dp *dp = pdev_dp->dp; + struct ath12k_base *ab = dp->ab; + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + struct hal_mon_dest_desc *mon_dst_desc; + struct sk_buff *skb; + struct ath12k_skb_rxcb *rxcb; + struct dp_srng *mon_dst_ring; + struct hal_srng *srng; + struct dp_rxdma_mon_ring *buf_ring; + struct ath12k_dp_link_peer *peer; + struct sk_buff_head skb_list; + u64 cookie; + int num_buffs_reaped = 0, srng_id, buf_id; + u32 hal_status, end_offset, info0, end_reason; + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); + + __skb_queue_head_init(&skb_list); + srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); + mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; + buf_ring = &dp->rxdma_mon_buf_ring; + + srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; + spin_lock_bh(&srng->lock); + ath12k_hal_srng_access_begin(ab, srng); + + while (likely(*budget)) { + mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); + if (unlikely(!mon_dst_desc)) + break; + + /* In case of empty descriptor, the cookie in the ring descriptor + * is invalid. Therefore, this entry is skipped, and ring processing + * continues. + */ + info0 = le32_to_cpu(mon_dst_desc->info0); + if (u32_get_bits(info0, HAL_MON_DEST_INFO0_EMPTY_DESC)) + goto move_next; + + cookie = le32_to_cpu(mon_dst_desc->cookie); + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&buf_ring->idr_lock); + skb = idr_remove(&buf_ring->bufs_idr, buf_id); + spin_unlock_bh(&buf_ring->idr_lock); + + if (unlikely(!skb)) { + ath12k_warn(ab, "monitor destination with invalid buf_id %d\n", + buf_id); + goto move_next; + } + + rxcb = ATH12K_SKB_RXCB(skb); + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); + + /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of + * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got + * truncated due to a system level error. In both the cases, buffer data + * can be discarded + */ + if ((end_reason == HAL_MON_FLUSH_DETECTED) || + (end_reason == HAL_MON_PPDU_TRUNCATED)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Monitor dest descriptor end reason %d", end_reason); + dev_kfree_skb_any(skb); + goto move_next; + } + + /* Calculate the budget when the ring descriptor with the + * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always + * reaped. This helps to efficiently utilize the NAPI budget. + */ + if (end_reason == HAL_MON_END_OF_PPDU) { + *budget -= 1; + rxcb->is_end_of_ppdu = true; + } + + end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); + if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { + skb_put(skb, end_offset); + } else { + ath12k_warn(ab, + "invalid offset on mon stats destination %u\n", + end_offset); + skb_put(skb, DP_RX_BUFFER_SIZE); + } + + __skb_queue_tail(&skb_list, skb); + +move_next: + ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); + ath12k_hal_srng_dst_get_next_entry(ab, srng); + num_buffs_reaped++; + } + + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + if (!num_buffs_reaped) + return 0; + + /* In some cases, one PPDU worth of data can be spread across multiple NAPI + * schedules, To avoid losing existing parsed ppdu_info information, skip + * the memset of the ppdu_info structure and continue processing it. + */ + if (!ppdu_info->ppdu_continuation) + ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + + while ((skb = __skb_dequeue(&skb_list))) { + hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); + if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { + ppdu_info->ppdu_continuation = true; + dev_kfree_skb_any(skb); + continue; + } + + if (ppdu_info->peer_id == HAL_INVALID_PEERID) + goto free_skb; + + rcu_read_lock(); + peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "failed to find the peer with monitor peer_id %d\n", + ppdu_info->peer_id); + goto next_skb; + } + + if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { + ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); + } else if ((ppdu_info->fc_valid) && + (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { + ath12k_dp_mon_rx_process_ulofdma(ppdu_info); + ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); + } + +next_skb: + rcu_read_unlock(); +free_skb: + dev_kfree_skb_any(skb); + ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + } + + return num_buffs_reaped; +} + +int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, + struct napi_struct *napi, int budget, + enum dp_monitor_mode monitor_mode) +{ + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); + struct ath12k_pdev_dp *dp_pdev; + struct ath12k *ar; + int num_buffs_reaped = 0; + + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + return 0; + } + + if (dp->hw_params->rxdma1_enable) { + if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) + num_buffs_reaped = ath12k_wifi7_dp_mon_srng_process(dp_pdev, + &budget, + napi); + } else { + ar = ath12k_pdev_dp_to_ar(dp_pdev); + + if (ar->monitor_started) + num_buffs_reaped = + __ath12k_wifi7_dp_mon_process_ring(ar, mac_id, napi, + &budget); + } + + rcu_read_unlock(); + + return num_buffs_reaped; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h new file mode 100644 index 0000000000000..3cf82864c41cd --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_MON_WIFI7_H +#define ATH12K_DP_MON_WIFI7_H + +#include "hw.h" + +enum dp_monitor_mode; + +int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, + struct napi_struct *napi, int budget, + enum dp_monitor_mode monitor_mode); +#endif From fd588a98989875018fd28d39171b48b3567714c9 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:03 +0530 Subject: [PATCH 456/659] wifi: ath12k: Move monitor status processing to Wi-Fi 7 module Split Wi-Fi 7-specific monitor status processing out of ath12k common code and into the Wi-Fi 7 module to improve modularity. Move the following functions to wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_parse_mon_status() - ath12k_dp_rx_reap_mon_status_ring() - ath12k_dp_mon_parse_rx_dest() - ath12k_dp_rx_mon_buf_done() - ath12k_dp_rx_mon_dest_process() - ath12k_dp_mon_rx_memset_ppdu_info() Export helper functions required by the Wi-Fi 7 monitor path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-3-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 409 +----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 38 +- drivers/net/wireless/ath/ath12k/hal.c | 2 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 399 ++++++++++++++++- 4 files changed, 433 insertions(+), 415 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 861137f59cd82..dfcca4ac02e39 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1494,7 +1494,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, RX_MSDU_END_INFO11_DECAP_FORMAT); } -static enum hal_rx_mon_status +enum hal_rx_mon_status ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct hal_tlv_64_hdr *tlv) @@ -1763,6 +1763,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, return HAL_RX_MON_STATUS_PPDU_NOT_DONE; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv); static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, @@ -1791,7 +1792,7 @@ ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, } } -static struct sk_buff +struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id) @@ -1834,46 +1835,7 @@ static struct sk_buff fail_alloc_skb: return NULL; } - -static enum dp_mon_status_buf_state -ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, - struct dp_rxdma_mon_ring *rx_ring) -{ - struct ath12k_skb_rxcb *rxcb; - struct hal_tlv_64_hdr *tlv; - struct sk_buff *skb; - void *status_desc; - dma_addr_t paddr; - u32 cookie; - int buf_id; - u8 rbm; - - status_desc = ath12k_hal_srng_src_next_peek(ab, srng); - if (!status_desc) - return DP_MON_STATUS_NO_DMA; - - ath12k_hal_rx_buf_addr_info_get(&ab->hal, status_desc, &paddr, &cookie, &rbm); - - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&rx_ring->idr_lock); - skb = idr_find(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - if (!skb) - return DP_MON_STATUS_NO_DMA; - - rxcb = ATH12K_SKB_RXCB(skb); - dma_sync_single_for_cpu(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - tlv = (struct hal_tlv_64_hdr *)skb->data; - if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE) - return DP_MON_STATUS_NO_DMA; - - return DP_MON_STATUS_REPLINISH; -} +EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf); static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) { @@ -2392,10 +2354,10 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi) +int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi) { struct sk_buff *mon_skb, *skb_next, *header; struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; @@ -2446,8 +2408,9 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, } return -EINVAL; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver); -static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) +int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) { if (skb->len > len) { skb_trim(skb, len); @@ -2464,6 +2427,7 @@ static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) return 0; } +EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); /* Hardware fill buffer with 128 bytes aligned. So need to reap it * with 128 bytes aligned. @@ -2537,7 +2501,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } -static int +int ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, enum hal_rx_mon_status hal_status, @@ -2574,87 +2538,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } - -enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, - struct sk_buff *skb) -{ - struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); - struct hal_tlv_64_hdr *tlv; - struct ath12k_skb_rxcb *rxcb; - enum hal_rx_mon_status hal_status; - u16 tlv_tag, tlv_len; - u8 *ptr = skb->data; - - do { - tlv = (struct hal_tlv_64_hdr *)ptr; - tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); - - /* The actual length of PPDU_END is the combined length of many PHY - * TLVs that follow. Skip the TLV header and - * rx_rxpcu_classification_overview that follows the header to get to - * next TLV. - */ - - if (tlv_tag == HAL_RX_PPDU_END) - tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); - else - tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - - hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); - - if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, - tlv->value)) - return HAL_RX_MON_STATUS_PPDU_DONE; - - ptr += sizeof(*tlv) + tlv_len; - ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN); - - if ((ptr - skb->data) > skb->len) - break; - - } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) || - (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) || - (hal_status == HAL_RX_MON_STATUS_MPDU_START) || - (hal_status == HAL_RX_MON_STATUS_MPDU_END) || - (hal_status == HAL_RX_MON_STATUS_MSDU_END)); - - rxcb = ATH12K_SKB_RXCB(skb); - if (rxcb->is_end_of_ppdu) - hal_status = HAL_RX_MON_STATUS_PPDU_DONE; - - return hal_status; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest); - -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi) -{ - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct dp_mon_mpdu *tmp; - struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; - enum hal_rx_mon_status hal_status; - - hal_status = ath12k_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); - if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) - return hal_status; - - list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { - list_del(&mon_mpdu->list); - - if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); - - kfree(mon_mpdu); - } - - return hal_status; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_mon_status); +EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest_tlv); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, @@ -3800,161 +3684,7 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); -void -ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) -{ - memset(ppdu_info, 0, sizeof(*ppdu_info)); - ppdu_info->peer_id = HAL_INVALID_PEERID; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_memset_ppdu_info); - -int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list) -{ - const struct ath12k_hw_hal_params *hal_params; - int buf_id, srng_id, num_buffs_reaped = 0; - enum dp_mon_status_buf_state reap_status; - struct dp_rxdma_mon_ring *rx_ring; - struct ath12k_mon_data *pmon; - struct ath12k_skb_rxcb *rxcb; - struct hal_tlv_64_hdr *tlv; - void *rx_mon_status_desc; - struct hal_srng *srng; - struct ath12k_dp *dp; - struct sk_buff *skb; - struct ath12k *ar; - dma_addr_t paddr; - u32 cookie; - u8 rbm; - - ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; - dp = ath12k_ab_to_dp(ab); - pmon = &ar->dp.mon_data; - srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); - rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; - - srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (*budget) { - *budget -= 1; - rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng); - if (!rx_mon_status_desc) { - pmon->buf_state = DP_MON_STATUS_REPLINISH; - break; - } - ath12k_hal_rx_buf_addr_info_get(&ab->hal, rx_mon_status_desc, &paddr, - &cookie, &rbm); - if (paddr) { - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&rx_ring->idr_lock); - skb = idr_find(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - if (!skb) { - ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n", - buf_id); - pmon->buf_state = DP_MON_STATUS_REPLINISH; - goto move_next; - } - - rxcb = ATH12K_SKB_RXCB(skb); - - dma_sync_single_for_cpu(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - tlv = (struct hal_tlv_64_hdr *)skb->data; - if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != - HAL_RX_STATUS_BUFFER_DONE) { - pmon->buf_state = DP_MON_STATUS_NO_DMA; - ath12k_warn(ab, - "mon status DONE not set %llx, buf_id %d\n", - le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG), - buf_id); - /* RxDMA status done bit might not be set even - * though tp is moved by HW. - */ - - /* If done status is missing: - * 1. As per MAC team's suggestion, - * when HP + 1 entry is peeked and if DMA - * is not done and if HP + 2 entry's DMA done - * is set. skip HP + 1 entry and - * start processing in next interrupt. - * 2. If HP + 2 entry's DMA done is not set, - * poll onto HP + 1 entry DMA done to be set. - * Check status for same buffer for next time - * dp_rx_mon_status_srng_process - */ - reap_status = ath12k_dp_rx_mon_buf_done(ab, srng, - rx_ring); - if (reap_status == DP_MON_STATUS_NO_DMA) - continue; - - spin_lock_bh(&rx_ring->idr_lock); - idr_remove(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - dev_kfree_skb_any(skb); - pmon->buf_state = DP_MON_STATUS_REPLINISH; - goto move_next; - } - - spin_lock_bh(&rx_ring->idr_lock); - idr_remove(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) { - dev_kfree_skb_any(skb); - goto move_next; - } - __skb_queue_tail(skb_list, skb); - } else { - pmon->buf_state = DP_MON_STATUS_REPLINISH; - } -move_next: - skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, - &buf_id); - hal_params = ab->hal.hal_params; - - if (!skb) { - ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, - 0, 0, hal_params->rx_buf_rbm); - num_buffs_reaped++; - break; - } - rxcb = ATH12K_SKB_RXCB(skb); - - cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | - u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - - ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, rxcb->paddr, - cookie, hal_params->rx_buf_rbm); - ath12k_hal_srng_src_get_next_entry(ab, srng); - num_buffs_reaped++; - } - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - return num_buffs_reaped; -} -EXPORT_SYMBOL(ath12k_dp_rx_reap_mon_status_ring); - -static u32 +u32 ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, struct sk_buff **tail_msdu, @@ -4141,113 +3871,4 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, return rx_bufs_used; } - -/* The destination ring processing is stuck if the destination is not - * moving while status ring moves 16 PPDU. The destination ring processing - * skips this destination ring PPDU as a workaround. - */ -#define MON_DEST_RING_STUCK_MAX_CNT 16 - -void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_pdev_mon_stats *rx_mon_stats; - u32 ppdu_id, rx_bufs_used = 0, ring_id; - u32 mpdu_rx_bufs_used, npackets = 0; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - void *ring_entry, *mon_dst_srng; - struct dp_mon_mpdu *tmp_mpdu; - LIST_HEAD(rx_desc_used_list); - struct hal_srng *srng; - - ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id; - srng = &ab->hal.srng_list[ring_id]; - - mon_dst_srng = &ab->hal.srng_list[ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, mon_dst_srng); - - ppdu_id = pmon->mon_ppdu_info.ppdu_id; - rx_mon_stats = &pmon->rx_mon_stats; - - while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { - struct sk_buff *head_msdu, *tail_msdu; - - head_msdu = NULL; - tail_msdu = NULL; - - mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, - &head_msdu, &tail_msdu, - &rx_desc_used_list, - &npackets, &ppdu_id); - - rx_bufs_used += mpdu_rx_bufs_used; - - if (mpdu_rx_bufs_used) { - dp->mon_dest_ring_stuck_cnt = 0; - } else { - dp->mon_dest_ring_stuck_cnt++; - rx_mon_stats->dest_mon_not_reaped++; - } - - if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) { - rx_mon_stats->dest_mon_stuck++; - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n", - pmon->mon_ppdu_info.ppdu_id, ppdu_id, - dp->mon_dest_ring_stuck_cnt, - rx_mon_stats->dest_mon_not_reaped, - rx_mon_stats->dest_mon_stuck); - spin_lock_bh(&pmon->mon_lock); - pmon->mon_ppdu_info.ppdu_id = ppdu_id; - spin_unlock_bh(&pmon->mon_lock); - continue; - } - - if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { - spin_lock_bh(&pmon->mon_lock); - pmon->mon_ppdu_status = DP_PPDU_STATUS_START; - spin_unlock_bh(&pmon->mon_lock); - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n", - ppdu_id, pmon->mon_ppdu_info.ppdu_id, - rx_mon_stats->dest_mon_not_reaped, - rx_mon_stats->dest_mon_stuck); - break; - } - - if (head_msdu && tail_msdu) { - tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); - if (!tmp_mpdu) - break; - - tmp_mpdu->head = head_msdu; - tmp_mpdu->tail = tail_msdu; - tmp_mpdu->err_bitmap = pmon->err_bitmap; - tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, - &pmon->mon_ppdu_info, napi); - rx_mon_stats->dest_mpdu_done++; - kfree(tmp_mpdu); - } - - ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab, - mon_dst_srng); - } - ath12k_hal_srng_access_end(ar->ab, mon_dst_srng); - - spin_unlock_bh(&srng->lock); - - if (rx_bufs_used) { - rx_mon_stats->dest_ppdu_done++; - ath12k_dp_rx_bufs_replenish(ar->ab->dp, - &dp->rx_refill_buf_ring, - &rx_desc_used_list, - rx_bufs_used); - } -} -EXPORT_SYMBOL(ath12k_dp_rx_mon_dest_process); +EXPORT_SYMBOL(ath12k_dp_rx_mon_mpdu_pop); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 689d7a0fff5c1..726434ab74aca 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -78,11 +78,6 @@ struct dp_mon_tx_ppdu_info { struct dp_mon_mpdu *tx_mon_mpdu; }; -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, int req_entries); @@ -101,18 +96,33 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, - struct sk_buff *skb); -int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list); -void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi); void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info); +u32 +ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, + void *ring_entry, struct sk_buff **head_msdu, + struct sk_buff **tail_msdu, + struct list_head *used_list, + u32 *npackets, u32 *ppdu_id); +int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); +int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi); +int +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + enum hal_rx_mon_status hal_status, + const void *tlv_data); +enum hal_rx_mon_status +ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct hal_tlv_64_hdr *tlv); +struct sk_buff +*ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, + struct dp_rxdma_mon_ring *rx_ring, + int *buf_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index efa039f6df924..91d697ad1799d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -402,6 +402,7 @@ void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_src_next_peek); void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab, struct hal_srng *srng) @@ -447,6 +448,7 @@ void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng) return srng->ring_base_vaddr + srng->u.src_ring.hp; } +EXPORT_SYMBOL(ath12k_hal_srng_src_peek); void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab, struct hal_srng *srng) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 4135ff5e87590..ffebeb1652e7b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -12,6 +12,390 @@ #include "dp_rx.h" #include "../peer.h" +static void +ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) +{ + memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; +} + +/* The destination ring processing is stuck if the destination is not + * moving while status ring moves 16 PPDU. The destination ring processing + * skips this destination ring PPDU as a workaround. + */ +#define MON_DEST_RING_STUCK_MAX_CNT 16 + +static void +ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_pdev_mon_stats *rx_mon_stats; + u32 ppdu_id, rx_bufs_used = 0, ring_id; + u32 mpdu_rx_bufs_used, npackets = 0; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + void *ring_entry, *mon_dst_srng; + struct dp_mon_mpdu *tmp_mpdu; + LIST_HEAD(rx_desc_used_list); + struct hal_srng *srng; + + ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id; + srng = &ab->hal.srng_list[ring_id]; + + mon_dst_srng = &ab->hal.srng_list[ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, mon_dst_srng); + + ppdu_id = pmon->mon_ppdu_info.ppdu_id; + rx_mon_stats = &pmon->rx_mon_stats; + + while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { + struct sk_buff *head_msdu, *tail_msdu; + + head_msdu = NULL; + tail_msdu = NULL; + + mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, + &head_msdu, &tail_msdu, + &rx_desc_used_list, + &npackets, &ppdu_id); + + rx_bufs_used += mpdu_rx_bufs_used; + + if (mpdu_rx_bufs_used) { + dp->mon_dest_ring_stuck_cnt = 0; + } else { + dp->mon_dest_ring_stuck_cnt++; + rx_mon_stats->dest_mon_not_reaped++; + } + + if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) { + rx_mon_stats->dest_mon_stuck++; + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n", + pmon->mon_ppdu_info.ppdu_id, ppdu_id, + dp->mon_dest_ring_stuck_cnt, + rx_mon_stats->dest_mon_not_reaped, + rx_mon_stats->dest_mon_stuck); + spin_lock_bh(&pmon->mon_lock); + pmon->mon_ppdu_info.ppdu_id = ppdu_id; + spin_unlock_bh(&pmon->mon_lock); + continue; + } + + if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { + spin_lock_bh(&pmon->mon_lock); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + spin_unlock_bh(&pmon->mon_lock); + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n", + ppdu_id, pmon->mon_ppdu_info.ppdu_id, + rx_mon_stats->dest_mon_not_reaped, + rx_mon_stats->dest_mon_stuck); + break; + } + + if (head_msdu && tail_msdu) { + tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); + if (!tmp_mpdu) + break; + + tmp_mpdu->head = head_msdu; + tmp_mpdu->tail = tail_msdu; + tmp_mpdu->err_bitmap = pmon->err_bitmap; + tmp_mpdu->decap_format = pmon->decap_format; + ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, + &pmon->mon_ppdu_info, napi); + rx_mon_stats->dest_mpdu_done++; + kfree(tmp_mpdu); + } + + ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab, + mon_dst_srng); + } + ath12k_hal_srng_access_end(ar->ab, mon_dst_srng); + + spin_unlock_bh(&srng->lock); + + if (rx_bufs_used) { + rx_mon_stats->dest_ppdu_done++; + ath12k_dp_rx_bufs_replenish(ar->ab->dp, + &dp->rx_refill_buf_ring, + &rx_desc_used_list, + rx_bufs_used); + } +} + +static enum dp_mon_status_buf_state +ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, + struct dp_rxdma_mon_ring *rx_ring) +{ + struct ath12k_skb_rxcb *rxcb; + struct hal_tlv_64_hdr *tlv; + struct sk_buff *skb; + void *status_desc; + dma_addr_t paddr; + u32 cookie; + int buf_id; + u8 rbm; + + status_desc = ath12k_hal_srng_src_next_peek(ab, srng); + if (!status_desc) + return DP_MON_STATUS_NO_DMA; + + ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&rx_ring->idr_lock); + skb = idr_find(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + if (!skb) + return DP_MON_STATUS_NO_DMA; + + rxcb = ATH12K_SKB_RXCB(skb); + dma_sync_single_for_cpu(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + tlv = (struct hal_tlv_64_hdr *)skb->data; + if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE) + return DP_MON_STATUS_NO_DMA; + + return DP_MON_STATUS_REPLINISH; +} + +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb) +{ + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + struct hal_tlv_64_hdr *tlv; + struct ath12k_skb_rxcb *rxcb; + enum hal_rx_mon_status hal_status; + u16 tlv_tag, tlv_len; + u8 *ptr = skb->data; + + do { + tlv = (struct hal_tlv_64_hdr *)ptr; + tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); + + /* The actual length of PPDU_END is the combined length of many PHY + * TLVs that follow. Skip the TLV header and + * rx_rxpcu_classification_overview that follows the header to get to + * next TLV. + */ + + if (tlv_tag == HAL_RX_PPDU_END) + tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); + else + tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); + + hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); + + if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && + ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) + return HAL_RX_MON_STATUS_PPDU_DONE; + + ptr += sizeof(*tlv) + tlv_len; + ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN); + + if ((ptr - skb->data) > skb->len) + break; + + } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) || + (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) || + (hal_status == HAL_RX_MON_STATUS_MPDU_START) || + (hal_status == HAL_RX_MON_STATUS_MPDU_END) || + (hal_status == HAL_RX_MON_STATUS_MSDU_END)); + + rxcb = ATH12K_SKB_RXCB(skb); + if (rxcb->is_end_of_ppdu) + hal_status = HAL_RX_MON_STATUS_PPDU_DONE; + + return hal_status; +} + +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi) +{ + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + struct dp_mon_mpdu *tmp; + struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; + enum hal_rx_mon_status hal_status; + + hal_status = ath12k_wifi7_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); + if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) + return hal_status; + + list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { + list_del(&mon_mpdu->list); + + if (mon_mpdu->head && mon_mpdu->tail) + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); + + kfree(mon_mpdu); + } + + return hal_status; +} + +static int +ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) +{ + const struct ath12k_hw_hal_params *hal_params; + int buf_id, srng_id, num_buffs_reaped = 0; + enum dp_mon_status_buf_state reap_status; + struct dp_rxdma_mon_ring *rx_ring; + struct ath12k_mon_data *pmon; + struct ath12k_skb_rxcb *rxcb; + struct hal_tlv_64_hdr *tlv; + void *rx_mon_status_desc; + struct hal_srng *srng; + struct ath12k_dp *dp; + struct sk_buff *skb; + struct ath12k *ar; + dma_addr_t paddr; + u32 cookie; + u8 rbm; + + ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; + dp = ath12k_ab_to_dp(ab); + pmon = &ar->dp.mon_data; + srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); + rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; + + srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (*budget) { + *budget -= 1; + rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng); + if (!rx_mon_status_desc) { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + break; + } + ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, + &cookie, &rbm); + if (paddr) { + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&rx_ring->idr_lock); + skb = idr_find(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + if (!skb) { + ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n", + buf_id); + pmon->buf_state = DP_MON_STATUS_REPLINISH; + goto move_next; + } + + rxcb = ATH12K_SKB_RXCB(skb); + + dma_sync_single_for_cpu(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + tlv = (struct hal_tlv_64_hdr *)skb->data; + if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != + HAL_RX_STATUS_BUFFER_DONE) { + pmon->buf_state = DP_MON_STATUS_NO_DMA; + ath12k_warn(ab, + "mon status DONE not set %llx, buf_id %d\n", + le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG), + buf_id); + /* RxDMA status done bit might not be set even + * though tp is moved by HW. + */ + + /* If done status is missing: + * 1. As per MAC team's suggestion, + * when HP + 1 entry is peeked and if DMA + * is not done and if HP + 2 entry's DMA done + * is set. skip HP + 1 entry and + * start processing in next interrupt. + * 2. If HP + 2 entry's DMA done is not set, + * poll onto HP + 1 entry DMA done to be set. + * Check status for same buffer for next time + * dp_rx_mon_status_srng_process + */ + reap_status = ath12k_wifi7_dp_rx_mon_buf_done(ab, srng, + rx_ring); + if (reap_status == DP_MON_STATUS_NO_DMA) + continue; + + spin_lock_bh(&rx_ring->idr_lock); + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + dev_kfree_skb_any(skb); + pmon->buf_state = DP_MON_STATUS_REPLINISH; + goto move_next; + } + + spin_lock_bh(&rx_ring->idr_lock); + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) { + dev_kfree_skb_any(skb); + goto move_next; + } + __skb_queue_tail(skb_list, skb); + } else { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + } +move_next: + skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, + &buf_id); + hal_params = ab->hal.hal_params; + + if (!skb) { + ath12k_warn(ab, "failed to alloc buffer for status ring\n"); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, + 0, 0, + hal_params->rx_buf_rbm); + num_buffs_reaped++; + break; + } + rxcb = ATH12K_SKB_RXCB(skb); + + cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | + u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); + + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, + cookie, hal_params->rx_buf_rbm); + ath12k_hal_srng_src_get_next_entry(ab, srng); + num_buffs_reaped++; + } + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + return num_buffs_reaped; +} + static int __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, struct napi_struct *napi, int *budget) @@ -26,8 +410,8 @@ __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, __skb_queue_head_init(&skb_list); - num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, - budget, &skb_list); + num_buffs_reaped = ath12k_wifi7_dp_rx_reap_mon_status_ring(ar->ab, mac_id, + budget, &skb_list); if (!num_buffs_reaped) goto exit; @@ -35,14 +419,14 @@ __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; - hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); + hal_status = ath12k_wifi7_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); if (ar->monitor_started && pmon->mon_ppdu_status == DP_PPDU_STATUS_START && hal_status == HAL_TLV_STATUS_PPDU_DONE) { rx_mon_stats->status_ppdu_done++; pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; - ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); + ath12k_wifi7_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -167,10 +551,11 @@ ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, * the memset of the ppdu_info structure and continue processing it. */ if (!ppdu_info->ppdu_continuation) - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + ath12k_wifi7_dp_mon_rx_memset_ppdu_info(ppdu_info); while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); + hal_status = ath12k_wifi7_dp_mon_rx_parse_mon_status(pdev_dp, pmon, + skb, napi); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ppdu_info->ppdu_continuation = true; dev_kfree_skb_any(skb); @@ -201,7 +586,7 @@ ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + ath12k_wifi7_dp_mon_rx_memset_ppdu_info(ppdu_info); } return num_buffs_reaped; From c1c542350d7a33199ec8c20f18a720eb37d4dd56 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:04 +0530 Subject: [PATCH 457/659] wifi: ath12k: Move MPDU pop functionality to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor code from ath12k common code to improve modularity. Move the following monitor MPDU pop function to the new file wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_rx_mon_mpdu_pop() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-4-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 207 +----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 15 +- drivers/net/wireless/ath/ath12k/hal.h | 5 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 201 ++++++++++++++++- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 11 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 5 - 7 files changed, 230 insertions(+), 217 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index dfcca4ac02e39..370fe9449f0c5 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,16 +17,6 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) -static bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - static void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -1837,7 +1827,7 @@ struct sk_buff } EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf); -static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) +u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) { u32 ret = 0; @@ -1856,8 +1846,8 @@ static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } return ret; } +EXPORT_SYMBOL(ath12k_dp_mon_comp_ppduid); -static void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, struct hal_rx_msdu_link *msdu_link, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, @@ -1871,6 +1861,7 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, *pp_buf_addr_info = buf_addr_info; } +EXPORT_SYMBOL(ath12k_dp_mon_next_link_desc_get); static void ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, @@ -2434,7 +2425,7 @@ EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); */ #define RXDMA_DATA_DMA_BLOCK_SIZE 128 -static void +void ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, bool *is_frag, u32 *total_len, u32 *frag_len, u32 *msdu_cnt) @@ -2454,6 +2445,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, *msdu_cnt -= 1; } } +EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); static int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, @@ -3683,192 +3675,3 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); - -u32 -ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, - void *ring_entry, struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, - struct list_head *used_list, - u32 *npackets, u32 *ppdu_id) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; - u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; - u32 rx_buf_size, rx_pkt_offset, sw_cookie; - bool is_frag, is_first_msdu, drop_mpdu = false; - struct hal_reo_entrance_ring *ent_desc = - (struct hal_reo_entrance_ring *)ring_entry; - u32 rx_bufs_used = 0, i = 0, desc_bank = 0; - struct hal_rx_desc *rx_desc, *tail_rx_desc; - struct hal_rx_msdu_link *msdu_link_desc; - struct sk_buff *msdu = NULL, *last = NULL; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_buffer_addr buf_info; - struct hal_rx_msdu_list msdu_list; - struct ath12k_skb_rxcb *rxcb; - u16 num_msdus = 0; - dma_addr_t paddr; - u8 rbm; - - ath12k_hal_rx_reo_ent_buf_paddr_get(&ab->hal, ring_entry, &paddr, - &sw_cookie, - &p_last_buf_addr_info, &rbm, - &msdu_cnt); - - spin_lock_bh(&pmon->mon_lock); - - if (le32_get_bits(ent_desc->info1, - HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) == - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { - u8 rxdma_err = le32_get_bits(ent_desc->info1, - HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE); - if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR || - rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR || - rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) { - drop_mpdu = true; - pmon->rx_mon_stats.dest_mpdu_drop++; - } - } - - is_frag = false; - is_first_msdu = true; - rx_pkt_offset = sizeof(struct hal_rx_desc); - - do { - if (pmon->mon_last_linkdesc_paddr == paddr) { - pmon->rx_mon_stats.dup_mon_linkdesc_cnt++; - spin_unlock_bh(&pmon->mon_lock); - return rx_bufs_used; - } - - desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); - msdu_link_desc = - dp->link_desc_banks[desc_bank].vaddr + - (paddr - dp->link_desc_banks[desc_bank].paddr); - - ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, - &num_msdus); - desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, - msdu_list.sw_cookie[num_msdus - 1]); - tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; - - for (i = 0; i < num_msdus; i++) { - u32 l2_hdr_offset; - - if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d last_cookie %d is same\n", - i, pmon->mon_last_buf_cookie); - drop_mpdu = true; - pmon->rx_mon_stats.dup_mon_buf_cnt++; - continue; - } - - desc_info = - ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); - msdu = desc_info->skb; - - if (!msdu) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "msdu_pop: invalid msdu (%d/%d)\n", - i + 1, num_msdus); - goto next_msdu; - } - rxcb = ATH12K_SKB_RXCB(msdu); - if (rxcb->paddr != msdu_list.paddr[i]) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d paddr %lx != %lx\n", - i, (unsigned long)rxcb->paddr, - (unsigned long)msdu_list.paddr[i]); - drop_mpdu = true; - continue; - } - if (!rxcb->unmapped) { - dma_unmap_single(ar->ab->dev, rxcb->paddr, - msdu->len + - skb_tailroom(msdu), - DMA_FROM_DEVICE); - rxcb->unmapped = 1; - } - if (drop_mpdu) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d drop msdu %p *ppdu_id %x\n", - i, msdu, *ppdu_id); - dev_kfree_skb_any(msdu); - msdu = NULL; - goto next_msdu; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc); - if (is_first_msdu) { - if (!ath12k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) { - drop_mpdu = true; - dev_kfree_skb_any(msdu); - msdu = NULL; - pmon->mon_last_linkdesc_paddr = paddr; - goto next_msdu; - } - msdu_ppdu_id = - ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); - - if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id, - ppdu_id)) { - spin_unlock_bh(&pmon->mon_lock); - return rx_bufs_used; - } - pmon->mon_last_linkdesc_paddr = paddr; - is_first_msdu = false; - } - ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], - &is_frag, &total_len, - &frag_len, &msdu_cnt); - rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; - - if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { - dev_kfree_skb_any(msdu); - goto next_msdu; - } - - if (!(*head_msdu)) - *head_msdu = msdu; - else if (last) - last->next = msdu; - - last = msdu; -next_msdu: - pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i]; - rx_bufs_used++; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, used_list); - } - - ath12k_hal_rx_buf_addr_info_set(&ab->hal, &buf_info, paddr, - sw_cookie, rbm); - - ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, - &sw_cookie, &rbm, - &p_buf_addr_info); - - ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - - p_last_buf_addr_info = p_buf_addr_info; - - } while (paddr && msdu_cnt); - - spin_unlock_bh(&pmon->mon_lock); - - if (last) - last->next = NULL; - - *tail_msdu = msdu; - - if (msdu_cnt == 0) - *npackets = 1; - - return rx_bufs_used; -} -EXPORT_SYMBOL(ath12k_dp_rx_mon_mpdu_pop); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 726434ab74aca..425bec6f0f3ca 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -101,12 +101,6 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); -u32 -ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, - void *ring_entry, struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, - struct list_head *used_list, - u32 *npackets, u32 *ppdu_id); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, @@ -125,4 +119,13 @@ struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id); +void +ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, + bool *is_frag, u32 *total_len, + u32 *frag_len, u32 *msdu_cnt); +void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, + dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, + struct ath12k_buffer_addr **pp_buf_addr_info); +u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 071f4897e4cd0..1d22173975f0f 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -592,6 +592,11 @@ struct hal_rx_eht_info { u32 user_info[EHT_MAX_USER_INFO]; }; +struct hal_rx_msdu_desc_info { + u32 msdu_flags; + u16 msdu_len; /* 14 bits for length */ +}; + struct hal_rx_mon_ppdu_info { u32 ppdu_id; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index ffebeb1652e7b..dae3f262cc507 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -19,6 +19,196 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static u32 +ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, + void *ring_entry, struct sk_buff **head_msdu, + struct sk_buff **tail_msdu, + struct list_head *used_list, + u32 *npackets, u32 *ppdu_id) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; + u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; + u32 rx_buf_size, rx_pkt_offset, sw_cookie; + bool is_frag, is_first_msdu, drop_mpdu = false; + struct hal_reo_entrance_ring *ent_desc = + (struct hal_reo_entrance_ring *)ring_entry; + u32 rx_bufs_used = 0, i = 0, desc_bank = 0; + struct hal_rx_desc *rx_desc, *tail_rx_desc; + struct hal_rx_msdu_link *msdu_link_desc; + struct sk_buff *msdu = NULL, *last = NULL; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_buffer_addr buf_info; + struct hal_rx_msdu_list msdu_list; + struct ath12k_skb_rxcb *rxcb; + u16 num_msdus = 0; + dma_addr_t paddr; + u8 rbm; + + ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr, + &sw_cookie, + &p_last_buf_addr_info, + &rbm, + &msdu_cnt); + + spin_lock_bh(&pmon->mon_lock); + + if (le32_get_bits(ent_desc->info1, + HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) == + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { + u8 rxdma_err = le32_get_bits(ent_desc->info1, + HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE); + if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR || + rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR || + rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) { + drop_mpdu = true; + pmon->rx_mon_stats.dest_mpdu_drop++; + } + } + + is_frag = false; + is_first_msdu = true; + rx_pkt_offset = sizeof(struct hal_rx_desc); + + do { + if (pmon->mon_last_linkdesc_paddr == paddr) { + pmon->rx_mon_stats.dup_mon_linkdesc_cnt++; + spin_unlock_bh(&pmon->mon_lock); + return rx_bufs_used; + } + + desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); + msdu_link_desc = + dp->link_desc_banks[desc_bank].vaddr + + (paddr - dp->link_desc_banks[desc_bank].paddr); + + ath12k_wifi7_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, + &num_msdus); + desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, + msdu_list.sw_cookie[num_msdus - 1]); + tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; + + for (i = 0; i < num_msdus; i++) { + u32 l2_hdr_offset; + + if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d last_cookie %d is same\n", + i, pmon->mon_last_buf_cookie); + drop_mpdu = true; + pmon->rx_mon_stats.dup_mon_buf_cnt++; + continue; + } + + desc_info = + ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); + msdu = desc_info->skb; + + if (!msdu) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "msdu_pop: invalid msdu (%d/%d)\n", + i + 1, num_msdus); + goto next_msdu; + } + rxcb = ATH12K_SKB_RXCB(msdu); + if (rxcb->paddr != msdu_list.paddr[i]) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d paddr %lx != %lx\n", + i, (unsigned long)rxcb->paddr, + (unsigned long)msdu_list.paddr[i]); + drop_mpdu = true; + continue; + } + if (!rxcb->unmapped) { + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + + skb_tailroom(msdu), + DMA_FROM_DEVICE); + rxcb->unmapped = 1; + } + if (drop_mpdu) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d drop msdu %p *ppdu_id %x\n", + i, msdu, *ppdu_id); + dev_kfree_skb_any(msdu); + msdu = NULL; + goto next_msdu; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc); + if (is_first_msdu) { + if (!ath12k_wifi7_dp_rxdesc_mpdu_valid(ar->ab, + rx_desc)) { + drop_mpdu = true; + dev_kfree_skb_any(msdu); + msdu = NULL; + pmon->mon_last_linkdesc_paddr = paddr; + goto next_msdu; + } + msdu_ppdu_id = + ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); + + if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id, + ppdu_id)) { + spin_unlock_bh(&pmon->mon_lock); + return rx_bufs_used; + } + pmon->mon_last_linkdesc_paddr = paddr; + is_first_msdu = false; + } + ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], + &is_frag, &total_len, + &frag_len, &msdu_cnt); + rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; + + if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { + dev_kfree_skb_any(msdu); + goto next_msdu; + } + + if (!(*head_msdu)) + *head_msdu = msdu; + else if (last) + last->next = msdu; + + last = msdu; +next_msdu: + pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i]; + rx_bufs_used++; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, used_list); + } + + ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, + sw_cookie, rbm); + + ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, + &sw_cookie, &rbm, + &p_buf_addr_info); + + ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + + p_last_buf_addr_info = p_buf_addr_info; + + } while (paddr && msdu_cnt); + + spin_unlock_bh(&pmon->mon_lock); + + if (last) + last->next = NULL; + + *tail_msdu = msdu; + + if (msdu_cnt == 0) + *npackets = 1; + + return rx_bufs_used; +} + /* The destination ring processing is stuck if the destination is not * moving while status ring moves 16 PPDU. The destination ring processing * skips this destination ring PPDU as a workaround. @@ -58,10 +248,13 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, head_msdu = NULL; tail_msdu = NULL; - mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, - &head_msdu, &tail_msdu, - &rx_desc_used_list, - &npackets, &ppdu_id); + mpdu_rx_bufs_used = ath12k_wifi7_dp_rx_mon_mpdu_pop(ar, mac_id, + ring_entry, + &head_msdu, + &tail_msdu, + &rx_desc_used_list, + &npackets, + &ppdu_id); rx_bufs_used += mpdu_rx_bufs_used; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 2138b20a04d57..08dcf170b801d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2141,3 +2141,14 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) spin_unlock_bh(&srng->lock); } + +bool +ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index b92f9cf173dc8..2d3eb2313b2f7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -49,6 +49,9 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); +bool +ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc); static inline void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, struct hal_rx_desc_data *rx_info, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index c0d57d9b1009d..4a0beb4d192ef 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -314,11 +314,6 @@ struct hal_rx_rxpcu_classification_overview { u32 rsvd0; } __packed; -struct hal_rx_msdu_desc_info { - u32 msdu_flags; - u16 msdu_len; /* 14 bits for length */ -}; - #define HAL_RX_NUM_MSDU_DESC 6 struct hal_rx_msdu_list { struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC]; From 80911306c0d9feaaa6af26ba7e6f94ce18f64d9d Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:05 +0530 Subject: [PATCH 458/659] wifi: ath12k: Move RX status TLV parsing to Wi-Fi 7 module Split Wi-Fi 7-specific monitor code out of ath12k common code to improve modularity. Move following RX status TLV parsing functions to the new file wifi7/dp_mon.c and rename the helpers with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_parse_status_tlv() - ath12k_dp_mon_parse_rx_dest_tlv() Export helper functions required by the Wi-Fi 7 module. Temporarily include wifi7/hal_rx.h from dp_mon.h to provide HAL structure definitions; remove this dependency in a later patch. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-5-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 371 ++---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 59 ++- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 319 ++++++++++++++- 3 files changed, 405 insertions(+), 344 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 370fe9449f0c5..417929d937ed3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,7 +17,7 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) -static void +void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) { @@ -26,6 +26,7 @@ ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_handle_ofdma_info); static void ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, @@ -40,7 +41,7 @@ ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *st HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); } -static void +void ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, struct hal_rx_user_status *rx_user_status) @@ -78,9 +79,10 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 nsts, info0, info1; u8 gi_setting; @@ -118,9 +120,10 @@ static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vh ppdu_info->vht_flag_values4 = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_vht_sig_a); -static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(ht_sig->info0); u32 info1 = __le32_to_cpu(ht_sig->info1); @@ -132,9 +135,10 @@ static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_ht_sig); -static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(lsigb->info0); u8 rate; @@ -163,9 +167,10 @@ static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, ppdu_info->rate = rate; ppdu_info->cck_flag = 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b); -static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(lsiga->info0); u8 rate; @@ -202,8 +207,9 @@ static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, ppdu_info->rate = rate; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); -static void +void ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -240,8 +246,9 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of ppdu_info->beamformed = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_ofdma); -static void +void ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -268,8 +275,9 @@ ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_mu); -static void +void ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -281,8 +289,9 @@ ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); ppdu_info->he_RU[0] = ru_tones; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b1_mu); -static void +void ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -414,9 +423,10 @@ ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_ ppdu_info->is_stbc = info1 & HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu); -static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0, info1, value; u32 dcm; @@ -562,6 +572,7 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info * HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1; ppdu_info->dcm = dcm; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_su); static void ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, @@ -736,7 +747,7 @@ ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, usig->mask = cpu_to_le32(mask); } -static void +void ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -754,8 +765,9 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, else ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); } +EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); -static void +void ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, u16 tlv_len, const void *tlv_data) { @@ -765,6 +777,7 @@ ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, ppdu_info->tlv_aggr.cur_len += tlv_len; } } +EXPORT_SYMBOL(ath12k_dp_mon_hal_aggr_tlv); static inline bool ath12k_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) @@ -1122,7 +1135,7 @@ ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, ppdu_info); } -static void +void ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, const void *tlv_data) { @@ -1135,6 +1148,7 @@ ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr); static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) @@ -1220,7 +1234,7 @@ hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) } } -static void +void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -1421,6 +1435,7 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_ mon_rx_user_status->ofdma_info_valid = 1; } } +EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_user_info); static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) { @@ -1474,7 +1489,7 @@ ath12k_parse_cmn_usr_info(const struct hal_phyrx_common_user_info *cmn_usr_info, ppdu_info->gi = cp_setting; } -static void +void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end) { @@ -1483,277 +1498,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, pmon->decap_format = le32_get_bits(msdu_end->info1, RX_MSDU_END_INFO11_DECAP_FORMAT); } - -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - const struct hal_tlv_64_hdr *tlv) -{ - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - const void *tlv_data = tlv->value; - u32 info[7], userid; - u16 tlv_tag, tlv_len; - - tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); - tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); - - if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { - ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); - - ppdu_info->tlv_aggr.in_progress = false; - ppdu_info->tlv_aggr.cur_len = 0; - } - - switch (tlv_tag) { - case HAL_RX_PPDU_START: { - const struct hal_rx_ppdu_start *ppdu_start = tlv_data; - - u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32, - ppdu_start->ppdu_start_ts_31_0); - - info[0] = __le32_to_cpu(ppdu_start->info0); - - ppdu_info->ppdu_id = u32_get_bits(info[0], - HAL_RX_PPDU_START_INFO0_PPDU_ID); - - info[1] = __le32_to_cpu(ppdu_start->info1); - ppdu_info->chan_num = u32_get_bits(info[1], - HAL_RX_PPDU_START_INFO1_CHAN_NUM); - ppdu_info->freq = u32_get_bits(info[1], - HAL_RX_PPDU_START_INFO1_CHAN_FREQ); - ppdu_info->ppdu_ts = ppdu_ts; - - if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { - ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; - ppdu_info->num_users = 0; - memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, - HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * - sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - } - break; - } - case HAL_RX_PPDU_END_USER_STATS: { - const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data; - u32 tid_bitmap; - - info[0] = __le32_to_cpu(eu_stats->info0); - info[1] = __le32_to_cpu(eu_stats->info1); - info[2] = __le32_to_cpu(eu_stats->info2); - info[4] = __le32_to_cpu(eu_stats->info4); - info[5] = __le32_to_cpu(eu_stats->info5); - info[6] = __le32_to_cpu(eu_stats->info6); - - ppdu_info->ast_index = - u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); - ppdu_info->fc_valid = - u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); - tid_bitmap = u32_get_bits(info[6], - HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP); - ppdu_info->tid = ffs(tid_bitmap) - 1; - ppdu_info->tcp_msdu_count = - u32_get_bits(info[4], - HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); - ppdu_info->udp_msdu_count = - u32_get_bits(info[4], - HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); - ppdu_info->other_msdu_count = - u32_get_bits(info[5], - HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); - ppdu_info->tcp_ack_msdu_count = - u32_get_bits(info[5], - HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); - ppdu_info->preamble_type = - u32_get_bits(info[1], - HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); - ppdu_info->num_mpdu_fcs_ok = - u32_get_bits(info[1], - HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); - ppdu_info->num_mpdu_fcs_err = - u32_get_bits(info[0], - HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); - ppdu_info->peer_id = - u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID); - - switch (ppdu_info->preamble_type) { - case HAL_RX_PREAMBLE_11N: - ppdu_info->ht_flags = 1; - break; - case HAL_RX_PREAMBLE_11AC: - ppdu_info->vht_flags = 1; - break; - case HAL_RX_PREAMBLE_11AX: - ppdu_info->he_flags = 1; - break; - case HAL_RX_PREAMBLE_11BE: - ppdu_info->is_eht = true; - break; - default: - break; - } - - if (userid < HAL_MAX_UL_MU_USERS) { - struct hal_rx_user_status *rxuser_stats = - &ppdu_info->userstats[userid]; - - if (ppdu_info->num_mpdu_fcs_ok > 1 || - ppdu_info->num_mpdu_fcs_err > 1) - ppdu_info->userstats[userid].ampdu_present = true; - - ppdu_info->num_users += 1; - - ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); - ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, - rxuser_stats); - } - ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); - ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); - break; - } - case HAL_RX_PPDU_END_USER_STATS_EXT: { - const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data; - - ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); - ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); - ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); - ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); - ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); - ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); - break; - } - case HAL_PHYRX_HT_SIG: - ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_RSSI_LEGACY: { - const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; - - info[0] = __le32_to_cpu(rssi->info0); - info[2] = __le32_to_cpu(rssi->info2); - - /* TODO: Please note that the combined rssi will not be accurate - * in MU case. Rssi in MU needs to be retrieved from - * PHYRX_OTHER_RECEIVE_INFO TLV. - */ - ppdu_info->rssi_comb = - u32_get_bits(info[2], - HAL_RX_RSSI_LEGACY_INFO_INFO2_RSSI_COMB_PPDU); - - ppdu_info->bw = u32_get_bits(info[0], - HAL_RX_RSSI_LEGACY_INFO_INFO0_RX_BW); - break; - } - case HAL_PHYRX_COMMON_USER_INFO: { - ath12k_parse_cmn_usr_info(tlv_data, ppdu_info); - break; - } - case HAL_RX_PPDU_START_USER_INFO: - ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); - break; - - case HAL_RXPCU_PPDU_END_INFO: { - const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data; - - info[0] = __le32_to_cpu(ppdu_rx_duration->info0); - ppdu_info->rx_duration = - u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION); - ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); - ppdu_info->tsft = (ppdu_info->tsft << 32) | - __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); - break; - } - case HAL_RX_MPDU_START: { - const struct hal_rx_mpdu_start *mpdu_start = tlv_data; - u16 peer_id; - - info[1] = __le32_to_cpu(mpdu_start->info1); - peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID); - if (peer_id) - ppdu_info->peer_id = peer_id; - - ppdu_info->mpdu_len += u32_get_bits(info[1], - HAL_RX_MPDU_START_INFO2_MPDU_LEN); - if (userid < HAL_MAX_UL_MU_USERS) { - info[0] = __le32_to_cpu(mpdu_start->info0); - ppdu_info->userid = userid; - ppdu_info->userstats[userid].ampdu_id = - u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); - } - - return HAL_RX_MON_STATUS_MPDU_START; - } - case HAL_RX_MSDU_START: - /* TODO: add msdu start parsing logic */ - break; - case HAL_MON_BUF_ADDR: - return HAL_RX_MON_STATUS_BUF_ADDR; - case HAL_RX_MSDU_END: - ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); - return HAL_RX_MON_STATUS_MSDU_END; - case HAL_RX_MPDU_END: - return HAL_RX_MON_STATUS_MPDU_END; - case HAL_PHYRX_GENERIC_U_SIG: - ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); - break; - case HAL_PHYRX_GENERIC_EHT_SIG: - /* Handle the case where aggregation is in progress - * or the current TLV is one of the TLVs which should be - * aggregated - */ - if (!ppdu_info->tlv_aggr.in_progress) { - ppdu_info->tlv_aggr.in_progress = true; - ppdu_info->tlv_aggr.tlv_tag = tlv_tag; - ppdu_info->tlv_aggr.cur_len = 0; - } - - ppdu_info->is_eht = true; - - ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); - break; - case HAL_DUMMY: - return HAL_RX_MON_STATUS_BUF_DONE; - case HAL_RX_PPDU_END_STATUS_DONE: - case 0: - return HAL_RX_MON_STATUS_PPDU_DONE; - default: - break; - } - - return HAL_RX_MON_STATUS_PPDU_NOT_DONE; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv); +EXPORT_SYMBOL(ath12k_dp_mon_parse_status_msdu_end); static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, @@ -2447,7 +2192,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, } EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); -static int +int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info) @@ -2492,45 +2237,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } - -int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - enum hal_rx_mon_status hal_status, - const void *tlv_data) -{ - switch (hal_status) { - case HAL_RX_MON_STATUS_MPDU_START: - if (WARN_ON_ONCE(pmon->mon_mpdu)) - break; - - pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC); - if (!pmon->mon_mpdu) - return -ENOMEM; - break; - case HAL_RX_MON_STATUS_BUF_ADDR: - return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); - case HAL_RX_MON_STATUS_MPDU_END: - /* If no MSDU then free empty MPDU */ - if (pmon->mon_mpdu->tail) { - pmon->mon_mpdu->tail->next = NULL; - list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list); - } else { - kfree(pmon->mon_mpdu); - } - pmon->mon_mpdu = NULL; - break; - case HAL_RX_MON_STATUS_MSDU_END: - pmon->mon_mpdu->decap_format = pmon->decap_format; - pmon->mon_mpdu->err_bitmap = pmon->err_bitmap; - break; - default: - break; - } - - return 0; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest_tlv); +EXPORT_SYMBOL(ath12k_dp_mon_parse_status_buf); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 425bec6f0f3ca..bfea7d4041cb9 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -9,6 +9,7 @@ #include "core.h" #include "wifi7/hal_desc.h" +#include "wifi7/hal_rx.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 @@ -106,15 +107,6 @@ int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppduinfo, struct napi_struct *napi); -int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - enum hal_rx_mon_status hal_status, - const void *tlv_data); -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - const struct hal_tlv_64_hdr *tlv); struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, @@ -128,4 +120,53 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, struct ath12k_buffer_addr **pp_buf_addr_info); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); +int +ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct dp_mon_packet_info *packet_info); +void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, + const void *tlv_data); +void +ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, + struct hal_rx_user_status *rx_user_status); +void +ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct hal_rx_user_status *rx_user_status); +void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, + u16 user_id, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end); +void +ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, + u16 tlv_len, const void *tlv_data); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index dae3f262cc507..076fb75a101f1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -10,6 +10,7 @@ #include "../debug.h" #include "hal_qcn9274.h" #include "dp_rx.h" +#include "../dp_tx.h" #include "../peer.h" static void @@ -19,6 +20,317 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct hal_tlv_64_hdr *tlv) +{ + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + const void *tlv_data = tlv->value; + u32 info[7], userid; + u16 tlv_tag, tlv_len; + + tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); + tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); + userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); + + if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { + ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); + + ppdu_info->tlv_aggr.in_progress = false; + ppdu_info->tlv_aggr.cur_len = 0; + } + + switch (tlv_tag) { + case HAL_RX_PPDU_START: { + const struct hal_rx_ppdu_start *ppdu_start = tlv_data; + + u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32, + ppdu_start->ppdu_start_ts_31_0); + + info[0] = __le32_to_cpu(ppdu_start->info0); + + ppdu_info->ppdu_id = u32_get_bits(info[0], + HAL_RX_PPDU_START_INFO0_PPDU_ID); + + info[1] = __le32_to_cpu(ppdu_start->info1); + ppdu_info->chan_num = u32_get_bits(info[1], + HAL_RX_PPDU_START_INFO1_CHAN_NUM); + ppdu_info->freq = u32_get_bits(info[1], + HAL_RX_PPDU_START_INFO1_CHAN_FREQ); + ppdu_info->ppdu_ts = ppdu_ts; + + if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { + ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; + ppdu_info->num_users = 0; + memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + } + break; + } + case HAL_RX_PPDU_END_USER_STATS: { + const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data; + u32 tid_bitmap; + + info[0] = __le32_to_cpu(eu_stats->info0); + info[1] = __le32_to_cpu(eu_stats->info1); + info[2] = __le32_to_cpu(eu_stats->info2); + info[4] = __le32_to_cpu(eu_stats->info4); + info[5] = __le32_to_cpu(eu_stats->info5); + info[6] = __le32_to_cpu(eu_stats->info6); + + ppdu_info->ast_index = + u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); + ppdu_info->fc_valid = + u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); + tid_bitmap = u32_get_bits(info[6], + HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP); + ppdu_info->tid = ffs(tid_bitmap) - 1; + ppdu_info->tcp_msdu_count = + u32_get_bits(info[4], + HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); + ppdu_info->udp_msdu_count = + u32_get_bits(info[4], + HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); + ppdu_info->other_msdu_count = + u32_get_bits(info[5], + HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); + ppdu_info->tcp_ack_msdu_count = + u32_get_bits(info[5], + HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); + ppdu_info->preamble_type = + u32_get_bits(info[1], + HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); + ppdu_info->num_mpdu_fcs_ok = + u32_get_bits(info[1], + HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); + ppdu_info->num_mpdu_fcs_err = + u32_get_bits(info[0], + HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); + ppdu_info->peer_id = + u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID); + + switch (ppdu_info->preamble_type) { + case HAL_RX_PREAMBLE_11N: + ppdu_info->ht_flags = 1; + break; + case HAL_RX_PREAMBLE_11AC: + ppdu_info->vht_flags = 1; + break; + case HAL_RX_PREAMBLE_11AX: + ppdu_info->he_flags = 1; + break; + case HAL_RX_PREAMBLE_11BE: + ppdu_info->is_eht = true; + break; + default: + break; + } + + if (userid < HAL_MAX_UL_MU_USERS) { + struct hal_rx_user_status *rxuser_stats = + &ppdu_info->userstats[userid]; + + if (ppdu_info->num_mpdu_fcs_ok > 1 || + ppdu_info->num_mpdu_fcs_err > 1) + ppdu_info->userstats[userid].ampdu_present = true; + + ppdu_info->num_users += 1; + + ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); + ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, + rxuser_stats); + } + ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); + ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); + break; + } + case HAL_RX_PPDU_END_USER_STATS_EXT: { + const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data; + + ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); + ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); + ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); + ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); + ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); + ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); + break; + } + case HAL_PHYRX_HT_SIG: + ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_L_SIG_B: + ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_L_SIG_A: + ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_VHT_SIG_A: + ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_A_SU: + ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_A_MU_DL: + ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B1_MU: + ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B2_MU: + ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B2_OFDMA: + ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_RSSI_LEGACY: { + const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; + + info[0] = __le32_to_cpu(rssi->info0); + info[1] = __le32_to_cpu(rssi->info1); + + /* TODO: Please note that the combined rssi will not be accurate + * in MU case. Rssi in MU needs to be retrieved from + * PHYRX_OTHER_RECEIVE_INFO TLV. + */ + ppdu_info->rssi_comb = + u32_get_bits(info[1], + HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB); + + ppdu_info->bw = u32_get_bits(info[0], + HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW); + break; + } + case HAL_PHYRX_OTHER_RECEIVE_INFO: { + const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data; + + ppdu_info->gi = le32_get_bits(cmn_usr_info->info0, + HAL_RX_PHY_CMN_USER_INFO0_GI); + break; + } + case HAL_RX_PPDU_START_USER_INFO: + ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); + break; + + case HAL_RXPCU_PPDU_END_INFO: { + const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data; + + info[0] = __le32_to_cpu(ppdu_rx_duration->info0); + ppdu_info->rx_duration = + u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION); + ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); + ppdu_info->tsft = (ppdu_info->tsft << 32) | + __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); + break; + } + case HAL_RX_MPDU_START: { + const struct hal_rx_mpdu_start *mpdu_start = tlv_data; + u16 peer_id; + + info[1] = __le32_to_cpu(mpdu_start->info1); + peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID); + if (peer_id) + ppdu_info->peer_id = peer_id; + + ppdu_info->mpdu_len += u32_get_bits(info[1], + HAL_RX_MPDU_START_INFO2_MPDU_LEN); + if (userid < HAL_MAX_UL_MU_USERS) { + info[0] = __le32_to_cpu(mpdu_start->info0); + ppdu_info->userid = userid; + ppdu_info->userstats[userid].ampdu_id = + u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); + } + + return HAL_RX_MON_STATUS_MPDU_START; + } + case HAL_RX_MSDU_START: + /* TODO: add msdu start parsing logic */ + break; + case HAL_MON_BUF_ADDR: + return HAL_RX_MON_STATUS_BUF_ADDR; + case HAL_RX_MSDU_END: + ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); + return HAL_RX_MON_STATUS_MSDU_END; + case HAL_RX_MPDU_END: + return HAL_RX_MON_STATUS_MPDU_END; + case HAL_PHYRX_GENERIC_U_SIG: + ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); + break; + case HAL_PHYRX_GENERIC_EHT_SIG: + /* Handle the case where aggregation is in progress + * or the current TLV is one of the TLVs which should be + * aggregated + */ + if (!ppdu_info->tlv_aggr.in_progress) { + ppdu_info->tlv_aggr.in_progress = true; + ppdu_info->tlv_aggr.tlv_tag = tlv_tag; + ppdu_info->tlv_aggr.cur_len = 0; + } + + ppdu_info->is_eht = true; + + ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); + break; + case HAL_DUMMY: + return HAL_RX_MON_STATUS_BUF_DONE; + case HAL_RX_PPDU_END_STATUS_DONE: + case 0: + return HAL_RX_MON_STATUS_PPDU_DONE; + default: + break; + } + + return HAL_RX_MON_STATUS_PPDU_NOT_DONE; +} + +static int +ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + enum hal_rx_mon_status hal_status, + const void *tlv_data) +{ + switch (hal_status) { + case HAL_RX_MON_STATUS_MPDU_START: + if (WARN_ON_ONCE(pmon->mon_mpdu)) + break; + + pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC); + if (!pmon->mon_mpdu) + return -ENOMEM; + break; + case HAL_RX_MON_STATUS_BUF_ADDR: + return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); + case HAL_RX_MON_STATUS_MPDU_END: + /* If no MSDU then free empty MPDU */ + if (pmon->mon_mpdu->tail) { + pmon->mon_mpdu->tail->next = NULL; + list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list); + } else { + kfree(pmon->mon_mpdu); + } + pmon->mon_mpdu = NULL; + break; + case HAL_RX_MON_STATUS_MSDU_END: + pmon->mon_mpdu->decap_format = pmon->decap_format; + pmon->mon_mpdu->err_bitmap = pmon->err_bitmap; + break; + default: + break; + } + + return 0; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, @@ -389,11 +701,12 @@ ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, else tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); + hal_status = ath12k_wifi7_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, + tlv); if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, - tlv->value)) + ath12k_wifi7_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) return HAL_RX_MON_STATUS_PPDU_DONE; ptr += sizeof(*tlv) + tlv_len; From 5a96260864143ba44226c0efe14d77a1db1c5016 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:06 +0530 Subject: [PATCH 459/659] wifi: ath12k: Move TX monitor functionality to Wi-Fi 7 module Separate Wi-Fi 7-specific TX monitor functionality from ath12k common code to improve modularity and maintainability. Move following TX monitor processing functions to wifi7/dp_mon.c and rename the functions with the ath12k_wifi7_ prefix: - ath12k_dp_mon_tx_get_ppdu_info() - ath12k_dp_mon_hal_tx_ppdu_info() - ath12k_dp_mon_tx_alloc_skb() - ath12k_dp_mon_tx_gen_cts2self_frame() - ath12k_dp_mon_tx_gen_rts_frame() - ath12k_dp_mon_tx_gen_3addr_qos_null_frame() - ath12k_dp_mon_tx_gen_4addr_qos_null_frame() - ath12k_dp_mon_tx_gen_ack_frame() - ath12k_dp_mon_tx_gen_prot_frame() - ath12k_dp_mon_tx_parse_status_tlv() - ath12k_dp_mon_tx_status_get_num_user() - ath12k_dp_mon_tx_process_ppdu_info() - ath12k_dp_mon_tx_parse_mon_status() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-6-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 671 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 11 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 676 ++++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.h | 6 + 4 files changed, 682 insertions(+), 682 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 417929d937ed3..ff5a64fe6447f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2403,677 +2403,6 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, return req_entries - num_remain; } -static struct dp_mon_tx_ppdu_info * -ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, - unsigned int ppdu_id, - enum dp_mon_tx_ppdu_info_type type) -{ - struct dp_mon_tx_ppdu_info *tx_ppdu_info; - - if (type == DP_MON_TX_PROT_PPDU_INFO) { - tx_ppdu_info = pmon->tx_prot_ppdu_info; - - if (tx_ppdu_info && !tx_ppdu_info->is_used) - return tx_ppdu_info; - kfree(tx_ppdu_info); - } else { - tx_ppdu_info = pmon->tx_data_ppdu_info; - - if (tx_ppdu_info && !tx_ppdu_info->is_used) - return tx_ppdu_info; - kfree(tx_ppdu_info); - } - - /* allocate new tx_ppdu_info */ - tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); - if (!tx_ppdu_info) - return NULL; - - tx_ppdu_info->is_used = 0; - tx_ppdu_info->ppdu_id = ppdu_id; - - if (type == DP_MON_TX_PROT_PPDU_INFO) - pmon->tx_prot_ppdu_info = tx_ppdu_info; - else - pmon->tx_data_ppdu_info = tx_ppdu_info; - - return tx_ppdu_info; -} - -static struct dp_mon_tx_ppdu_info * -ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, - u16 tlv_tag) -{ - switch (tlv_tag) { - case HAL_TX_FES_SETUP: - case HAL_TX_FLUSH: - case HAL_PCU_PPDU_SETUP_INIT: - case HAL_TX_PEER_ENTRY: - case HAL_TX_QUEUE_EXTENSION: - case HAL_TX_MPDU_START: - case HAL_TX_MSDU_START: - case HAL_TX_DATA: - case HAL_MON_BUF_ADDR: - case HAL_TX_MPDU_END: - case HAL_TX_LAST_MPDU_FETCHED: - case HAL_TX_LAST_MPDU_END: - case HAL_COEX_TX_REQ: - case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: - case HAL_SCH_CRITICAL_TLV_REFERENCE: - case HAL_TX_FES_SETUP_COMPLETE: - case HAL_TQM_MPDU_GLOBAL_START: - case HAL_SCHEDULER_END: - case HAL_TX_FES_STATUS_USER_PPDU: - break; - case HAL_TX_FES_STATUS_PROT: { - if (!pmon->tx_prot_ppdu_info->is_used) - pmon->tx_prot_ppdu_info->is_used = true; - - return pmon->tx_prot_ppdu_info; - } - } - - if (!pmon->tx_data_ppdu_info->is_used) - pmon->tx_data_ppdu_info->is_used = true; - - return pmon->tx_data_ppdu_info; -} - -#define MAX_MONITOR_HEADER 512 -#define MAX_DUMMY_FRM_BODY 128 - -struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); - if (!skb) - return NULL; - - skb_reserve(skb, MAX_MONITOR_HEADER); - - if (!IS_ALIGNED((unsigned long)skb->data, 4)) - skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); - - return skb; -} - -static int -ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_cts *cts; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - cts = (struct ieee80211_cts *)skb->data; - memset(cts, 0, MAX_DUMMY_FRM_BODY); - cts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); - cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); - - skb_put(skb, sizeof(*cts)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_rts *rts; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - rts = (struct ieee80211_rts *)skb->data; - memset(rts, 0, MAX_DUMMY_FRM_BODY); - rts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); - memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); - - skb_put(skb, sizeof(*rts)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_qos_hdr *qhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - qhdr = (struct ieee80211_qos_hdr *)skb->data; - memset(qhdr, 0, MAX_DUMMY_FRM_BODY); - qhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); - qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); - memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); - - skb_put(skb, sizeof(*qhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct dp_mon_qosframe_addr4 *qhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; - memset(qhdr, 0, MAX_DUMMY_FRM_BODY); - qhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); - qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); - memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); - memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); - - skb_put(skb, sizeof(*qhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct dp_mon_frame_min_one *fbmhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - fbmhdr = (struct dp_mon_frame_min_one *)skb->data; - memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); - fbmhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); - memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - - /* set duration zero for ack frame */ - fbmhdr->duration = 0; - - skb_put(skb, sizeof(*fbmhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - int ret = 0; - - switch (tx_ppdu_info->rx_status.medium_prot_type) { - case DP_MON_TX_MEDIUM_RTS_LEGACY: - case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: - case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: - ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_CTS2SELF: - ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: - ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: - ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); - break; - } - - return ret; -} - -static enum dp_mon_tx_tlv_status -ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, - struct ath12k_mon_data *pmon, - u16 tlv_tag, const void *tlv_data, u32 userid) -{ - struct dp_mon_tx_ppdu_info *tx_ppdu_info; - enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - u32 info[7]; - - tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); - - switch (tlv_tag) { - case HAL_TX_FES_SETUP: { - const struct hal_tx_fes_setup *tx_fes_setup = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_setup->info0); - tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); - tx_ppdu_info->num_users = - u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); - status = DP_MON_TX_FES_SETUP; - break; - } - - case HAL_TX_FES_STATUS_END: { - const struct hal_tx_fes_status_end *tx_fes_status_end = tlv_data; - u32 tst_15_0, tst_31_16; - - info[0] = __le32_to_cpu(tx_fes_status_end->info0); - tst_15_0 = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); - tst_31_16 = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); - - tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); - status = DP_MON_TX_FES_STATUS_END; - break; - } - - case HAL_RX_RESPONSE_REQUIRED_INFO: { - const struct hal_rx_resp_req_info *rx_resp_req_info = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(rx_resp_req_info->info0); - info[1] = __le32_to_cpu(rx_resp_req_info->info1); - info[2] = __le32_to_cpu(rx_resp_req_info->info2); - info[3] = __le32_to_cpu(rx_resp_req_info->info3); - info[4] = __le32_to_cpu(rx_resp_req_info->info4); - info[5] = __le32_to_cpu(rx_resp_req_info->info5); - - tx_ppdu_info->rx_status.ppdu_id = - u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); - tx_ppdu_info->rx_status.reception_type = - u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); - tx_ppdu_info->rx_status.rx_duration = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION); - tx_ppdu_info->rx_status.mcs = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); - tx_ppdu_info->rx_status.sgi = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI); - tx_ppdu_info->rx_status.is_stbc = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC); - tx_ppdu_info->rx_status.ldpc = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC); - tx_ppdu_info->rx_status.is_ampdu = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); - tx_ppdu_info->rx_status.num_users = - u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); - - addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); - addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); - addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); - - if (tx_ppdu_info->rx_status.reception_type == 0) - ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); - status = DP_MON_RX_RESPONSE_REQUIRED_INFO; - break; - } - - case HAL_PCU_PPDU_SETUP_INIT: { - const struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(ppdu_setup->info0); - info[1] = __le32_to_cpu(ppdu_setup->info1); - info[2] = __le32_to_cpu(ppdu_setup->info2); - info[3] = __le32_to_cpu(ppdu_setup->info3); - info[4] = __le32_to_cpu(ppdu_setup->info4); - info[5] = __le32_to_cpu(ppdu_setup->info5); - info[6] = __le32_to_cpu(ppdu_setup->info6); - - /* protection frame address 1 */ - addr_32 = u32_get_bits(info[1], - HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); - addr_16 = u32_get_bits(info[2], - HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - /* protection frame address 2 */ - addr_16 = u32_get_bits(info[2], - HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); - addr_32 = u32_get_bits(info[3], - HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); - - /* protection frame address 3 */ - addr_32 = u32_get_bits(info[4], - HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); - addr_16 = u32_get_bits(info[5], - HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3); - - /* protection frame address 4 */ - addr_16 = u32_get_bits(info[5], - HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); - addr_32 = u32_get_bits(info[6], - HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4); - - status = u32_get_bits(info[0], - HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); - break; - } - - case HAL_TX_QUEUE_EXTENSION: { - const struct hal_tx_queue_exten *tx_q_exten = tlv_data; - - info[0] = __le32_to_cpu(tx_q_exten->info0); - - tx_ppdu_info->rx_status.frame_control = - u32_get_bits(info[0], - HAL_TX_Q_EXT_INFO0_FRAME_CTRL); - tx_ppdu_info->rx_status.fc_valid = true; - break; - } - - case HAL_TX_FES_STATUS_START: { - const struct hal_tx_fes_status_start *tx_fes_start = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_start->info0); - - tx_ppdu_info->rx_status.medium_prot_type = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); - break; - } - - case HAL_TX_FES_STATUS_PROT: { - const struct hal_tx_fes_status_prot *tx_fes_status = tlv_data; - u32 start_timestamp; - u32 end_timestamp; - - info[0] = __le32_to_cpu(tx_fes_status->info0); - info[1] = __le32_to_cpu(tx_fes_status->info1); - - start_timestamp = - u32_get_bits(info[0], - HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); - start_timestamp |= - u32_get_bits(info[0], - HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; - end_timestamp = - u32_get_bits(info[1], - HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); - end_timestamp |= - u32_get_bits(info[1], - HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; - tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; - - ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info); - break; - } - - case HAL_TX_FES_STATUS_START_PPDU: - case HAL_TX_FES_STATUS_START_PROT: { - const struct hal_tx_fes_status_start_prot *tx_fes_stat_start = tlv_data; - u64 ppdu_ts; - - info[0] = __le32_to_cpu(tx_fes_stat_start->info0); - - tx_ppdu_info->rx_status.ppdu_ts = - u32_get_bits(info[0], - HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); - ppdu_ts = (u32_get_bits(info[1], - HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); - tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; - break; - } - - case HAL_TX_FES_STATUS_USER_PPDU: { - const struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); - - tx_ppdu_info->rx_status.rx_duration = - u32_get_bits(info[0], - HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); - break; - } - - case HAL_MACTX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_RX_FRAME_BITMAP_ACK: { - const struct hal_rx_frame_bitmap_ack *fbm_ack = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(fbm_ack->info0); - info[1] = __le32_to_cpu(fbm_ack->info1); - - addr_32 = u32_get_bits(info[0], - HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); - addr_16 = u32_get_bits(info[1], - HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info); - break; - } - - case HAL_MACTX_PHY_DESC: { - const struct hal_tx_phy_desc *tx_phy_desc = tlv_data; - - info[0] = __le32_to_cpu(tx_phy_desc->info0); - info[1] = __le32_to_cpu(tx_phy_desc->info1); - info[2] = __le32_to_cpu(tx_phy_desc->info2); - info[3] = __le32_to_cpu(tx_phy_desc->info3); - - tx_ppdu_info->rx_status.beamformed = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_BF_TYPE); - tx_ppdu_info->rx_status.preamble_type = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); - tx_ppdu_info->rx_status.mcs = - u32_get_bits(info[1], - HAL_TX_PHY_DESC_INFO1_MCS); - tx_ppdu_info->rx_status.ltf_size = - u32_get_bits(info[3], - HAL_TX_PHY_DESC_INFO3_LTF_SIZE); - tx_ppdu_info->rx_status.nss = - u32_get_bits(info[2], - HAL_TX_PHY_DESC_INFO2_NSS); - tx_ppdu_info->rx_status.chan_num = - u32_get_bits(info[3], - HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); - tx_ppdu_info->rx_status.bw = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_BANDWIDTH); - break; - } - - case HAL_TX_MPDU_START: { - struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; - - mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); - if (!mon_mpdu) - return DP_MON_TX_STATUS_PPDU_NOT_DONE; - status = DP_MON_TX_MPDU_START; - break; - } - - case HAL_TX_MPDU_END: - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - break; - } - - return status; -} - -enum dp_mon_tx_tlv_status -ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, - struct hal_tlv_hdr *tx_tlv, - u8 *num_users) -{ - u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - u32 info0; - - switch (tlv_tag) { - case HAL_TX_FES_SETUP: { - struct hal_tx_fes_setup *tx_fes_setup = - (struct hal_tx_fes_setup *)tx_tlv; - - info0 = __le32_to_cpu(tx_fes_setup->info0); - - *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); - tlv_status = DP_MON_TX_FES_SETUP; - break; - } - - case HAL_RX_RESPONSE_REQUIRED_INFO: { - /* TODO: need to update *num_users */ - tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; - break; - } - } - - return tlv_status; -} - -static void -ath12k_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct dp_mon_mpdu *tmp, *mon_mpdu; - - list_for_each_entry_safe(mon_mpdu, tmp, - &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { - list_del(&mon_mpdu->list); - - if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, - &tx_ppdu_info->rx_status, napi); - - kfree(mon_mpdu); - } -} - -enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi, - u32 ppdu_id) -{ - struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; - struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; - struct hal_tlv_hdr *tlv; - u8 *ptr = skb->data; - u16 tlv_tag; - u16 tlv_len; - u32 tlv_userid = 0; - u8 num_user; - u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - - tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, - DP_MON_TX_PROT_PPDU_INFO); - if (!tx_prot_ppdu_info) - return -ENOMEM; - - tlv = (struct hal_tlv_hdr *)ptr; - tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); - - tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tlv, &num_user); - if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) - return -EINVAL; - - tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, - DP_MON_TX_DATA_PPDU_INFO); - if (!tx_data_ppdu_info) - return -ENOMEM; - - do { - tlv = (struct hal_tlv_hdr *)ptr; - tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); - tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN); - tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID); - - tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon, - tlv_tag, ptr, - tlv_userid); - ptr += tlv_len; - ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); - if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) - break; - } while (tlv_status != DP_MON_TX_FES_STATUS_END); - - ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); - ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); - - return tlv_status; -} - static void ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_stats, struct hal_rx_mon_ppdu_info *ppdu_info, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index bfea7d4041cb9..1d2ec4072a83c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -85,17 +85,6 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); -enum dp_mon_tx_tlv_status -ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, - struct hal_tlv_hdr *tx_tlv, - u8 *num_users); -enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi, - u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 076fb75a101f1..abdfd3cfd0e48 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -331,6 +331,682 @@ ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } +static struct dp_mon_tx_ppdu_info * +ath12k_wifi7_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, + unsigned int ppdu_id, + enum dp_mon_tx_ppdu_info_type type) +{ + struct dp_mon_tx_ppdu_info *tx_ppdu_info; + + if (type == DP_MON_TX_PROT_PPDU_INFO) { + tx_ppdu_info = pmon->tx_prot_ppdu_info; + + if (tx_ppdu_info && !tx_ppdu_info->is_used) + return tx_ppdu_info; + kfree(tx_ppdu_info); + } else { + tx_ppdu_info = pmon->tx_data_ppdu_info; + + if (tx_ppdu_info && !tx_ppdu_info->is_used) + return tx_ppdu_info; + kfree(tx_ppdu_info); + } + + /* allocate new tx_ppdu_info */ + tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); + if (!tx_ppdu_info) + return NULL; + + tx_ppdu_info->is_used = 0; + tx_ppdu_info->ppdu_id = ppdu_id; + + if (type == DP_MON_TX_PROT_PPDU_INFO) + pmon->tx_prot_ppdu_info = tx_ppdu_info; + else + pmon->tx_data_ppdu_info = tx_ppdu_info; + + return tx_ppdu_info; +} + +static struct dp_mon_tx_ppdu_info * +ath12k_wifi7_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, + u16 tlv_tag) +{ + switch (tlv_tag) { + case HAL_TX_FES_SETUP: + case HAL_TX_FLUSH: + case HAL_PCU_PPDU_SETUP_INIT: + case HAL_TX_PEER_ENTRY: + case HAL_TX_QUEUE_EXTENSION: + case HAL_TX_MPDU_START: + case HAL_TX_MSDU_START: + case HAL_TX_DATA: + case HAL_MON_BUF_ADDR: + case HAL_TX_MPDU_END: + case HAL_TX_LAST_MPDU_FETCHED: + case HAL_TX_LAST_MPDU_END: + case HAL_COEX_TX_REQ: + case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: + case HAL_SCH_CRITICAL_TLV_REFERENCE: + case HAL_TX_FES_SETUP_COMPLETE: + case HAL_TQM_MPDU_GLOBAL_START: + case HAL_SCHEDULER_END: + case HAL_TX_FES_STATUS_USER_PPDU: + break; + case HAL_TX_FES_STATUS_PROT: { + if (!pmon->tx_prot_ppdu_info->is_used) + pmon->tx_prot_ppdu_info->is_used = true; + + return pmon->tx_prot_ppdu_info; + } + } + + if (!pmon->tx_data_ppdu_info->is_used) + pmon->tx_data_ppdu_info->is_used = true; + + return pmon->tx_data_ppdu_info; +} + +#define MAX_MONITOR_HEADER 512 +#define MAX_DUMMY_FRM_BODY 128 + +static struct +sk_buff *ath12k_wifi7_dp_mon_tx_alloc_skb(void) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); + if (!skb) + return NULL; + + skb_reserve(skb, MAX_MONITOR_HEADER); + + if (!IS_ALIGNED((unsigned long)skb->data, 4)) + skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); + + return skb; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_cts *cts; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + cts = (struct ieee80211_cts *)skb->data; + memset(cts, 0, MAX_DUMMY_FRM_BODY); + cts->frame_control = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); + cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); + + skb_put(skb, sizeof(*cts)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_rts *rts; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + rts = (struct ieee80211_rts *)skb->data; + memset(rts, 0, MAX_DUMMY_FRM_BODY); + rts->frame_control = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); + rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); + memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); + + skb_put(skb, sizeof(*rts)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_qos_hdr *qhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + qhdr = (struct ieee80211_qos_hdr *)skb->data; + memset(qhdr, 0, MAX_DUMMY_FRM_BODY); + qhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); + qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); + memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); + + skb_put(skb, sizeof(*qhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct dp_mon_qosframe_addr4 *qhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; + memset(qhdr, 0, MAX_DUMMY_FRM_BODY); + qhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); + qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); + memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); + memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); + + skb_put(skb, sizeof(*qhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct dp_mon_frame_min_one *fbmhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + fbmhdr = (struct dp_mon_frame_min_one *)skb->data; + memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); + fbmhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); + memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + + /* set duration zero for ack frame */ + fbmhdr->duration = 0; + + skb_put(skb, sizeof(*fbmhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + int ret = 0; + + switch (tx_ppdu_info->rx_status.medium_prot_type) { + case DP_MON_TX_MEDIUM_RTS_LEGACY: + case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: + case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: + ret = ath12k_wifi7_dp_mon_tx_gen_rts_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_CTS2SELF: + ret = ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: + ret = ath12k_wifi7_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: + ret = ath12k_wifi7_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); + break; + } + + return ret; +} + +static enum dp_mon_tx_tlv_status +ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, + struct ath12k_mon_data *pmon, + u16 tlv_tag, const void *tlv_data, + u32 userid) +{ + struct dp_mon_tx_ppdu_info *tx_ppdu_info; + enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + u32 info[7]; + + tx_ppdu_info = ath12k_wifi7_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); + + switch (tlv_tag) { + case HAL_TX_FES_SETUP: { + const struct hal_tx_fes_setup *tx_fes_setup = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_setup->info0); + tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); + tx_ppdu_info->num_users = + u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); + status = DP_MON_TX_FES_SETUP; + break; + } + + case HAL_TX_FES_STATUS_END: { + const struct hal_tx_fes_status_end *tx_fes_status_end = tlv_data; + u32 tst_15_0, tst_31_16; + + info[0] = __le32_to_cpu(tx_fes_status_end->info0); + tst_15_0 = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); + tst_31_16 = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); + + tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); + status = DP_MON_TX_FES_STATUS_END; + break; + } + + case HAL_RX_RESPONSE_REQUIRED_INFO: { + const struct hal_rx_resp_req_info *rx_resp_req_info = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(rx_resp_req_info->info0); + info[1] = __le32_to_cpu(rx_resp_req_info->info1); + info[2] = __le32_to_cpu(rx_resp_req_info->info2); + info[3] = __le32_to_cpu(rx_resp_req_info->info3); + info[4] = __le32_to_cpu(rx_resp_req_info->info4); + info[5] = __le32_to_cpu(rx_resp_req_info->info5); + + tx_ppdu_info->rx_status.ppdu_id = + u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); + tx_ppdu_info->rx_status.reception_type = + u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); + tx_ppdu_info->rx_status.rx_duration = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION); + tx_ppdu_info->rx_status.mcs = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); + tx_ppdu_info->rx_status.sgi = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI); + tx_ppdu_info->rx_status.is_stbc = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC); + tx_ppdu_info->rx_status.ldpc = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC); + tx_ppdu_info->rx_status.is_ampdu = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); + tx_ppdu_info->rx_status.num_users = + u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); + + addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); + addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); + addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); + + if (tx_ppdu_info->rx_status.reception_type == 0) + ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); + status = DP_MON_RX_RESPONSE_REQUIRED_INFO; + break; + } + + case HAL_PCU_PPDU_SETUP_INIT: { + const struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(ppdu_setup->info0); + info[1] = __le32_to_cpu(ppdu_setup->info1); + info[2] = __le32_to_cpu(ppdu_setup->info2); + info[3] = __le32_to_cpu(ppdu_setup->info3); + info[4] = __le32_to_cpu(ppdu_setup->info4); + info[5] = __le32_to_cpu(ppdu_setup->info5); + info[6] = __le32_to_cpu(ppdu_setup->info6); + + /* protection frame address 1 */ + addr_32 = u32_get_bits(info[1], + HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); + addr_16 = u32_get_bits(info[2], + HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + /* protection frame address 2 */ + addr_16 = u32_get_bits(info[2], + HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); + addr_32 = u32_get_bits(info[3], + HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); + + /* protection frame address 3 */ + addr_32 = u32_get_bits(info[4], + HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); + addr_16 = u32_get_bits(info[5], + HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3); + + /* protection frame address 4 */ + addr_16 = u32_get_bits(info[5], + HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); + addr_32 = u32_get_bits(info[6], + HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4); + + status = u32_get_bits(info[0], + HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); + break; + } + + case HAL_TX_QUEUE_EXTENSION: { + const struct hal_tx_queue_exten *tx_q_exten = tlv_data; + + info[0] = __le32_to_cpu(tx_q_exten->info0); + + tx_ppdu_info->rx_status.frame_control = + u32_get_bits(info[0], + HAL_TX_Q_EXT_INFO0_FRAME_CTRL); + tx_ppdu_info->rx_status.fc_valid = true; + break; + } + + case HAL_TX_FES_STATUS_START: { + const struct hal_tx_fes_status_start *tx_fes_start = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_start->info0); + + tx_ppdu_info->rx_status.medium_prot_type = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); + break; + } + + case HAL_TX_FES_STATUS_PROT: { + const struct hal_tx_fes_status_prot *tx_fes_status = tlv_data; + u32 start_timestamp; + u32 end_timestamp; + + info[0] = __le32_to_cpu(tx_fes_status->info0); + info[1] = __le32_to_cpu(tx_fes_status->info1); + + start_timestamp = + u32_get_bits(info[0], + HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); + start_timestamp |= + u32_get_bits(info[0], + HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; + end_timestamp = + u32_get_bits(info[1], + HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); + end_timestamp |= + u32_get_bits(info[1], + HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; + tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; + + ath12k_wifi7_dp_mon_tx_gen_prot_frame(tx_ppdu_info); + break; + } + + case HAL_TX_FES_STATUS_START_PPDU: + case HAL_TX_FES_STATUS_START_PROT: { + const struct hal_tx_fes_status_start_prot *tx_fes_stat_start = tlv_data; + u64 ppdu_ts; + + info[0] = __le32_to_cpu(tx_fes_stat_start->info0); + + tx_ppdu_info->rx_status.ppdu_ts = + u32_get_bits(info[0], + HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); + ppdu_ts = (u32_get_bits(info[1], + HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); + tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; + break; + } + + case HAL_TX_FES_STATUS_USER_PPDU: { + const struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); + + tx_ppdu_info->rx_status.rx_duration = + u32_get_bits(info[0], + HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); + break; + } + + case HAL_MACTX_HE_SIG_A_SU: + ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_A_MU_DL: + ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B1_MU: + ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B2_MU: + ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B2_OFDMA: + ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_VHT_SIG_A: + ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_L_SIG_A: + ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_L_SIG_B: + ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_RX_FRAME_BITMAP_ACK: { + const struct hal_rx_frame_bitmap_ack *fbm_ack = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(fbm_ack->info0); + info[1] = __le32_to_cpu(fbm_ack->info1); + + addr_32 = u32_get_bits(info[0], + HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); + addr_16 = u32_get_bits(info[1], + HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + ath12k_wifi7_dp_mon_tx_gen_ack_frame(tx_ppdu_info); + break; + } + + case HAL_MACTX_PHY_DESC: { + const struct hal_tx_phy_desc *tx_phy_desc = tlv_data; + + info[0] = __le32_to_cpu(tx_phy_desc->info0); + info[1] = __le32_to_cpu(tx_phy_desc->info1); + info[2] = __le32_to_cpu(tx_phy_desc->info2); + info[3] = __le32_to_cpu(tx_phy_desc->info3); + + tx_ppdu_info->rx_status.beamformed = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_BF_TYPE); + tx_ppdu_info->rx_status.preamble_type = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); + tx_ppdu_info->rx_status.mcs = + u32_get_bits(info[1], + HAL_TX_PHY_DESC_INFO1_MCS); + tx_ppdu_info->rx_status.ltf_size = + u32_get_bits(info[3], + HAL_TX_PHY_DESC_INFO3_LTF_SIZE); + tx_ppdu_info->rx_status.nss = + u32_get_bits(info[2], + HAL_TX_PHY_DESC_INFO2_NSS); + tx_ppdu_info->rx_status.chan_num = + u32_get_bits(info[3], + HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); + tx_ppdu_info->rx_status.bw = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_BANDWIDTH); + break; + } + + case HAL_TX_MPDU_START: { + struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; + + mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); + if (!mon_mpdu) + return DP_MON_TX_STATUS_PPDU_NOT_DONE; + status = DP_MON_TX_MPDU_START; + break; + } + + case HAL_TX_MPDU_END: + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + break; + } + + return status; +} + +static enum dp_mon_tx_tlv_status +ath12k_wifi7_dp_mon_tx_status_get_num_user(u16 tlv_tag, + struct hal_tlv_hdr *tx_tlv, + u8 *num_users) +{ + u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + u32 info0; + + switch (tlv_tag) { + case HAL_TX_FES_SETUP: { + struct hal_tx_fes_setup *tx_fes_setup = + (struct hal_tx_fes_setup *)tx_tlv; + + info0 = __le32_to_cpu(tx_fes_setup->info0); + + *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); + tlv_status = DP_MON_TX_FES_SETUP; + break; + } + + case HAL_RX_RESPONSE_REQUIRED_INFO: { + /* TODO: need to update *num_users */ + tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; + break; + } + } + + return tlv_status; +} + +static void +ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct dp_mon_mpdu *tmp, *mon_mpdu; + + list_for_each_entry_safe(mon_mpdu, tmp, + &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { + list_del(&mon_mpdu->list); + + if (mon_mpdu->head) + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + &tx_ppdu_info->rx_status, napi); + + kfree(mon_mpdu); + } +} + +enum hal_rx_mon_status +ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi, + u32 ppdu_id) +{ + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; + struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; + struct hal_tlv_hdr *tlv; + u8 *ptr = skb->data; + u16 tlv_tag; + u16 tlv_len; + u32 tlv_userid = 0; + u8 num_user; + u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + + tx_prot_ppdu_info = + ath12k_wifi7_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, + DP_MON_TX_PROT_PPDU_INFO); + if (!tx_prot_ppdu_info) + return -ENOMEM; + + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); + + tlv_status = ath12k_wifi7_dp_mon_tx_status_get_num_user(tlv_tag, tlv, + &num_user); + if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) + return -EINVAL; + + tx_data_ppdu_info = + ath12k_wifi7_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, + DP_MON_TX_DATA_PPDU_INFO); + if (!tx_data_ppdu_info) + return -ENOMEM; + + do { + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); + tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN); + tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID); + + tlv_status = ath12k_wifi7_dp_mon_tx_parse_status_tlv(ab, pmon, + tlv_tag, ptr, + tlv_userid); + ptr += tlv_len; + ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); + if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) + break; + } while (tlv_status != DP_MON_TX_FES_STATUS_END); + + ath12k_wifi7_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); + ath12k_wifi7_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); + + return tlv_status; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h index 3cf82864c41cd..148d1e0b70fe8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h @@ -14,4 +14,10 @@ enum dp_monitor_mode; int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode); +enum hal_rx_mon_status +ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi, + u32 ppdu_id); #endif From 7e5cc5395b806f48d3b2153fa40db561e23fa7b2 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:07 +0530 Subject: [PATCH 460/659] wifi: ath12k: Move HT/VHT SIG processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor parsing from ath12k common code to improve modularity and keep Wi-Fi 7 logic within the Wi-Fi 7 module. Move following HT/VHT SIG parsing functions to wifi7/dp_mon.c and rename the functions with the ath12k_wifi7 prefix: - ath12k_dp_mon_parse_vht_sig_a() - ath12k_dp_mon_parse_ht_sig() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-7-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 56 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 4 -- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 62 ++++++++++++++++++- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index ff5a64fe6447f..46727434c703e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -81,62 +81,6 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * } EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 nsts, info0, info1; - u8 gi_setting; - - info0 = __le32_to_cpu(vht_sig->info0); - info1 = __le32_to_cpu(vht_sig->info1); - - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); - ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); - gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); - switch (gi_setting) { - case HAL_RX_VHT_SIG_A_NORMAL_GI: - ppdu_info->gi = HAL_RX_GI_0_8_US; - break; - case HAL_RX_VHT_SIG_A_SHORT_GI: - case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: - ppdu_info->gi = HAL_RX_GI_0_4_US; - break; - } - - ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); - nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); - if (ppdu_info->is_stbc && nsts > 0) - nsts = ((nsts + 1) >> 1) - 1; - - ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK) + 1; - ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); - ppdu_info->beamformed = u32_get_bits(info1, - HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); - ppdu_info->vht_flag_values5 = u32_get_bits(info0, - HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); - ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | - ppdu_info->nss); - ppdu_info->vht_flag_values2 = ppdu_info->bw; - ppdu_info->vht_flag_values4 = - u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_vht_sig_a); - -void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(ht_sig->info0); - u32 info1 = __le32_to_cpu(ht_sig->info1); - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); - ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW); - ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); - ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); - ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_ht_sig); - void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, struct hal_rx_mon_ppdu_info *ppdu_info) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 1d2ec4072a83c..86d0c18d8c07c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -113,8 +113,6 @@ int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); -void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, const void *tlv_data); @@ -135,8 +133,6 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of void ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, struct hal_rx_mon_ppdu_info *ppdu_info); void diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index abdfd3cfd0e48..0c83df4be9daf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -20,6 +20,62 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 nsts, info0, info1; + u8 gi_setting; + + info0 = __le32_to_cpu(vht_sig->info0); + info1 = __le32_to_cpu(vht_sig->info1); + + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); + ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); + gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); + switch (gi_setting) { + case HAL_RX_VHT_SIG_A_NORMAL_GI: + ppdu_info->gi = HAL_RX_GI_0_8_US; + break; + case HAL_RX_VHT_SIG_A_SHORT_GI: + case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: + ppdu_info->gi = HAL_RX_GI_0_4_US; + break; + } + + ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); + nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); + if (ppdu_info->is_stbc && nsts > 0) + nsts = ((nsts + 1) >> 1) - 1; + + ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK); + ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); + ppdu_info->beamformed = u32_get_bits(info1, + HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); + ppdu_info->vht_flag_values5 = u32_get_bits(info0, + HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); + ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | + ppdu_info->nss); + ppdu_info->vht_flag_values2 = ppdu_info->bw; + ppdu_info->vht_flag_values4 = + u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); +} + +static void +ath12k_wifi7_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(ht_sig->info0); + u32 info1 = __le32_to_cpu(ht_sig->info1); + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); + ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW); + ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); + ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); + ppdu_info->nss = (ppdu_info->mcs >> 3); +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -158,7 +214,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; } case HAL_PHYRX_HT_SIG: - ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_ht_sig(tlv_data, ppdu_info); break; case HAL_PHYRX_L_SIG_B: @@ -170,7 +226,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_A_SU: @@ -819,7 +875,7 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, break; case HAL_MACTX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_L_SIG_A: From 67d9a8368b9bc329efc662c2b6b7593ed96de7a3 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:08 +0530 Subject: [PATCH 461/659] wifi: ath12k: Move HE SIG processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor code from ath12k common code to improve modularity. Move following HE SIG processing functions to the wifi7/dp_mon.c and rename the relocated functions with the ath12k_wifi7 prefix: - ath12k_dp_mon_parse_he_sig_b2_ofdma() - ath12k_dp_mon_parse_he_sig_b2_mu() - ath12k_dp_mon_parse_he_sig_b1_mu() - ath12k_dp_mon_parse_he_sig_mu() - ath12k_dp_mon_parse_he_sig_su() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-8-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 365 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 14 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 380 +++++++++++++++++- 3 files changed, 370 insertions(+), 389 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 46727434c703e..8d08f70f5b87b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -153,371 +153,6 @@ void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, } EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); -void -ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, value; - - info0 = __le32_to_cpu(ofdma->info0); - - ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; - - /* HE-data2 */ - ppdu_info->he_data2 |= HE_TXBF_KNOWN; - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); - value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); - value = value << HE_DCM_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); - ppdu_info->ldpc = value; - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - - /* HE-data4 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); - value = value << HE_STA_ID_SHIFT; - ppdu_info->he_data4 |= value; - - ppdu_info->nss = - u32_get_bits(info0, - HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS) + 1; - ppdu_info->beamformed = u32_get_bits(info0, - HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_ofdma); - -void -ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, value; - - info0 = __le32_to_cpu(he_sig_b2_mu->info0); - - ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); - value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); - ppdu_info->ldpc = value; - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); - value = value << HE_STA_ID_SHIFT; - ppdu_info->he_data4 |= value; - - ppdu_info->nss = - u32_get_bits(info0, - HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_mu); - -void -ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); - u16 ru_tones; - - ru_tones = u32_get_bits(info0, - HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); - ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); - ppdu_info->he_RU[0] = ru_tones; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b1_mu); - -void -ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, info1, value; - u16 he_gi = 0, he_ltf = 0; - - info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); - info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); - - ppdu_info->he_mu_flags = 1; - - ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; - ppdu_info->he_data1 |= - HE_BSS_COLOR_KNOWN | - HE_DL_UL_KNOWN | - HE_LDPC_EXTRA_SYMBOL_KNOWN | - HE_STBC_KNOWN | - HE_DATA_BW_RU_KNOWN | - HE_DOPPLER_KNOWN; - - ppdu_info->he_data2 = - HE_GI_KNOWN | - HE_LTF_SYMBOLS_KNOWN | - HE_PRE_FEC_PADDING_KNOWN | - HE_PE_DISAMBIGUITY_KNOWN | - HE_TXOP_KNOWN | - HE_MIDABLE_PERIODICITY_KNOWN; - - /* data3 */ - ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); - value = value << HE_DL_UL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); - value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); - value = value << HE_STBC_SHIFT; - ppdu_info->he_data3 |= value; - - /* data4 */ - ppdu_info->he_data4 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); - ppdu_info->he_data4 = value; - - /* data5 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); - ppdu_info->he_data5 = value; - ppdu_info->bw = value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); - switch (value) { - case 0: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_4_X; - break; - case 1: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_2_X; - break; - case 2: - he_gi = HE_GI_1_6; - he_ltf = HE_LTF_2_X; - break; - case 3: - he_gi = HE_GI_3_2; - he_ltf = HE_LTF_4_X; - break; - } - - ppdu_info->gi = he_gi; - value = he_gi << HE_GI_SHIFT; - ppdu_info->he_data5 |= value; - - value = he_ltf << HE_LTF_SIZE_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); - value = (value << HE_LTF_SYM_SHIFT); - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); - value = value << HE_PRE_FEC_PAD_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); - value = value << HE_PE_DISAMBIGUITY_SHIFT; - ppdu_info->he_data5 |= value; - - /*data6*/ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); - value = value << HE_DOPPLER_SHIFT; - ppdu_info->he_data6 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); - value = value << HE_TXOP_SHIFT; - ppdu_info->he_data6 |= value; - - /* HE-MU Flags */ - /* HE-MU-flags1 */ - ppdu_info->he_flags1 = - HE_SIG_B_MCS_KNOWN | - HE_SIG_B_DCM_KNOWN | - HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | - HE_SIG_B_SYM_NUM_KNOWN | - HE_RU_0_KNOWN; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); - ppdu_info->he_flags1 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); - value = value << HE_DCM_FLAG_1_SHIFT; - ppdu_info->he_flags1 |= value; - - /* HE-MU-flags2 */ - ppdu_info->he_flags2 = HE_BW_KNOWN; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); - ppdu_info->he_flags2 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); - value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; - ppdu_info->he_flags2 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); - value = value - 1; - value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; - ppdu_info->he_flags2 |= value; - - ppdu_info->is_stbc = info1 & - HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu); - -void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, info1, value; - u32 dcm; - u8 he_dcm = 0, he_stbc = 0; - u16 he_gi = 0, he_ltf = 0; - - ppdu_info->he_flags = 1; - - info0 = __le32_to_cpu(he_sig_a->info0); - info1 = __le32_to_cpu(he_sig_a->info1); - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); - if (value == 0) - ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; - else - ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; - - ppdu_info->he_data1 |= - HE_BSS_COLOR_KNOWN | - HE_BEAM_CHANGE_KNOWN | - HE_DL_UL_KNOWN | - HE_MCS_KNOWN | - HE_DCM_KNOWN | - HE_CODING_KNOWN | - HE_LDPC_EXTRA_SYMBOL_KNOWN | - HE_STBC_KNOWN | - HE_DATA_BW_RU_KNOWN | - HE_DOPPLER_KNOWN; - - ppdu_info->he_data2 |= - HE_GI_KNOWN | - HE_TXBF_KNOWN | - HE_PE_DISAMBIGUITY_KNOWN | - HE_TXOP_KNOWN | - HE_LTF_SYMBOLS_KNOWN | - HE_PRE_FEC_PADDING_KNOWN | - HE_MIDABLE_PERIODICITY_KNOWN; - - ppdu_info->he_data3 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); - value = value << HE_BEAM_CHANGE_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); - value = value << HE_DL_UL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); - ppdu_info->mcs = value; - value = value << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); - he_dcm = value; - value = value << HE_DCM_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); - value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); - he_stbc = value; - value = value << HE_STBC_SHIFT; - ppdu_info->he_data3 |= value; - - /* data4 */ - ppdu_info->he_data4 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); - - /* data5 */ - value = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); - ppdu_info->he_data5 = value; - ppdu_info->bw = value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); - switch (value) { - case 0: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_1_X; - break; - case 1: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_2_X; - break; - case 2: - he_gi = HE_GI_1_6; - he_ltf = HE_LTF_2_X; - break; - case 3: - if (he_dcm && he_stbc) { - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_4_X; - } else { - he_gi = HE_GI_3_2; - he_ltf = HE_LTF_4_X; - } - break; - } - ppdu_info->gi = he_gi; - value = he_gi << HE_GI_SHIFT; - ppdu_info->he_data5 |= value; - value = he_ltf << HE_LTF_SIZE_SHIFT; - ppdu_info->ltf_size = he_ltf; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); - value = (value << HE_LTF_SYM_SHIFT); - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); - value = value << HE_PRE_FEC_PAD_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); - value = value << HE_TXBF_SHIFT; - ppdu_info->he_data5 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); - value = value << HE_PE_DISAMBIGUITY_SHIFT; - ppdu_info->he_data5 |= value; - - /* data6 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); - value++; - ppdu_info->he_data6 = value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); - value = value << HE_DOPPLER_SHIFT; - ppdu_info->he_data6 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); - value = value << HE_TXOP_SHIFT; - ppdu_info->he_data6 |= value; - - ppdu_info->mcs = - u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); - ppdu_info->bw = - u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); - ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); - ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); - dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); - ppdu_info->nss = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1; - ppdu_info->dcm = dcm; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_su); - static void ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, struct hal_rx_mon_ppdu_info *ppdu_info) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 86d0c18d8c07c..90811a2f75a73 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -128,20 +128,6 @@ void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, struct hal_rx_mon_ppdu_info *ppdu_info); void -ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, - struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, - struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, struct hal_rx_mon_ppdu_info *ppdu_info); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 0c83df4be9daf..f6d41ded57150 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -76,6 +76,362 @@ ath12k_wifi7_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->nss = (ppdu_info->mcs >> 3); } +static void +ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, value; + + info0 = __le32_to_cpu(ofdma->info0); + + ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; + + /* HE-data2 */ + ppdu_info->he_data2 |= HE_TXBF_KNOWN; + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); + value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); + value = value << HE_DCM_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); + ppdu_info->ldpc = value; + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + + /* HE-data4 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); + value = value << HE_STA_ID_SHIFT; + ppdu_info->he_data4 |= value; + + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); + ppdu_info->beamformed = u32_get_bits(info0, + HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, value; + + info0 = __le32_to_cpu(he_sig_b2_mu->info0); + + ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); + value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); + ppdu_info->ldpc = value; + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); + value = value << HE_STA_ID_SHIFT; + ppdu_info->he_data4 |= value; + + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); + u16 ru_tones; + + ru_tones = u32_get_bits(info0, + HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); + ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); + ppdu_info->he_RU[0] = ru_tones; +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, info1, value; + u16 he_gi = 0, he_ltf = 0; + + info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); + info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); + + ppdu_info->he_mu_flags = 1; + + ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; + ppdu_info->he_data1 |= + HE_BSS_COLOR_KNOWN | + HE_DL_UL_KNOWN | + HE_LDPC_EXTRA_SYMBOL_KNOWN | + HE_STBC_KNOWN | + HE_DATA_BW_RU_KNOWN | + HE_DOPPLER_KNOWN; + + ppdu_info->he_data2 = + HE_GI_KNOWN | + HE_LTF_SYMBOLS_KNOWN | + HE_PRE_FEC_PADDING_KNOWN | + HE_PE_DISAMBIGUITY_KNOWN | + HE_TXOP_KNOWN | + HE_MIDABLE_PERIODICITY_KNOWN; + + /* data3 */ + ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); + value = value << HE_DL_UL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); + value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); + value = value << HE_STBC_SHIFT; + ppdu_info->he_data3 |= value; + + /* data4 */ + ppdu_info->he_data4 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); + ppdu_info->he_data4 = value; + + /* data5 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); + ppdu_info->he_data5 = value; + ppdu_info->bw = value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); + switch (value) { + case 0: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_4_X; + break; + case 1: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_2_X; + break; + case 2: + he_gi = HE_GI_1_6; + he_ltf = HE_LTF_2_X; + break; + case 3: + he_gi = HE_GI_3_2; + he_ltf = HE_LTF_4_X; + break; + } + + ppdu_info->gi = he_gi; + value = he_gi << HE_GI_SHIFT; + ppdu_info->he_data5 |= value; + + value = he_ltf << HE_LTF_SIZE_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); + value = (value << HE_LTF_SYM_SHIFT); + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); + value = value << HE_PRE_FEC_PAD_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); + value = value << HE_PE_DISAMBIGUITY_SHIFT; + ppdu_info->he_data5 |= value; + + /*data6*/ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); + value = value << HE_DOPPLER_SHIFT; + ppdu_info->he_data6 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); + value = value << HE_TXOP_SHIFT; + ppdu_info->he_data6 |= value; + + /* HE-MU Flags */ + /* HE-MU-flags1 */ + ppdu_info->he_flags1 = + HE_SIG_B_MCS_KNOWN | + HE_SIG_B_DCM_KNOWN | + HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | + HE_SIG_B_SYM_NUM_KNOWN | + HE_RU_0_KNOWN; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); + ppdu_info->he_flags1 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); + value = value << HE_DCM_FLAG_1_SHIFT; + ppdu_info->he_flags1 |= value; + + /* HE-MU-flags2 */ + ppdu_info->he_flags2 = HE_BW_KNOWN; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); + ppdu_info->he_flags2 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); + value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; + ppdu_info->he_flags2 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); + value = value - 1; + value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; + ppdu_info->he_flags2 |= value; + + ppdu_info->is_stbc = info1 & + HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, info1, value; + u32 dcm; + u8 he_dcm = 0, he_stbc = 0; + u16 he_gi = 0, he_ltf = 0; + + ppdu_info->he_flags = 1; + + info0 = __le32_to_cpu(he_sig_a->info0); + info1 = __le32_to_cpu(he_sig_a->info1); + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); + if (value == 0) + ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; + else + ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; + + ppdu_info->he_data1 |= + HE_BSS_COLOR_KNOWN | + HE_BEAM_CHANGE_KNOWN | + HE_DL_UL_KNOWN | + HE_MCS_KNOWN | + HE_DCM_KNOWN | + HE_CODING_KNOWN | + HE_LDPC_EXTRA_SYMBOL_KNOWN | + HE_STBC_KNOWN | + HE_DATA_BW_RU_KNOWN | + HE_DOPPLER_KNOWN; + + ppdu_info->he_data2 |= + HE_GI_KNOWN | + HE_TXBF_KNOWN | + HE_PE_DISAMBIGUITY_KNOWN | + HE_TXOP_KNOWN | + HE_LTF_SYMBOLS_KNOWN | + HE_PRE_FEC_PADDING_KNOWN | + HE_MIDABLE_PERIODICITY_KNOWN; + + ppdu_info->he_data3 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); + value = value << HE_BEAM_CHANGE_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); + value = value << HE_DL_UL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); + ppdu_info->mcs = value; + value = value << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); + he_dcm = value; + value = value << HE_DCM_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); + value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); + he_stbc = value; + value = value << HE_STBC_SHIFT; + ppdu_info->he_data3 |= value; + + /* data4 */ + ppdu_info->he_data4 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); + + /* data5 */ + value = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); + ppdu_info->he_data5 = value; + ppdu_info->bw = value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); + switch (value) { + case 0: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_1_X; + break; + case 1: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_2_X; + break; + case 2: + he_gi = HE_GI_1_6; + he_ltf = HE_LTF_2_X; + break; + case 3: + if (he_dcm && he_stbc) { + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_4_X; + } else { + he_gi = HE_GI_3_2; + he_ltf = HE_LTF_4_X; + } + break; + } + ppdu_info->gi = he_gi; + value = he_gi << HE_GI_SHIFT; + ppdu_info->he_data5 |= value; + value = he_ltf << HE_LTF_SIZE_SHIFT; + ppdu_info->ltf_size = he_ltf; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + value = (value << HE_LTF_SYM_SHIFT); + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); + value = value << HE_PRE_FEC_PAD_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); + value = value << HE_TXBF_SHIFT; + ppdu_info->he_data5 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); + value = value << HE_PE_DISAMBIGUITY_SHIFT; + ppdu_info->he_data5 |= value; + + /* data6 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + value++; + ppdu_info->he_data6 = value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); + value = value << HE_DOPPLER_SHIFT; + ppdu_info->he_data6 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); + value = value << HE_TXOP_SHIFT; + ppdu_info->he_data6 |= value; + + ppdu_info->mcs = + u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); + ppdu_info->bw = + u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); + ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); + ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); + dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + ppdu_info->dcm = dcm; +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -230,23 +586,23 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); break; case HAL_PHYRX_RSSI_LEGACY: { @@ -855,23 +1211,27 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, } case HAL_MACTX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_su(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_VHT_SIG_A: From b4966a1771c8b5d99cba4292557b1c48eb86dfce Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:09 +0530 Subject: [PATCH 462/659] wifi: ath12k: Move EHT SIG processing to Wi-Fi 7 module Split Wi-Fi 7 specific EHT SIG parsing out of ath12k common code into the Wi-Fi 7 module to improve modularity. Move the following EHT SIG processing functions to wifi7/dp_mon.c and add the ath12k_wifi7 prefix to each relocated function. - ath12k_dp_mon_hal_aggr_tlv() - ath12k_dp_mon_hal_rx_is_frame_type_ndp() - ath12k_dp_mon_hal_rx_is_non_ofdma() - ath12k_dp_mon_hal_rx_is_ofdma() - ath12k_dp_mon_hal_rx_parse_eht_sig_ndp() - ath12k_dp_mon_hal_rx_parse_usig_overflow() - ath12k_dp_mon_hal_rx_parse_non_ofdma_users() - ath12k_dp_mon_hal_rx_parse_eht_mumimo_user() - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user() - ath12k_dp_mon_hal_rx_is_mu_mimo_user() - ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma() - ath12k_dp_mon_hal_rx_parse_ru_allocation() - ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma() - ath12k_dp_mon_parse_eht_sig_hdr() Export helper functions needed by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-9-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 389 ------------------ drivers/net/wireless/ath/ath12k/dp_mon.h | 12 +- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 386 ++++++++++++++++- 3 files changed, 390 insertions(+), 397 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 8d08f70f5b87b..a667c5acf7a50 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,12 +11,6 @@ #include "dp_tx.h" #include "peer.h" -#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \ - u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) - -#define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ - u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) - void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -346,389 +340,6 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, } EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); -void -ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, - u16 tlv_len, const void *tlv_data) -{ - if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) { - memcpy(ppdu_info->tlv_aggr.buf + ppdu_info->tlv_aggr.cur_len, - tlv_data, tlv_len); - ppdu_info->tlv_aggr.cur_len += tlv_len; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_hal_aggr_tlv); - -static inline bool -ath12k_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == 1 && - usig_info->eht_sig_mcs == 0 && - usig_info->num_eht_sig_sym == 0) - return true; - - return false; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_non_ofdma(const struct hal_rx_u_sig_info *usig_info) -{ - u32 ppdu_type_comp_mode = usig_info->ppdu_type_comp_mode; - u32 ul_dl = usig_info->ul_dl; - - if ((ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 0) || - (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_OFDMA && ul_dl == 0) || - (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 1)) - return true; - - return false; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_ofdma(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == 0 && usig_info->ul_dl == 0) - return true; - - return false; -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_ndp(const struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | - IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | - IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S | - IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S | - IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 | - IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[0]); - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_SPATIAL_REUSE, - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); - /* GI and LTF size are separately indicated in radiotap header - * and hence will be parsed from other TLV - */ - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_NUM_LTF_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_DISREGARD, - IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S); - eht->data[0] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[7]); - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_NSS, - IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_BEAMFORMED, - IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); - eht->data[7] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_usig_overflow(const struct hal_eht_sig_usig_overflow *ovflow, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | - IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[0]); - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_SPATIAL_REUSE, - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); - - /* GI and LTF size are separately indicated in radiotap header - * and hence will be parsed from other TLV - */ - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_NUM_LTF_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_LDPC_EXTA_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_PRE_FEC_PAD_FACTOR, - IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISAMBIGUITY, - IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISREGARD, - IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O); - eht->data[0] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_non_ofdma_users(const struct hal_eht_sig_non_ofdma_cmn_eb *eb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[7]); - data |= ATH12K_LE32_DEC_ENC(eb->info0, - HAL_RX_EHT_SIG_NON_OFDMA_INFO0_NUM_USERS, - IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); - eht->data[7] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_mumimo_user(const struct hal_eht_sig_mu_mimo *user, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; - u32 user_idx; - - if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) - return; - - user_idx = eht_info->num_user_info++; - - eht_info->user_info[user_idx] |= - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_STA_ID, - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS, - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_SPATIAL_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M); - - ppdu_info->mcs = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS); -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(const struct hal_eht_sig_non_mu_mimo *user, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; - u32 user_idx; - - if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) - return; - - user_idx = eht_info->num_user_info++; - - eht_info->user_info[user_idx] |= - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | - IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_STA_ID, - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS, - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS, - IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_BEAMFORMED, - IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); - - ppdu_info->mcs = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS); - - ppdu_info->nss = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS) + 1; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_mu_mimo_user(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_SU && - usig_info->ul_dl == 1) - return true; - - return false; -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma(const void *tlv, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_non_ofdma_cmn_eb *eb = tlv; - - ath12k_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); - ath12k_dp_mon_hal_rx_parse_non_ofdma_users(eb, ppdu_info); - - if (ath12k_dp_mon_hal_rx_is_mu_mimo_user(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_mumimo_user(&eb->user_field.mu_mimo, - ppdu_info); - else - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(&eb->user_field.n_mu_mimo, - ppdu_info); -} - -static void -ath12k_dp_mon_hal_rx_parse_ru_allocation(const struct hal_eht_sig_ofdma_cmn_eb *eb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1 = &eb->eb1; - const struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2 = &eb->eb2; - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - enum ieee80211_radiotap_eht_data ru_123, ru_124, ru_125, ru_126; - enum ieee80211_radiotap_eht_data ru_121, ru_122, ru_112, ru_111; - u32 data; - - ru_123 = IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3; - ru_124 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4; - ru_125 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5; - ru_126 = IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6; - ru_121 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1; - ru_122 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2; - ru_112 = IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2; - ru_111 = IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1; - - switch (ppdu_info->u_sig_info.bw) { - case HAL_EHT_BW_320_2: - case HAL_EHT_BW_320_1: - data = __le32_to_cpu(eht->data[4]); - /* CC1 2::3 */ - data |= IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_3, - ru_123); - eht->data[4] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[5]); - /* CC1 2::4 */ - data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4, - ru_124); - - /* CC1 2::5 */ - data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5, - ru_125); - eht->data[5] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[6]); - /* CC1 2::6 */ - data |= IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6, - ru_126); - eht->data[6] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_160: - data = __le32_to_cpu(eht->data[3]); - /* CC1 2::1 */ - data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_1, - ru_121); - /* CC1 2::2 */ - data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_2, - ru_122); - eht->data[3] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_80: - data = __le32_to_cpu(eht->data[2]); - /* CC1 1::2 */ - data |= IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, - HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_2, - ru_112); - eht->data[2] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_40: - fallthrough; - case HAL_EHT_BW_20: - data = __le32_to_cpu(eht->data[1]); - /* CC1 1::1 */ - data |= IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, - HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_1, - ru_111); - eht->data[1] = cpu_to_le32(data); - break; - default: - break; - } -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_ofdma_cmn_eb *ofdma = tlv; - - ath12k_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); - ath12k_dp_mon_hal_rx_parse_ru_allocation(ofdma, ppdu_info); - - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(&ofdma->user_field.n_mu_mimo, - ppdu_info); -} - -void -ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, - const void *tlv_data) -{ - ppdu_info->is_eht = true; - - if (ath12k_dp_mon_hal_rx_is_frame_type_ndp(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_ndp(tlv_data, ppdu_info); - else if (ath12k_dp_mon_hal_rx_is_non_ofdma(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma(tlv_data, ppdu_info); - else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr); - static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 90811a2f75a73..d2bee88f561f4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -14,6 +14,12 @@ #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 +#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \ + u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) + +#define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ + u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) + enum dp_monitor_mode { ATH12K_DP_TX_MONITOR_MODE, ATH12K_DP_RX_MONITOR_MODE @@ -114,9 +120,6 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); void -ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, - const void *tlv_data); -void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status); void @@ -137,7 +140,4 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, void ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, - u16 tlv_len, const void *tlv_data); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index f6d41ded57150..b924180007c53 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -13,6 +13,17 @@ #include "../dp_tx.h" #include "../peer.h" +static void +ath12k_wifi7_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, + u16 tlv_len, const void *tlv_data) +{ + if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) { + memcpy(ppdu_info->tlv_aggr.buf + ppdu_info->tlv_aggr.cur_len, + tlv_data, tlv_len); + ppdu_info->tlv_aggr.cur_len += tlv_len; + } +} + static void ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -432,6 +443,376 @@ ath12k_wifi7_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig ppdu_info->dcm = dcm; } +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_non_ofdma(const struct hal_rx_u_sig_info *usig_info) +{ + u32 ppdu_type_comp_mode = usig_info->ppdu_type_comp_mode; + u32 ul_dl = usig_info->ul_dl; + + if ((ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 0) || + (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_OFDMA && ul_dl == 0) || + (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 1)) + return true; + + return false; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_ofdma(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == 0 && usig_info->ul_dl == 0) + return true; + + return false; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == 1 && + usig_info->eht_sig_mcs == 0 && + usig_info->num_eht_sig_sym == 0) + return true; + + return false; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ndp(const struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | + IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | + IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S | + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S | + IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 | + IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[0]); + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_SPATIAL_REUSE, + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); + /* GI and LTF size are separately indicated in radiotap header + * and hence will be parsed from other TLV + */ + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_NUM_LTF_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_DISREGARD, + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S); + eht->data[0] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[7]); + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_NSS, + IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_BEAMFORMED, + IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); + eht->data[7] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(const struct hal_eht_sig_usig_overflow *ovflow, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | + IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[0]); + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_SPATIAL_REUSE, + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); + + /* GI and LTF size are separately indicated in radiotap header + * and hence will be parsed from other TLV + */ + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_NUM_LTF_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_LDPC_EXTA_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_PRE_FEC_PAD_FACTOR, + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISAMBIGUITY, + IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISREGARD, + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O); + eht->data[0] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_non_ofdma_users(const struct hal_eht_sig_non_ofdma_cmn_eb *eb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[7]); + data |= ATH12K_LE32_DEC_ENC(eb->info0, + HAL_RX_EHT_SIG_NON_OFDMA_INFO0_NUM_USERS, + IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); + eht->data[7] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_mumimo_user(const struct hal_eht_sig_mu_mimo *user, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; + u32 user_idx; + + if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) + return; + + user_idx = eht_info->num_user_info++; + + eht_info->user_info[user_idx] |= + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_STA_ID, + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS, + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_SPATIAL_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M); + + ppdu_info->mcs = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(const struct hal_eht_sig_non_mu_mimo *user, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; + u32 user_idx; + + if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) + return; + + user_idx = eht_info->num_user_info++; + + eht_info->user_info[user_idx] |= + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_STA_ID, + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS, + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS, + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_BEAMFORMED, + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); + + ppdu_info->mcs = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS); + + ppdu_info->nss = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS) + 1; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_mu_mimo_user(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_SU && + usig_info->ul_dl == 1) + return true; + + return false; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_non_ofdma(const void *tlv, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_non_ofdma_cmn_eb *eb = tlv; + + ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_non_ofdma_users(eb, ppdu_info); + + if (ath12k_wifi7_dp_mon_hal_rx_is_mu_mimo_user(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_mumimo_user(&eb->user_field.mu_mimo, + ppdu_info); + else + ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(&eb->user_field.n_mu_mimo, + ppdu_info); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_ru_allocation(const struct hal_eht_sig_ofdma_cmn_eb *eb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1 = &eb->eb1; + const struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2 = &eb->eb2; + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + enum ieee80211_radiotap_eht_data ru_123, ru_124, ru_125, ru_126; + enum ieee80211_radiotap_eht_data ru_121, ru_122, ru_112, ru_111; + u32 data; + + ru_123 = IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3; + ru_124 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4; + ru_125 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5; + ru_126 = IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6; + ru_121 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1; + ru_122 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2; + ru_112 = IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2; + ru_111 = IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1; + + switch (ppdu_info->u_sig_info.bw) { + case HAL_EHT_BW_320_2: + case HAL_EHT_BW_320_1: + data = __le32_to_cpu(eht->data[4]); + /* CC1 2::3 */ + data |= IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_3, + ru_123); + eht->data[4] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[5]); + /* CC1 2::4 */ + data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4, + ru_124); + + /* CC1 2::5 */ + data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5, + ru_125); + eht->data[5] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[6]); + /* CC1 2::6 */ + data |= IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6, + ru_126); + eht->data[6] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_160: + data = __le32_to_cpu(eht->data[3]); + /* CC1 2::1 */ + data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_1, + ru_121); + /* CC1 2::2 */ + data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_2, + ru_122); + eht->data[3] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_80: + data = __le32_to_cpu(eht->data[2]); + /* CC1 1::2 */ + data |= IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, + HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_2, + ru_112); + eht->data[2] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_40: + fallthrough; + case HAL_EHT_BW_20: + data = __le32_to_cpu(eht->data[1]); + /* CC1 1::1 */ + data |= IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, + HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_1, + ru_111); + eht->data[1] = cpu_to_le32(data); + break; + default: + break; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_ofdma_cmn_eb *ofdma = tlv; + + ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_ru_allocation(ofdma, ppdu_info); + + ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(&ofdma->user_field.n_mu_mimo, + ppdu_info); +} + +static void +ath12k_wifi7_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, + const void *tlv_data) +{ + ppdu_info->is_eht = true; + + if (ath12k_wifi7_dp_mon_hal_rx_is_frame_type_ndp(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ndp(tlv_data, ppdu_info); + else if (ath12k_wifi7_dp_mon_hal_rx_is_non_ofdma(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_non_ofdma(tlv_data, ppdu_info); + else if (ath12k_wifi7_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -447,7 +828,8 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { - ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); + ath12k_wifi7_dp_mon_parse_eht_sig_hdr(ppdu_info, + ppdu_info->tlv_aggr.buf); ppdu_info->tlv_aggr.in_progress = false; ppdu_info->tlv_aggr.cur_len = 0; @@ -691,7 +1073,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, ppdu_info->is_eht = true; - ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); + ath12k_wifi7_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); break; case HAL_DUMMY: return HAL_RX_MON_STATUS_BUF_DONE; From f1a746f5bc9a14fdc92653404b4e702d6291c403 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:10 +0530 Subject: [PATCH 463/659] wifi: ath12k: Move remaining SIG TLV parsing to Wi-Fi 7 module The ath12k common monitor path still contains Wi-Fi 7 specific SIG TLV parsing. Move these SIG TLV parsing to the Wi-Fi 7 module to improve modularity. Relocate the following functions into wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_parse_l_sig_b() - ath12k_dp_mon_parse_l_sig_a() - ath12k_dp_mon_hal_rx_parse_u_sig_cmn() - ath12k_dp_mon_hal_rx_parse_u_sig_tb() - ath12k_dp_mon_hal_rx_parse_u_sig_mu() - ath12k_dp_mon_hal_rx_parse_u_sig_hdr() Export the helper symbols needed by the Wi-Fi 7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-10-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 265 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 7 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 274 +++++++++++++++++- 3 files changed, 269 insertions(+), 277 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index a667c5acf7a50..f1f31e656ba83 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -75,271 +75,6 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * } EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(lsigb->info0); - u8 rate; - - rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); - switch (rate) { - case 1: - rate = HAL_RX_LEGACY_RATE_1_MBPS; - break; - case 2: - case 5: - rate = HAL_RX_LEGACY_RATE_2_MBPS; - break; - case 3: - case 6: - rate = HAL_RX_LEGACY_RATE_5_5_MBPS; - break; - case 4: - case 7: - rate = HAL_RX_LEGACY_RATE_11_MBPS; - break; - default: - rate = HAL_RX_LEGACY_RATE_INVALID; - } - - ppdu_info->rate = rate; - ppdu_info->cck_flag = 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b); - -void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(lsiga->info0); - u8 rate; - - rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); - switch (rate) { - case 8: - rate = HAL_RX_LEGACY_RATE_48_MBPS; - break; - case 9: - rate = HAL_RX_LEGACY_RATE_24_MBPS; - break; - case 10: - rate = HAL_RX_LEGACY_RATE_12_MBPS; - break; - case 11: - rate = HAL_RX_LEGACY_RATE_6_MBPS; - break; - case 12: - rate = HAL_RX_LEGACY_RATE_54_MBPS; - break; - case 13: - rate = HAL_RX_LEGACY_RATE_36_MBPS; - break; - case 14: - rate = HAL_RX_LEGACY_RATE_18_MBPS; - break; - case 15: - rate = HAL_RX_LEGACY_RATE_9_MBPS; - break; - default: - rate = HAL_RX_LEGACY_RATE_INVALID; - } - - ppdu_info->rate = rate; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 common; - - ppdu_info->u_sig_info.bw = le32_get_bits(cmn->info0, - HAL_RX_USIG_CMN_INFO0_BW); - ppdu_info->u_sig_info.ul_dl = le32_get_bits(cmn->info0, - HAL_RX_USIG_CMN_INFO0_UL_DL); - - common = __le32_to_cpu(ppdu_info->u_sig_info.usig.common); - common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_PHY_VERSION, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) | - u32_encode_bits(ppdu_info->u_sig_info.bw, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) | - u32_encode_bits(ppdu_info->u_sig_info.ul_dl, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_BSS_COLOR, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_TXOP, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); - ppdu_info->u_sig_info.usig.common = cpu_to_le32(common); - - switch (ppdu_info->u_sig_info.bw) { - default: - fallthrough; - case HAL_EHT_BW_20: - ppdu_info->bw = HAL_RX_BW_20MHZ; - break; - case HAL_EHT_BW_40: - ppdu_info->bw = HAL_RX_BW_40MHZ; - break; - case HAL_EHT_BW_80: - ppdu_info->bw = HAL_RX_BW_80MHZ; - break; - case HAL_EHT_BW_160: - ppdu_info->bw = HAL_RX_BW_160MHZ; - break; - case HAL_EHT_BW_320_1: - case HAL_EHT_BW_320_2: - ppdu_info->bw = HAL_RX_BW_320MHZ; - break; - } -} - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; - enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2; - u32 common, value, mask; - - spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1; - spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2; - - common = __le32_to_cpu(usig->common); - value = __le32_to_cpu(usig->value); - mask = __le32_to_cpu(usig->mask); - - ppdu_info->u_sig_info.ppdu_type_comp_mode = - le32_get_bits(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE); - - common |= ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); - - value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | - u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1, - spatial_reuse1) | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2, - spatial_reuse2) | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_TAIL, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL); - - mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | - spatial_reuse1 | spatial_reuse2 | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL; - - usig->common = cpu_to_le32(common); - usig->value = cpu_to_le32(value); - usig->mask = cpu_to_le32(mask); -} - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; - enum ieee80211_radiotap_eht_usig_mu sig_symb, punc; - u32 common, value, mask; - - sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS; - punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO; - - common = __le32_to_cpu(usig->common); - value = __le32_to_cpu(usig->value); - mask = __le32_to_cpu(usig->mask); - - ppdu_info->u_sig_info.ppdu_type_comp_mode = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); - ppdu_info->u_sig_info.eht_sig_mcs = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS); - ppdu_info->u_sig_info.num_eht_sig_sym = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM); - - common |= ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); - - value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | - u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO, - punc) | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | - u32_encode_bits(ppdu_info->u_sig_info.eht_sig_mcs, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) | - u32_encode_bits(ppdu_info->u_sig_info.num_eht_sig_sym, - sig_symb) | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_TAIL, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL); - - mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | - punc | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS | - sig_symb | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL; - - usig->common = cpu_to_le32(common); - usig->value = cpu_to_le32(value); - usig->mask = cpu_to_le32(mask); -} - -void -ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u8 comp_mode; - - ppdu_info->eht_usig = true; - - ath12k_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info); - - comp_mode = le32_get_bits(usig->non_cmn.mu.info0, - HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); - - if (comp_mode == 0 && ppdu_info->u_sig_info.ul_dl) - ath12k_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, ppdu_info); - else - ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); -} -EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); - static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index d2bee88f561f4..063d57512db70 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -126,10 +126,6 @@ void ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, struct hal_rx_user_status *rx_user_status); -void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, @@ -137,7 +133,4 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_ void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end); -void -ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, - struct hal_rx_mon_ppdu_info *ppdu_info); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index b924180007c53..2d67fd553776f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,270 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(lsigb->info0); + u8 rate; + + rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); + switch (rate) { + case 1: + rate = HAL_RX_LEGACY_RATE_1_MBPS; + break; + case 2: + case 5: + rate = HAL_RX_LEGACY_RATE_2_MBPS; + break; + case 3: + case 6: + rate = HAL_RX_LEGACY_RATE_5_5_MBPS; + break; + case 4: + case 7: + rate = HAL_RX_LEGACY_RATE_11_MBPS; + break; + default: + rate = HAL_RX_LEGACY_RATE_INVALID; + } + + ppdu_info->rate = rate; + ppdu_info->cck_flag = 1; +} + +static void +ath12k_wifi7_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(lsiga->info0); + u8 rate; + + rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); + switch (rate) { + case 8: + rate = HAL_RX_LEGACY_RATE_48_MBPS; + break; + case 9: + rate = HAL_RX_LEGACY_RATE_24_MBPS; + break; + case 10: + rate = HAL_RX_LEGACY_RATE_12_MBPS; + break; + case 11: + rate = HAL_RX_LEGACY_RATE_6_MBPS; + break; + case 12: + rate = HAL_RX_LEGACY_RATE_54_MBPS; + break; + case 13: + rate = HAL_RX_LEGACY_RATE_36_MBPS; + break; + case 14: + rate = HAL_RX_LEGACY_RATE_18_MBPS; + break; + case 15: + rate = HAL_RX_LEGACY_RATE_9_MBPS; + break; + default: + rate = HAL_RX_LEGACY_RATE_INVALID; + } + + ppdu_info->rate = rate; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 common; + + ppdu_info->u_sig_info.bw = le32_get_bits(cmn->info0, + HAL_RX_USIG_CMN_INFO0_BW); + ppdu_info->u_sig_info.ul_dl = le32_get_bits(cmn->info0, + HAL_RX_USIG_CMN_INFO0_UL_DL); + + common = __le32_to_cpu(ppdu_info->u_sig_info.usig.common); + common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_PHY_VERSION, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) | + u32_encode_bits(ppdu_info->u_sig_info.bw, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) | + u32_encode_bits(ppdu_info->u_sig_info.ul_dl, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_BSS_COLOR, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_TXOP, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); + ppdu_info->u_sig_info.usig.common = cpu_to_le32(common); + + switch (ppdu_info->u_sig_info.bw) { + default: + fallthrough; + case HAL_EHT_BW_20: + ppdu_info->bw = HAL_RX_BW_20MHZ; + break; + case HAL_EHT_BW_40: + ppdu_info->bw = HAL_RX_BW_40MHZ; + break; + case HAL_EHT_BW_80: + ppdu_info->bw = HAL_RX_BW_80MHZ; + break; + case HAL_EHT_BW_160: + ppdu_info->bw = HAL_RX_BW_160MHZ; + break; + case HAL_EHT_BW_320_1: + case HAL_EHT_BW_320_2: + ppdu_info->bw = HAL_RX_BW_320MHZ; + break; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; + enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2; + u32 common, value, mask; + + spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1; + spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2; + + common = __le32_to_cpu(usig->common); + value = __le32_to_cpu(usig->value); + mask = __le32_to_cpu(usig->mask); + + ppdu_info->u_sig_info.ppdu_type_comp_mode = + le32_get_bits(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE); + + common |= ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); + + value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | + u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1, + spatial_reuse1) | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2, + spatial_reuse2) | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_TAIL, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL); + + mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | + spatial_reuse1 | spatial_reuse2 | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL; + + usig->common = cpu_to_le32(common); + usig->value = cpu_to_le32(value); + usig->mask = cpu_to_le32(mask); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; + enum ieee80211_radiotap_eht_usig_mu sig_symb, punc; + u32 common, value, mask; + + sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS; + punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO; + + common = __le32_to_cpu(usig->common); + value = __le32_to_cpu(usig->value); + mask = __le32_to_cpu(usig->mask); + + ppdu_info->u_sig_info.ppdu_type_comp_mode = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); + ppdu_info->u_sig_info.eht_sig_mcs = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS); + ppdu_info->u_sig_info.num_eht_sig_sym = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM); + + common |= ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); + + value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | + u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO, + punc) | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | + u32_encode_bits(ppdu_info->u_sig_info.eht_sig_mcs, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) | + u32_encode_bits(ppdu_info->u_sig_info.num_eht_sig_sym, + sig_symb) | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_TAIL, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL); + + mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | + punc | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS | + sig_symb | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL; + + usig->common = cpu_to_le32(common); + usig->value = cpu_to_le32(value); + usig->mask = cpu_to_le32(mask); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u8 comp_mode; + + ppdu_info->eht_usig = true; + + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info); + + comp_mode = le32_get_bits(usig->non_cmn.mu.info0, + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); + + if (comp_mode == 0 && ppdu_info->u_sig_info.ul_dl) + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, ppdu_info); + else + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); +} + static void ath12k_wifi7_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -956,11 +1220,11 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); break; case HAL_PHYRX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); break; case HAL_PHYRX_VHT_SIG_A: @@ -1058,7 +1322,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, case HAL_RX_MPDU_END: return HAL_RX_MON_STATUS_MPDU_END; case HAL_PHYRX_GENERIC_U_SIG: - ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); break; case HAL_PHYRX_GENERIC_EHT_SIG: /* Handle the case where aggregation is in progress @@ -1621,11 +1885,11 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, break; case HAL_MACTX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_RX_FRAME_BITMAP_ACK: { From bcd6e4736a5ed65f481b888a340bc594c5bc03c7 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:11 +0530 Subject: [PATCH 464/659] wifi: ath12k: Move MU user processing to Wi-Fi 7 module Move Wi-Fi 7-specific monitor functionality out of ath12k common code into the Wi-Fi 7 module to improve modularity. Move and rename the following MU user processing functions to wifi7/dp_mon.c with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_handle_ofdma_info() - ath12k_dp_mon_rx_populate_mu_user_info() - ath12k_dp_mon_hal_rx_parse_user_info() Move the helper functions hal_rx_mon_hal_ru_size_to_ath12k_ru_size and hal_rx_ul_ofdma_ru_size_to_width to the Wi-Fi 7 module, and export the helpers required by the ath12k_wifi7 code. Isolate the parsing of MU-specific user information within the Wi-Fi 7 module to keep common code generic. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-11-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 351 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 11 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 356 +++++++++++++++++- 3 files changed, 352 insertions(+), 366 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index f1f31e656ba83..2f6991b5d8abc 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,357 +11,6 @@ #include "dp_tx.h" #include "peer.h" -void -ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->ul_ofdma_user_v0_word0 = - __le32_to_cpu(ppdu_end_user->usr_resp_ref); - rx_user_status->ul_ofdma_user_v0_word1 = - __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_handle_ofdma_info); - -static void -ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, - void *ppduinfo, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->mpdu_ok_byte_count = - le32_get_bits(stats->info7, - HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT); - rx_user_status->mpdu_err_byte_count = - le32_get_bits(stats->info8, - HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); -} - -void -ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, - struct hal_rx_mon_ppdu_info *ppdu_info, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->ast_index = ppdu_info->ast_index; - rx_user_status->tid = ppdu_info->tid; - rx_user_status->tcp_ack_msdu_count = - ppdu_info->tcp_ack_msdu_count; - rx_user_status->tcp_msdu_count = - ppdu_info->tcp_msdu_count; - rx_user_status->udp_msdu_count = - ppdu_info->udp_msdu_count; - rx_user_status->other_msdu_count = - ppdu_info->other_msdu_count; - rx_user_status->frame_control = ppdu_info->frame_control; - rx_user_status->frame_control_info_valid = - ppdu_info->frame_control_info_valid; - rx_user_status->data_sequence_control_info_valid = - ppdu_info->data_sequence_control_info_valid; - rx_user_status->first_data_seq_ctrl = - ppdu_info->first_data_seq_ctrl; - rx_user_status->preamble_type = ppdu_info->preamble_type; - rx_user_status->ht_flags = ppdu_info->ht_flags; - rx_user_status->vht_flags = ppdu_info->vht_flags; - rx_user_status->he_flags = ppdu_info->he_flags; - rx_user_status->rs_flags = ppdu_info->rs_flags; - - rx_user_status->mpdu_cnt_fcs_ok = - ppdu_info->num_mpdu_fcs_ok; - rx_user_status->mpdu_cnt_fcs_err = - ppdu_info->num_mpdu_fcs_err; - memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], - HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * - sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - - ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); - -static inline enum ath12k_eht_ru_size -hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) -{ - switch (hal_ru_size) { - case HAL_EHT_RU_26: - return ATH12K_EHT_RU_26; - case HAL_EHT_RU_52: - return ATH12K_EHT_RU_52; - case HAL_EHT_RU_78: - return ATH12K_EHT_RU_52_26; - case HAL_EHT_RU_106: - return ATH12K_EHT_RU_106; - case HAL_EHT_RU_132: - return ATH12K_EHT_RU_106_26; - case HAL_EHT_RU_242: - return ATH12K_EHT_RU_242; - case HAL_EHT_RU_484: - return ATH12K_EHT_RU_484; - case HAL_EHT_RU_726: - return ATH12K_EHT_RU_484_242; - case HAL_EHT_RU_996: - return ATH12K_EHT_RU_996; - case HAL_EHT_RU_996x2: - return ATH12K_EHT_RU_996x2; - case HAL_EHT_RU_996x3: - return ATH12K_EHT_RU_996x3; - case HAL_EHT_RU_996x4: - return ATH12K_EHT_RU_996x4; - case HAL_EHT_RU_NONE: - return ATH12K_EHT_RU_INVALID; - case HAL_EHT_RU_996_484: - return ATH12K_EHT_RU_996_484; - case HAL_EHT_RU_996x2_484: - return ATH12K_EHT_RU_996x2_484; - case HAL_EHT_RU_996x3_484: - return ATH12K_EHT_RU_996x3_484; - case HAL_EHT_RU_996_484_242: - return ATH12K_EHT_RU_996_484_242; - default: - return ATH12K_EHT_RU_INVALID; - } -} - -static inline u32 -hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) -{ - switch (ru_size) { - case ATH12K_EHT_RU_26: - return RU_26; - case ATH12K_EHT_RU_52: - return RU_52; - case ATH12K_EHT_RU_52_26: - return RU_52_26; - case ATH12K_EHT_RU_106: - return RU_106; - case ATH12K_EHT_RU_106_26: - return RU_106_26; - case ATH12K_EHT_RU_242: - return RU_242; - case ATH12K_EHT_RU_484: - return RU_484; - case ATH12K_EHT_RU_484_242: - return RU_484_242; - case ATH12K_EHT_RU_996: - return RU_996; - case ATH12K_EHT_RU_996_484: - return RU_996_484; - case ATH12K_EHT_RU_996_484_242: - return RU_996_484_242; - case ATH12K_EHT_RU_996x2: - return RU_2X996; - case ATH12K_EHT_RU_996x2_484: - return RU_2X996_484; - case ATH12K_EHT_RU_996x3: - return RU_3X996; - case ATH12K_EHT_RU_996x3_484: - return RU_3X996_484; - case ATH12K_EHT_RU_996x4: - return RU_4X996; - default: - return RU_INVALID; - } -} - -void -ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, - u16 user_id, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_user_status *mon_rx_user_status = NULL; - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - enum ath12k_eht_ru_size rtap_ru_size = ATH12K_EHT_RU_INVALID; - u32 ru_width, reception_type, ru_index = HAL_EHT_RU_INVALID; - u32 ru_type_80_0, ru_start_index_80_0; - u32 ru_type_80_1, ru_start_index_80_1; - u32 ru_type_80_2, ru_start_index_80_2; - u32 ru_type_80_3, ru_start_index_80_3; - u32 ru_size = 0, num_80mhz_with_ru = 0; - u64 ru_index_320mhz = 0; - u32 ru_index_per80mhz; - - reception_type = le32_get_bits(rx_usr_info->info0, - HAL_RX_USR_INFO0_RECEPTION_TYPE); - - switch (reception_type) { - case HAL_RECEPTION_TYPE_SU: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; - break; - case HAL_RECEPTION_TYPE_DL_MU_MIMO: - case HAL_RECEPTION_TYPE_UL_MU_MIMO: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; - break; - case HAL_RECEPTION_TYPE_DL_MU_OFMA: - case HAL_RECEPTION_TYPE_UL_MU_OFDMA: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; - break; - case HAL_RECEPTION_TYPE_DL_MU_OFDMA_MIMO: - case HAL_RECEPTION_TYPE_UL_MU_OFDMA_MIMO: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO; - } - - ppdu_info->is_stbc = le32_get_bits(rx_usr_info->info0, HAL_RX_USR_INFO0_STBC); - ppdu_info->ldpc = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_LDPC); - ppdu_info->dcm = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_STA_DCM); - ppdu_info->bw = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_RX_BW); - ppdu_info->mcs = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_MCS); - ppdu_info->nss = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_NSS) + 1; - - if (user_id < HAL_MAX_UL_MU_USERS) { - mon_rx_user_status = &ppdu_info->userstats[user_id]; - mon_rx_user_status->mcs = ppdu_info->mcs; - mon_rx_user_status->nss = ppdu_info->nss; - } - - if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || - ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || - ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) - return; - - /* RU allocation present only for OFDMA reception */ - ru_type_80_0 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_0); - ru_start_index_80_0 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_0); - if (ru_type_80_0 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_0; - ru_index_per80mhz = ru_start_index_80_0; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_0, 0, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_1 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_1); - ru_start_index_80_1 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_1); - if (ru_type_80_1 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_1; - ru_index_per80mhz = ru_start_index_80_1; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_1, 1, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_2 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_2); - ru_start_index_80_2 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_2); - if (ru_type_80_2 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_2; - ru_index_per80mhz = ru_start_index_80_2; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_2, 2, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_3 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_3); - ru_start_index_80_3 = le32_get_bits(rx_usr_info->info2, - HAL_RX_USR_INFO3_RU_START_IDX_80_3); - if (ru_type_80_3 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_3; - ru_index_per80mhz = ru_start_index_80_3; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_3, 3, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - if (num_80mhz_with_ru > 1) { - /* Calculate the MRU index */ - switch (ru_index_320mhz) { - case HAL_EHT_RU_996_484_0: - case HAL_EHT_RU_996x2_484_0: - case HAL_EHT_RU_996x3_484_0: - ru_index = 0; - break; - case HAL_EHT_RU_996_484_1: - case HAL_EHT_RU_996x2_484_1: - case HAL_EHT_RU_996x3_484_1: - ru_index = 1; - break; - case HAL_EHT_RU_996_484_2: - case HAL_EHT_RU_996x2_484_2: - case HAL_EHT_RU_996x3_484_2: - ru_index = 2; - break; - case HAL_EHT_RU_996_484_3: - case HAL_EHT_RU_996x2_484_3: - case HAL_EHT_RU_996x3_484_3: - ru_index = 3; - break; - case HAL_EHT_RU_996_484_4: - case HAL_EHT_RU_996x2_484_4: - case HAL_EHT_RU_996x3_484_4: - ru_index = 4; - break; - case HAL_EHT_RU_996_484_5: - case HAL_EHT_RU_996x2_484_5: - case HAL_EHT_RU_996x3_484_5: - ru_index = 5; - break; - case HAL_EHT_RU_996_484_6: - case HAL_EHT_RU_996x2_484_6: - case HAL_EHT_RU_996x3_484_6: - ru_index = 6; - break; - case HAL_EHT_RU_996_484_7: - case HAL_EHT_RU_996x2_484_7: - case HAL_EHT_RU_996x3_484_7: - ru_index = 7; - break; - case HAL_EHT_RU_996x2_484_8: - ru_index = 8; - break; - case HAL_EHT_RU_996x2_484_9: - ru_index = 9; - break; - case HAL_EHT_RU_996x2_484_10: - ru_index = 10; - break; - case HAL_EHT_RU_996x2_484_11: - ru_index = 11; - break; - default: - ru_index = HAL_EHT_RU_INVALID; - break; - } - - ru_size += 4; - } - - rtap_ru_size = hal_rx_mon_hal_ru_size_to_ath12k_ru_size(ru_size); - if (rtap_ru_size != ATH12K_EHT_RU_INVALID) { - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[1]); - data |= u32_encode_bits(rtap_ru_size, - IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE); - eht->data[1] = cpu_to_le32(data); - } - - if (ru_index != HAL_EHT_RU_INVALID) { - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[1]); - data |= u32_encode_bits(rtap_ru_size, - IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX); - eht->data[1] = cpu_to_le32(data); - } - - if (mon_rx_user_status && ru_index != HAL_EHT_RU_INVALID && - rtap_ru_size != ATH12K_EHT_RU_INVALID) { - mon_rx_user_status->ul_ofdma_ru_start_index = ru_index; - mon_rx_user_status->ul_ofdma_ru_size = rtap_ru_size; - - ru_width = hal_rx_ul_ofdma_ru_size_to_width(rtap_ru_size); - - mon_rx_user_status->ul_ofdma_ru_width = ru_width; - mon_rx_user_status->ofdma_info_valid = 1; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_user_info); - static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) { if (info & RX_MSDU_END_INFO13_FCS_ERR) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 063d57512db70..6dac4e9569b6e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -120,17 +120,6 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); void -ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, - struct hal_rx_user_status *rx_user_status); -void -ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, - struct hal_rx_mon_ppdu_info *ppdu_info, - struct hal_rx_user_status *rx_user_status); -void -ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, - u16 user_id, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 2d67fd553776f..8d913d09f8826 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,354 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->ul_ofdma_user_v0_word0 = + __le32_to_cpu(ppdu_end_user->usr_resp_ref); + rx_user_status->ul_ofdma_user_v0_word1 = + __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); +} + +static void +ath12k_wifi7_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, + void *ppduinfo, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->mpdu_ok_byte_count = + le32_get_bits(stats->info7, + HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT); + rx_user_status->mpdu_err_byte_count = + le32_get_bits(stats->info8, + HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); +} + +static void +ath12k_wifi7_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->ast_index = ppdu_info->ast_index; + rx_user_status->tid = ppdu_info->tid; + rx_user_status->tcp_ack_msdu_count = + ppdu_info->tcp_ack_msdu_count; + rx_user_status->tcp_msdu_count = + ppdu_info->tcp_msdu_count; + rx_user_status->udp_msdu_count = + ppdu_info->udp_msdu_count; + rx_user_status->other_msdu_count = + ppdu_info->other_msdu_count; + rx_user_status->frame_control = ppdu_info->frame_control; + rx_user_status->frame_control_info_valid = + ppdu_info->frame_control_info_valid; + rx_user_status->data_sequence_control_info_valid = + ppdu_info->data_sequence_control_info_valid; + rx_user_status->first_data_seq_ctrl = + ppdu_info->first_data_seq_ctrl; + rx_user_status->preamble_type = ppdu_info->preamble_type; + rx_user_status->ht_flags = ppdu_info->ht_flags; + rx_user_status->vht_flags = ppdu_info->vht_flags; + rx_user_status->he_flags = ppdu_info->he_flags; + rx_user_status->rs_flags = ppdu_info->rs_flags; + + rx_user_status->mpdu_cnt_fcs_ok = + ppdu_info->num_mpdu_fcs_ok; + rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->num_mpdu_fcs_err; + memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + + ath12k_wifi7_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); +} + +static inline enum ath12k_eht_ru_size +hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) +{ + switch (hal_ru_size) { + case HAL_EHT_RU_26: + return ATH12K_EHT_RU_26; + case HAL_EHT_RU_52: + return ATH12K_EHT_RU_52; + case HAL_EHT_RU_78: + return ATH12K_EHT_RU_52_26; + case HAL_EHT_RU_106: + return ATH12K_EHT_RU_106; + case HAL_EHT_RU_132: + return ATH12K_EHT_RU_106_26; + case HAL_EHT_RU_242: + return ATH12K_EHT_RU_242; + case HAL_EHT_RU_484: + return ATH12K_EHT_RU_484; + case HAL_EHT_RU_726: + return ATH12K_EHT_RU_484_242; + case HAL_EHT_RU_996: + return ATH12K_EHT_RU_996; + case HAL_EHT_RU_996x2: + return ATH12K_EHT_RU_996x2; + case HAL_EHT_RU_996x3: + return ATH12K_EHT_RU_996x3; + case HAL_EHT_RU_996x4: + return ATH12K_EHT_RU_996x4; + case HAL_EHT_RU_NONE: + return ATH12K_EHT_RU_INVALID; + case HAL_EHT_RU_996_484: + return ATH12K_EHT_RU_996_484; + case HAL_EHT_RU_996x2_484: + return ATH12K_EHT_RU_996x2_484; + case HAL_EHT_RU_996x3_484: + return ATH12K_EHT_RU_996x3_484; + case HAL_EHT_RU_996_484_242: + return ATH12K_EHT_RU_996_484_242; + default: + return ATH12K_EHT_RU_INVALID; + } +} + +static inline u32 +hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) +{ + switch (ru_size) { + case ATH12K_EHT_RU_26: + return RU_26; + case ATH12K_EHT_RU_52: + return RU_52; + case ATH12K_EHT_RU_52_26: + return RU_52_26; + case ATH12K_EHT_RU_106: + return RU_106; + case ATH12K_EHT_RU_106_26: + return RU_106_26; + case ATH12K_EHT_RU_242: + return RU_242; + case ATH12K_EHT_RU_484: + return RU_484; + case ATH12K_EHT_RU_484_242: + return RU_484_242; + case ATH12K_EHT_RU_996: + return RU_996; + case ATH12K_EHT_RU_996_484: + return RU_996_484; + case ATH12K_EHT_RU_996_484_242: + return RU_996_484_242; + case ATH12K_EHT_RU_996x2: + return RU_2X996; + case ATH12K_EHT_RU_996x2_484: + return RU_2X996_484; + case ATH12K_EHT_RU_996x3: + return RU_3X996; + case ATH12K_EHT_RU_996x3_484: + return RU_3X996_484; + case ATH12K_EHT_RU_996x4: + return RU_4X996; + default: + return RU_INVALID; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, + u16 user_id, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_user_status *mon_rx_user_status = NULL; + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + enum ath12k_eht_ru_size rtap_ru_size = ATH12K_EHT_RU_INVALID; + u32 ru_width, reception_type, ru_index = HAL_EHT_RU_INVALID; + u32 ru_type_80_0, ru_start_index_80_0; + u32 ru_type_80_1, ru_start_index_80_1; + u32 ru_type_80_2, ru_start_index_80_2; + u32 ru_type_80_3, ru_start_index_80_3; + u32 ru_size = 0, num_80mhz_with_ru = 0; + u64 ru_index_320mhz = 0; + u32 ru_index_per80mhz; + + reception_type = le32_get_bits(rx_usr_info->info0, + HAL_RX_USR_INFO0_RECEPTION_TYPE); + + switch (reception_type) { + case HAL_RECEPTION_TYPE_SU: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + case HAL_RECEPTION_TYPE_DL_MU_MIMO: + case HAL_RECEPTION_TYPE_UL_MU_MIMO: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; + break; + case HAL_RECEPTION_TYPE_DL_MU_OFMA: + case HAL_RECEPTION_TYPE_UL_MU_OFDMA: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; + break; + case HAL_RECEPTION_TYPE_DL_MU_OFDMA_MIMO: + case HAL_RECEPTION_TYPE_UL_MU_OFDMA_MIMO: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO; + } + + ppdu_info->is_stbc = le32_get_bits(rx_usr_info->info0, HAL_RX_USR_INFO0_STBC); + ppdu_info->ldpc = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_LDPC); + ppdu_info->dcm = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_STA_DCM); + ppdu_info->bw = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_RX_BW); + ppdu_info->mcs = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_MCS); + ppdu_info->nss = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_NSS) + 1; + + if (user_id < HAL_MAX_UL_MU_USERS) { + mon_rx_user_status = &ppdu_info->userstats[user_id]; + mon_rx_user_status->mcs = ppdu_info->mcs; + mon_rx_user_status->nss = ppdu_info->nss; + } + + if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || + ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || + ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) + return; + + /* RU allocation present only for OFDMA reception */ + ru_type_80_0 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_0); + ru_start_index_80_0 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_0); + if (ru_type_80_0 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_0; + ru_index_per80mhz = ru_start_index_80_0; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_0, 0, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_1 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_1); + ru_start_index_80_1 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_1); + if (ru_type_80_1 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_1; + ru_index_per80mhz = ru_start_index_80_1; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_1, 1, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_2 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_2); + ru_start_index_80_2 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_2); + if (ru_type_80_2 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_2; + ru_index_per80mhz = ru_start_index_80_2; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_2, 2, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_3 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_3); + ru_start_index_80_3 = le32_get_bits(rx_usr_info->info2, + HAL_RX_USR_INFO3_RU_START_IDX_80_3); + if (ru_type_80_3 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_3; + ru_index_per80mhz = ru_start_index_80_3; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_3, 3, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + if (num_80mhz_with_ru > 1) { + /* Calculate the MRU index */ + switch (ru_index_320mhz) { + case HAL_EHT_RU_996_484_0: + case HAL_EHT_RU_996x2_484_0: + case HAL_EHT_RU_996x3_484_0: + ru_index = 0; + break; + case HAL_EHT_RU_996_484_1: + case HAL_EHT_RU_996x2_484_1: + case HAL_EHT_RU_996x3_484_1: + ru_index = 1; + break; + case HAL_EHT_RU_996_484_2: + case HAL_EHT_RU_996x2_484_2: + case HAL_EHT_RU_996x3_484_2: + ru_index = 2; + break; + case HAL_EHT_RU_996_484_3: + case HAL_EHT_RU_996x2_484_3: + case HAL_EHT_RU_996x3_484_3: + ru_index = 3; + break; + case HAL_EHT_RU_996_484_4: + case HAL_EHT_RU_996x2_484_4: + case HAL_EHT_RU_996x3_484_4: + ru_index = 4; + break; + case HAL_EHT_RU_996_484_5: + case HAL_EHT_RU_996x2_484_5: + case HAL_EHT_RU_996x3_484_5: + ru_index = 5; + break; + case HAL_EHT_RU_996_484_6: + case HAL_EHT_RU_996x2_484_6: + case HAL_EHT_RU_996x3_484_6: + ru_index = 6; + break; + case HAL_EHT_RU_996_484_7: + case HAL_EHT_RU_996x2_484_7: + case HAL_EHT_RU_996x3_484_7: + ru_index = 7; + break; + case HAL_EHT_RU_996x2_484_8: + ru_index = 8; + break; + case HAL_EHT_RU_996x2_484_9: + ru_index = 9; + break; + case HAL_EHT_RU_996x2_484_10: + ru_index = 10; + break; + case HAL_EHT_RU_996x2_484_11: + ru_index = 11; + break; + default: + ru_index = HAL_EHT_RU_INVALID; + break; + } + + ru_size += 4; + } + + rtap_ru_size = hal_rx_mon_hal_ru_size_to_ath12k_ru_size(ru_size); + if (rtap_ru_size != ATH12K_EHT_RU_INVALID) { + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[1]); + data |= u32_encode_bits(rtap_ru_size, + IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE); + eht->data[1] = cpu_to_le32(data); + } + + if (ru_index != HAL_EHT_RU_INVALID) { + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[1]); + data |= u32_encode_bits(rtap_ru_size, + IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX); + eht->data[1] = cpu_to_le32(data); + } + + if (mon_rx_user_status && ru_index != HAL_EHT_RU_INVALID && + rtap_ru_size != ATH12K_EHT_RU_INVALID) { + mon_rx_user_status->ul_ofdma_ru_start_index = ru_index; + mon_rx_user_status->ul_ofdma_ru_size = rtap_ru_size; + + ru_width = hal_rx_ul_ofdma_ru_size_to_width(rtap_ru_size); + + mon_rx_user_status->ul_ofdma_ru_width = ru_width; + mon_rx_user_status->ofdma_info_valid = 1; + } +} + static void ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -1196,9 +1544,9 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, ppdu_info->num_users += 1; - ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); - ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, - rxuser_stats); + ath12k_wifi7_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); + ath12k_wifi7_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, + rxuser_stats); } ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); @@ -1277,7 +1625,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; } case HAL_RX_PPDU_START_USER_INFO: - ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); break; case HAL_RXPCU_PPDU_END_INFO: { From 674b4857b1fef7ab9ab77c607fed072133769e6a Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:12 +0530 Subject: [PATCH 465/659] wifi: ath12k: Move MSDU END TLV processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor handling from ath12k common code to improve modularity. Move the following MSDU END TLV processing functions into wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_parse_rx_msdu_end_err() - ath12k_dp_mon_parse_status_msdu_end() - ath12k_dp_mon_next_link_desc_get() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-12-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 50 ---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 9 --- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 58 +++++++++++++++++-- 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 2f6991b5d8abc..5388c3cebaa2b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,30 +11,6 @@ #include "dp_tx.h" #include "peer.h" -static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) -{ - if (info & RX_MSDU_END_INFO13_FCS_ERR) - *errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - *errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - *errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; -} - static void ath12k_parse_cmn_usr_info(const struct hal_phyrx_common_user_info *cmn_usr_info, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -63,17 +39,6 @@ ath12k_parse_cmn_usr_info(const struct hal_phyrx_common_user_info *cmn_usr_info, ppdu_info->gi = cp_setting; } -void -ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, - const struct hal_rx_msdu_end *msdu_end) -{ - ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), - &pmon->err_bitmap); - pmon->decap_format = le32_get_bits(msdu_end->info1, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_status_msdu_end); - static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) @@ -167,21 +132,6 @@ u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } EXPORT_SYMBOL(ath12k_dp_mon_comp_ppduid); -void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, - struct hal_rx_msdu_link *msdu_link, - dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, - struct ath12k_buffer_addr **pp_buf_addr_info) -{ - struct ath12k_buffer_addr *buf_addr_info; - - buf_addr_info = &msdu_link->buf_addr_info; - - ath12k_hal_rx_buf_addr_info_get(&ab->hal, buf_addr_info, paddr, sw_cookie, rbm); - - *pp_buf_addr_info = buf_addr_info; -} -EXPORT_SYMBOL(ath12k_dp_mon_next_link_desc_get); - static void ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppdu_info, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 6dac4e9569b6e..f5debe947ad69 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -8,8 +8,6 @@ #define ATH12K_DP_MON_H #include "core.h" -#include "wifi7/hal_desc.h" -#include "wifi7/hal_rx.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 @@ -110,16 +108,9 @@ void ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, bool *is_frag, u32 *total_len, u32 *frag_len, u32 *msdu_cnt); -void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, - struct hal_rx_msdu_link *msdu_link, - dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, - struct ath12k_buffer_addr **pp_buf_addr_info); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); -void -ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, - const struct hal_rx_msdu_end *msdu_end); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 8d913d09f8826..6d829d3e1b0c9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -1425,6 +1425,40 @@ ath12k_wifi7_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); } +static void ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) +{ + if (info & RX_MSDU_END_INFO13_FCS_ERR) + *errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + *errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + *errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; +} + +static void +ath12k_wifi7_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end) +{ + ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), + &pmon->err_bitmap); + pmon->decap_format = le32_get_bits(msdu_end->info1, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -1665,7 +1699,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, case HAL_MON_BUF_ADDR: return HAL_RX_MON_STATUS_BUF_ADDR; case HAL_RX_MSDU_END: - ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); + ath12k_wifi7_dp_mon_parse_status_msdu_end(pmon, tlv_data); return HAL_RX_MON_STATUS_MSDU_END; case HAL_RX_MPDU_END: return HAL_RX_MON_STATUS_MPDU_END; @@ -2417,6 +2451,21 @@ ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, return tlv_status; } +static void +ath12k_wifi7_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, + dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, + struct ath12k_buffer_addr **pp_buf_addr_info) +{ + struct ath12k_buffer_addr *buf_addr_info; + + buf_addr_info = &msdu_link->buf_addr_info; + + ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + + *pp_buf_addr_info = buf_addr_info; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, @@ -2583,9 +2632,10 @@ ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); - ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, - &sw_cookie, &rbm, - &p_buf_addr_info); + ath12k_wifi7_dp_mon_next_link_desc_get(ab, + msdu_link_desc, &paddr, + &sw_cookie, &rbm, + &p_buf_addr_info); ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); From d37b3ba075109ff19fa27e0fac48707e7ed94058 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:13 +0530 Subject: [PATCH 466/659] wifi: ath12k: Remove Wi-Fi 7 header dependencies from common ath12k module Remove all remaining Wi-Fi 7 header dependencies from dp_mon.c to finalize separation of Wi-Fi 7 specific monitor mode functionality. Remove these includes from dp_mon.c: - wifi7/hal_desc.h - wifi7/hal_qcn9274.h - wifi7/dp_rx.h Relocate hal_mon_buf_ring from wifi7/hal_desc.h to hal.h. Relocate HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID and HAL_RX_FCS_LEN macros from wifi7/hal_rx.h to hal.h or dp_rx.h as appropriate. Move the following functions to the new file wifi7/dp_mon.c and add the ath12k_wifi7 prefix: - ath12k_dp_mon_rx_merg_msdus() - ath12k_dp_mon_update_radiotap() - ath12k_dp_mon_rx_deliver_msdu() - ath12k_dp_mon_get_buf_len() - ath12k_dp_mon_rx_deliver() Export several helper functions needed by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-13-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 111 +++--------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 27 +++-- drivers/net/wireless/ath/ath12k/dp_rx.h | 9 ++ drivers/net/wireless/ath/ath12k/hal.h | 28 +++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 99 ++++++++++++++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 8 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 8 -- .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 19 --- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 10 -- 9 files changed, 165 insertions(+), 154 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 5388c3cebaa2b..407803328f8fb 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,8 +6,6 @@ #include "dp_mon.h" #include "debug.h" -#include "wifi7/hal_qcn9274.h" -#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" @@ -233,7 +231,7 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k_base *ab, skb_pull(head_msdu, total_offset); } -static struct sk_buff * +struct sk_buff * ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppdu_info, @@ -361,6 +359,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, } return NULL; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_merg_msdus); static void ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status, @@ -410,10 +409,10 @@ ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, rtap_buf[rtap_len] = rx_status->he_RU[3]; } -static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct sk_buff *mon_skb, - struct ieee80211_rx_status *rxs) +void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs) { struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ieee80211_supported_band *sband; @@ -519,13 +518,13 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, rxs->mactime = ppduinfo->tsft; } +EXPORT_SYMBOL(ath12k_dp_mon_update_radiotap); -static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct sk_buff *msdu, - const struct hal_rx_mon_ppdu_info *ppduinfo, - struct ieee80211_rx_status *status, - u8 decap) +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap) { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; @@ -554,7 +553,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); rcu_read_lock(); spin_lock_bh(&dp->dp_lock); @@ -613,62 +612,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } - -int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi) -{ - struct sk_buff *mon_skb, *skb_next, *header; - struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; - u8 decap = DP_RX_DECAP_TYPE_RAW; - - mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); - if (!mon_skb) - goto mon_deliver_fail; - - header = mon_skb; - rxs->flag = 0; - - if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS) - rxs->flag = RX_FLAG_FAILED_FCS_CRC; - - do { - skb_next = mon_skb->next; - if (!skb_next) - rxs->flag &= ~RX_FLAG_AMSDU_MORE; - else - rxs->flag |= RX_FLAG_AMSDU_MORE; - - if (mon_skb == header) { - header = NULL; - rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; - } else { - rxs->flag |= RX_FLAG_ALLOW_SAME_PN; - } - rxs->flag |= RX_FLAG_ONLY_MONITOR; - - if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) - decap = mon_mpdu->decap_format; - - ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); - ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); - mon_skb = skb_next; - } while (mon_skb); - rxs->flag = 0; - - return 0; - -mon_deliver_fail: - mon_skb = mon_mpdu->head; - while (mon_skb) { - skb_next = mon_skb->next; - dev_kfree_skb_any(mon_skb); - mon_skb = skb_next; - } - return -EINVAL; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver); +EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver_msdu); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) { @@ -689,33 +633,6 @@ int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) } EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); -/* Hardware fill buffer with 128 bytes aligned. So need to reap it - * with 128 bytes aligned. - */ -#define RXDMA_DATA_DMA_BLOCK_SIZE 128 - -void -ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, - bool *is_frag, u32 *total_len, - u32 *frag_len, u32 *msdu_cnt) -{ - if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) { - *is_frag = true; - *frag_len = (RX_MON_STATUS_BASE_BUF_SIZE - - sizeof(struct hal_rx_desc)) & - ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); - *total_len += *frag_len; - } else { - if (*is_frag) - *frag_len = info->msdu_len - *total_len; - else - *frag_len = info->msdu_len; - - *msdu_cnt -= 1; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); - int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index f5debe947ad69..394463ea19e0b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -96,21 +96,32 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); -int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi); struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id); -void -ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, - bool *is_frag, u32 *total_len, - u32 *frag_len, u32 *msdu_cnt); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); +void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs); +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap); +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap); +struct sk_buff * +ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct ieee80211_rx_status *rxs); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 916cf41aa5c31..8d045f71e955e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -179,6 +179,15 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } +static inline +void ath12k_dp_extract_rx_desc_data(struct ath12k_hal *hal, + struct hal_rx_desc_data *rx_info, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); +} + void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 1d22173975f0f..ce038906bd069 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -73,6 +73,16 @@ struct ath12k_base; #define HAL_RX_MAX_NSS 8 #define HAL_RX_MAX_NUM_LEGACY_RATES 12 +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) +#define HAL_RX_FCS_LEN 4 + enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, @@ -597,6 +607,24 @@ struct hal_rx_msdu_desc_info { u16 msdu_len; /* 14 bits for length */ }; +/* hal_mon_buf_ring + * Producer : SW + * Consumer : Monitor + * + * paddr_lo + * Lower 32-bit physical address of the buffer pointer from the source ring. + * paddr_hi + * bit range 7-0 : upper 8 bit of the physical address. + * bit range 31-8 : reserved. + * cookie + * Consumer: RxMon/TxMon 64 bit cookie of the buffers. + */ +struct hal_mon_buf_ring { + __le32 paddr_lo; + __le32 paddr_hi; + __le64 cookie; +}; + struct hal_rx_mon_ppdu_info { u32 ppdu_id; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 6d829d3e1b0c9..9878553289c47 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,32 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +/* Hardware fill buffer with 128 bytes aligned. So need to reap it + * with 128 bytes aligned. + */ +#define RXDMA_DATA_DMA_BLOCK_SIZE 128 + +static void +ath12k_wifi7_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, + bool *is_frag, u32 *total_len, + u32 *frag_len, u32 *msdu_cnt) +{ + if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) { + *is_frag = true; + *frag_len = (RX_MON_STATUS_BASE_BUF_SIZE - + sizeof(struct hal_rx_desc)) & + ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); + *total_len += *frag_len; + } else { + if (*is_frag) + *frag_len = info->msdu_len - *total_len; + else + *frag_len = info->msdu_len; + + *msdu_cnt -= 1; + } +} + static void ath12k_wifi7_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -2373,6 +2399,62 @@ ath12k_wifi7_dp_mon_tx_status_get_num_user(u16 tlv_tag, return tlv_status; } +static int +ath12k_wifi7_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi) +{ + struct sk_buff *mon_skb, *skb_next, *header; + struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; + u8 decap = DP_RX_DECAP_TYPE_RAW; + + mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); + if (!mon_skb) + goto mon_deliver_fail; + + header = mon_skb; + rxs->flag = 0; + + if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS) + rxs->flag = RX_FLAG_FAILED_FCS_CRC; + + do { + skb_next = mon_skb->next; + if (!skb_next) + rxs->flag &= ~RX_FLAG_AMSDU_MORE; + else + rxs->flag |= RX_FLAG_AMSDU_MORE; + + if (mon_skb == header) { + header = NULL; + rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; + } else { + rxs->flag |= RX_FLAG_ALLOW_SAME_PN; + } + rxs->flag |= RX_FLAG_ONLY_MONITOR; + + if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) + decap = mon_mpdu->decap_format; + + ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); + ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); + mon_skb = skb_next; + } while (mon_skb); + rxs->flag = 0; + + return 0; + +mon_deliver_fail: + mon_skb = mon_mpdu->head; + while (mon_skb) { + skb_next = mon_skb->next; + dev_kfree_skb_any(mon_skb); + mon_skb = skb_next; + } + return -EINVAL; +} + static void ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, @@ -2385,8 +2467,8 @@ ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, list_del(&mon_mpdu->list); if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, - &tx_ppdu_info->rx_status, napi); + ath12k_wifi7_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + &tx_ppdu_info->rx_status, napi); kfree(mon_mpdu); } @@ -2606,9 +2688,9 @@ ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, pmon->mon_last_linkdesc_paddr = paddr; is_first_msdu = false; } - ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], - &is_frag, &total_len, - &frag_len, &msdu_cnt); + ath12k_wifi7_dp_mon_get_buf_len(&msdu_list.msdu_info[i], + &is_frag, &total_len, + &frag_len, &msdu_cnt); rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { @@ -2748,8 +2830,8 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, tmp_mpdu->tail = tail_msdu; tmp_mpdu->err_bitmap = pmon->err_bitmap; tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, - &pmon->mon_ppdu_info, napi); + ath12k_wifi7_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, + &pmon->mon_ppdu_info, napi); rx_mon_stats->dest_mpdu_done++; kfree(tmp_mpdu); } @@ -2883,7 +2965,8 @@ ath12k_wifi7_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, list_del(&mon_mpdu->list); if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); + ath12k_wifi7_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + ppdu_info, napi); kfree(mon_mpdu); } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 08dcf170b801d..af50dafc03499 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -524,7 +524,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); + ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); if (!rx_info->msdu_done) { ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; @@ -1035,7 +1035,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; @@ -1333,7 +1333,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, } rx_desc = (struct hal_rx_desc *)msdu->data; - ath12k_wifi7_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { @@ -1714,7 +1714,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 2d3eb2313b2f7..d15bffe223c7d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -52,12 +52,4 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, bool ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -static inline -void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, - struct hal_rx_desc_data *rx_info, - struct hal_rx_desc *rx_desc, - struct hal_rx_desc *ldesc) -{ - hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); -} #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 4a249ba7357d1..9dad8f7ca9f21 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -2682,25 +2682,6 @@ struct hal_tcl_entrance_from_ppe_ring { __le32 info0; } __packed; -struct hal_mon_buf_ring { - __le32 paddr_lo; - __le32 paddr_hi; - __le64 cookie; -}; - -/* hal_mon_buf_ring - * Producer : SW - * Consumer : Monitor - * - * paddr_lo - * Lower 32-bit physical address of the buffer pointer from the source ring. - * paddr_hi - * bit range 7-0 : upper 8 bit of the physical address. - * bit range 31-8 : reserved. - * cookie - * Consumer: RxMon/TxMon 64 bit cookie of the buffers. - */ - #define HAL_MON_DEST_COOKIE_BUF_ID GENMASK(17, 0) #define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(11, 0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 4a0beb4d192ef..1f2cfba3aac1c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -45,7 +45,6 @@ struct hal_rx_mon_status_tlv_hdr { #define HAL_TLV_STATUS_PPDU_DONE 1 #define HAL_TLV_STATUS_BUF_DONE 2 #define HAL_TLV_STATUS_PPDU_NON_STD_DONE 3 -#define HAL_RX_FCS_LEN 4 enum hal_rx_mon_status { HAL_RX_MON_STATUS_PPDU_NOT_DONE, @@ -366,15 +365,6 @@ struct hal_rx_resp_req_info { #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3 0xCDBEEF -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) - /* HE Radiotap data1 Mask */ #define HE_SU_FORMAT_TYPE 0x0000 #define HE_EXT_SU_FORMAT_TYPE 0x0001 From f39492dcc1df2f19903e56681529b34017cf5ad0 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Wed, 19 Nov 2025 10:15:57 +0800 Subject: [PATCH 467/659] wifi: ath12k: add the missing RCU lock in ath12k_dp_tx_free_txbuf() RCU read lock is missing in ath12k_dp_tx_free_txbuf() before calling ath12k_dp_to_pdev_dp(), causing below warning: WARNING: suspicious RCU usage ----------------------------- drivers/net/wireless/ath/ath12k/dp.h:653 ath12k dp to dp pdev called without rcu lock! Call Trace: show_stack dump_stack_lvl dump_stack lockdep_rcu_suspicious.cold ath12k_dp_tx_free_txbuf ath12k_wifi7_dp_tx_completion_handler ath12k_wifi7_dp_service_srng ath12k_pci_ext_grp_napi_poll [...] Invoke guard(rcu) to fix it. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251119-ath12k-fix-missing-rcu-lock-v1-1-8155de1dc4fc@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_tx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index 1d4444f3936ff..c10da6195c9c3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -194,8 +194,6 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, skb_cb = ATH12K_SKB_CB(msdu); - dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); - dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, @@ -203,6 +201,10 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, dev_kfree_skb_any(desc_params->skb_ext_desc); } + guard(rcu)(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) From 76106eb1bf36996f94835ca999069e932361b55d Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Wed, 19 Nov 2025 10:24:47 +0800 Subject: [PATCH 468/659] wifi: ath12k: move firmware stats request outside of atomic context In ath12k_mac_op_link_sta_statistics(), the atomic context scope introduced by dp_lock also covers firmware stats request. Since that request could block, below issue is hit: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 6866, name: iw preempt_count: 201, expected: 0 RCU nest depth: 0, expected: 0 3 locks held by iw/6866: #0:[...] #1:[...] #2: ffff9748f43230c8 (&dp->dp_lock){+.-.}-{3:3}, at: ath12k_mac_op_link_sta_statistics+0xc6/0x380 [ath12k] Preemption disabled at: [] ath12k_mac_op_link_sta_statistics+0xc6/0x380 [ath12k] Call Trace: show_stack dump_stack_lvl dump_stack __might_resched.cold __might_sleep __mutex_lock mutex_lock_nested ath12k_mac_get_fw_stats ath12k_mac_op_link_sta_statistics Since firmware stats request doesn't require protection from dp_lock, move it outside to fix this issue. While moving, also refine that code hunk to make function parameters get populated when really necessary. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251119-ath12k-ng-sleep-in-atomic-v1-1-5d1a726597db@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 44 +++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index b1bf9434dd6f5..5811ebe52d5ab 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13358,10 +13358,12 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - guard(spinlock_bh)(&ar->ab->dp->dp_lock); + spin_lock_bh(&ar->ab->dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); - if (!peer) + if (!peer) { + spin_unlock_bh(&ar->ab->dp->dp_lock); return; + } link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); @@ -13388,18 +13390,28 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } + link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); + if (!db2dbm) + link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + + link_sinfo->tx_retries = peer->tx_retry_count; + link_sinfo->tx_failed = peer->tx_retry_failed; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + /* TODO: Use real NF instead of default one. */ signal = peer->rssi_comb; - params.pdev_id = ar->pdev->pdev_id; - params.vdev_id = 0; - params.stats_id = WMI_REQUEST_VDEV_STAT; + spin_unlock_bh(&ar->ab->dp->dp_lock); - if (!signal && - ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA && - !(ath12k_mac_get_fw_stats(ar, ¶ms))) { - signal = arsta->rssi_beacon; - ath12k_fw_stats_reset(ar); + if (!signal && ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA) { + params.pdev_id = ar->pdev->pdev_id; + params.vdev_id = 0; + params.stats_id = WMI_REQUEST_VDEV_STAT; + + if (!ath12k_mac_get_fw_stats(ar, ¶ms)) + signal = arsta->rssi_beacon; } if (signal) { @@ -13407,18 +13419,6 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm ? signal : signal + ATH12K_DEFAULT_NOISE_FLOOR; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - - link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); - - if (!db2dbm) - link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; - - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - - link_sinfo->tx_retries = peer->tx_retry_count; - link_sinfo->tx_failed = peer->tx_retry_failed; - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); From 55071d41f631805838da0ec9df4fedccbbd461e4 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Sun, 7 Dec 2025 12:57:17 +0530 Subject: [PATCH 469/659] wifi: ath12k: Skip DP peer creation for scan vdev Consider a multi-link AP configuration: MLD vif (MAC addr: aa:bb) |-- 2.4 GHz link (BSSID: aa:bb) |-- 5 GHz link (BSSID: cc:dd) For AP vdevs, ath12k creates a DP peer using the arvif's BSSID and stores it in dp_hw->dp_peers_list. During scan operations, the driver assigns an arvif to the scan vdev and uses the vif's MAC address as its BSSID. In the above scenario, the scan vdev MAC address (aa:bb) matches the BSSID of the 2.4 GHz AP link, causing a duplicate entry in dp_hw->dp_peers_list and leading to scan vdev creation failure. Failure in vif bringup sequence: 1. Create AP vdev for 2.4 GHz link: - Assign arvif with BSSID = aa:bb and link_id = 0. - Create DP peer with address aa:bb and add to dp_hw->dp_peers_list. 2. Create scan vdev for 5 GHz link: - Assign arvif with BSSID = aa:bb (same as vif MAC address) and link_id = 15. - Attempt to create another DP peer with address aa:bb. - Operation fails because aa:bb already exists in dp_hw->dp_peers_list, resulting in duplicate entry conflict. 3. Delete scan vdev for 5 GHz link. 4. Create AP vdev for 5 GHz link. Since DP peer is not needed for scan operations, identify scan vdev using arvif->link_id >= IEEE80211_MLD_MAX_NUM_LINKS and skip DP peer creation and deletion. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251207072717.95542-1-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 12 +++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 5811ebe52d5ab..3b2c37cc5d280 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1253,7 +1253,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) /* Delete all the self dp_peers on asserted radio */ list_for_each_entry_safe_reverse(arvif, tmp_vif, &ar->arvifs, list) { - if (arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) { + if ((arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) && + (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS)) { ath12k_dp_peer_delete(dp_hw, arvif->bssid, NULL); arvif->num_stations = 0; } @@ -4188,7 +4189,8 @@ static void ath12k_mac_remove_link_interface(struct ieee80211_hw *hw, ath12k_warn(ar->ab, "failed to submit AP self-peer removal on vdev %d link id %d: %d", arvif->vdev_id, arvif->link_id, ret); - ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); + if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) + ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); } ath12k_mac_vdev_delete(ar, arvif); } @@ -10043,6 +10045,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) u8 link_id; struct ath12k_dp_link_vif *dp_link_vif = NULL; struct ath12k_dp_peer_create_params params = {}; + bool dp_peer_created = false; lockdep_assert_wiphy(hw->wiphy); @@ -10134,11 +10137,14 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) case WMI_VDEV_TYPE_AP: params.ucast_ra_only = true; - ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, ¶ms); - if (ret) { - ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n", - arvif->vdev_id, ret); - goto err_vdev_del; + if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) { + ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, ¶ms); + if (ret) { + ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n", + arvif->vdev_id, ret); + goto err_vdev_del; + } + dp_peer_created = true; } peer_param.vdev_id = arvif->vdev_id; @@ -10255,7 +10261,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) } err_dp_peer_del: - if (ahvif->vdev_type == WMI_VDEV_TYPE_AP) + if (dp_peer_created) ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); err_vdev_del: diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index c2fb5bbd6ceae..5f3bd3b9a3e97 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -241,11 +241,13 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, spin_unlock_bh(&dp->dp_lock); - ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab), - &(ath12k_ar_to_ah(ar)->dp_hw), - arvif->vdev_id, sta, - (u8 *)arg->peer_addr, link_id, - ar->hw_link_id); + if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) { + ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), + arvif->vdev_id, sta, + (u8 *)arg->peer_addr, link_id, + ar->hw_link_id); + } return ret; } From 1a5dd6ec38bdb52e6cb0060dc40c39297cd089bf Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 30 Jan 2026 18:19:40 +0800 Subject: [PATCH 470/659] Merge branch 'ath12k-ng' into ath-next As originally proposed in [1], the ath12k driver was re-architected in the ath12k-ng branch to separate the logic specific to 802.11be (Wi-Fi 7) from the core logic. This separation will allow ath12k to also support 802.11bn (Wi-Fi 8) in the future. Now merge this into ath-next. Many thanks to everyone who worked on this re-architecture. Special thanks to Vasanthakumar Thiagarajan and Baochen Qiang who reviewed every patch, and to Ripan Deuri for the ath12k-ng => ath-next merge conflict resolution. Link: https://lore.kernel.org/all/4a17d730-ede8-463e-98d8-9b0291d0ca45@oss.qualcomm.com/ # [1] Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ce.h | 2 +- drivers/net/wireless/ath/ath12k/debugfs.c | 2 + drivers/net/wireless/ath/ath12k/dp.h | 43 +++-- drivers/net/wireless/ath/ath12k/dp_mon.c | 29 +-- drivers/net/wireless/ath/ath12k/dp_mon.h | 6 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 106 +++-------- drivers/net/wireless/ath/ath12k/dp_rx.h | 5 + drivers/net/wireless/ath/ath12k/hal.c | 6 + drivers/net/wireless/ath/ath12k/hal.h | 1 + drivers/net/wireless/ath/ath12k/htc.c | 1 - drivers/net/wireless/ath/ath12k/mac.c | 8 +- drivers/net/wireless/ath/ath12k/mhi.c | 2 +- drivers/net/wireless/ath/ath12k/mhi.h | 1 - drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 61 ++++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 180 +++++++++++------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 10 +- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 1 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 1 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 + drivers/net/wireless/ath/ath12k/wmi.c | 38 +--- 23 files changed, 268 insertions(+), 241 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index 38f986ea1cd2b..df4f2a4f84809 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_CE_H diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index 64d89d82332ba..358031fa14ebb 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1157,6 +1157,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, len += scnprintf(buf + len, size - len, "\n"); + rcu_read_lock(); for (i = 0; i < ab->num_radios; i++) { ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i)); if (ar) { @@ -1165,6 +1166,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, atomic_read(&ar->dp.num_tx_pending)); } } + rcu_read_unlock(); len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n"); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index dc18423812ec0..f8cfc7bb29dd7 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -21,6 +21,7 @@ struct ath12k_vif; struct ath12k_link_vif; struct ath12k_ext_irq_grp; struct ath12k_dp_rx_tid; +struct ath12k_dp_rx_tid_rxq; #define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 @@ -392,7 +393,7 @@ struct ath12k_dp_arch_ops { u32 (*tx_get_vdev_bank_config)(struct ath12k_base *ab, struct ath12k_link_vif *arvif); int (*reo_cmd_send)(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid, + struct ath12k_dp_rx_tid_rxq *rx_tid, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, void (*cb)(struct ath12k_dp *dp, void *ctx, @@ -402,8 +403,8 @@ struct ath12k_dp_arch_ops { u32 cipher, enum set_key_cmd key_cmd); void (*rx_peer_tid_delete)(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid); - void (*reo_cache_flush)(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid); + int (*reo_cache_flush)(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid); int (*rx_link_desc_return)(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); @@ -419,6 +420,9 @@ struct ath12k_dp_arch_ops { u16 ssn, enum hal_pn_type pn_type); void (*peer_rx_tid_qref_setup)(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); + void (*peer_rx_tid_qref_reset)(struct ath12k_base *ab, u16 peer_id, u16 tid); + int (*rx_tid_delete_handler)(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid); }; struct ath12k_device_dp_tx_err_stats { @@ -444,6 +448,7 @@ struct ath12k_device_dp_stats { u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; u32 tx_completed[DP_TCL_NUM_RING_MAX]; + u32 reo_excep_msdu_buf_type; }; struct ath12k_dp { @@ -554,7 +559,7 @@ static inline u32 ath12k_dp_arch_tx_get_vdev_bank_config(struct ath12k_dp *dp, } static inline int ath12k_dp_arch_reo_cmd_send(struct ath12k_dp *dp, - struct ath12k_dp_rx_tid *rx_tid, + struct ath12k_dp_rx_tid_rxq *rx_tid, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, void (*cb)(struct ath12k_dp *dp, void *ctx, @@ -563,11 +568,12 @@ static inline int ath12k_dp_arch_reo_cmd_send(struct ath12k_dp *dp, return dp->ops->reo_cmd_send(dp->ab, rx_tid, type, cmd, cb); } -static inline void ath12k_dp_arch_setup_pn_check_reo_cmd(struct ath12k_dp *dp, - struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, - enum set_key_cmd key_cmd) +static inline +void ath12k_dp_arch_setup_pn_check_reo_cmd(struct ath12k_dp *dp, + struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, + enum set_key_cmd key_cmd) { dp->ops->setup_pn_check_reo_cmd(cmd, rx_tid, cipher, key_cmd); } @@ -579,10 +585,10 @@ static inline void ath12k_dp_arch_rx_peer_tid_delete(struct ath12k_dp *dp, dp->ops->rx_peer_tid_delete(dp->ab, peer, tid); } -static inline void ath12k_dp_arch_reo_cache_flush(struct ath12k_dp *dp, - struct ath12k_dp_rx_tid *rx_tid) +static inline int ath12k_dp_arch_reo_cache_flush(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid_rxq *rx_tid) { - dp->ops->reo_cache_flush(dp->ab, rx_tid); + return dp->ops->reo_cache_flush(dp->ab, rx_tid); } static inline @@ -626,6 +632,19 @@ static inline void ath12k_dp_arch_peer_rx_tid_qref_setup(struct ath12k_dp *dp, dp->ops->peer_rx_tid_qref_setup(dp->ab, peer_id, tid, paddr); } +static inline void ath12k_dp_arch_peer_rx_tid_qref_reset(struct ath12k_dp *dp, + u16 peer_id, u16 tid) +{ + dp->ops->peer_rx_tid_qref_reset(dp->ab, peer_id, tid); +} + +static inline +int ath12k_dp_arch_rx_tid_delete_handler(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid_rxq *rx_tid) +{ + return dp->ops->rx_tid_delete_handler(dp->ab, rx_tid); +} + static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) { memcpy(addr, &addr_l32, 4); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 407803328f8fb..737287a9aa462 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -9,34 +9,6 @@ #include "dp_tx.h" #include "peer.h" -static void -ath12k_parse_cmn_usr_info(const struct hal_phyrx_common_user_info *cmn_usr_info, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data, cp_setting, ltf_size; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_GI | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF; - eht->known = cpu_to_le32(known); - - cp_setting = le32_get_bits(cmn_usr_info->info0, - HAL_RX_CMN_USR_INFO0_CP_SETTING); - ltf_size = le32_get_bits(cmn_usr_info->info0, - HAL_RX_CMN_USR_INFO0_LTF_SIZE); - - data = __le32_to_cpu(eht->data[0]); - data |= u32_encode_bits(cp_setting, IEEE80211_RADIOTAP_EHT_DATA0_GI); - data |= u32_encode_bits(ltf_size, IEEE80211_RADIOTAP_EHT_DATA0_LTF); - eht->data[0] = cpu_to_le32(data); - - if (!ppdu_info->ltf_size) - ppdu_info->ltf_size = ltf_size; - if (!ppdu_info->gi) - ppdu_info->gi = cp_setting; -} - static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) @@ -523,6 +495,7 @@ EXPORT_SYMBOL(ath12k_dp_mon_update_radiotap); void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, + const struct hal_rx_mon_ppdu_info *ppduinfo, struct ieee80211_rx_status *status, u8 decap) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 394463ea19e0b..167028d27513b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -112,11 +112,7 @@ void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, - struct ieee80211_rx_status *status, - u8 decap); -void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct sk_buff *msdu, + const struct hal_rx_mon_ppdu_info *ppduinfo, struct ieee80211_rx_status *status, u8 decap); struct sk_buff * diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index d236c0638dabf..a32ee9f8061af 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -345,13 +345,15 @@ static int ath12k_dp_rx_pdev_srng_alloc(struct ath12k *ar) return 0; } -static void ath12k_dp_init_rx_tid_rxq(struct ath12k_dp_rx_tid_rxq *rx_tid_rxq, - struct ath12k_dp_rx_tid *rx_tid) +void ath12k_dp_init_rx_tid_rxq(struct ath12k_dp_rx_tid_rxq *rx_tid_rxq, + struct ath12k_dp_rx_tid *rx_tid, + bool active) { rx_tid_rxq->tid = rx_tid->tid; - rx_tid_rxq->active = rx_tid->active; + rx_tid_rxq->active = active; rx_tid_rxq->qbuf = rx_tid->qbuf; } +EXPORT_SYMBOL(ath12k_dp_init_rx_tid_rxq); static void ath12k_dp_rx_tid_cleanup(struct ath12k_base *ab, struct ath12k_reoq_buf *tid_qbuf) @@ -395,7 +397,6 @@ void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab) } spin_unlock_bh(&dp->reo_cmd_lock); } -EXPORT_SYMBOL(ath12k_dp_reo_cmd_free); void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status) @@ -408,8 +409,9 @@ void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, ath12k_dp_rx_tid_cleanup(dp->ab, &rx_tid->qbuf); } +EXPORT_SYMBOL(ath12k_dp_reo_cmd_free); -static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp) +void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp) { struct ath12k_base *ab = dp->ab; struct dp_reo_update_rx_queue_elem *elem, *tmp; @@ -423,10 +425,10 @@ static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp * if (ath12k_dp_rx_tid_delete_handler(ab, &elem->rx_tid)) break; - ath12k_peer_rx_tid_qref_reset(ab, - elem->is_ml_peer ? elem->ml_peer_id : - elem->peer_id, - elem->rx_tid.tid); + ath12k_dp_arch_peer_rx_tid_qref_reset(dp, + elem->is_ml_peer ? + elem->ml_peer_id : elem->peer_id, + elem->rx_tid.tid); if (ab->hw_params->reoq_lut_support) ath12k_hal_reo_shared_qaddr_cache_clear(ab); @@ -437,7 +439,7 @@ static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp * spin_unlock_bh(&dp->reo_rxq_flush_lock); } -EXPORT_SYMBOL(ath12k_dp_rx_tid_del_func); +EXPORT_SYMBOL(ath12k_dp_rx_process_reo_cmd_update_rx_queue_list); void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status) @@ -458,9 +460,9 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, /* Retry the HAL_REO_CMD_UPDATE_RX_QUEUE command for entries * in the pending queue list marked TID as inactive */ - spin_lock_bh(&dp->ab->base_lock); + spin_lock_bh(&dp->dp_lock); ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(dp); - spin_unlock_bh(&dp->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); elem = kzalloc(sizeof(*elem), GFP_ATOMIC); if (!elem) @@ -492,6 +494,7 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, list_del(&elem->list); dp->reo_cmd_cache_flush_count--; + kfree(elem); } } @@ -501,25 +504,17 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, free_desc: ath12k_dp_rx_tid_cleanup(ab, &rx_tid->qbuf); } +EXPORT_SYMBOL(ath12k_dp_rx_tid_del_func); static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, struct ath12k_dp_rx_tid_rxq *rx_tid) { - struct ath12k_hal_reo_cmd cmd = {}; - - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; - /* Observed flush cache failure, to avoid that set vld bit during delete */ - cmd.upd1 |= HAL_REO_CMD_UPD1_VLD; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - return ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - ath12k_dp_rx_tid_del_func); + return ath12k_dp_arch_rx_tid_delete_handler(dp, rx_tid); } -static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 tid) +void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 tid) { struct dp_reo_update_rx_queue_elem *elem; struct ath12k_dp_rx_tid_rxq *rx_tid; @@ -536,6 +531,7 @@ static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 } spin_unlock_bh(&dp->reo_rxq_flush_lock); } +EXPORT_SYMBOL(ath12k_dp_mark_tid_as_inactive); void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer) { @@ -562,12 +558,12 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer } static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid) { struct dp_reo_update_rx_queue_elem *elem; - lockdep_assert_held(&dp->ab->base_lock); + lockdep_assert_held(&dp->dp_lock); elem = kzalloc(sizeof(*elem), GFP_ATOMIC); if (!elem) @@ -577,7 +573,8 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, elem->is_ml_peer = peer->mlo; elem->ml_peer_id = peer->ml_id; - ath12k_dp_init_rx_tid_rxq(&elem->rx_tid, rx_tid); + ath12k_dp_init_rx_tid_rxq(&elem->rx_tid, rx_tid, + (peer->rx_tid_active_bitmask & (1 << rx_tid->tid))); spin_lock_bh(&dp->reo_rxq_flush_lock); list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); @@ -675,7 +672,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ if (ret) { ath12k_warn(ab, "failed to alloc update_rxq_list for rx tid %u\n", tid); ath12k_dp_rx_tid_cleanup(ab, &rx_tid->qbuf); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } @@ -823,12 +820,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, continue; rx_tid = &peer->dp_peer->rx_tid[tid]; - - ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - + ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid, + (peer->rx_tid_active_bitmask & (1 << tid))); ath12k_dp_arch_setup_pn_check_reo_cmd(dp, &cmd, rx_tid, key->cipher, key_cmd); - ret = ath12k_dp_arch_reo_cmd_send(dp, rx_tid, + ret = ath12k_dp_arch_reo_cmd_send(dp, &rx_tid_rxq, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL); if (ret) { @@ -1296,7 +1292,7 @@ void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, } if (unlikely(rx_status->band == NUM_NL80211_BANDS || - !ath12k_ar_to_hw(ar)->wiphy->bands[rx_status->band])) { + !ath12k_pdev_dp_to_hw(dp_pdev)->wiphy->bands[rx_status->band])) { struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); ath12k_warn(ar->ab, "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n", @@ -1602,50 +1598,6 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) } EXPORT_SYMBOL(ath12k_dp_rx_h_get_pn); -static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, - struct list_head *list, - struct hal_reo_dest_ring *desc) -{ - struct ath12k_rx_desc_info *desc_info; - struct ath12k_skb_rxcb *rxcb; - struct sk_buff *msdu; - u64 desc_va; - - ab->device_stats.reo_excep_msdu_buf_type++; - - desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | - le32_to_cpu(desc->buf_va_lo); - desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; - if (!desc_info) { - u32 cookie; - - cookie = le32_get_bits(desc->buf_addr_info.info1, - BUFFER_ADDR_INFO1_SW_COOKIE); - desc_info = ath12k_dp_get_rx_desc(ab, cookie); - if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", - cookie); - return -EINVAL; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { - ath12k_warn(ab, "rx exception, magic check failed with value: %u\n", - desc_info->magic); - return -EINVAL; - } - - msdu = desc_info->skb; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, list); - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - dev_kfree_skb_any(msdu); - - return 0; -} - void ath12k_dp_rx_free(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 8d045f71e955e..1ec5382f59955 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -260,4 +260,9 @@ void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status); void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status); +void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp); +void ath12k_dp_init_rx_tid_rxq(struct ath12k_dp_rx_tid_rxq *rx_tid_rxq, + struct ath12k_dp_rx_tid *rx_tid, + bool active); +void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 tid); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 91d697ad1799d..c7a152490fa09 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -101,6 +101,12 @@ void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng) ab->hal.ops->reo_init_cmd_ring(ab, srng); } +void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) +{ + ab->hal.ops->reo_shared_qaddr_cache_clear(ab); +} +EXPORT_SYMBOL(ath12k_hal_reo_shared_qaddr_cache_clear); + void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, struct ath12k_buffer_addr *binfo, dma_addr_t paddr, u32 cookie, u8 manager) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index ce038906bd069..f23ba1f9eaac2 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1408,6 +1408,7 @@ struct hal_ops { u32 end_offset); void (*reo_init_cmd_ring)(struct ath12k_base *ab, struct hal_srng *srng); + void (*reo_shared_qaddr_cache_clear)(struct ath12k_base *ab); void (*reo_hw_setup)(struct ath12k_base *ab, u32 ring_hash_map); void (*rx_buf_addr_info_set)(struct ath12k_buffer_addr *binfo, dma_addr_t paddr, u32 cookie, u8 manager); diff --git a/drivers/net/wireless/ath/ath12k/htc.c b/drivers/net/wireless/ath/ath12k/htc.c index fe8218a56125b..92138caa2a82f 100644 --- a/drivers/net/wireless/ath/ath12k/htc.c +++ b/drivers/net/wireless/ath/ath12k/htc.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 3b2c37cc5d280..5cd10752b22e1 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13209,6 +13209,7 @@ int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_get_survey); static void ath12k_mac_put_chain_rssi(struct station_info *sinfo, struct ath12k_link_sta *arsta) @@ -13230,7 +13231,6 @@ static void ath12k_mac_put_chain_rssi(struct station_info *sinfo, } } } -EXPORT_SYMBOL(ath12k_mac_op_get_survey); void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -13397,8 +13397,10 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, } link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); + if (!db2dbm) link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); link_sinfo->tx_retries = peer->tx_retry_count; @@ -13416,8 +13418,10 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, params.vdev_id = 0; params.stats_id = WMI_REQUEST_VDEV_STAT; - if (!ath12k_mac_get_fw_stats(ar, ¶ms)) + if (!ath12k_mac_get_fw_stats(ar, ¶ms)) { signal = arsta->rssi_beacon; + ath12k_fw_stats_reset(ar); + } } if (signal) { diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c index 1f680f6e65d30..45c0f66dcc5ea 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.c +++ b/drivers/net/wireless/ath/ath12k/mhi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include diff --git a/drivers/net/wireless/ath/ath12k/mhi.h b/drivers/net/wireless/ath/ath12k/mhi.h index 5e1363650a9a7..3674326763858 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.h +++ b/drivers/net/wireless/ath/ath12k/mhi.h @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef _ATH12K_MHI_H diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 0b2c7f37c7566..2b194879ee80d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -151,6 +151,8 @@ static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .peer_rx_tid_reo_update = ath12k_wifi7_peer_rx_tid_reo_update, .rx_assign_reoq = ath12k_wifi7_dp_rx_assign_reoq, .peer_rx_tid_qref_setup = ath12k_wifi7_peer_rx_tid_qref_setup, + .peer_rx_tid_qref_reset = ath12k_wifi7_peer_rx_tid_qref_reset, + .rx_tid_delete_handler = ath12k_wifi7_dp_rx_tid_delete_handler, }; /* TODO: remove export once this file is built with wifi7 ko */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 9878553289c47..bd741532b7dc8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -697,7 +697,7 @@ ath12k_wifi7_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, if (ppdu_info->is_stbc && nsts > 0) nsts = ((nsts + 1) >> 1) - 1; - ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK); + ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK) + 1; ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); @@ -722,7 +722,7 @@ ath12k_wifi7_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); - ppdu_info->nss = (ppdu_info->mcs >> 3); + ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; } static void @@ -756,7 +756,9 @@ ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_in value = value << HE_STA_ID_SHIFT; ppdu_info->he_data4 |= value; - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); + ppdu_info->nss = + u32_get_bits(info0, + HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS) + 1; ppdu_info->beamformed = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); } @@ -784,7 +786,9 @@ ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he value = value << HE_STA_ID_SHIFT; ppdu_info->he_data4 |= value; - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); + ppdu_info->nss = + u32_get_bits(info0, + HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1; } static void @@ -1077,7 +1081,8 @@ ath12k_wifi7_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + ppdu_info->nss = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1; ppdu_info->dcm = dcm; } @@ -1475,6 +1480,34 @@ static void ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; } +static void +ath12k_wifi7_parse_cmn_usr_info(const struct hal_phyrx_common_user_info *cmn_usr_info, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data, cp_setting, ltf_size; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_GI | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF; + eht->known = cpu_to_le32(known); + + cp_setting = le32_get_bits(cmn_usr_info->info0, + HAL_RX_CMN_USR_INFO0_CP_SETTING); + ltf_size = le32_get_bits(cmn_usr_info->info0, + HAL_RX_CMN_USR_INFO0_LTF_SIZE); + + data = __le32_to_cpu(eht->data[0]); + data |= u32_encode_bits(cp_setting, IEEE80211_RADIOTAP_EHT_DATA0_GI); + data |= u32_encode_bits(ltf_size, IEEE80211_RADIOTAP_EHT_DATA0_LTF); + eht->data[0] = cpu_to_le32(data); + + if (!ppdu_info->ltf_size) + ppdu_info->ltf_size = ltf_size; + if (!ppdu_info->gi) + ppdu_info->gi = cp_setting; +} + static void ath12k_wifi7_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end) @@ -1663,25 +1696,22 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; info[0] = __le32_to_cpu(rssi->info0); - info[1] = __le32_to_cpu(rssi->info1); + info[2] = __le32_to_cpu(rssi->info2); /* TODO: Please note that the combined rssi will not be accurate * in MU case. Rssi in MU needs to be retrieved from * PHYRX_OTHER_RECEIVE_INFO TLV. */ ppdu_info->rssi_comb = - u32_get_bits(info[1], - HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB); + u32_get_bits(info[2], + HAL_RX_RSSI_LEGACY_INFO_INFO2_RSSI_COMB_PPDU); ppdu_info->bw = u32_get_bits(info[0], - HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW); + HAL_RX_RSSI_LEGACY_INFO_INFO0_RX_BW); break; } - case HAL_PHYRX_OTHER_RECEIVE_INFO: { - const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data; - - ppdu_info->gi = le32_get_bits(cmn_usr_info->info0, - HAL_RX_PHY_CMN_USER_INFO0_GI); + case HAL_PHYRX_COMMON_USER_INFO: { + ath12k_wifi7_parse_cmn_usr_info(tlv_data, ppdu_info); break; } case HAL_RX_PPDU_START_USER_INFO: @@ -2438,7 +2468,8 @@ ath12k_wifi7_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, decap = mon_mpdu->decap_format; ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); - ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); + ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, ppduinfo, + rxs, decap); mon_skb = skb_next; } while (mon_skb); rxs->flag = 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index af50dafc03499..a1ca55fe51c06 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -64,8 +64,8 @@ void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u1 ath12k_hal_reo_shared_qaddr_cache_clear(ab); } -static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, - u16 peer_id, u16 tid) +void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, + u16 peer_id, u16 tid) { struct ath12k_reo_queue_ref *qref; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); @@ -94,35 +94,13 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid) { - struct ath12k_hal_reo_cmd cmd = {}; - struct ath12k_dp_rx_tid *rx_tid = &peer->dp_peer->rx_tid[tid]; - int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); if (!(peer->rx_tid_active_bitmask & (1 << tid))) return; - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.upd0 = HAL_REO_CMD_UPD0_VLD; - ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - ath12k_dp_rx_tid_del_func); - if (ret) { - ath12k_err(ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", - tid, ret); - dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, - rx_tid->qbuf.size, DMA_BIDIRECTIONAL); - kfree(rx_tid->qbuf.vaddr); - rx_tid->qbuf.vaddr = NULL; - } - - if (peer->mlo) - ath12k_wifi7_peer_rx_tid_qref_reset(ab, peer->ml_id, tid); - else - ath12k_wifi7_peer_rx_tid_qref_reset(ab, peer->peer_id, tid); - - peer->rx_tid_active_bitmask &= ~(1 << tid); + ath12k_dp_mark_tid_as_inactive(dp, peer->peer_id, tid); + ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(dp); } int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_dp *dp, @@ -157,7 +135,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_dp *dp, } int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid, + struct ath12k_dp_rx_tid_rxq *rx_tid, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, void (*cb)(struct ath12k_dp *dp, void *ctx, @@ -211,9 +189,13 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_base *ab = dp->ab; int ret; + struct ath12k_dp_rx_tid_rxq rx_tid_rxq; - cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid, + (peer->rx_tid_active_bitmask & (1 << rx_tid->tid))); + + cmd.addr_lo = lower_32_bits(rx_tid_rxq.qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid_rxq.qbuf.paddr_aligned); cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE; cmd.ba_window_size = ba_win_sz; @@ -223,12 +205,12 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); } - ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + ret = ath12k_wifi7_dp_reo_cmd_send(ab, &rx_tid_rxq, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL); if (ret) { ath12k_warn(ab, "failed to update rx tid queue, tid %d (%d)\n", - rx_tid->tid, ret); + rx_tid_rxq.tid, ret); return ret; } @@ -237,44 +219,33 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, return 0; } -void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid) +int ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid) { struct ath12k_hal_reo_cmd cmd = {}; - unsigned long tot_desc_sz, desc_sz; int ret; - tot_desc_sz = rx_tid->qbuf.size; - desc_sz = ath12k_wifi7_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); - - while (tot_desc_sz > desc_sz) { - tot_desc_sz -= desc_sz; - cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz); - cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, &cmd, - NULL); - if (ret) - ath12k_warn(ab, - "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", - rx_tid->tid, ret); - } - - memset(&cmd, 0, sizeof(cmd)); cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + /* HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS - all pending MPDUs + *in the bitmap will be forwarded/flushed to REO output rings + */ + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS | + HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS; + + /* For all QoS TIDs (except NON_QOS), the driver allocates a maximum + * window size of 1024. In such cases, the driver can issue a single + * 1KB descriptor flush command instead of sending multiple 128-byte + * flush commands for each QoS TID, improving efficiency. + */ + + if (rx_tid->tid != HAL_DESC_REO_NON_QOS_TID) + cmd.flag |= HAL_REO_CMD_FLG_FLUSH_QUEUE_1K_DESC; + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, HAL_REO_CMD_FLUSH_CACHE, &cmd, ath12k_dp_reo_cmd_free); - if (ret) { - ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", - rx_tid->tid, ret); - dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size, - DMA_BIDIRECTIONAL); - kfree(rx_tid->qbuf.vaddr); - rx_tid->qbuf.vaddr = NULL; - } + return ret; } int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, @@ -327,6 +298,23 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer return 0; } +int ath12k_wifi7_dp_rx_tid_delete_handler(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid) +{ + struct ath12k_hal_reo_cmd cmd = {}; + + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; + /* Observed flush cache failure, to avoid that set vld bit during delete */ + cmd.upd1 |= HAL_REO_CMD_UPD1_VLD; + + return ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + ath12k_dp_rx_tid_del_func); +} + static void ath12k_wifi7_dp_rx_h_csum_offload(struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { @@ -1356,6 +1344,50 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } +static int ath12k_dp_h_msdu_buffer_type(struct ath12k_dp *dp, + struct list_head *list, + struct hal_reo_dest_ring *desc) +{ + struct ath12k_rx_desc_info *desc_info; + struct ath12k_skb_rxcb *rxcb; + struct sk_buff *msdu; + u64 desc_va; + + dp->device_stats.reo_excep_msdu_buf_type++; + + desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo); + desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; + if (!desc_info) { + u32 cookie; + + cookie = le32_get_bits(desc->buf_addr_info.info1, + BUFFER_ADDR_INFO1_SW_COOKIE); + desc_info = ath12k_dp_get_rx_desc(dp, cookie); + if (!desc_info) { + ath12k_warn(dp->ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", + cookie); + return -EINVAL; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { + ath12k_warn(dp->ab, "rx exception, magic check failed with value: %u\n", + desc_info->magic); + return -EINVAL; + } + + msdu = desc_info->skb; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, list); + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + dev_kfree_skb_any(msdu); + + return 0; +} + int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget) { @@ -1405,6 +1437,26 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap drop = false; dp->device_stats.err_ring_pkts++; + hw_link_id = le32_get_bits(reo_desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + device_id = hw_links[hw_link_id].device_id; + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + + /* Below case is added to handle data packet from un-associated clients. + * As it is expected that AST lookup will fail for + * un-associated station's data packets. + */ + if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == + HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { + if (!ath12k_dp_h_msdu_buffer_type(partner_dp, + &rx_desc_used_list[device_id], + reo_desc)) { + num_buffs_reaped[device_id]++; + tot_n_bufs_reaped++; + } + goto next_desc; + } + ret = ath12k_wifi7_hal_desc_reo_parse_err(dp, reo_desc, &paddr, &desc_bank); if (ret) { @@ -1413,11 +1465,6 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap continue; } - hw_link_id = le32_get_bits(reo_desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - device_id = hw_links[hw_link_id].device_id; - partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); @@ -1479,6 +1526,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap rcu_read_unlock(); +next_desc: if (tot_n_bufs_reaped >= quota) { tot_n_bufs_reaped = quota; goto exit; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index d15bffe223c7d..a98836b83f482 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -37,19 +37,23 @@ void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u1 dma_addr_t paddr); void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid); -int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, +int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, void (*cb)(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status)); -void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid); +int ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid); int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); +void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid); bool ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); +int ath12k_wifi7_dp_rx_tid_delete_handler(struct ath12k_base *ab, + struct ath12k_dp_rx_tid_rxq *rx_tid); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 0a39862d07c45..7d65b82c61f25 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -383,6 +383,7 @@ #define HAL_REO_CMD_FLG_FLUSH_ALL BIT(6) #define HAL_REO_CMD_FLG_UNBLK_RESOURCE BIT(7) #define HAL_REO_CMD_FLG_UNBLK_CACHE BIT(8) +#define HAL_REO_CMD_FLG_FLUSH_QUEUE_1K_DESC BIT(9) /* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO0_UPD_* fields */ #define HAL_REO_CMD_UPD0_RX_QUEUE_NUM BIT(8) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 4b6f43389b2d9..c129e937132b4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1022,6 +1022,7 @@ const struct hal_ops hal_qcn9274_ops = { .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, .cc_config = ath12k_wifi7_hal_cc_config, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 241fa0d9a2842..903fb52a03bfd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -954,7 +954,7 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) ring_hash_map); } -void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) +void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) { u32 val; struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 1f2cfba3aac1c..8a0f4a781d8a2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -862,6 +862,7 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, u16 *num_msdus); void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); +void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, int tid, u32 ba_window_size, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index f243bc3ab4097..7108cc41536d1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -794,6 +794,7 @@ const struct hal_ops hal_wcn7850_ops = { .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 158466680b521..17ffc4822741c 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4089,7 +4089,6 @@ int ath12k_wmi_wait_for_unified_ready(struct ath12k_base *ab) int ath12k_wmi_set_hw_mode(struct ath12k_base *ab, enum wmi_host_hw_mode_config_type mode) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_wmi_pdev_set_hw_mode_cmd *cmd; struct sk_buff *skb; struct ath12k_wmi_base *wmi_ab = &ab->wmi_ab; @@ -4121,6 +4120,7 @@ int ath12k_wmi_set_hw_mode(struct ath12k_base *ab, int ath12k_wmi_cmd_init(struct ath12k_base *ab) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_wmi_base *wmi_ab = &ab->wmi_ab; struct ath12k_wmi_init_cmd_arg arg = {}; @@ -7276,8 +7276,8 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff struct wmi_peer_sta_kickout_arg arg = {}; struct ath12k_link_vif *arvif; struct ieee80211_sta *sta; + struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; - unsigned int link_id; struct ath12k *ar; if (ath12k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) { @@ -7297,34 +7297,16 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff goto exit; } - arvif = ath12k_mac_get_arvif_by_vdev_id(ab, peer->vdev_id); + arvif = arsta->arvif; if (!arvif) { - ath12k_warn(ab, "invalid vdev id in peer sta kickout ev %d", - peer->vdev_id); + ath12k_warn(ab, "invalid arvif in peer sta kickout ev for STA %pM", + arg.mac_addr); goto exit; } ar = arvif->ar; - - if (peer->mlo) { - sta = ieee80211_find_sta_by_link_addrs(ath12k_ar_to_hw(ar), - arg.mac_addr, - NULL, &link_id); - if (peer->link_id != link_id) { - ath12k_warn(ab, - "Spurious quick kickout for MLO STA %pM with invalid link_id, peer: %d, sta: %d\n", - arg.mac_addr, peer->link_id, link_id); - goto exit; - } - } else { - sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar), - arg.mac_addr, NULL); - } - if (!sta) { - ath12k_warn(ab, "Spurious quick kickout for %sSTA %pM\n", - peer->mlo ? "MLO " : "", arg.mac_addr); - goto exit; - } + ahsta = arsta->ahsta; + sta = ath12k_ahsta_to_sta(ahsta); ath12k_dbg(ab, ATH12K_DBG_WMI, "peer sta kickout event %pM reason: %d rssi: %d\n", @@ -7421,10 +7403,10 @@ static void ath12k_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb) } rcu_read_lock(); - ar = arsta->arvif->ar; + ar = ath12k_mac_get_ar_by_vdev_id(ab, le32_to_cpu(ch_info_ev.vdev_id)); if (!ar) { - ath12k_warn(ab, "invalid ar in peer sta kickout ev for STA %pM\n", - arg.mac_addr); + ath12k_warn(ab, "invalid vdev id in chan info ev %d", + ch_info_ev.vdev_id); rcu_read_unlock(); return; } From 480f490d3cb65df2b9d2c809f6c6e644b3ceb2cf Mon Sep 17 00:00:00 2001 From: Alexander Minchev Date: Thu, 27 Nov 2025 07:29:37 +0000 Subject: [PATCH 471/659] wifi: ath12k: remove redundant pci_set_drvdata() call pci_set_drvdata() is called twice in ath12k_pci_probe() with the same pointer. Remove the earlier call so drvdata is set after ath12k_base and ath12k_pci initialization is complete. Having two calls might suggest that drvdata needs to be set early for some reason, even though it is not used until after the 'ab' struct ath12k_base is fully populated. Even though exact placement is not critical, keeping a single pci_set_drvdata() at the end of the initialization makes it clearer that drvdata points to a fully initialized structure and avoids confusion for future changes. Tested on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Reviewed-by: Baochen Qiang Signed-off-by: Alexander Minchev Link: https://patch.msgid.link/20251127072839.14167-2-adminchev@proton.me Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index a42c4289c6b27..151ae0c354780 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1541,7 +1541,6 @@ static int ath12k_pci_probe(struct pci_dev *pdev, } ab->dev = &pdev->dev; - pci_set_drvdata(pdev, ab); ab_pci = ath12k_pci_priv(ab); ab_pci->dev_id = pci_dev->device; ab_pci->ab = ab; From 1fa163383d254de35e9b5ba44527453fe34a078e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 18 Dec 2025 10:44:20 +0300 Subject: [PATCH 472/659] wifi: ath12k: clean up on error in ath12k_dp_setup() Destroy the rhash_tbl before returning the error code. Fixes: a88cf5f71adf ("wifi: ath12k: Add hash table for ath12k_dp_link_peer") Signed-off-by: Dan Carpenter Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/aUOw1J0TU4VgeXj6@stanley.mountain Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 9f05eea6695a5..ab54c8a84d3e0 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1513,7 +1513,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab) HAL_WBM_IDLE_LINK, srng, n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup link desc: %d\n", ret); - return ret; + goto rhash_destroy; } ret = ath12k_dp_cc_init(ab); From 90dea84e19a315a70e0bb6a1efecd339ec1965ed Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 3 Nov 2025 10:44:49 +0800 Subject: [PATCH 473/659] wifi: ath12k: do WoW offloads only on primary link In case of multi-link connection, WCN7850 firmware crashes due to WoW offloads enabled on both primary and secondary links. Change to do it only on primary link to fix it. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Fixes: 32f7b19668bd ("wifi: ath12k: support MLO as well if single_chip_mlo_support flag is set") Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251103-ath12-primary-link-wow-v1-1-3cf523dc09f0@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wow.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c index f56ec44a16361..bb08e17405825 100644 --- a/drivers/net/wireless/ath/ath12k/wow.c +++ b/drivers/net/wireless/ath/ath12k/wow.c @@ -135,6 +135,9 @@ static int ath12k_wow_cleanup(struct ath12k *ar) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + ret = ath12k_wow_vif_cleanup(arvif); if (ret) { ath12k_warn(ar->ab, "failed to clean wow wakeups on vdev %i: %d\n", @@ -479,8 +482,12 @@ static int ath12k_wow_set_wakeups(struct ath12k *ar, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + if (ath12k_wow_is_p2p_vdev(arvif->ahvif)) continue; + ret = ath12k_wow_vif_set_wakeups(arvif, wowlan); if (ret) { ath12k_warn(ar->ab, "failed to set wow wakeups on vdev %i: %d\n", @@ -538,6 +545,9 @@ static int ath12k_wow_nlo_cleanup(struct ath12k *ar) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + if (ath12k_wow_is_p2p_vdev(arvif->ahvif)) continue; @@ -745,6 +755,9 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable) list_for_each_entry(arvif, &ar->arvifs, list) { ahvif = arvif->ahvif; + if (arvif != &ahvif->deflink) + continue; + if (ahvif->vdev_type != WMI_VDEV_TYPE_STA) continue; @@ -776,6 +789,9 @@ static int ath12k_gtk_rekey_offload(struct ath12k *ar, bool enable) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA || !arvif->is_up || !arvif->rekey_data.enable_offload) From b3919aaff9e596021fe00f065d6991da12172aed Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:21 +0800 Subject: [PATCH 474/659] wifi: ath12k: refactor PCI window register access Currently offset of PCI window register address is defined as 0x310c which is same across existing chips. However QCC2072 has a different offset 0x3278. In order to make the window selection logic work for QCC2072 as well, change to initialize this parameter per device at the probe time. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-1-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 11 +++++------ drivers/net/wireless/ath/ath12k/pci.h | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/pci.c | 12 ++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 151ae0c354780..69579e59b5563 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -23,7 +23,6 @@ #define ATH12K_PCI_IRQ_CE0_OFFSET 3 #define WINDOW_ENABLE_BIT 0x40000000 -#define WINDOW_REG_ADDRESS 0x310c #define WINDOW_VALUE_MASK GENMASK(24, 19) #define WINDOW_START 0x80000 #define WINDOW_RANGE_MASK GENMASK(18, 0) @@ -125,8 +124,8 @@ static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset) if (window != ab_pci->register_window) { iowrite32(WINDOW_ENABLE_BIT | window, - ab->mem + WINDOW_REG_ADDRESS); - ioread32(ab->mem + WINDOW_REG_ADDRESS); + ab->mem + ab_pci->window_reg_addr); + ioread32(ab->mem + ab_pci->window_reg_addr); ab_pci->register_window = window; } } @@ -145,7 +144,7 @@ static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci) ab_pci->register_window = window; spin_unlock_bh(&ab_pci->window_lock); - iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + WINDOW_REG_ADDRESS); + iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + ab_pci->window_reg_addr); } static u32 ath12k_pci_get_window_start(struct ath12k_base *ab, @@ -178,8 +177,8 @@ static void ath12k_pci_restore_window(struct ath12k_base *ab) spin_lock_bh(&ab_pci->window_lock); iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window, - ab->mem + WINDOW_REG_ADDRESS); - ioread32(ab->mem + WINDOW_REG_ADDRESS); + ab->mem + ab_pci->window_reg_addr); + ioread32(ab->mem + ab_pci->window_reg_addr); spin_unlock_bh(&ab_pci->window_lock); } diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 1cc4f0e050f95..a74b09d23a6a1 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -130,6 +130,8 @@ struct ath12k_pci { u64 dma_mask; const struct ath12k_pci_device_family_ops *device_family_ops; const struct ath12k_pci_reg_base *reg_base; + + u32 window_reg_addr; }; struct ath12k_pci_driver { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index dedc88858bb0f..6c477fe97298f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -27,6 +27,8 @@ #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) +#define WINDOW_REG_ADDRESS 0x310c + static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, @@ -104,6 +106,11 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; + /* + * init window reg addr before reading hardware version + * as it will be used there + */ + ab_pci->window_reg_addr = WINDOW_REG_ADDRESS; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ath12k_core_get_memory_mode(ab); @@ -126,6 +133,11 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = false; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; + /* + * init window reg addr before reading hardware version + * as it will be used there + */ + ab_pci->window_reg_addr = WINDOW_REG_ADDRESS; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; From 4d4d40f386aeb4c90df57436392b516859e6abb0 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:22 +0800 Subject: [PATCH 475/659] wifi: ath12k: refactor REO CMD ring handling The entry of REO CMD ring of existing chips has a 64 bit TLV header, hence below functions take a 64 bit TLV assumption by default ath12k_wifi7_hal_reo_init_cmd_ring() ath12k_wifi7_hal_reo_cmd_queue_stats() ath12k_wifi7_hal_reo_cmd_flush_cache() ath12k_wifi7_hal_reo_cmd_update_rx_queue() However this is not the case for QCC2072 of which the TLV is 32 bit, meaning above functions don't work for it. Rename/refactor above functions to prepare for QCC2072 support: Rename the first one to ath12k_wifi7_hal_reo_init_cmd_ring_tlv64() to better reflect what it is doing. There will be a 32 bit variant when QCC2072 support is in place. For the last ones, remove TLV length assumption and offload TLV encoding work to a newly added callback _reo_cmd_enc_tlv_hdr. This way each chip can register its own handler hence can do the work accordingly. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-2-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 11 ++++++ drivers/net/wireless/ath/ath12k/hal.h | 23 +++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 21 ---------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 3 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 39 ++++++++----------- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 4 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 3 +- 7 files changed, 56 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index c7a152490fa09..b19bec8ea082d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -823,3 +823,14 @@ void ath12k_hal_dump_srng_stats(struct ath12k_base *ab) jiffies_to_msecs(jiffies - srng->timestamp)); } } + +void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len) +{ + struct hal_tlv_64_hdr *tlv64 = tlv; + + tlv64->tl = le64_encode_bits(tag, HAL_TLV_HDR_TAG) | + le64_encode_bits(len, HAL_TLV_HDR_LEN); + + return tlv64->value; +} +EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index f23ba1f9eaac2..595e490464715 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1426,8 +1426,30 @@ struct hal_ops { u32 *sw_cookie, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); + void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len); }; +#define HAL_TLV_HDR_TAG GENMASK(9, 1) +#define HAL_TLV_HDR_LEN GENMASK(25, 10) +#define HAL_TLV_USR_ID GENMASK(31, 26) + +#define HAL_TLV_ALIGN 4 + +struct hal_tlv_hdr { + __le32 tl; + u8 value[]; +} __packed; + +#define HAL_TLV_64_HDR_TAG GENMASK(9, 1) +#define HAL_TLV_64_HDR_LEN GENMASK(21, 10) +#define HAL_TLV_64_USR_ID GENMASK(31, 26) +#define HAL_TLV_64_ALIGN 8 + +struct hal_tlv_64_hdr { + __le64 tl; + u8 value[]; +} __packed; + dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1515,4 +1537,5 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); +void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 9dad8f7ca9f21..cdcf24b1d6eba 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -487,27 +487,6 @@ enum hal_tlv_tag { HAL_TLV_BASE = 511 /* 0x1ff */, }; -#define HAL_TLV_HDR_TAG GENMASK(9, 1) -#define HAL_TLV_HDR_LEN GENMASK(25, 10) -#define HAL_TLV_USR_ID GENMASK(31, 26) - -#define HAL_TLV_ALIGN 4 - -struct hal_tlv_hdr { - __le32 tl; - u8 value[]; -} __packed; - -#define HAL_TLV_64_HDR_TAG GENMASK(9, 1) -#define HAL_TLV_64_HDR_LEN GENMASK(21, 10) -#define HAL_TLV_64_USR_ID GENMASK(31, 26) -#define HAL_TLV_64_ALIGN 8 - -struct hal_tlv_64_hdr { - __le64 tl; - u8 value[]; -} __packed; - #define RX_MPDU_DESC_INFO0_MSDU_COUNT GENMASK(7, 0) #define RX_MPDU_DESC_INFO0_FRAG_FLAG BIT(8) #define RX_MPDU_DESC_INFO0_MPDU_RETRY BIT(9) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index c129e937132b4..ff26e9684e9e3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1020,7 +1020,7 @@ const struct hal_ops hal_qcn9274_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, - .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, @@ -1029,4 +1029,5 @@ const struct hal_ops hal_qcn9274_ops = { .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 903fb52a03bfd..3b8710a3b6ad2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -23,15 +23,13 @@ void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, hdr->info0 |= le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED); } -static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, +static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct ath12k_hal *hal, void *tlv, struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_get_queue_stats *desc; - tlv->tl = le64_encode_bits(HAL_REO_GET_QUEUE_STATS, HAL_TLV_HDR_TAG) | - le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN); - - desc = (struct hal_reo_get_queue_stats *)tlv->value; + desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_GET_QUEUE_STATS, + sizeof(*desc)); memset_startat(desc, 0, queue_addr_lo); desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); @@ -47,8 +45,7 @@ static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, - struct hal_tlv_64_hdr *tlv, +static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, void *tlv, struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_flush_cache *desc; @@ -61,10 +58,8 @@ static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, hal->current_blk_index = avail_slot; } - tlv->tl = le64_encode_bits(HAL_REO_FLUSH_CACHE, HAL_TLV_HDR_TAG) | - le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN); - - desc = (struct hal_reo_flush_cache *)tlv->value; + desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_FLUSH_CACHE, + sizeof(*desc)); memset_startat(desc, 0, cache_addr_lo); desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); @@ -98,15 +93,13 @@ static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, } static int -ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, +ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct ath12k_hal *hal, void *tlv, struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_update_rx_queue *desc; - tlv->tl = le64_encode_bits(HAL_REO_UPDATE_RX_REO_QUEUE, HAL_TLV_HDR_TAG) | - le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN); - - desc = (struct hal_reo_update_rx_queue *)tlv->value; + desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_UPDATE_RX_REO_QUEUE, + sizeof(*desc)); memset_startat(desc, 0, queue_addr_lo); desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); @@ -227,7 +220,8 @@ int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd) { - struct hal_tlv_64_hdr *reo_desc; + struct ath12k_hal *hal = &ab->hal; + void *reo_desc; int ret; spin_lock_bh(&srng->lock); @@ -241,14 +235,13 @@ int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, switch (type) { case HAL_REO_CMD_GET_QUEUE_STATS: - ret = ath12k_wifi7_hal_reo_cmd_queue_stats(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_queue_stats(hal, reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_CACHE: - ret = ath12k_wifi7_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, - cmd); + ret = ath12k_wifi7_hal_reo_cmd_flush_cache(hal, reo_desc, cmd); break; case HAL_REO_CMD_UPDATE_RX_QUEUE: - ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(hal, reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_QUEUE: case HAL_REO_CMD_UNBLOCK_CACHE: @@ -891,8 +884,8 @@ void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); } -void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng) +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, + struct hal_srng *srng) { struct hal_srng_params params; struct hal_tlv_64_hdr *tlv; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 8a0f4a781d8a2..aa1bca8139557 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -860,8 +860,8 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, void *link_desc, void *msdu_list_opaque, u16 *num_msdus); -void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng); +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, + struct hal_srng *srng); void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 7108cc41536d1..49c45431c0c79 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -793,7 +793,7 @@ const struct hal_ops hal_wcn7850_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, - .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, .reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, @@ -802,4 +802,5 @@ const struct hal_ops hal_wcn7850_ops = { .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, }; From 0f966b3dd091860a5d4f6721b0d1bd9611189f2a Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:23 +0800 Subject: [PATCH 476/659] wifi: ath12k: refactor REO status ring handling The entry of REO status ring of existing chips has a 64 bit TLV header, hence below functions take a 64 bit TLV assumption by default ath12k_wifi7_dp_rx_process_reo_status() ath12k_wifi7_hal_reo_status_queue_stats() ath12k_wifi7_hal_reo_flush_queue_status() ath12k_wifi7_hal_reo_flush_cache_status() ath12k_wifi7_hal_reo_unblk_cache_status() ath12k_wifi7_hal_reo_flush_timeout_list_status() ath12k_wifi7_hal_reo_desc_thresh_reached_status() ath12k_wifi7_hal_reo_update_rx_reo_queue_status() However this is not the case for QCC2072 of which the TLV is 32 bit. Refactor above functions to prepare for QCC2072 support, this is done by removing TLV length assumption and offloading TLV decoding work to a newly added callback _reo_status_dec_tlv_hdr. This way each chip can register its own handler hence can do the work accordingly. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-3-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 12 +++++++ drivers/net/wireless/ath/ath12k/hal.h | 5 +++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 18 +++++----- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 3 -- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 33 ++++--------------- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 24 +++++++------- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 + 8 files changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index b19bec8ea082d..bafb49ab5475f 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -834,3 +834,15 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len) return tlv64->value; } EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr); + +u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc) +{ + struct hal_tlv_64_hdr *tlv64 = tlv; + u16 tag; + + tag = le64_get_bits(tlv64->tl, HAL_SRNG_TLV_HDR_TAG); + *desc = tlv64->value; + + return tag; +} +EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 595e490464715..81b0cb002b38c 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1427,6 +1427,7 @@ struct hal_ops { struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len); + u16 (*reo_status_dec_tlv_hdr)(void *tlv, void **desc); }; #define HAL_TLV_HDR_TAG GENMASK(9, 1) @@ -1450,6 +1451,9 @@ struct hal_tlv_64_hdr { u8 value[]; } __packed; +#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) +#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) + dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1538,4 +1542,5 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); +u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index a1ca55fe51c06..dc8d72aeca457 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2114,12 +2114,12 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) { struct ath12k_base *ab = dp->ab; struct ath12k_hal *hal = dp->hal; - struct hal_tlv_64_hdr *hdr; struct hal_srng *srng; struct ath12k_dp_rx_reo_cmd *cmd, *tmp; bool found = false; u16 tag; struct hal_reo_status reo_status; + void *hdr, *desc; srng = &hal->srng_list[dp->reo_status_ring.ring_id]; @@ -2130,35 +2130,35 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) ath12k_hal_srng_access_begin(ab, srng); while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); + tag = hal->ops->reo_status_dec_tlv_hdr(hdr, &desc); switch (tag) { case HAL_REO_GET_QUEUE_STATS_STATUS: - ath12k_wifi7_hal_reo_status_queue_stats(ab, hdr, + ath12k_wifi7_hal_reo_status_queue_stats(ab, desc, &reo_status); break; case HAL_REO_FLUSH_QUEUE_STATUS: - ath12k_wifi7_hal_reo_flush_queue_status(ab, hdr, + ath12k_wifi7_hal_reo_flush_queue_status(ab, desc, &reo_status); break; case HAL_REO_FLUSH_CACHE_STATUS: - ath12k_wifi7_hal_reo_flush_cache_status(ab, hdr, + ath12k_wifi7_hal_reo_flush_cache_status(ab, desc, &reo_status); break; case HAL_REO_UNBLOCK_CACHE_STATUS: - ath12k_wifi7_hal_reo_unblk_cache_status(ab, hdr, + ath12k_wifi7_hal_reo_unblk_cache_status(ab, desc, &reo_status); break; case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: - ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, hdr, + ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, desc, &reo_status); break; case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: - ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, hdr, + ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, desc, &reo_status); break; case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: - ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, hdr, + ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, desc, &reo_status); break; default: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 7d65b82c61f25..9337225a52533 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -369,9 +369,6 @@ #define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) #define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000) -#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) -#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) - #define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 #define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index ff26e9684e9e3..95850e6dc6c72 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1030,4 +1030,5 @@ const struct hal_ops hal_qcn9274_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 3b8710a3b6ad2..a88ef126aadab 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -543,12 +543,9 @@ ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_get_queue_stats_status *desc, struct hal_reo_status *status) { - struct hal_reo_get_queue_stats_status *desc = - (struct hal_reo_get_queue_stats_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -607,12 +604,9 @@ void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_queue_status *desc, struct hal_reo_status *status) { - struct hal_reo_flush_queue_status *desc = - (struct hal_reo_flush_queue_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -626,12 +620,10 @@ void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_cache_status *desc, struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; - struct hal_reo_flush_cache_status *desc = - (struct hal_reo_flush_cache_status *)tlv->value; status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, @@ -668,12 +660,10 @@ ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_unblock_cache_status *desc, struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; - struct hal_reo_unblock_cache_status *desc = - (struct hal_reo_unblock_cache_status *)tlv->value; status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, @@ -697,12 +687,9 @@ void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_timeout_list_status *desc, struct hal_reo_status *status) { - struct hal_reo_flush_timeout_list_status *desc = - (struct hal_reo_flush_timeout_list_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -727,12 +714,9 @@ ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_desc_thresh_reached_status *desc, struct hal_reo_status *status) { - struct hal_reo_desc_thresh_reached_status *desc = - (struct hal_reo_desc_thresh_reached_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -762,12 +746,9 @@ ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_status_hdr *desc, struct hal_reo_status *status) { - struct hal_reo_status_hdr *desc = - (struct hal_reo_status_hdr *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index aa1bca8139557..95f5595b30ad1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -813,25 +813,27 @@ enum hal_mon_reception_type { (HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz)) void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_get_queue_stats_status *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_queue_status *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_cache_status *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_unblock_cache_status *desc, struct hal_reo_status *status); -void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); +void +ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, + struct hal_reo_flush_timeout_list_status *desc, + struct hal_reo_status *status); +void +ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, + struct hal_reo_desc_thresh_reached_status *desc, + struct hal_reo_status *status); void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_status_hdr *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, u32 *msdu_cookies, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 49c45431c0c79..c3093c01af878 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -803,4 +803,5 @@ const struct hal_ops hal_wcn7850_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; From 867bc1dd908cd6146f8b26c915de4e2b86ce6827 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:24 +0800 Subject: [PATCH 477/659] wifi: ath12k: fix preferred hardware mode calculation For single pdev device like WCN7850/QCC2072, preferred_hw_mode is initialized to WMI_HOST_HW_MODE_SINGLE. Later when firmware sends supported modes to host, each mode is compared with the initial one and if the priority of the new mode is higher, update the parameter and store mode capability. For WCN7850, this does not result in issue, as one of the supported mode indeed has a higher priority. However the only available mode of QCC2072 at this stage is WMI_HOST_HW_MODE_SINGLE, which fails the comparison, hence mode capability is not stored. Subsequently driver initialization fails. Fix it by accepting a mode with the same priority. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-4-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 17ffc4822741c..32c4e7fe03c45 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4449,7 +4449,7 @@ static int ath12k_wmi_hw_mode_caps(struct ath12k_base *soc, pref = soc->wmi_ab.preferred_hw_mode; - if (ath12k_hw_mode_pri_map[mode] < ath12k_hw_mode_pri_map[pref]) { + if (ath12k_hw_mode_pri_map[mode] <= ath12k_hw_mode_pri_map[pref]) { svc_rdy_ext->pref_hw_mode_caps = *hw_mode_caps; soc->wmi_ab.preferred_hw_mode = mode; } From 6782b64e7dced5702a6b244615538aa4b2f355db Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:25 +0800 Subject: [PATCH 478/659] wifi: ath12k: refactor 320 MHz bandwidth support parsing For single pdev device, 320 MHz bandwidth support is reported only in capability of WMI_HOST_HW_MODE_SINGLE mode, hence commit d4e244c85e45 ("wifi: ath12k: enable 320 MHz bandwidth for 6 GHz band in EHT PHY capability for WCN7850") relaxed the condition check in ath12k_wmi_tlv_mac_phy_caps_ext() to allow SINGLE mode getting parsed in ath12k_wmi_tlv_mac_phy_caps_ext_parse(). Since SINGLE mode is not assumed to be preferred, the function returns unconditionally after parsing 320 MHz support. This works for WCN7850 because it prefers another mode indeed, while it breaks QCC2072 since it prefers SINGLE mode. Due to the unconditional return, the subsequent EHT parsing is skipped. Consequently EHT related features are disabled. Refactor it by moving 320 MHz parsing to ath12k_wmi_tlv_mac_phy_caps_ext(), before the mode checking. This makes the code more straightforward, and work for both WCN7850 and QCC2072. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-5-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 32c4e7fe03c45..248933eac061e 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4918,19 +4918,10 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab, const struct ath12k_wmi_caps_ext_params *caps, struct ath12k_pdev *pdev) { - struct ath12k_band_cap *cap_band; - u32 bands, support_320mhz; + u32 bands; int i; if (ab->hw_params->single_pdev_only) { - if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) { - support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) & - IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; - cap_band = &pdev->cap.band[NL80211_BAND_6GHZ]; - cap_band->eht_cap_phy_info[0] |= support_320mhz; - return 0; - } - for (i = 0; i < ab->fw_pdev_count; i++) { struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i]; @@ -4983,14 +4974,22 @@ static int ath12k_wmi_tlv_mac_phy_caps_ext(struct ath12k_base *ab, u16 tag, void *data) { const struct ath12k_wmi_caps_ext_params *caps = ptr; + struct ath12k_band_cap *cap_band; + u32 support_320mhz; int i = 0, ret; if (tag != WMI_TAG_MAC_PHY_CAPABILITIES_EXT) return -EPROTO; if (ab->hw_params->single_pdev_only) { - if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id) && - caps->hw_mode_id != WMI_HOST_HW_MODE_SINGLE) + if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) { + support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) & + IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; + cap_band = &ab->pdevs[0].cap.band[NL80211_BAND_6GHZ]; + cap_band->eht_cap_phy_info[0] |= support_320mhz; + } + + if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id)) return 0; } else { for (i = 0; i < ab->num_radios; i++) { From 501bda9e459721ce8765f9c2b2e6cc969ccab7a2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:26 +0800 Subject: [PATCH 479/659] wifi: ath12k: fix mac phy capability parsing Currently ath12k_pull_mac_phy_cap_svc_ready_ext() assumes only one band supported in each phy, hence it skips 5 GHz band if 2 GHz band support is detected. This does not work for device which gets only one phy but has both bands supported, such as QCC2072. Change to check each band individually to fix this issue. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-6-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 248933eac061e..79a26203afad6 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -399,6 +399,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, struct ath12k_band_cap *cap_band; struct ath12k_pdev_cap *pdev_cap = &pdev->cap; struct ath12k_fw_pdev *fw_pdev; + u32 supported_bands; u32 phy_map; u32 hw_idx, phy_idx = 0; int i; @@ -422,14 +423,19 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, return -EINVAL; mac_caps = wmi_mac_phy_caps + phy_idx; + supported_bands = le32_to_cpu(mac_caps->supported_bands); + + if (!(supported_bands & WMI_HOST_WLAN_2GHZ_CAP) && + !(supported_bands & WMI_HOST_WLAN_5GHZ_CAP)) + return -EINVAL; pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps); pdev->hw_link_id = ath12k_wmi_mac_phy_get_hw_link_id(mac_caps); - pdev_cap->supported_bands |= le32_to_cpu(mac_caps->supported_bands); + pdev_cap->supported_bands |= supported_bands; pdev_cap->ampdu_density = le32_to_cpu(mac_caps->ampdu_density); fw_pdev = &ab->fw_pdev[ab->fw_pdev_count]; - fw_pdev->supported_bands = le32_to_cpu(mac_caps->supported_bands); + fw_pdev->supported_bands = supported_bands; fw_pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps); fw_pdev->phy_id = le32_to_cpu(mac_caps->phy_id); ab->fw_pdev_count++; @@ -438,10 +444,12 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, * band to band for a single radio, need to see how this should be * handled. */ - if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) { + if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) { pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_2g); pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_2g); - } else if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) { + } + + if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) { pdev_cap->vht_cap = le32_to_cpu(mac_caps->vht_cap_info_5g); pdev_cap->vht_mcs = le32_to_cpu(mac_caps->vht_supp_mcs_5g); pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g); @@ -451,8 +459,6 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, WMI_NSS_RATIO_EN_DIS_GET(mac_caps->nss_ratio); pdev_cap->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_caps->nss_ratio); - } else { - return -EINVAL; } /* tx/rx chainmask reported from fw depends on the actual hw chains used, @@ -468,7 +474,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, pdev_cap->rx_chain_mask_shift = find_first_bit((unsigned long *)&pdev_cap->rx_chain_mask, 32); - if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) { + if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) { cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; cap_band->phy_id = le32_to_cpu(mac_caps->phy_id); cap_band->max_bw_supported = le32_to_cpu(mac_caps->max_bw_supported_2g); @@ -488,7 +494,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, le32_to_cpu(mac_caps->he_ppet2g.ppet16_ppet8_ru3_ru0[i]); } - if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) { + if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) { cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; cap_band->phy_id = le32_to_cpu(mac_caps->phy_id); cap_band->max_bw_supported = From 37ecb32713242ee5c492e02e4a925d2f2bf4ab5b Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:27 +0800 Subject: [PATCH 480/659] wifi: ath12k: add hardware registers for QCC2072 Add hardware registers and populate hw_regs field in ath12k_wifi7_hw_ver_map for QCC2072. Note for some registers not defined and not used by QCC2072, a magic value is assigned. Also populate other fields to be the same with WCN7850. Among them, however, QCC2072 requires different HAL ops and descriptor size, both will be updated in upcoming patches. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-7-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/hal.h | 2 + .../net/wireless/ath/ath12k/wifi7/Makefile | 3 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 8 ++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 94 +++++++++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.h | 8 ++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 31d5d10beb85a..667cf5993cf15 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -155,6 +155,7 @@ enum ath12k_hw_rev { ATH12K_HW_QCN9274_HW20, ATH12K_HW_WCN7850_HW20, ATH12K_HW_IPQ5332_HW10, + ATH12K_HW_QCC2072_HW10, }; enum ath12k_firmware_mode { diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 81b0cb002b38c..94ecc035fc493 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1121,6 +1121,8 @@ struct ath12k_hw_hal_params { u32 wbm2sw_cc_enable; }; +#define ATH12K_HW_REG_UNDEFINED 0xdeadbeaf + struct ath12k_hw_regs { u32 tcl1_ring_id; u32 tcl1_ring_misc; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index dcfa732bb95bc..45b561cdba4b1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -14,6 +14,7 @@ ath12k_wifi7-y += core.o \ dp_mon.o \ hal.o \ hal_qcn9274.o \ - hal_wcn7850.o + hal_wcn7850.o \ + hal_qcc2072.o ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 03a007dd6857f..b957ebc9b7c5c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -12,6 +12,7 @@ #include "../hif.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" +#include "hal_qcc2072.h" static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { [ATH12K_HW_QCN9274_HW10] = { @@ -42,6 +43,13 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { .hal_params = &ath12k_hw_hal_params_ipq5332, .hw_regs = &ipq5332_regs, }, + [ATH12K_HW_QCC2072_HW10] = { + .hal_ops = &hal_wcn7850_ops, + .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, + .hal_params = &ath12k_hw_hal_params_wcn7850, + .hw_regs = &qcc2072_regs, + }, }; int ath12k_wifi7_hal_init(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c new file mode 100644 index 0000000000000..6c4986050bc6a --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_qcc2072.h" + +const struct ath12k_hw_regs qcc2072_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .tcl1_ring_id = 0x00000920, + .tcl1_ring_misc = 0x00000928, + .tcl1_ring_tp_addr_lsb = 0x00000934, + .tcl1_ring_tp_addr_msb = 0x00000938, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000948, + .tcl1_ring_consumer_int_setup_ix1 = 0x0000094c, + .tcl1_ring_msi1_base_lsb = 0x00000960, + .tcl1_ring_msi1_base_msb = 0x00000964, + .tcl1_ring_msi1_data = 0x00000968, + .tcl_ring_base_lsb = 0x00000b70, + .tcl1_ring_base_lsb = 0x00000918, + .tcl1_ring_base_msb = 0x0000091c, + .tcl2_ring_base_lsb = 0x00000990, + + /* TCL STATUS ring address */ + .tcl_status_ring_base_lsb = 0x00000d50, + + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x00000027c, + + .wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw1_release_ring_base_lsb = ATH12K_HW_REG_UNDEFINED, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, + .pcie_pcs_osc_dtct_config_base = 0x01e0cc58, + + /* PPE release ring address */ + .ppe_rel_ring_base = 0x0000046c, + + /* REO DEST ring address */ + .reo2_ring_base = 0x00000578, + .reo1_misc_ctrl_addr = 0x00000ba0, + .reo1_sw_cookie_cfg0 = 0x0000006c, + .reo1_sw_cookie_cfg1 = 0x00000070, + .reo1_qdesc_lut_base0 = ATH12K_HW_REG_UNDEFINED, + .reo1_qdesc_lut_base1 = ATH12K_HW_REG_UNDEFINED, + + .reo1_ring_base_lsb = 0x00000500, + .reo1_ring_base_msb = 0x00000504, + .reo1_ring_id = 0x00000508, + .reo1_ring_misc = 0x00000510, + .reo1_ring_hp_addr_lsb = 0x00000514, + .reo1_ring_hp_addr_msb = 0x00000518, + .reo1_ring_producer_int_setup = 0x00000524, + .reo1_ring_msi1_base_lsb = 0x00000548, + .reo1_ring_msi1_base_msb = 0x0000054c, + .reo1_ring_msi1_data = 0x00000550, + .reo1_aging_thres_ix0 = 0x00000b2c, + .reo1_aging_thres_ix1 = 0x00000b30, + .reo1_aging_thres_ix2 = 0x00000b34, + .reo1_aging_thres_ix3 = 0x00000b38, + + /* REO Exception ring address */ + .reo2_sw0_ring_base = 0x000008c0, + + /* REO Reinject ring address */ + .sw2reo_ring_base = 0x00000320, + .sw2reo1_ring_base = 0x00000398, + + /* REO cmd ring address */ + .reo_cmd_ring_base = 0x000002a8, + + /* REO status ring address */ + .reo_status_ring_base = 0x00000aa0, + + /* CE base address */ + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e65304, +}; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h new file mode 100644 index 0000000000000..744d7e02b46e6 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "../hal.h" + +extern const struct ath12k_hw_regs qcc2072_regs; From a13247220fde12742ed8a491adf9a88a96ca93f5 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:28 +0800 Subject: [PATCH 481/659] wifi: ath12k: add hardware parameters for QCC2072 Add hardware parameters for QCC2072, these parameters are directly taken from WCN7850, with exceptions to hardware name, revision, firmware directory, iova_mask and RFKILL parameter set. Compared to WCN7850, QCC2072 doesn't require aligned IOVA when transmitting packets, hence iova_mask is set to zero. Besides, WCN7850 has a dedicated GPIO for RFKILL purpose, however QCC2072 has it coupled with WLAN_EN pin. For QCC2072, host is not allowed to send any RFKILL configuration info to firmware, or firmware crashes. Hence those parameters are all cleared to skip configuring command. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-8-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 1f5dda73230d0..ef0a59f6339cf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -652,6 +652,91 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .dp_primary_link_only = true, }, + { + .name = "qcc2072 hw1.0", + .hw_rev = ATH12K_HW_QCC2072_HW10, + + .fw = { + .dir = "QCC2072/hw1.0", + .board_size = 256 * 1024, + .cal_offset = 256 * 1024, + .m3_loader = ath12k_m3_fw_loader_driver, + }, + + .max_radios = 1, + .single_pdev_only = true, + .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, + .internal_sleep_clock = true, + + .hw_ops = &wcn7850_ops, + .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, + + .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, + .ce_count = 9, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850, + .target_ce_count = 9, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850, + .svc_to_ce_map_len = 14, + + .rxdma1_enable = false, + .num_rxdma_per_pdev = 2, + .num_rxdma_dst_ring = 1, + .rx_mac_buf_ring = true, + .vdev_start_delay = true, + + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_DEVICE) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO), + .supports_monitor = true, + + .idle_ps = true, + .download_calib = false, + .supports_suspend = true, + .tcl_ring_retry = false, + .reoq_lut_support = false, + .supports_shadow_regs = true, + + .num_tcl_banks = 7, + .max_tx_ring = 3, + + .mhi_config = &ath12k_wifi7_mhi_config_wcn7850, + + .wmi_init = ath12k_wifi7_wmi_init_wcn7850, + + .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | + BIT(CNSS_PCIE_PERST_NO_PULL_V01), + + .rfkill_pin = 0, + .rfkill_cfg = 0, + .rfkill_on_level = 0, + + .rddm_size = 0x780000, + + .def_num_link = 2, + .max_mlo_peer = 32, + + .otp_board_id_register = 0, + + .supports_sta_ps = true, + + .acpi_guid = &wcn7850_uuid, + .supports_dynamic_smps_6ghz = false, + + .iova_mask = 0, + + .supports_aspm = true, + + .ce_ie_addr = NULL, + .ce_remap = NULL, + .bdf_addr_offset = 0, + + .current_cc_support = true, + + .dp_primary_link_only = false, + }, }; /* Note: called under rcu_read_lock() */ From c77c995a28bbfbb03d795020c7bf54776acc4056 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:29 +0800 Subject: [PATCH 482/659] wifi: ath12k: support LPASS_SHARED target memory type QCC2072 requires a new type of QMI target memory named LPASS_SHARED_V01, add support for it. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-9-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/qmi.c | 1 + drivers/net/wireless/ath/ath12k/qmi.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index b7c48b6706dfc..4966697f4e625 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2609,6 +2609,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) case M3_DUMP_REGION_TYPE: case PAGEABLE_MEM_REGION_TYPE: case CALDB_MEM_REGION_TYPE: + case LPASS_SHARED_V01_REGION_TYPE: ret = ath12k_qmi_alloc_chunk(ab, chunk); if (ret) goto err; diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h index 7a88268aa1e9e..050dcaca1cb75 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.h +++ b/drivers/net/wireless/ath/ath12k/qmi.h @@ -178,6 +178,7 @@ enum ath12k_qmi_target_mem { CALDB_MEM_REGION_TYPE = 0x4, MLO_GLOBAL_MEM_REGION_TYPE = 0x8, PAGEABLE_MEM_REGION_TYPE = 0x9, + LPASS_SHARED_V01_REGION_TYPE = 0xb, }; enum qmi_wlanfw_host_build_type { From efa0b4d8441d9bbf583fef13eafdd6cd614fb0d4 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:30 +0800 Subject: [PATCH 483/659] wifi: ath12k: support downloading auxiliary ucode image for QCC2072 QCC2072 requires another firmware image named aux_ucode.bin, add support to download it. Add a new hardware parameter download_aux_ucode to make sure other chips are not affected. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-10-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 + drivers/net/wireless/ath/ath12k/fw.c | 10 +- drivers/net/wireless/ath/ath12k/fw.h | 3 +- drivers/net/wireless/ath/ath12k/hw.h | 2 + drivers/net/wireless/ath/ath12k/qmi.c | 179 ++++++++++++++++++++- drivers/net/wireless/ath/ath12k/qmi.h | 15 ++ drivers/net/wireless/ath/ath12k/wifi7/hw.c | 8 +- 7 files changed, 215 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 667cf5993cf15..990934ec92fca 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1082,6 +1082,8 @@ struct ath12k_base { size_t amss_dualmac_len; const u8 *m3_data; size_t m3_len; + const u8 *aux_uc_data; + size_t aux_uc_len; DECLARE_BITMAP(fw_features, ATH12K_FW_FEATURE_COUNT); bool fw_features_valid; diff --git a/drivers/net/wireless/ath/ath12k/fw.c b/drivers/net/wireless/ath/ath12k/fw.c index 5ac497f80cad8..22074653cbb82 100644 --- a/drivers/net/wireless/ath/ath12k/fw.c +++ b/drivers/net/wireless/ath/ath12k/fw.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "core.h" @@ -121,6 +121,14 @@ static int ath12k_fw_request_firmware_api_n(struct ath12k_base *ab, ab->fw.m3_data = data; ab->fw.m3_len = ie_len; break; + case ATH12K_FW_IE_AUX_UC_IMAGE: + ath12k_dbg(ab, ATH12K_DBG_BOOT, + "found aux_uc image ie (%zd B)\n", + ie_len); + + ab->fw.aux_uc_data = data; + ab->fw.aux_uc_len = ie_len; + break; case ATH12K_FW_IE_AMSS_DUALMAC_IMAGE: ath12k_dbg(ab, ATH12K_DBG_BOOT, "found dualmac fw image ie (%zd B)\n", diff --git a/drivers/net/wireless/ath/ath12k/fw.h b/drivers/net/wireless/ath/ath12k/fw.h index 7afaefed5086f..e146d24dfea4d 100644 --- a/drivers/net/wireless/ath/ath12k/fw.h +++ b/drivers/net/wireless/ath/ath12k/fw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_FW_H @@ -15,6 +15,7 @@ enum ath12k_fw_ie_type { ATH12K_FW_IE_AMSS_IMAGE = 2, ATH12K_FW_IE_M3_IMAGE = 3, ATH12K_FW_IE_AMSS_DUALMAC_IMAGE = 4, + ATH12K_FW_IE_AUX_UC_IMAGE = 5, }; enum ath12k_fw_features { diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 655753d0413ae..a9888e0521a1d 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -78,6 +78,7 @@ #define ATH12K_DEFAULT_CAL_FILE "caldata.bin" #define ATH12K_AMSS_FILE "amss.bin" #define ATH12K_M3_FILE "m3.bin" +#define ATH12K_AUX_UC_FILE "aux_ucode.bin" #define ATH12K_REGDB_FILE_NAME "regdb.bin" #define ATH12K_PCIE_MAX_PAYLOAD_SIZE 128 @@ -142,6 +143,7 @@ struct ath12k_hw_params { size_t board_size; size_t cal_offset; enum ath12k_m3_fw_loaders m3_loader; + bool download_aux_ucode:1; } fw; u8 max_radios; diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index 4966697f4e625..cfde4147c8fc9 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -1623,6 +1623,47 @@ static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { }, }; +static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_req_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, addr), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, size), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_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 qmi_wlanfw_aux_uc_info_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, + }, +}; + static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, @@ -3237,6 +3278,131 @@ int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) return ret; } +static void ath12k_qmi_aux_uc_free(struct ath12k_base *ab) +{ + struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem; + + if (!aux_uc_mem->vaddr) + return; + + dma_free_coherent(ab->dev, aux_uc_mem->total_size, + aux_uc_mem->vaddr, aux_uc_mem->paddr); + aux_uc_mem->vaddr = NULL; + aux_uc_mem->total_size = 0; + aux_uc_mem->size = 0; +} + +static int ath12k_qmi_aux_uc_load(struct ath12k_base *ab) +{ + struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem; + const struct firmware *fw = NULL; + const void *aux_uc_data; + char path[100]; + size_t aux_uc_len; + int ret; + + if (ab->fw.aux_uc_data && ab->fw.aux_uc_len > 0) { + /* firmware-N.bin had a aux_uc firmware file so use that */ + aux_uc_data = ab->fw.aux_uc_data; + aux_uc_len = ab->fw.aux_uc_len; + } else { + /* + * No aux_uc file in firmware-N.bin so try to request old + * separate aux_ucode.bin. + */ + fw = ath12k_core_firmware_request(ab, ATH12K_AUX_UC_FILE); + if (IS_ERR(fw)) { + ret = PTR_ERR(fw); + ath12k_core_create_firmware_path(ab, ATH12K_AUX_UC_FILE, + path, sizeof(path)); + ath12k_err(ab, "failed to load %s: %d\n", path, ret); + return ret; + } + + aux_uc_data = fw->data; + aux_uc_len = fw->size; + } + + /* In recovery/resume cases, AUX_UC buffer is not freed, try to reuse that */ + if (aux_uc_mem->vaddr) { + if (aux_uc_mem->total_size >= aux_uc_len) + goto copy; + + /* Old buffer is too small, free and reallocate */ + ath12k_qmi_aux_uc_free(ab); + } + + aux_uc_mem->vaddr = dma_alloc_coherent(ab->dev, aux_uc_len, + &aux_uc_mem->paddr, GFP_KERNEL); + if (!aux_uc_mem->vaddr) { + ret = -ENOMEM; + goto out; + } + + aux_uc_mem->total_size = aux_uc_len; + +copy: + memcpy(aux_uc_mem->vaddr, aux_uc_data, aux_uc_len); + aux_uc_mem->size = aux_uc_len; + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static noinline_for_stack +int ath12k_qmi_wlanfw_aux_uc_info_send(struct ath12k_base *ab) +{ + struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem; + struct qmi_wlanfw_aux_uc_info_req_msg_v01 req = {}; + struct qmi_wlanfw_aux_uc_info_resp_msg_v01 resp = {}; + struct qmi_txn txn; + int ret = 0; + + ret = ath12k_qmi_aux_uc_load(ab); + if (ret) { + ath12k_err(ab, "failed to load aux_uc firmware: %d", ret); + return ret; + } + + req.addr = aux_uc_mem->paddr; + req.size = aux_uc_mem->size; + + ret = qmi_txn_init(&ab->qmi.handle, &txn, + qmi_wlanfw_aux_uc_info_resp_msg_v01_ei, &resp); + if (ret < 0) + goto out; + + ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, + QMI_WLANFW_AUX_UC_INFO_REQ_V01, + QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN, + qmi_wlanfw_aux_uc_info_req_msg_v01_ei, &req); + if (ret < 0) { + qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to send AUX_UC information request, err = %d\n", + ret); + goto out; + } + + ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); + if (ret < 0) { + ath12k_warn(ab, "qmi failed AUX_UC information request %d\n", ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + ath12k_warn(ab, "qmi AUX_UC info request failed, result: %d, err: %d\n", + resp.resp.result, resp.resp.error); + ret = -EINVAL; + goto out; + } +out: + return ret; +} + static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab, u32 mode) { @@ -3601,6 +3767,7 @@ static noinline_for_stack int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) { struct ath12k_base *ab = qmi->ab; + const struct ath12k_hw_params *hw_params = ab->hw_params; int ret; ret = ath12k_qmi_request_target_cap(ab); @@ -3621,7 +3788,7 @@ int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) return ret; } - if (ab->hw_params->download_calib) { + if (hw_params->download_calib) { ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION); if (ret < 0) ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret); @@ -3633,6 +3800,14 @@ int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) return ret; } + if (hw_params->fw.download_aux_ucode) { + ret = ath12k_qmi_wlanfw_aux_uc_info_send(ab); + if (ret < 0) { + ath12k_warn(ab, "qmi failed to send aux_uc info req: %d\n", ret); + return ret; + } + } + return ret; } @@ -3906,6 +4081,7 @@ void ath12k_qmi_deinit_service(struct ath12k_base *ab) qmi_handle_release(&ab->qmi.handle); cancel_work_sync(&ab->qmi.event_work); destroy_workqueue(ab->qmi.event_wq); + ath12k_qmi_aux_uc_free(ab); ath12k_qmi_m3_free(ab); ath12k_qmi_free_target_mem_chunk(ab); ab->qmi.ab = NULL; @@ -3914,5 +4090,6 @@ void ath12k_qmi_deinit_service(struct ath12k_base *ab) void ath12k_qmi_free_resource(struct ath12k_base *ab) { ath12k_qmi_free_target_mem_chunk(ab); + ath12k_qmi_aux_uc_free(ab); ath12k_qmi_m3_free(ab); } diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h index 050dcaca1cb75..b5a4a01391cba 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.h +++ b/drivers/net/wireless/ath/ath12k/qmi.h @@ -154,6 +154,7 @@ struct ath12k_qmi { u8 num_radios; struct target_info target; struct m3_mem_region m3_mem; + struct m3_mem_region aux_uc_mem; unsigned int service_ins_id; struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01]; }; @@ -203,6 +204,7 @@ enum ath12k_qmi_cnss_feature { CNSS_FEATURE_MIN_ENUM_VAL_V01 = INT_MIN, CNSS_QDSS_CFG_MISS_V01 = 3, CNSS_PCIE_PERST_NO_PULL_V01 = 4, + CNSS_AUX_UC_SUPPORT_V01 = 6, CNSS_MAX_FEATURE_V01 = 64, CNSS_FEATURE_MAX_ENUM_VAL_V01 = INT_MAX, }; @@ -541,6 +543,19 @@ struct qmi_wlanfw_m3_info_resp_msg_v01 { struct qmi_response_type_v01 resp; }; +#define QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN 18 +#define QMI_WLANFW_AUX_UC_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 +#define QMI_WLANFW_AUX_UC_INFO_REQ_V01 0x005A + +struct qmi_wlanfw_aux_uc_info_req_msg_v01 { + u64 addr; + u32 size; +}; + +struct qmi_wlanfw_aux_uc_info_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + #define QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN 11 #define QMI_WLANFW_WLAN_MODE_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN 803 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index ef0a59f6339cf..38c388319e008 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -339,6 +339,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 128 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = false, }, .max_radios = 1, .single_pdev_only = false, @@ -421,6 +422,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 256 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = false, }, .max_radios = 1, @@ -505,6 +507,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 128 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = false, }, .max_radios = 2, .single_pdev_only = false, @@ -586,6 +589,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 128 * 1024, .m3_loader = ath12k_m3_fw_loader_remoteproc, + .download_aux_ucode = false, }, .max_radios = 1, .single_pdev_only = false, @@ -661,6 +665,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 256 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = true, }, .max_radios = 1, @@ -707,7 +712,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_wcn7850, .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | - BIT(CNSS_PCIE_PERST_NO_PULL_V01), + BIT(CNSS_PCIE_PERST_NO_PULL_V01) | + BIT(CNSS_AUX_UC_SUPPORT_V01), .rfkill_pin = 0, .rfkill_cfg = 0, From c61b7e0867b8adbd9047daf3b3abe9b6ceac1cd2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:31 +0800 Subject: [PATCH 484/659] wifi: ath12k: add HAL descriptor and ops for QCC2072 QCC2072 has different HAL descriptors hence require different HAL handling, compared to other chips. Add support for this. REO CMD/status ring handling is currently using the 64 bit ops .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, these will be updated to use 32 bit variants in upcoming patches. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-11-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 4 +- .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 362 ++++++++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.h | 2 + .../wireless/ath/ath12k/wifi7/hal_rx_desc.h | 17 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 1 + 6 files changed, 385 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index b957ebc9b7c5c..bd1753ca0db67 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -44,8 +44,8 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { .hw_regs = &ipq5332_regs, }, [ATH12K_HW_QCC2072_HW10] = { - .hal_ops = &hal_wcn7850_ops, - .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + .hal_ops = &hal_qcc2072_ops, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcc2072), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, .hal_params = &ath12k_hw_hal_params_wcn7850, .hw_regs = &qcc2072_regs, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 6c4986050bc6a..847484ece2044 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -4,6 +4,7 @@ */ #include "hal_qcc2072.h" +#include "hal_wcn7850.h" const struct ath12k_hw_regs qcc2072_regs = { /* SW2TCL(x) R0 ring configuration address */ @@ -92,3 +93,364 @@ const struct ath12k_hw_regs qcc2072_regs = { .gcc_gcc_pcie_hot_rst = 0x1e65304, }; + +static void ath12k_hal_rx_desc_set_msdu_len_qcc2072(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.qcc2072.msdu_end.info10); + + info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; + info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); + + desc->u.qcc2072.msdu_end.info10 = __cpu_to_le32(info); +} + +static void ath12k_hal_rx_desc_get_dot11_hdr_qcc2072(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + hdr->frame_control = desc->u.qcc2072.mpdu_start.frame_ctrl; + hdr->duration_id = desc->u.qcc2072.mpdu_start.duration; + ether_addr_copy(hdr->addr1, desc->u.qcc2072.mpdu_start.addr1); + ether_addr_copy(hdr->addr2, desc->u.qcc2072.mpdu_start.addr2); + ether_addr_copy(hdr->addr3, desc->u.qcc2072.mpdu_start.addr3); + + if (__le32_to_cpu(desc->u.qcc2072.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) + ether_addr_copy(hdr->addr4, desc->u.qcc2072.mpdu_start.addr4); + + hdr->seq_ctrl = desc->u.qcc2072.mpdu_start.seq_ctrl; +} + +static void ath12k_hal_rx_desc_get_crypto_hdr_qcc2072(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + unsigned int key_id; + + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: + return; + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: + case HAL_ENCRYPT_TYPE_TKIP_MIC: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[1] = 0; + crypto_hdr[2] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[0]); + break; + case HAL_ENCRYPT_TYPE_CCMP_128: + case HAL_ENCRYPT_TYPE_CCMP_256: + case HAL_ENCRYPT_TYPE_GCMP_128: + case HAL_ENCRYPT_TYPE_AES_GCMP_256: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[1] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[2] = 0; + break; + case HAL_ENCRYPT_TYPE_WEP_40: + case HAL_ENCRYPT_TYPE_WEP_104: + case HAL_ENCRYPT_TYPE_WEP_128: + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: + case HAL_ENCRYPT_TYPE_WAPI: + return; + } + + key_id = u32_get_bits(__le32_to_cpu(desc->u.qcc2072.mpdu_start.info5), + RX_MPDU_START_INFO5_KEY_ID); + crypto_hdr[3] = 0x20 | (key_id << 6); + crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[1]); + crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[1]); +} + +static void ath12k_hal_rx_desc_copy_end_tlv_qcc2072(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + memcpy(&fdesc->u.qcc2072.msdu_end, &ldesc->u.qcc2072.msdu_end, + sizeof(struct rx_msdu_end_qcn9274)); +} + +static u8 ath12k_hal_rx_desc_get_msdu_src_link_qcc2072(struct hal_rx_desc *desc) +{ + return 0; +} + +static u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.qcc2072.msdu_end.info5, + RX_MSDU_END_INFO5_L3_HDR_PADDING); +} + +static u32 ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.mpdu_start_tag, + HAL_TLV_HDR_TAG); +} + +static u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcc2072(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcc2072.mpdu_start.phy_ppdu_id); +} + +static u8 *ath12k_hal_rx_desc_get_msdu_payload_qcc2072(struct hal_rx_desc *desc) +{ + return &desc->u.qcc2072.msdu_payload[0]; +} + +static bool ath12k_hal_rx_desc_get_first_msdu_qcc2072(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcc2072.msdu_end.info5, + RX_MSDU_END_INFO5_FIRST_MSDU); +} + +static bool ath12k_hal_rx_desc_get_last_msdu_qcc2072(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcc2072.msdu_end.info5, + RX_MSDU_END_INFO5_LAST_MSDU); +} + +static bool ath12k_hal_rx_desc_encrypt_valid_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); +} + +static u32 ath12k_hal_rx_desc_get_encrypt_type_qcc2072(struct hal_rx_desc *desc) +{ + if (!ath12k_hal_rx_desc_encrypt_valid_qcc2072(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + + return le32_get_bits(desc->u.qcc2072.mpdu_start.info2, + RX_MPDU_START_INFO2_ENC_TYPE); +} + +static u8 ath12k_hal_rx_desc_get_decap_type_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info11, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + +static u8 ath12k_hal_rx_desc_get_mesh_ctl_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info11, + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); +} + +static bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); +} + +static bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); +} + +static u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); +} + +static u16 ath12k_hal_rx_desc_get_msdu_len_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info10, + RX_MSDU_END_INFO10_MSDU_LENGTH); +} + +static u8 ath12k_hal_rx_desc_get_msdu_sgi_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_SGI); +} + +static u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_RATE_MCS); +} + +static u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_RECV_BW); +} + +static u32 ath12k_hal_rx_desc_get_msdu_freq_qcc2072(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcc2072.msdu_end.phy_meta_data); +} + +static u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_PKT_TYPE); +} + +static u8 ath12k_hal_rx_desc_get_msdu_nss_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_MIMO_SS_BITMAP); +} + +static u8 ath12k_hal_rx_desc_get_mpdu_tid_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.mpdu_start.info2, + RX_MPDU_START_INFO2_TID); +} + +static u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcc2072(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcc2072.mpdu_start.sw_peer_id); +} + +static bool ath12k_hal_rx_desc_mac_addr2_valid_qcc2072(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcc2072.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; +} + +static u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcc2072(struct hal_rx_desc *desc) +{ + return desc->u.qcc2072.mpdu_start.addr2; +} + +static bool ath12k_hal_rx_desc_is_da_mcbc_qcc2072(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcc2072.msdu_end.info13) & + RX_MSDU_END_INFO13_MCAST_BCAST; +} + +static bool ath12k_hal_rx_h_msdu_done_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.msdu_end.info14, + RX_MSDU_END_INFO14_MSDU_DONE); +} + +static bool ath12k_hal_rx_h_l4_cksum_fail_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.msdu_end.info13, + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); +} + +static bool ath12k_hal_rx_h_ip_cksum_fail_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.msdu_end.info13, + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); +} + +static bool ath12k_hal_rx_h_is_decrypted_qcc2072(struct hal_rx_desc *desc) +{ + return (le32_get_bits(desc->u.qcc2072.msdu_end.info14, + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == + RX_DESC_DECRYPT_STATUS_CODE_OK); +} + +static u32 ath12k_hal_rx_h_mpdu_err_qcc2072(struct hal_rx_desc *desc) +{ + u32 info = __le32_to_cpu(desc->u.qcc2072.msdu_end.info13); + u32 errmap = 0; + + if (info & RX_MSDU_END_INFO13_FCS_ERR) + errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; + + return errmap; +} + +static void ath12k_hal_extract_rx_desc_data_qcc2072(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcc2072(ldesc); + rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcc2072(ldesc); + rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072(ldesc); + rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_qcc2072(rx_desc); + rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_qcc2072(rx_desc); + rx_desc_data->mesh_ctrl_present = + ath12k_hal_rx_desc_get_mesh_ctl_qcc2072(rx_desc); + rx_desc_data->seq_ctl_valid = + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcc2072(rx_desc); + rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcc2072(rx_desc); + rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcc2072(rx_desc); + rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcc2072(ldesc); + rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcc2072(rx_desc); + rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcc2072(rx_desc); + rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcc2072(rx_desc); + rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_qcc2072(rx_desc); + rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcc2072(rx_desc); + rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_qcc2072(rx_desc)); + rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_qcc2072(rx_desc); + rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcc2072(rx_desc); + rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_qcc2072(rx_desc); + rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcc2072(rx_desc); + rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcc2072(rx_desc); + rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_qcc2072(ldesc); + rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcc2072(rx_desc); + rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcc2072(rx_desc); + rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcc2072(rx_desc); + rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcc2072(rx_desc); +} + +const struct hal_ops hal_qcc2072_ops = { + .create_srng_config = ath12k_hal_srng_create_config_wcn7850, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcc2072, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcc2072, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcc2072, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcc2072, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcc2072, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcc2072, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, + .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, + .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, + .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, + .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, + .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, + .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, + .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, + .tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map, + .tx_configure_bank_register = + ath12k_wifi7_hal_tx_configure_bank_register, + .reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable, + .reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid, + .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, + .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, + .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, + .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, + .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, + .cc_config = ath12k_wifi7_hal_cc_config, + .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, + .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, + .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, +}; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h index 744d7e02b46e6..392bfbb6a4124 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h @@ -4,5 +4,7 @@ */ #include "../hal.h" +#include "hal.h" extern const struct ath12k_hw_regs qcc2072_regs; +extern const struct hal_ops hal_qcc2072_ops; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h index cc5e1d336376a..0d19a9cbb68ce 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h @@ -1481,10 +1481,27 @@ struct hal_rx_desc_wcn7850 { u8 msdu_payload[]; }; +struct rx_pkt_hdr_tlv_qcc2072 { + __le32 tag; + __le64 phy_ppdu_id; + u8 rx_pkt_hdr[HAL_RX_BE_PKT_HDR_TLV_LEN]; +}; + +struct hal_rx_desc_qcc2072 { + __le32 msdu_end_tag; + struct rx_msdu_end_qcn9274 msdu_end; + u8 rx_padding0[RX_BE_PADDING0_BYTES]; + __le32 mpdu_start_tag; + struct rx_mpdu_start_qcn9274 mpdu_start; + struct rx_pkt_hdr_tlv_qcc2072 pkt_hdr_tlv; + u8 msdu_payload[]; +}; + struct hal_rx_desc { union { struct hal_rx_desc_qcn9274_compact qcn9274_compact; struct hal_rx_desc_wcn7850 wcn7850; + struct hal_rx_desc_qcc2072 qcc2072; } u; } __packed; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index c3093c01af878..88f51a3828aac 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -614,7 +614,7 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); } -static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal) +int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal) { struct hal_srng_config *s; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 46047fd6a3127..a56ca9fd3de4e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -36,4 +36,5 @@ void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); +int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal); #endif From 8d27a358645967e9a70476628b3bae26b232fe38 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:32 +0800 Subject: [PATCH 485/659] wifi: ath12k: add hardware ops support for QCC2072 Due to HAL descriptors, QCC2027 has different offsets of MPDU start tag and MSDU end tag, compared with other chips. Hence add new hardware ops structure for QCC2072. All ops are directly taken from WCN7850, with the exception to rxdma_ring_sel_config, which needs a new function ath12k_dp_rxdma_ring_sel_config_qcc2072() to handle the difference mentioned above. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-12-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 44 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 1 + .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 10 +++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.h | 3 ++ drivers/net/wireless/ath/ath12k/wifi7/hw.c | 12 ++++- 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index dc8d72aeca457..7450938adf657 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -9,6 +9,7 @@ #include "../peer.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" +#include "hal_qcc2072.h" static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp, enum ath12k_peer_metadata_version ver, @@ -2110,6 +2111,49 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } +int ath12k_dp_rxdma_ring_sel_config_qcc2072(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct htt_rx_ring_tlv_filter tlv_filter = {}; + u32 ring_id; + int ret = 0; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + int i; + + ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; + + tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; + tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; + tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; + tlv_filter.offset_valid = true; + tlv_filter.rx_packet_offset = hal_rx_desc_sz; + + tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_qcc2072, pkt_hdr_tlv); + + tlv_filter.rx_mpdu_start_offset = + ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(); + tlv_filter.rx_msdu_end_offset = + ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(); + + /* + * TODO: Selectively subscribe to required qwords within msdu_end + * and mpdu_start and setup the mask in below msg + * and modify the rx_desc struct + */ + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = dp->rx_mac_buf_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + } + + return ret; +} + void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) { struct ath12k_base *ab = dp->ab; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index a98836b83f482..8aa79faf567fd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -22,6 +22,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int mac_id, void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); +int ath12k_dp_rxdma_ring_sel_config_qcc2072(struct ath12k_base *ab); void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, struct ath12k_dp_rx_tid *rx_tid, u32 cipher, enum set_key_cmd key_cmd); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 847484ece2044..522b94b04f9f4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -454,3 +454,13 @@ const struct hal_ops hal_qcc2072_ops = { .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; + +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void) +{ + return offsetof(struct hal_rx_desc_qcc2072, mpdu_start_tag); +} + +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(void) +{ + return offsetof(struct hal_rx_desc_qcc2072, msdu_end_tag); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h index 392bfbb6a4124..6de943df77864 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h @@ -8,3 +8,6 @@ extern const struct ath12k_hw_regs qcc2072_regs; extern const struct hal_ops hal_qcc2072_ops; + +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void); +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(void); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 38c388319e008..f75690f586cd9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -170,6 +170,16 @@ static const struct ath12k_hw_ops wcn7850_ops = { .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850, }; +static const struct ath12k_hw_ops qcc2072_ops = { + .get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id, + .mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850, + .mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850, + .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcc2072, + .get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850, + .dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850, + .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850, +}; + #define ATH12K_TX_RING_MASK_0 0x1 #define ATH12K_TX_RING_MASK_1 0x2 #define ATH12K_TX_RING_MASK_2 0x4 @@ -673,7 +683,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, .internal_sleep_clock = true, - .hw_ops = &wcn7850_ops, + .hw_ops = &qcc2072_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, From 8052b4e77ba9ffac738c16d2ec90edaff4641568 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:33 +0800 Subject: [PATCH 486/659] wifi: ath12k: handle REO CMD ring for QCC2072 As far as REO CMD ring is concerned, there are two differences between QCC2072 and the existing chips: For the first, the TLV header of ring descriptor for QCC2072 is 32 bits while 64 bits for existing chips. For the second, QCC2072 has different hal_reo_get_queue_stats, hal_reo_flush_cache and hal_reo_update_rx_queue structures. Take hal_reo_get_queue_stats as an example: QCC2072: struct hal_reo_get_queue_stats_qcc2072 { struct hal_reo_cmd_hdr cmd; [...] __le32 rsvd0[6]; } __packed; QCN9274/WCN7850: struct hal_reo_get_queue_stats { struct hal_reo_cmd_hdr cmd; [...] __le32 rsvd0[6]; __le32 tlv64_pad; } __packed; Note there is no tlv64_pad at the end for QCC2072, but all other former fields share the same layout. These make different ring entry size, so that parameter has to be updated with respect to existing chips. This is done in the newly introduced ath12k_hal_srng_create_config_qcc2072() function, which first creates all ring configs by utilizing ath12k_hal_srng_create_config_wcn7850() and then updates the individual field. Besides, the REO command TLV encoding also need to be corrected because of the different TLV bits. This is done by introducing a 32 bit variant for each of the existing 64 bit callback. Note the hal_reo_get_queue_stats_qcc2072 structure is introduced for the purpose of calculating ring entry size. Existing hal_reo_get_queue_stats structure gets used elsewhere even for QCC2072. This is working because the only difference is the tlv64_pad field that is located at the end and not getting used, hence can be ignored. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-13-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 11 ++++++++ drivers/net/wireless/ath/ath12k/hal.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 7 ++++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 22 +++++++++++++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 25 +++++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 2 ++ 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index bafb49ab5475f..5ce5e0f89ca88 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -835,6 +835,17 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len) } EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr); +void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len) +{ + struct hal_tlv_hdr *tlv32 = tlv; + + tlv32->tl = le32_encode_bits(tag, HAL_TLV_HDR_TAG) | + le32_encode_bits(len, HAL_TLV_HDR_LEN); + + return tlv32->value; +} +EXPORT_SYMBOL(ath12k_hal_encode_tlv32_hdr); + u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc) { struct hal_tlv_64_hdr *tlv64 = tlv; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 94ecc035fc493..f322000e8ac9f 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1544,5 +1544,6 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); +void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len); u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index cdcf24b1d6eba..c4c7ca9ee827a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1049,6 +1049,13 @@ struct hal_reo_get_queue_stats { * Hole_count */ +struct hal_reo_get_queue_stats_qcc2072 { + struct hal_reo_cmd_hdr cmd; + __le32 queue_addr_lo; + __le32 info0; + __le32 rsvd0[6]; +} __packed; + #define HAL_REO_FLUSH_QUEUE_INFO0_DESC_ADDR_HI GENMASK(7, 0) #define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_DESC_ADDR BIT(8) #define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_RESRC_IDX GENMASK(10, 9) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 522b94b04f9f4..0ae5b073287ab 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -412,8 +412,24 @@ static void ath12k_hal_extract_rx_desc_data_qcc2072(struct hal_rx_desc_data *rx_ rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcc2072(rx_desc); } +static int ath12k_hal_srng_create_config_qcc2072(struct ath12k_hal *hal) +{ + struct hal_srng_config *s; + int ret; + + ret = ath12k_hal_srng_create_config_wcn7850(hal); + if (ret) + return ret; + + s = &hal->srng_config[HAL_REO_CMD]; + s->entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_reo_get_queue_stats_qcc2072)) >> 2; + + return 0; +} + const struct hal_ops hal_qcc2072_ops = { - .create_srng_config = ath12k_hal_srng_create_config_wcn7850, + .create_srng_config = ath12k_hal_srng_create_config_qcc2072, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072, .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcc2072, .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072, @@ -443,7 +459,7 @@ const struct hal_ops hal_qcc2072_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, - .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv32, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, @@ -451,7 +467,7 @@ const struct hal_ops hal_qcc2072_ops = { .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, - .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr, .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index a88ef126aadab..49c6932897094 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -890,6 +890,31 @@ void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, } } +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct hal_reo_get_queue_stats *desc; + struct hal_srng_params params; + struct hal_tlv_hdr *tlv; + int i, cmd_num = 1; + int entry_size; + u8 *entry; + + memset(¶ms, 0, sizeof(params)); + + entry_size = ath12k_hal_srng_get_entrysize(ab, HAL_REO_CMD); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + entry = (u8 *)params.ring_base_vaddr; + + for (i = 0; i < params.num_entries; i++) { + tlv = (struct hal_tlv_hdr *)entry; + desc = (struct hal_reo_get_queue_stats *)tlv->value; + desc->cmd.info0 = le32_encode_bits(cmd_num++, + HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); + entry += entry_size; + } +} + void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 95f5595b30ad1..ac2a8ac03288f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -864,6 +864,8 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, u16 *num_msdus); void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, struct hal_srng *srng); +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab, + struct hal_srng *srng); void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, From c56665b129380f0c169a77fd970f613b1e7aa80e Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:34 +0800 Subject: [PATCH 487/659] wifi: ath12k: handle REO status ring for QCC2072 For QCC2072 below REO status descriptors are different compared with QCN9274/WCN7850: hal_reo_get_queue_stats_status hal_reo_flush_queue_status hal_reo_flush_cache_status hal_reo_unblock_cache_status hal_reo_flush_timeout_list_status hal_reo_desc_thresh_reached_status Take hal_reo_get_queue_stats_status as an example: QCC2072: struct hal_reo_get_queue_stats_status_qcc2072 { __le32 tlv32_padding; struct hal_reo_get_queue_stats_status status; } __packed; QCN9274/WCN7850: struct hal_reo_get_queue_stats_status; Besides, QCC2072 has a 32 bits TLV header while QCN9274/WCN7850 has 64. This means that there is no difference between these 3 devices in layout of actual fields, because they all start after a 8 bytes offset QCC2072: { struct hal_tlv_hdr tlv; __le32 tlv32_padding; struct hal_reo_get_queue_stats_status status; } QCN9274/WCN7850: { struct hal_tlv_64_hdr tlv; struct hal_reo_get_queue_stats_status status; } Therefore current implementation luckily works for QCC2072 as well. However it leads to misunderstanding, which should be avoided. So add individual REO status ring handling for QCC2072. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-14-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 12 +++++++++++ drivers/net/wireless/ath/ath12k/hal.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 5 +++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 21 ++++++++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 5ce5e0f89ca88..a164563fff289 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -857,3 +857,15 @@ u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc) return tag; } EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr); + +u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc) +{ + struct hal_tlv_hdr *tlv32 = tlv; + u16 tag; + + tag = le32_get_bits(tlv32->tl, HAL_SRNG_TLV_HDR_TAG); + *desc = tlv32->value; + + return tag; +} +EXPORT_SYMBOL(ath12k_hal_decode_tlv32_hdr); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index f322000e8ac9f..520587305dfa6 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1546,4 +1546,5 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len); u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc); +u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index c4c7ca9ee827a..e1ab47b44433d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -2439,6 +2439,11 @@ struct hal_reo_get_queue_stats_status { * entries into this Ring has looped around the ring. */ +struct hal_reo_get_queue_stats_status_qcc2072 { + __le32 tlv32_padding; + struct hal_reo_get_queue_stats_status status; +} __packed; + #define HAL_REO_STATUS_LOOP_CNT GENMASK(31, 28) #define HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED BIT(0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 0ae5b073287ab..ee2427fadfc14 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -425,9 +425,28 @@ static int ath12k_hal_srng_create_config_qcc2072(struct ath12k_hal *hal) s->entry_size = (sizeof(struct hal_tlv_hdr) + sizeof(struct hal_reo_get_queue_stats_qcc2072)) >> 2; + s = &hal->srng_config[HAL_REO_STATUS]; + s->entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_reo_get_queue_stats_status_qcc2072)) >> 2; + return 0; } +static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcc2072(void *tlv, void **desc) +{ + struct hal_reo_get_queue_stats_status_qcc2072 *status_tlv; + u16 tag; + + tag = ath12k_hal_decode_tlv32_hdr(tlv, (void **)&status_tlv); + /* + * actual desc of REO status entry starts after tlv32_padding, + * see hal_reo_get_queue_stats_status_qcc2072 + */ + *desc = &status_tlv->status; + + return tag; +} + const struct hal_ops hal_qcc2072_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcc2072, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072, @@ -468,7 +487,7 @@ const struct hal_ops hal_qcc2072_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr, - .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcc2072, }; u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void) From f6462f794cc3191287353bf97512dd10d349b76a Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:35 +0800 Subject: [PATCH 488/659] wifi: ath12k: limit number of channels per WMI command Currently the number of channels can be sent in a single WMI command is calculated based on the maximum message length of the target, this results in WMI exchange hang for QCC2072 as its firmware can not support those many channels in a single command. Add a limit to avoid this issue. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-15-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 3 ++- drivers/net/wireless/ath/ath12k/wmi.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 79a26203afad6..0e1e6853ab850 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -2806,7 +2806,8 @@ int ath12k_wmi_send_scan_chan_list_cmd(struct ath12k *ar, max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) / sizeof(*chan_info); - num_send_chans = min(arg->nallchans, max_chan_limit); + num_send_chans = min3(arg->nallchans, max_chan_limit, + ATH12K_WMI_MAX_NUM_CHAN_PER_CMD); arg->nallchans -= num_send_chans; len += sizeof(*chan_info) * num_send_chans; diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 65f0d7ed4178d..daee2787cdfd6 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -6322,6 +6322,9 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg { s8 min_nf_dbm; }; +/* each WMI cmd can hold 58 channel entries at most */ +#define ATH12K_WMI_MAX_NUM_CHAN_PER_CMD 58 + int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); From 31de58ad4973322a5ddebc46bc8ea707270185d9 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:36 +0800 Subject: [PATCH 489/659] wifi: ath12k: send peer meta data version to firmware Peer meta data version is currently not delivered to firmware, resulting in QCC2072 data path issues. Parse it from service ready ext2 event and send to firmware in WMI init command. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-16-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/wmi.c | 5 +++++ drivers/net/wireless/ath/ath12k/wmi.c | 4 ++++ drivers/net/wireless/ath/ath12k/wmi.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c index c575b44a33f3b..ed538d20d324a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c @@ -102,4 +102,9 @@ void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab, config->num_multicast_filter_entries = 0x20; config->num_wow_filters = 0x16; config->num_keep_alive_pattern = 0; + + if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) + config->peer_metadata_ver = ATH12K_PEER_METADATA_V1A; + else + config->peer_metadata_ver = ab->wmi_ab.dp_peer_meta_data_ver; } diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 0e1e6853ab850..cce3d699112d7 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -5477,6 +5477,10 @@ static int ath12k_wmi_svc_rdy_ext2_parse(struct ath12k_base *ab, ret); return ret; } + + ab->wmi_ab.dp_peer_meta_data_ver = + u32_get_bits(parse->arg.target_cap_flags, + WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION); break; case WMI_TAG_ARRAY_STRUCT: diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index daee2787cdfd6..fdc203fdba0a0 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2783,6 +2783,8 @@ enum wmi_channel_width { #define WMI_EHT_MCS_NSS_10_11 GENMASK(11, 8) #define WMI_EHT_MCS_NSS_12_13 GENMASK(15, 12) +#define WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION GENMASK(1, 0) + struct wmi_service_ready_ext2_event { __le32 reg_db_version; __le32 hw_min_max_tx_power_2ghz; @@ -5230,6 +5232,8 @@ struct ath12k_wmi_base { struct ath12k_svc_ext_info svc_ext_info; u32 sbs_lower_band_end_freq; struct ath12k_hw_mode_info hw_mode_info; + + u8 dp_peer_meta_data_ver; }; struct wmi_pdev_set_bios_interface_cmd { From bb1d15f8fb3a01a0ac315e37f314a3500a191061 Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Mon, 12 Jan 2026 15:36:37 +0800 Subject: [PATCH 490/659] wifi: ath12k: fix PCIE_LOCAL_REG_QRTR_NODE_ID definition for QCC2072 The definition of PCIE_LOCAL_REG_QRTR_NODE_ID in QCC2072 is incorrect, which causes the QMI connection to fail when ATH12K_FW_FEATURE_MULTI_QRTR_ID is enabled. To resolve this issue, move it to the hardware register table. Note IPQ5332 is not affected as it is not PCIe based device. Tested-on: QCC2072 hw1.0 PCI CI_WLAN.COL.1.0-01668.1-QCACOLSWPL_V1_TO_SILICONZ-9 Signed-off-by: Miaoqing Pan Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-17-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.h | 2 ++ drivers/net/wireless/ath/ath12k/pci.c | 6 +----- drivers/net/wireless/ath/ath12k/pci.h | 5 +++++ drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 ++++ drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 ++ 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 520587305dfa6..43e3880f82579 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1201,6 +1201,8 @@ struct ath12k_hw_regs { u32 reo_status_ring_base; u32 gcc_gcc_pcie_hot_rst; + + u32 qrtr_node_id; }; /* HAL context to be used to access SRNG APIs (currently used by data path diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 69579e59b5563..375277ca2b892 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -34,10 +34,6 @@ */ #define ACCESS_ALWAYS_OFF 0xFE0 -#define PCIE_LOCAL_REG_QRTR_NODE_ID 0x1E03164 -#define DOMAIN_NUMBER_MASK GENMASK(7, 4) -#define BUS_NUMBER_MASK GENMASK(3, 0) - static struct ath12k_pci_driver *ath12k_pci_family_drivers[ATH12K_DEVICE_FAMILY_MAX]; static const struct ath12k_msi_config msi_config_one_msi = { .total_vectors = 1, @@ -918,7 +914,7 @@ static void ath12k_pci_update_qrtr_node_id(struct ath12k_base *ab) * writes to the given register, it is available for firmware when the QMI service * is spawned. */ - reg = PCIE_LOCAL_REG_QRTR_NODE_ID & WINDOW_RANGE_MASK; + reg = PCIE_LOCAL_REG_QRTR_NODE_ID(ab) & WINDOW_RANGE_MASK; ath12k_pci_write32(ab, reg, ab_pci->qmi_instance); ath12k_dbg(ab, ATH12K_DBG_PCI, "pci reg 0x%x instance 0x%x read val 0x%x\n", diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index a74b09d23a6a1..0e0e2020c6ae5 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -59,6 +59,11 @@ #define QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB 0x1E20338 #define OTP_BOARD_ID_MASK GENMASK(15, 0) +#define PCIE_LOCAL_REG_QRTR_NODE_ID(ab) \ + ((ab)->hal.regs->qrtr_node_id) +#define DOMAIN_NUMBER_MASK GENMASK(7, 4) +#define BUS_NUMBER_MASK GENMASK(3, 0) + #define PCI_BAR_WINDOW0_BASE 0x1E00000 #define PCI_BAR_WINDOW0_END 0x1E7FFFC #define PCI_SOC_RANGE_MASK 0x3FFF diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index ee2427fadfc14..1eefb931a853e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -92,6 +92,8 @@ const struct ath12k_hw_regs qcc2072_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e65304, + + .qrtr_node_id = 0x1e03300, }; static void ath12k_hal_rx_desc_set_msdu_len_qcc2072(struct hal_rx_desc *desc, u16 len) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 95850e6dc6c72..41c918eb17673 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -297,6 +297,8 @@ const struct ath12k_hw_regs qcn9274_v1_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, + + .qrtr_node_id = 0x1e03164, }; const struct ath12k_hw_regs qcn9274_v2_regs = { @@ -390,6 +392,8 @@ const struct ath12k_hw_regs qcn9274_v2_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, + + .qrtr_node_id = 0x1e03164, }; const struct ath12k_hw_regs ipq5332_regs = { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 88f51a3828aac..e64e512cac7df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -256,6 +256,8 @@ const struct ath12k_hw_regs wcn7850_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e40304, + + .qrtr_node_id = 0x1e03164, }; static inline From 4aed1f90c5015f46647f49c62836ffc4fb0d59d8 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:38 +0800 Subject: [PATCH 491/659] wifi: ath12k: enable QCC2072 support QCC2072 is a PCI based device that is very much like WCN7850, the major difference is that QCC2072 has only one phy hence does not support DBS. With previous patches handling such similarity and difference, it is now ready to finally enable supporting this device. Add QCC2072's ID to the PCI device ID table, to allow it getting probed hence enable support. Also populate some necessary parameters when probing. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-18-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 6c477fe97298f..6c96b52dec131 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -19,6 +19,7 @@ #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 +#define QCC2072_DEVICE_ID 0x1112 #define ATH12K_PCI_W7_SOC_HW_VERSION_1 1 #define ATH12K_PCI_W7_SOC_HW_VERSION_2 2 @@ -28,10 +29,12 @@ #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) #define WINDOW_REG_ADDRESS 0x310c +#define WINDOW_REG_ADDRESS_QCC2072 0x3278 static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, + { PCI_VDEVICE(QCOM, QCC2072_DEVICE_ID) }, {} }; @@ -152,7 +155,16 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return -EOPNOTSUPP; } break; - + case QCC2072_DEVICE_ID: + ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; + ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->static_window_map = false; + ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; + ab_pci->window_reg_addr = WINDOW_REG_ADDRESS_QCC2072; + ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; + /* there is only one version till now */ + ab->hw_rev = ATH12K_HW_QCC2072_HW10; + break; default: dev_err(&pdev->dev, "Unknown Wi-Fi 7 PCI device found: 0x%x\n", pci_dev->device); From c8b4ee20b588aba9458bff7c510f587fd8959b6d Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Thu, 22 Jan 2026 22:48:16 -0800 Subject: [PATCH 492/659] wifi: ath12k: add WMI support for spatial reuse parameter configuration Add WMI support for configuring SRG and non-SRG OBSS PD bitmaps at the pdev level. The new commands allow the host to set BSS color bitmaps, partial BSSID bitmaps, and the corresponding enable masks used for SRG/non-SRG OBSS PD processing. Introduce new WMI command IDs, TLV tags, a service flag (WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT), and a bitmap payload structure required by these commands. These additions are needed to support HE Spatial Reuse and firmware-managed OBSS PD behavior. The APIs introduced in this patch will be utilized in an upcoming patch. Tested-on: WCN7850 hw2.0 PCI WLAN.IOE_HMT.1.1-00011-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Tested-on: QCN9274 hw2.0 WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Wei Zhang Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260123064817.364047-2-wei.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 142 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wmi.h | 46 +++++++++ 2 files changed, 188 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index cce3d699112d7..7617fc3a2479c 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -126,6 +126,14 @@ struct wmi_tlv_mgmt_rx_parse { bool frame_buf_done; }; +struct wmi_pdev_set_obss_bitmap_arg { + u32 tlv_tag; + u32 pdev_id; + u32 cmd_id; + const u32 *bitmap; + const char *label; +}; + static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = { [WMI_TAG_ARRAY_BYTE] = { .min_len = 0 }, [WMI_TAG_ARRAY_UINT32] = { .min_len = 0 }, @@ -3560,6 +3568,140 @@ ath12k_wmi_send_obss_spr_cmd(struct ath12k *ar, u32 vdev_id, return ret; } +u32 ath12k_wmi_build_obss_pd(const struct ath12k_wmi_obss_pd_arg *arg) +{ + u32 param_val = 0; + + param_val |= u32_encode_bits((u8)arg->srg_th, GENMASK(15, 8)); + param_val |= u32_encode_bits((u8)arg->non_srg_th, GENMASK(7, 0)); + + if (arg->srp_support) + param_val |= ATH12K_OBSS_PD_THRESHOLD_IN_DBM; + + if (arg->srg_enabled && arg->srp_support) + param_val |= ATH12K_OBSS_PD_SRG_EN; + + if (arg->non_srg_enabled) + param_val |= ATH12K_OBSS_PD_NON_SRG_EN; + + return param_val; +} + +static int ath12k_wmi_pdev_set_obss_bitmap(struct ath12k *ar, + const struct wmi_pdev_set_obss_bitmap_arg *arg) +{ + struct wmi_pdev_obss_pd_bitmap_cmd *cmd; + struct ath12k_wmi_pdev *wmi = ar->wmi; + const int len = sizeof(*cmd); + struct sk_buff *skb; + int ret; + + skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; + cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(arg->tlv_tag, len); + cmd->pdev_id = cpu_to_le32(arg->pdev_id); + memcpy(cmd->bitmap, arg->bitmap, sizeof(cmd->bitmap)); + + ath12k_dbg(ar->ab, ATH12K_DBG_WMI, + "wmi set pdev %u %s %08x %08x\n", + arg->pdev_id, arg->label, arg->bitmap[0], arg->bitmap[1]); + + ret = ath12k_wmi_cmd_send(wmi, skb, arg->cmd_id); + if (ret) { + ath12k_warn(ar->ab, "failed to send %s: %d\n", arg->label, ret); + dev_kfree_skb(skb); + } + + return ret; +} + +int ath12k_wmi_pdev_set_srg_bss_color_bitmap(struct ath12k *ar, + u32 pdev_id, const u32 *bitmap) +{ + struct wmi_pdev_set_obss_bitmap_arg arg = { + .tlv_tag = WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD, + .pdev_id = pdev_id, + .cmd_id = WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID, + .bitmap = bitmap, + .label = "SRG bss color bitmap", + }; + + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); +} + +int ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(struct ath12k *ar, + u32 pdev_id, const u32 *bitmap) +{ + struct wmi_pdev_set_obss_bitmap_arg arg = { + .tlv_tag = WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, + .pdev_id = pdev_id, + .cmd_id = WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID, + .bitmap = bitmap, + .label = "SRG partial bssid bitmap", + }; + + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); +} + +int ath12k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath12k *ar, + u32 pdev_id, const u32 *bitmap) +{ + struct wmi_pdev_set_obss_bitmap_arg arg = { + .tlv_tag = WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, + .pdev_id = pdev_id, + .cmd_id = WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, + .bitmap = bitmap, + .label = "SRG obss color enable bitmap", + }; + + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); +} + +int ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath12k *ar, + u32 pdev_id, const u32 *bitmap) +{ + struct wmi_pdev_set_obss_bitmap_arg arg = { + .tlv_tag = WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, + .pdev_id = pdev_id, + .cmd_id = WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, + .bitmap = bitmap, + .label = "SRG obss bssid enable bitmap", + }; + + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); +} + +int ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath12k *ar, + u32 pdev_id, const u32 *bitmap) +{ + struct wmi_pdev_set_obss_bitmap_arg arg = { + .tlv_tag = WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, + .pdev_id = pdev_id, + .cmd_id = WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, + .bitmap = bitmap, + .label = "non SRG obss color enable bitmap", + }; + + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); +} + +int ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath12k *ar, + u32 pdev_id, const u32 *bitmap) +{ + struct wmi_pdev_set_obss_bitmap_arg arg = { + .tlv_tag = WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, + .pdev_id = pdev_id, + .cmd_id = WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, + .bitmap = bitmap, + .label = "non SRG obss bssid enable bitmap", + }; + + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); +} + int ath12k_wmi_obss_color_cfg_cmd(struct ath12k *ar, u32 vdev_id, u8 bss_color, u32 period, bool enable) diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index fdc203fdba0a0..2a81819ef5432 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -374,6 +374,12 @@ enum wmi_tlv_cmd_id { WMI_PDEV_DMA_RING_CFG_REQ_CMDID, WMI_PDEV_HE_TB_ACTION_FRM_CMDID, WMI_PDEV_PKTLOG_FILTER_CMDID, + WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID = 0x403b, + WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID, + WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, + WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, + WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, + WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID = 0x4044, WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID = 0x4045, WMI_PDEV_SET_BIOS_INTERFACE_CMDID = 0x404A, @@ -1076,6 +1082,9 @@ enum wmi_tlv_pdev_param { WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE, WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE, WMI_PDEV_PARAM_MESH_MCAST_ENABLE, + WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc, + WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe, + WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6, }; enum wmi_tlv_vdev_param { @@ -1987,6 +1996,12 @@ enum wmi_tlv_tag { WMI_TAG_SERVICE_READY_EXT2_EVENT = 0x334, WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344, WMI_TAG_MAC_PHY_CAPABILITIES_EXT = 0x36F, + WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b, + WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, + WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD = 0x381, + WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, + WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, + WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9, WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT, WMI_TAG_TPC_STATS_GET_CMD = 0x38B, @@ -4925,6 +4940,12 @@ struct wmi_obss_spatial_reuse_params_cmd { __le32 vdev_id; } __packed; +struct wmi_pdev_obss_pd_bitmap_cmd { + __le32 tlv_header; + __le32 pdev_id; + __le32 bitmap[2]; +} __packed; + #define ATH12K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200 #define ATH12K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0 #define ATH12K_OBSS_COLOR_COLLISION_DETECTION 1 @@ -6329,6 +6350,18 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg { /* each WMI cmd can hold 58 channel entries at most */ #define ATH12K_WMI_MAX_NUM_CHAN_PER_CMD 58 +#define ATH12K_OBSS_PD_THRESHOLD_IN_DBM BIT(29) +#define ATH12K_OBSS_PD_SRG_EN BIT(30) +#define ATH12K_OBSS_PD_NON_SRG_EN BIT(31) + +struct ath12k_wmi_obss_pd_arg { + bool srp_support; + bool srg_enabled; + bool non_srg_enabled; + s8 srg_th; + s8 non_srg_th; +}; + int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); @@ -6432,6 +6465,19 @@ int ath12k_wmi_send_twt_enable_cmd(struct ath12k *ar, u32 pdev_id); int ath12k_wmi_send_twt_disable_cmd(struct ath12k *ar, u32 pdev_id); int ath12k_wmi_send_obss_spr_cmd(struct ath12k *ar, u32 vdev_id, struct ieee80211_he_obss_pd *he_obss_pd); +u32 ath12k_wmi_build_obss_pd(const struct ath12k_wmi_obss_pd_arg *arg); +int ath12k_wmi_pdev_set_srg_bss_color_bitmap(struct ath12k *ar, u32 pdev_id, + const u32 *bitmap); +int ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(struct ath12k *ar, u32 pdev_id, + const u32 *bitmap); +int ath12k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath12k *ar, u32 pdev_id, + const u32 *bitmap); +int ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath12k *ar, u32 pdev_id, + const u32 *bitmap); +int ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath12k *ar, u32 pdev_id, + const u32 *bitmap); +int ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath12k *ar, u32 pdev_id, + const u32 *bitmap); int ath12k_wmi_obss_color_cfg_cmd(struct ath12k *ar, u32 vdev_id, u8 bss_color, u32 period, bool enable); From d02a2496da94380b0a9dee2d4cc03e154e462bce Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Thu, 22 Jan 2026 22:48:17 -0800 Subject: [PATCH 493/659] wifi: ath12k: support OBSS PD configuration for AP mode Configure HE OBSS PD for spatial reuse in ath12k based on mac80211 HE SPR parameters in AP mode. This adds a pdev-level helper that programs SRG/non-SRG OBSS PD thresholds, per-AC enablement, SR prohibit control, and SRG/non-SRG BSS color and partial BSSID bitmaps via WMI. Replace the previous vdev-level OBSS SPR command usage with the new pdev-level configuration path, allowing firmware to apply HE spatial reuse behavior according to the HE SPR/OBSS PD settings provided by mac80211. Tested-on: WCN7850 hw2.0 PCI WLAN.IOE_HMT.1.1-00011-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Tested-on: QCN9274 hw2.0 WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Wei Zhang Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260123064817.364047-3-wei.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 170 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath12k/mac.h | 3 + drivers/net/wireless/ath/ath12k/wmi.h | 1 + 3 files changed, 171 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 5cd10752b22e1..a027295342de2 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4505,6 +4505,166 @@ static void ath12k_wmi_vdev_params_up(struct ath12k *ar, arvif->vdev_id, ret); } +static int ath12k_mac_config_obss_pd(struct ath12k_link_vif *arvif, + const struct ieee80211_he_obss_pd *he_obss_pd) +{ + struct ath12k_wmi_obss_pd_arg obss_pd_arg = {}; + u32 srg_bitmap[2], non_srg_bitmap[2]; + struct ath12k *ar = arvif->ar; + u32 param_id, pdev_id; + u32 param_val; + int ret; + + if (ar->ab->hw_params->single_pdev_only) + pdev_id = ath12k_mac_get_target_pdev_id_from_vif(arvif); + else + pdev_id = ar->pdev->pdev_id; + + /* Set and enable SRG/non-SRG OBSS PD threshold */ + param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD; + if (ar->monitor_started || !he_obss_pd->enable) { + ret = ath12k_wmi_pdev_set_param(ar, param_id, 0, pdev_id); + if (ret) + ath12k_warn(ar->ab, + "failed to set OBSS PD threshold for pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* + * This service flag indicates firmware support for SRG/SRP-based + * spatial reuse. It also specifies whether OBSS PD threshold values + * should be interpreted as dB (offset) or dBm (absolute) units. + */ + obss_pd_arg.srp_support = test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT, + ar->ab->wmi_ab.svc_map); + + if (!(he_obss_pd->sr_ctrl & + IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED)) { + if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) + obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD + + he_obss_pd->non_srg_max_offset; + else + obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD; + + if (!obss_pd_arg.srp_support) + obss_pd_arg.non_srg_th -= ATH12K_DEFAULT_NOISE_FLOOR; + + obss_pd_arg.non_srg_enabled = true; + } + + if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) { + obss_pd_arg.srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD + + he_obss_pd->max_offset; + obss_pd_arg.srg_enabled = true; + } + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "pdev %u OBSS PD sr_ctrl 0x%x srg_th %d dBm non_srg_th %d dBm\n", + pdev_id, he_obss_pd->sr_ctrl, + obss_pd_arg.srg_th, obss_pd_arg.non_srg_th); + + param_val = ath12k_wmi_build_obss_pd(&obss_pd_arg); + ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id); + if (ret) { + ath12k_warn(ar->ab, + "failed to set OBSS PD threshold for pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* Enable OBSS PD for all access category */ + param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC; + param_val = 0xf; + ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id); + if (ret) { + ath12k_warn(ar->ab, + "failed to set OBSS PD per ac for pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* Set SR prohibit */ + param_id = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT; + param_val = !!(he_obss_pd->sr_ctrl & + IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED); + ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id); + if (ret) { + ath12k_warn(ar->ab, "failed to set SR prohibit for pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + if (!obss_pd_arg.srp_support) + return 0; + + memcpy(srg_bitmap, he_obss_pd->bss_color_bitmap, sizeof(srg_bitmap)); + /* Set SRG BSS color bitmap */ + ret = ath12k_wmi_pdev_set_srg_bss_color_bitmap(ar, pdev_id, srg_bitmap); + if (ret) { + ath12k_warn(ar->ab, + "failed to set SRG bss color bitmap for pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* Enable BSS colors for SRG */ + ret = ath12k_wmi_pdev_srg_obss_color_enable_bitmap(ar, pdev_id, srg_bitmap); + if (ret) { + ath12k_warn(ar->ab, + "failed to enable SRG bss color bitmap pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + memcpy(srg_bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(srg_bitmap)); + /* Set SRG partial bssid bitmap */ + ret = ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(ar, pdev_id, srg_bitmap); + if (ret) { + ath12k_warn(ar->ab, + "failed to set SRG partial bssid bitmap for pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* Enable partial bssid mask for SRG */ + ret = ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(ar, pdev_id, srg_bitmap); + if (ret) { + ath12k_warn(ar->ab, + "failed to enable SRG bssid bitmap pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* + * No explicit non-SRG bitmap from mac80211; enable all colors/bssids + * as non-SRG candidates. Actual SRG members are filtered by SRG bitmaps. + */ + memset(non_srg_bitmap, 0xff, sizeof(non_srg_bitmap)); + + /* Enable BSS colors for non-SRG */ + ret = ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(ar, pdev_id, + non_srg_bitmap); + if (ret) { + ath12k_warn(ar->ab, + "failed to enable non SRG color bitmap pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + /* Enable partial bssid mask for non-SRG */ + ret = ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(ar, pdev_id, + non_srg_bitmap); + if (ret) { + ath12k_warn(ar->ab, + "failed to enable non SRG bssid bitmap pdev %u: %d\n", + pdev_id, ret); + return ret; + } + + return 0; +} + static void ath12k_mac_bss_info_changed(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ieee80211_bss_conf *info, @@ -4796,9 +4956,13 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, ath12k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id); } - if (changed & BSS_CHANGED_HE_OBSS_PD) - ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, - &info->he_obss_pd); + if (changed & BSS_CHANGED_HE_OBSS_PD) { + if (vif->type == NL80211_IFTYPE_AP) + ath12k_mac_config_obss_pd(arvif, &info->he_obss_pd); + else + ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, + &info->he_obss_pd); + } if (changed & BSS_CHANGED_HE_BSS_COLOR) { if (vif->type == NL80211_IFTYPE_AP) { diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 422bd3b095cd2..7b50c59763840 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -138,6 +138,9 @@ struct ath12k_reg_tpc_power_info { struct ath12k_chan_power_info chan_power_info[ATH12K_NUM_PWR_LEVELS]; }; +#define ATH12K_OBSS_PD_MAX_THRESHOLD -82 +#define ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62 + extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default; #define ATH12K_SCAN_11D_INTERVAL 600000 diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 2a81819ef5432..0bf0a7941cd3c 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2259,6 +2259,7 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219, WMI_TLV_SERVICE_EXT2_MSG = 220, WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT = 244, + WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253, WMI_MAX_EXT_SERVICE = 256, From 796b32a77bc7acda376f2a7c1a5ba4d63c620e10 Mon Sep 17 00:00:00 2001 From: Aaradhana Sahu Date: Fri, 23 Jan 2026 12:42:51 +0530 Subject: [PATCH 494/659] wifi: ath12k: Fix index decrement when array_len is zero Currently, print_array_to_buf_index() decrements index unconditionally. This may lead to invalid buffer access when array_len is zero. Fix this by decrementing index only when array_len is non-zero. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: adf6df963c03 ("wifi: ath12k: Add support to parse requested stats_type") Signed-off-by: Aaradhana Sahu Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260123071253.2202644-2-aaradhana.sahu@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c index 48b010a1b7566..4f749d473d0e1 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -29,8 +29,10 @@ print_array_to_buf_index(u8 *buf, u32 offset, const char *header, u32 stats_inde " %u:%u,", stats_index++, le32_to_cpu(array[i])); } /* To overwrite the last trailing comma */ - index--; - *(buf + offset + index) = '\0'; + if (array_len > 0) { + index--; + *(buf + offset + index) = '\0'; + } if (footer) { index += scnprintf(buf + offset + index, From 1f96dcbce2cd2089b461a82a4929b989570c0698 Mon Sep 17 00:00:00 2001 From: Aaradhana Sahu Date: Fri, 23 Jan 2026 12:42:52 +0530 Subject: [PATCH 495/659] wifi: ath12k: Add support RX PDEV stats Add support to request and receive RX pdev firmware stats using HTT stats type 2. This stats type reports PPDU and MPDU counters, firmware ring and buffer statistics, and RX suspend and resume counts. Note: Currently, firmware on mobile-centric chipsets do not maintain these statistics, so a query will not return any information. Sample output: ------------- echo 2 >/sys/kernel/debug/ath12k/pci-0000\:58\:00.0/mac0/htt_stats_type cat /sys/kernel/debug/ath12k/pci-0000\:58\:00.0/mac0/htt_stats HTT_RX_PDEV_FW_STATS_TLV: mac_id = 0 ppdu_recvd = 1522 mpdu_cnt_fcs_ok = 1522 mpdu_cnt_fcs_err = 0 ... fw_ring_mpdu_ind = 1522 fw_ring_mgmt_subtype = 0:0, 1:0, 2:0, 3:0, 4:21, 5:0, 6:0, 7:0, 8:1501, 9:0, 10:0, 11:0, 12:0, 13:0, 14:0, 15:0 fw_ring_ctrl_subtype = 0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0, 13:0, 14:0, 15:0 fw_ring_mcast_data_msdu = 0 fw_pkt_buf_ring_refill_cnt = 1567 fw_pkt_buf_ring_empty_cnt = 1 ... rx_suspend_cnt = 4 rx_suspend_fail_cnt = 0 rx_resume_cnt = 4 rx_resume_fail_cnt = 0 rx_ring_switch_cnt = 0 rx_ring_restore_cnt = 0 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Aaradhana Sahu Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260123071253.2202644-3-aaradhana.sahu@oss.qualcomm.com Signed-off-by: Jeff Johnson --- .../wireless/ath/ath12k/debugfs_htt_stats.c | 125 ++++++++++++++++++ .../wireless/ath/ath12k/debugfs_htt_stats.h | 55 ++++++++ 2 files changed, 180 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c index 4f749d473d0e1..a667eb9966c9c 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c @@ -5539,6 +5539,128 @@ ath12k_htt_print_pdev_rtt_tbr_cmd_res_stats_tlv(const void *tag_buf, u16 tag_len stats_req->buf_len = len; } +static void +ath12k_htt_print_rx_pdev_fw_stats_tlv(const void *tag_buf, u16 tag_len, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_rx_pdev_fw_stats_tlv *htt_stats_buf = tag_buf; + u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; + u32 len = stats_req->buf_len; + u8 *buf = stats_req->buf; + + if (tag_len < sizeof(*htt_stats_buf)) + return; + + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", + le32_to_cpu(htt_stats_buf->mac_id__word) & 0xFF); + len += scnprintf(buf + len, buf_len - len, "ppdu_recvd = %u\n", + le32_to_cpu(htt_stats_buf->ppdu_recvd)); + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_cnt_fcs_ok)); + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_err = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_cnt_fcs_err)); + len += scnprintf(buf + len, buf_len - len, "tcp_msdu_cnt = %u\n", + le32_to_cpu(htt_stats_buf->tcp_msdu_cnt)); + len += scnprintf(buf + len, buf_len - len, "tcp_ack_msdu_cnt = %u\n", + le32_to_cpu(htt_stats_buf->tcp_ack_msdu_cnt)); + len += scnprintf(buf + len, buf_len - len, "udp_msdu_cnt = %u\n", + le32_to_cpu(htt_stats_buf->udp_msdu_cnt)); + len += scnprintf(buf + len, buf_len - len, "other_msdu_cnt = %u\n", + le32_to_cpu(htt_stats_buf->other_msdu_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u\n", + le32_to_cpu(htt_stats_buf->fw_ring_mpdu_ind)); + len += print_array_to_buf(buf, len, "fw_ring_mgmt_subtype", + htt_stats_buf->fw_ring_mgmt_subtype, + ATH12K_HTT_STATS_SUBTYPE_MAX, "\n"); + len += print_array_to_buf(buf, len, "fw_ring_ctrl_subtype", + htt_stats_buf->fw_ring_ctrl_subtype, + ATH12K_HTT_STATS_SUBTYPE_MAX, "\n"); + len += scnprintf(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u\n", + le32_to_cpu(htt_stats_buf->fw_ring_mcast_data_msdu)); + len += scnprintf(buf + len, buf_len - len, "fw_ring_bcast_data_msdu = %u\n", + le32_to_cpu(htt_stats_buf->fw_ring_bcast_data_msdu)); + len += scnprintf(buf + len, buf_len - len, "fw_ring_ucast_data_msdu = %u\n", + le32_to_cpu(htt_stats_buf->fw_ring_ucast_data_msdu)); + len += scnprintf(buf + len, buf_len - len, "fw_ring_null_data_msdu = %u\n", + le32_to_cpu(htt_stats_buf->fw_ring_null_data_msdu)); + len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_drop = %u\n", + le32_to_cpu(htt_stats_buf->fw_ring_mpdu_drop)); + len += scnprintf(buf + len, buf_len - len, "ofld_local_data_ind_cnt = %u\n", + le32_to_cpu(htt_stats_buf->ofld_local_data_ind_cnt)); + len += scnprintf(buf + len, buf_len - len, + "ofld_local_data_buf_recycle_cnt = %u\n", + le32_to_cpu(htt_stats_buf->ofld_local_data_buf_recycle_cnt)); + len += scnprintf(buf + len, buf_len - len, "drx_local_data_ind_cnt = %u\n", + le32_to_cpu(htt_stats_buf->drx_local_data_ind_cnt)); + len += scnprintf(buf + len, buf_len - len, + "drx_local_data_buf_recycle_cnt = %u\n", + le32_to_cpu(htt_stats_buf->drx_local_data_buf_recycle_cnt)); + len += scnprintf(buf + len, buf_len - len, "local_nondata_ind_cnt = %u\n", + le32_to_cpu(htt_stats_buf->local_nondata_ind_cnt)); + len += scnprintf(buf + len, buf_len - len, "local_nondata_buf_recycle_cnt = %u\n", + le32_to_cpu(htt_stats_buf->local_nondata_buf_recycle_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->fw_status_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->fw_status_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->fw_pkt_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->fw_pkt_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->fw_link_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->fw_link_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->host_pkt_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->host_pkt_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_pkt_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_pkt_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, + "mon_status_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_status_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_status_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_status_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_refill_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_desc_buf_ring_refill_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_empty_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_desc_buf_ring_empty_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_update_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_dest_ring_update_cnt)); + len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_full_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mon_dest_ring_full_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_suspend_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_suspend_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_suspend_fail_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_suspend_fail_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_resume_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_resume_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_resume_fail_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_resume_fail_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_ring_switch_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_ring_switch_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_ring_restore_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_ring_restore_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_flush_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_recovery_reset_cnt = %u\n", + le32_to_cpu(htt_stats_buf->rx_recovery_reset_cnt)); + len += scnprintf(buf + len, buf_len - len, "rx_lwm_prom_filter_dis = %u\n", + le32_to_cpu(htt_stats_buf->rx_lwm_prom_filter_dis)); + len += scnprintf(buf + len, buf_len - len, "rx_hwm_prom_filter_en = %u\n", + le32_to_cpu(htt_stats_buf->rx_hwm_prom_filter_en)); + len += scnprintf(buf + len, buf_len - len, "bytes_received_low_32 = %u\n", + le32_to_cpu(htt_stats_buf->bytes_received_low_32)); + len += scnprintf(buf + len, buf_len - len, "bytes_received_high_32 = %u\n", + le32_to_cpu(htt_stats_buf->bytes_received_high_32)); + + stats_req->buf_len = len; +} + static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab, u16 tag, u16 len, const void *tag_buf, void *user_data) @@ -5692,6 +5814,9 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab, case HTT_STATS_SFM_CLIENT_USER_TAG: ath12k_htt_print_sfm_client_user_tlv(tag_buf, len, stats_req); break; + case HTT_STATS_RX_PDEV_FW_STATS_TAG: + ath12k_htt_print_rx_pdev_fw_stats_tlv(tag_buf, len, stats_req); + break; case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG: ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, len, stats_req); break; diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h index 8008658371aae..a6656f20b8457 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h @@ -127,6 +127,7 @@ struct ath12k_htt_extd_stats_msg { enum ath12k_dbg_htt_ext_stats_type { ATH12K_DBG_HTT_EXT_STATS_RESET = 0, ATH12K_DBG_HTT_EXT_STATS_PDEV_TX = 1, + ATH12K_DBG_HTT_EXT_STATS_PDEV_RX = 2, ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED = 4, ATH12K_DBG_HTT_EXT_STATS_PDEV_ERROR = 5, ATH12K_DBG_HTT_EXT_STATS_PDEV_TQM = 6, @@ -188,6 +189,7 @@ enum ath12k_dbg_htt_tlv_tag { HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG = 25, HTT_STATS_SFM_CMN_TAG = 26, HTT_STATS_SRING_STATS_TAG = 27, + HTT_STATS_RX_PDEV_FW_STATS_TAG = 28, HTT_STATS_TX_PDEV_RATE_STATS_TAG = 34, HTT_STATS_RX_PDEV_RATE_STATS_TAG = 35, HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG = 36, @@ -2075,4 +2077,57 @@ struct ath12k_htt_stats_pdev_rtt_tbr_cmd_result_stats_tlv { __le32 mu_res[ATH12K_HTT_FTYPE_MAX][ATH12K_HTT_MAX_SCH_CMD_RESULT]; } __packed; +struct htt_rx_pdev_fw_stats_tlv { + __le32 mac_id__word; + __le32 ppdu_recvd; + __le32 mpdu_cnt_fcs_ok; + __le32 mpdu_cnt_fcs_err; + __le32 tcp_msdu_cnt; + __le32 tcp_ack_msdu_cnt; + __le32 udp_msdu_cnt; + __le32 other_msdu_cnt; + __le32 fw_ring_mpdu_ind; + __le32 fw_ring_mgmt_subtype[ATH12K_HTT_STATS_SUBTYPE_MAX]; + __le32 fw_ring_ctrl_subtype[ATH12K_HTT_STATS_SUBTYPE_MAX]; + __le32 fw_ring_mcast_data_msdu; + __le32 fw_ring_bcast_data_msdu; + __le32 fw_ring_ucast_data_msdu; + __le32 fw_ring_null_data_msdu; + __le32 fw_ring_mpdu_drop; + __le32 ofld_local_data_ind_cnt; + __le32 ofld_local_data_buf_recycle_cnt; + __le32 drx_local_data_ind_cnt; + __le32 drx_local_data_buf_recycle_cnt; + __le32 local_nondata_ind_cnt; + __le32 local_nondata_buf_recycle_cnt; + __le32 fw_status_buf_ring_refill_cnt; + __le32 fw_status_buf_ring_empty_cnt; + __le32 fw_pkt_buf_ring_refill_cnt; + __le32 fw_pkt_buf_ring_empty_cnt; + __le32 fw_link_buf_ring_refill_cnt; + __le32 fw_link_buf_ring_empty_cnt; + __le32 host_pkt_buf_ring_refill_cnt; + __le32 host_pkt_buf_ring_empty_cnt; + __le32 mon_pkt_buf_ring_refill_cnt; + __le32 mon_pkt_buf_ring_empty_cnt; + __le32 mon_status_buf_ring_refill_cnt; + __le32 mon_status_buf_ring_empty_cnt; + __le32 mon_desc_buf_ring_refill_cnt; + __le32 mon_desc_buf_ring_empty_cnt; + __le32 mon_dest_ring_update_cnt; + __le32 mon_dest_ring_full_cnt; + __le32 rx_suspend_cnt; + __le32 rx_suspend_fail_cnt; + __le32 rx_resume_cnt; + __le32 rx_resume_fail_cnt; + __le32 rx_ring_switch_cnt; + __le32 rx_ring_restore_cnt; + __le32 rx_flush_cnt; + __le32 rx_recovery_reset_cnt; + __le32 rx_lwm_prom_filter_dis; + __le32 rx_hwm_prom_filter_en; + __le32 bytes_received_low_32; + __le32 bytes_received_high_32; +} __packed; + #endif From 4e1fe1c72394d827670564314ee348b811311372 Mon Sep 17 00:00:00 2001 From: Aaradhana Sahu Date: Fri, 23 Jan 2026 12:42:53 +0530 Subject: [PATCH 496/659] wifi: ath12k: Add support TX hardware queue stats Add support to request and receive TX hardware queue stats using HTT stats type 3. This stats type reports MPDU mac id and hardware queue information, including xretry, BAR, RTS, CTS, self, and QoS-null counts, along with underrun, flush, and filter counters. Sample output: ------------- echo 3 >/sys/kernel/debug/ath12k/pci-0000\:58\:00.0/mac0/htt_stats_type cat /sys/kernel/debug/ath12k/pci-0000\:58\:00.0/mac0/htt_stats HTT_TX_HWQ_STATS_CMN_TLV: mac_id = 0 hwq_id = 0 xretry = 0 underrun_cnt = 0 flush_cnt = 0 filt_cnt = 0 null_mpdu_bmap = 0 user_ack_failure = 379 ack_tlv_proc = 0 sched_id_proc = 0 null_mpdu_tx_count = 0 mpdu_bmap_not_recvd = 0 num_bar = 0 rts = 0 cts2self = 0 qos_null = 0 mpdu_tried_cnt = 379 mpdu_queued_cnt = 379 mpdu_ack_fail_cnt = 0 mpdu_filt_cnt = 0 false_mpdu_ack_count = 0 txq_timeout = 0 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Aaradhana Sahu Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260123071253.2202644-4-aaradhana.sahu@oss.qualcomm.com Signed-off-by: Jeff Johnson --- .../wireless/ath/ath12k/debugfs_htt_stats.c | 64 +++++++++++++++++++ .../wireless/ath/ath12k/debugfs_htt_stats.h | 26 ++++++++ 2 files changed, 90 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c index a667eb9966c9c..7f6ca07fb3359 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c @@ -5661,6 +5661,67 @@ ath12k_htt_print_rx_pdev_fw_stats_tlv(const void *tag_buf, u16 tag_len, stats_req->buf_len = len; } +static void +ath12k_htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, u16 tag_len, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_tx_hwq_stats_cmn_tlv *htt_stats_buf = tag_buf; + u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; + u32 len = stats_req->buf_len; + u8 *buf = stats_req->buf; + + if (tag_len < sizeof(*htt_stats_buf)) + return; + + len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", + le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word) & 0xFF); + len += scnprintf(buf + len, buf_len - len, "hwq_id = %u\n", + (le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word) & 0xFF00) >> 8); + len += scnprintf(buf + len, buf_len - len, "xretry = %u\n", + le32_to_cpu(htt_stats_buf->xretry)); + len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n", + le32_to_cpu(htt_stats_buf->underrun_cnt)); + len += scnprintf(buf + len, buf_len - len, "flush_cnt = %u\n", + le32_to_cpu(htt_stats_buf->flush_cnt)); + len += scnprintf(buf + len, buf_len - len, "filt_cnt = %u\n", + le32_to_cpu(htt_stats_buf->filt_cnt)); + len += scnprintf(buf + len, buf_len - len, "null_mpdu_bmap = %u\n", + le32_to_cpu(htt_stats_buf->null_mpdu_bmap)); + len += scnprintf(buf + len, buf_len - len, "user_ack_failure = %u\n", + le32_to_cpu(htt_stats_buf->user_ack_failure)); + len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", + le32_to_cpu(htt_stats_buf->ack_tlv_proc)); + len += scnprintf(buf + len, buf_len - len, "sched_id_proc = %u\n", + le32_to_cpu(htt_stats_buf->sched_id_proc)); + len += scnprintf(buf + len, buf_len - len, "null_mpdu_tx_count = %u\n", + le32_to_cpu(htt_stats_buf->null_mpdu_tx_count)); + len += scnprintf(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_bmap_not_recvd)); + len += scnprintf(buf + len, buf_len - len, "num_bar = %u\n", + le32_to_cpu(htt_stats_buf->num_bar)); + len += scnprintf(buf + len, buf_len - len, "rts = %u\n", + le32_to_cpu(htt_stats_buf->rts)); + len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n", + le32_to_cpu(htt_stats_buf->cts2self)); + len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n", + le32_to_cpu(htt_stats_buf->qos_null)); + len += scnprintf(buf + len, buf_len - len, "mpdu_tried_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_tried_cnt)); + len += scnprintf(buf + len, buf_len - len, "mpdu_queued_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_queued_cnt)); + len += scnprintf(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_ack_fail_cnt)); + len += scnprintf(buf + len, buf_len - len, "mpdu_filt_cnt = %u\n", + le32_to_cpu(htt_stats_buf->mpdu_filt_cnt)); + len += scnprintf(buf + len, buf_len - len, "false_mpdu_ack_count = %u\n", + le32_to_cpu(htt_stats_buf->false_mpdu_ack_count)); + len += scnprintf(buf + len, buf_len - len, "txq_timeout = %u\n", + le32_to_cpu(htt_stats_buf->txq_timeout)); + + stats_req->buf_len = len; +} + static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab, u16 tag, u16 len, const void *tag_buf, void *user_data) @@ -5960,6 +6021,9 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab, case HTT_STATS_PDEV_RTT_TBR_CMD_RESULT_STATS_TAG: ath12k_htt_print_pdev_rtt_tbr_cmd_res_stats_tlv(tag_buf, len, stats_req); break; + case HTT_STATS_TX_HWQ_CMN_TAG: + ath12k_htt_print_tx_hwq_stats_cmn_tlv(tag_buf, len, stats_req); + break; default: break; } diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h index a6656f20b8457..bfabe6500d44d 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h @@ -128,6 +128,7 @@ enum ath12k_dbg_htt_ext_stats_type { ATH12K_DBG_HTT_EXT_STATS_RESET = 0, ATH12K_DBG_HTT_EXT_STATS_PDEV_TX = 1, ATH12K_DBG_HTT_EXT_STATS_PDEV_RX = 2, + ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_HWQ = 3, ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED = 4, ATH12K_DBG_HTT_EXT_STATS_PDEV_ERROR = 5, ATH12K_DBG_HTT_EXT_STATS_PDEV_TQM = 6, @@ -174,6 +175,7 @@ enum ath12k_dbg_htt_tlv_tag { HTT_STATS_TX_PDEV_SIFS_TAG = 2, HTT_STATS_TX_PDEV_FLUSH_TAG = 3, HTT_STATS_STRING_TAG = 5, + HTT_STATS_TX_HWQ_CMN_TAG = 6, HTT_STATS_TX_TQM_GEN_MPDU_TAG = 11, HTT_STATS_TX_TQM_LIST_MPDU_TAG = 12, HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG = 13, @@ -2130,4 +2132,28 @@ struct htt_rx_pdev_fw_stats_tlv { __le32 bytes_received_high_32; } __packed; +struct htt_tx_hwq_stats_cmn_tlv { + __le32 mac_id__hwq_id__word; + __le32 xretry; + __le32 underrun_cnt; + __le32 flush_cnt; + __le32 filt_cnt; + __le32 null_mpdu_bmap; + __le32 user_ack_failure; + __le32 ack_tlv_proc; + __le32 sched_id_proc; + __le32 null_mpdu_tx_count; + __le32 mpdu_bmap_not_recvd; + __le32 num_bar; + __le32 rts; + __le32 cts2self; + __le32 qos_null; + __le32 mpdu_tried_cnt; + __le32 mpdu_queued_cnt; + __le32 mpdu_ack_fail_cnt; + __le32 mpdu_filt_cnt; + __le32 false_mpdu_ack_count; + __le32 txq_timeout; +} __packed; + #endif From a58d6f508c09754039a79b93d0573266f2d99e28 Mon Sep 17 00:00:00 2001 From: Aaradhana Sahu Date: Tue, 27 Jan 2026 09:04:00 +0530 Subject: [PATCH 497/659] wifi: ath12k: clear stale link mapping of ahvif->links_map When an arvif is initialized in non-AP STA mode but MLO connection preparation fails before the arvif is created (arvif->is_created remains false), the error path attempts to delete all links. However, link deletion only executes when arvif->is_created is true. As a result, ahvif retains a stale entry of arvif that is initialized but not created. When a new arvif is initialized with the same link id, this stale mapping triggers the following WARN_ON. WARNING: drivers/net/wireless/ath/ath12k/mac.c:4271 at ath12k_mac_op_change_vif_links+0x140/0x180 [ath12k], CPU#3: wpa_supplicant/275 Call trace: ath12k_mac_op_change_vif_links+0x140/0x180 [ath12k] (P) drv_change_vif_links+0xbc/0x1a4 [mac80211] ieee80211_vif_update_links+0x54c/0x6a0 [mac80211] ieee80211_vif_set_links+0x40/0x70 [mac80211] ieee80211_prep_connection+0x84/0x450 [mac80211] ieee80211_mgd_auth+0x200/0x480 [mac80211] ieee80211_auth+0x14/0x20 [mac80211] cfg80211_mlme_auth+0x90/0xf0 [cfg80211] nl80211_authenticate+0x32c/0x380 [cfg80211] genl_family_rcv_msg_doit+0xc8/0x134 Fix this issue by unassigning the link vif and clearing ahvif->links_map if arvif is only initialized but not created. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Fixes: 81e4be30544e ("wifi: ath12k: handle link removal in change_vif_links()") Signed-off-by: Aaradhana Sahu Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260127033400.1721220-1-aaradhana.sahu@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index a027295342de2..6da26a5babc21 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4281,8 +4281,10 @@ ath12k_mac_op_change_vif_links(struct ieee80211_hw *hw, if (WARN_ON(!arvif)) return -EINVAL; - if (!arvif->is_created) + if (!arvif->is_created) { + ath12k_mac_unassign_link_vif(arvif); continue; + } if (WARN_ON(!arvif->ar)) return -EINVAL; From 4d59732813751b7a8c470d58bc630e1d2d048372 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 23 Dec 2025 19:05:26 -0800 Subject: [PATCH 498/659] mhi: host: Add support for loading dual ELF image format Currently, the FBC image contains a single ELF header followed by segments for both SBL and WLAN FW. However, TME-L (Trust Management Engine Lite) supported devices (e.g., QCC2072) require separate ELF headers for SBL and WLAN FW segments due to TME-L image authentication requirements. Current image format contains two sections in a single binary: - First 512KB: ELF header + SBL segments - Remaining: WLAN FW segments (raw data) The TME-L supported image format contains two complete ELF files in a single binary: - First 512KB: Complete SBL ELF file (ELF header + SBL segments) - Remaining: Complete WLAN FW ELF file (ELF header + WLAN FW segments) Download behavior: - Legacy: 1. First 512KB via BHI (ELF header + SBL) 2. Full image via BHIe - TME-L: 1. First 512KB via BHI (SBL ELF file) 2. Remaining via BHIe (WLAN FW ELF file only) Add runtime detection to automatically identify the image format by checking for the presence of a second ELF header at the 512KB boundary. When detected, MHI skips the first 512KB during WLAN FW download over BHIe as it is loaded in BHI phase. Signed-off-by: Qiang Yu Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20251223-wlan_image_load_skip_512k-v5-1-8d4459d720b5@oss.qualcomm.com --- drivers/bus/mhi/host/boot.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 205d83ac069f1..c76db35bc29a9 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -584,6 +584,16 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) * device transitioning into MHI READY state */ if (fw_load_type == MHI_FW_LOAD_FBC) { + /* + * Some FW combine two separate ELF images (SBL + WLAN FW) in a single + * file. Hence, check for the existence of the second ELF header after + * SBL. If present, load the second image separately. + */ + if (!memcmp(fw_data + mhi_cntrl->sbl_size, ELFMAG, SELFMAG)) { + fw_data += mhi_cntrl->sbl_size; + fw_sz -= mhi_cntrl->sbl_size; + } + ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz); if (ret) { release_firmware(firmware); From 1e63ca955dbe40f871766db6e619315d246b284b Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Thu, 8 Jan 2026 18:31:52 +0800 Subject: [PATCH 499/659] wifi: ath12k: Fix wrong P2P device link id issue Wrong P2P device link id value of 0 was introduced in ath12k_mac_op_tx() by [1]. During the P2P negotiation process, there is only one scan vdev with link ID 15. Currently, the device link ID is incorrectly set to 0 in ath12k_mac_op_tx() during the P2P negotiation process, which leads to TX failures. Set the correct P2P device link ID to 15 to fix the TX failure issue. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: 648a121bafa3 ("wifi: ath12k: ath12k_mac_op_tx(): MLO support") # [1] Signed-off-by: Yingying Tang Link: https://lore.kernel.org/linux-wireless/20260113054636.2620035-1-yingying.tang@oss.qualcomm.com/ --- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index f75690f586cd9..df045ddf42da9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -806,7 +806,10 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw, return; } } else { - link_id = 0; + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) + link_id = ATH12K_FIRST_SCAN_LINK; + else + link_id = 0; } arvif = rcu_dereference(ahvif->link[link_id]); From 12287e54c6772afe134ba5df936177e1a033fac9 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Tue, 3 Feb 2026 15:46:32 +0800 Subject: [PATCH 500/659] 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 c2e9da995f440..6f5dba014767c 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -3955,6 +3955,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>, @@ -4068,6 +4097,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>; @@ -4738,6 +4883,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 da0734bc91cd2f225f444fb0684707ce3288d3b0 Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Fri, 14 Nov 2025 12:10:22 +0800 Subject: [PATCH 501/659] wifi: ath11k: add usecase firmware handling based on device compatible For M.2 WLAN chips, there is no suitable DTS node to specify the firmware-name property. In addition, assigning firmware for the M.2 PCIe interface causes chips that do not use usecase specific firmware to fail. Therefore, abandoning the approach of specifying firmware in DTS. As an alternative, propose a static lookup table mapping device compatible to firmware names. Currently, only WCN6855 HW2.1 requires this. However, support for the firmware-name property is retained to keep the ABI backwards compatible. For details on usecase specific firmware, see: https://lore.kernel.org/all/20250522013444.1301330-3-miaoqing.pan@oss.qualcomm.com/. Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Fixes: edbbc647c4f3 ("wifi: ath11k: support usercase-specific firmware overrides") Signed-off-by: Miaoqing Pan --- drivers/net/wireless/ath/ath11k/core.c | 27 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/core.h | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 812686173ac8a..06b4df2370e95 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -997,6 +997,33 @@ static const struct dmi_system_id ath11k_pm_quirk_table[] = { {} }; +static const struct __ath11k_core_usecase_firmware_table { + u32 hw_rev; + const char *compatible; + const char *firmware_name; +} ath11k_core_usecase_firmware_table[] = { + { ATH11K_HW_WCN6855_HW21, "qcom,lemans-evk", "nfa765"}, + { ATH11K_HW_WCN6855_HW21, "qcom,monaco-evk", "nfa765"}, + { ATH11K_HW_WCN6855_HW21, "qcom,hamoa-iot-evk", "nfa765"}, + { /* Sentinel */ } +}; + +const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab) +{ + const struct __ath11k_core_usecase_firmware_table *entry = NULL; + + entry = ath11k_core_usecase_firmware_table; + while (entry->compatible) { + if (ab->hw_rev == entry->hw_rev && + of_machine_is_compatible(entry->compatible)) + return entry->firmware_name; + entry++; + } + + return NULL; +} +EXPORT_SYMBOL(ath11k_core_get_usecase_firmware); + void ath11k_fw_stats_pdevs_free(struct list_head *head) { struct ath11k_fw_stats_pdev *i, *tmp; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index e8780b05ce11e..834988dad591c 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1275,6 +1275,7 @@ bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab); const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, const char *filename); +const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab); static inline const char *ath11k_scan_state_str(enum ath11k_scan_state state) { @@ -1329,6 +1330,9 @@ static inline void ath11k_core_create_firmware_path(struct ath11k_base *ab, of_property_read_string(ab->dev->of_node, "firmware-name", &fw_name); + if (!fw_name) + fw_name = ath11k_core_get_usecase_firmware(ab); + if (fw_name && strncmp(filename, "board", 5)) snprintf(buf, buf_len, "%s/%s/%s/%s", ATH11K_FW_DIR, ab->hw_params.fw.dir, fw_name, filename); From 1a2a6e269912544af8769f8e681726c16e67a667 Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Mon, 17 Nov 2025 13:53:58 +0800 Subject: [PATCH 502/659] dt-bindings: net: wireless: ath11k-pci: deprecate 'firmware-name' property The firmware-name property was originally introduced to allow end-users and integrators to select use-case-specific firmware for the WCN6855. However, specifying firmware for an M.2 WLAN module in the Device Tree is not appropriate. Instead, this functionality will be handled within the ath11k driver. Therefore, the firmware-name property is now deprecated. Acked-by: Rob Herring (Arm) Signed-off-by: Miaoqing Pan --- .../devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml index e34d42a30192b..0162e365798b7 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml @@ -37,6 +37,7 @@ properties: firmware-name: maxItems: 1 + deprecated: true description: If present, a board or platform specific string used to lookup usecase-specific firmware files for the device. From 25e3f03e79bcf649cd708c465f3d73cce6938827 Mon Sep 17 00:00:00 2001 From: Qian Zhang Date: Thu, 8 Jan 2026 11:46:07 +0800 Subject: [PATCH 503/659] wifi: ath11k: Fix failure to connect to a 6 GHz AP STA fails to connect to a 6 GHz AP with the following errors: ath11k_pci 0000:01:00.0: failed to handle chan list with power type 1 wlp1s0: deauthenticating from c8:a3:e8:dd:41:e3 by local choice (Reason: 3=DEAUTH_LEAVING) ath11k_reg_handle_chan_list() treats the update as redundant and returns -EINVAL. That causes the connection attempt to fail. Avoid unnecessary validation during association. Apply the regulatory redundant check only when the power type is IEEE80211_REG_UNSET_AP, which only occurs during core initialization. Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 Signed-off-by: Qian Zhang Reviewed-by: Baochen Qiang --- drivers/net/wireless/ath/ath11k/reg.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index d62a2014315a0..49b79648752cf 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -926,8 +926,11 @@ int ath11k_reg_handle_chan_list(struct ath11k_base *ab, */ if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] && !memcmp((char *)ab->default_regd[pdev_idx]->alpha2, - (char *)reg_info->alpha2, 2)) - goto retfail; + (char *)reg_info->alpha2, 2) && + power_type == IEEE80211_REG_UNSET_AP) { + ath11k_reg_reset_info(reg_info); + return 0; + } /* Intersect new rules with default regd if a new country setting was * requested, i.e a default regd was already set during initialization From a9fe64a68732529c1fb1e0f2c12640b95aaea614 Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 30 Dec 2025 13:55:15 +0530 Subject: [PATCH 504/659] FROMGIT: wifi: ath11k: Add initialization and deinitialization sequence for CFR module Channel Frequency Response (CFR) module will be initialized only when the following criteria passes: * Enabled CFR support for the hardware through the hardware param 'cfr_support' * WMI service enabled for the CFR support 'WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT' Also, provide a configuration option CONFIG_ATH11K_CFR to enable CFR feature support during the compilation time. CFR module initialization includes Direct Buffer(DB) ring initialization where hardware uses the DB ring buffers to copy CFR data to host. Number of buffers and buffer size of the ring is based on the DB ring capabilities advertised by the firmware through WMI service ready. Also ring configurations are sent to firmware through ath11k_dbring_wmi_cfg_setup(). Predefine ath11k_cfr_dma_hdr, ath11k_look_up_table, and ath11k_cfr structs and fields for subsequent patches. Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Signed-off-by: Qian Zhang Link: https://patch.msgid.link/20251230082520.3401007-2-qian.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/Kconfig | 11 ++ drivers/net/wireless/ath/ath11k/Makefile | 1 + drivers/net/wireless/ath/ath11k/cfr.c | 170 +++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 85 ++++++++++++ drivers/net/wireless/ath/ath11k/core.c | 41 +++++- drivers/net/wireless/ath/ath11k/core.h | 8 +- drivers/net/wireless/ath/ath11k/dbring.c | 40 ++++-- drivers/net/wireless/ath/ath11k/dbring.h | 6 +- drivers/net/wireless/ath/ath11k/hal.c | 3 +- drivers/net/wireless/ath/ath11k/hw.h | 5 +- drivers/net/wireless/ath/ath11k/wmi.h | 1 + 11 files changed, 354 insertions(+), 17 deletions(-) create mode 100644 drivers/net/wireless/ath/ath11k/cfr.c create mode 100644 drivers/net/wireless/ath/ath11k/cfr.h diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig index 659ef134ef168..47dfd39caa89a 100644 --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig @@ -58,3 +58,14 @@ config ATH11K_SPECTRAL Enable ath11k spectral scan support Say Y to enable access to the FFT/spectral data via debugfs. + +config ATH11K_CFR + bool "ath11k channel frequency response support" + depends on ATH11K_DEBUGFS + depends on RELAY + help + Enable ath11k channel frequency response dump support. + This option exposes debugfs nodes that will allow the user + to enable, disable, and dump data. + + Say Y to enable CFR data dump collection via debugfs. diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile index d9092414b362d..b1435fcf3e1bf 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -28,6 +28,7 @@ ath11k-$(CONFIG_THERMAL) += thermal.o ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o ath11k-$(CONFIG_PM) += wow.o ath11k-$(CONFIG_DEV_COREDUMP) += coredump.o +ath11k-$(CONFIG_ATH11K_CFR) += cfr.o obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o ath11k_ahb-y += ahb.o diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c new file mode 100644 index 0000000000000..78e356672ebad --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include "core.h" +#include "debug.h" + +static int ath11k_cfr_process_data(struct ath11k *ar, + struct ath11k_dbring_data *param) +{ + return 0; +} + +void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, + u32 buf_id) +{ + struct ath11k_cfr *cfr = &ar->cfr; + + if (cfr->lut) + cfr->lut[buf_id].dbr_address = paddr; +} + +static void ath11k_cfr_ring_free(struct ath11k *ar) +{ + struct ath11k_cfr *cfr = &ar->cfr; + + ath11k_dbring_buf_cleanup(ar, &cfr->rx_ring); + ath11k_dbring_srng_cleanup(ar, &cfr->rx_ring); +} + +static int ath11k_cfr_ring_alloc(struct ath11k *ar, + struct ath11k_dbring_cap *db_cap) +{ + struct ath11k_cfr *cfr = &ar->cfr; + int ret; + + ret = ath11k_dbring_srng_setup(ar, &cfr->rx_ring, + ATH11K_CFR_NUM_RING_ENTRIES, + db_cap->min_elem); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring: %d\n", ret); + return ret; + } + + ath11k_dbring_set_cfg(ar, &cfr->rx_ring, + ATH11K_CFR_NUM_RESP_PER_EVENT, + ATH11K_CFR_EVENT_TIMEOUT_MS, + ath11k_cfr_process_data); + + ret = ath11k_dbring_buf_setup(ar, &cfr->rx_ring, db_cap); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring buffer: %d\n", ret); + goto srng_cleanup; + } + + ret = ath11k_dbring_wmi_cfg_setup(ar, &cfr->rx_ring, WMI_DIRECT_BUF_CFR); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg: %d\n", ret); + goto buffer_cleanup; + } + + return 0; + +buffer_cleanup: + ath11k_dbring_buf_cleanup(ar, &cfr->rx_ring); +srng_cleanup: + ath11k_dbring_srng_cleanup(ar, &cfr->rx_ring); + return ret; +} + +void ath11k_cfr_deinit(struct ath11k_base *ab) +{ + struct ath11k_cfr *cfr; + struct ath11k *ar; + int i; + + if (!test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, ab->wmi_ab.svc_map) || + !ab->hw_params.cfr_support) + return; + + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + cfr = &ar->cfr; + + if (!cfr->enabled) + continue; + + ath11k_cfr_ring_free(ar); + + spin_lock_bh(&cfr->lut_lock); + kfree(cfr->lut); + cfr->lut = NULL; + cfr->enabled = false; + spin_unlock_bh(&cfr->lut_lock); + } +} + +int ath11k_cfr_init(struct ath11k_base *ab) +{ + struct ath11k_dbring_cap db_cap; + struct ath11k_cfr *cfr; + u32 num_lut_entries; + struct ath11k *ar; + int i, ret; + + if (!test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, ab->wmi_ab.svc_map) || + !ab->hw_params.cfr_support) + return 0; + + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + cfr = &ar->cfr; + + ret = ath11k_dbring_get_cap(ar->ab, ar->pdev_idx, + WMI_DIRECT_BUF_CFR, &db_cap); + if (ret) + continue; + + idr_init(&cfr->rx_ring.bufs_idr); + spin_lock_init(&cfr->rx_ring.idr_lock); + spin_lock_init(&cfr->lock); + spin_lock_init(&cfr->lut_lock); + + num_lut_entries = min_t(u32, CFR_MAX_LUT_ENTRIES, db_cap.min_elem); + cfr->lut = kcalloc(num_lut_entries, sizeof(*cfr->lut), + GFP_KERNEL); + if (!cfr->lut) { + ret = -ENOMEM; + goto err; + } + + ret = ath11k_cfr_ring_alloc(ar, &db_cap); + if (ret) { + ath11k_warn(ab, "failed to init cfr ring for pdev %d: %d\n", + i, ret); + spin_lock_bh(&cfr->lut_lock); + kfree(cfr->lut); + cfr->lut = NULL; + cfr->enabled = false; + spin_unlock_bh(&cfr->lut_lock); + goto err; + } + + cfr->lut_num = num_lut_entries; + cfr->enabled = true; + } + + return 0; + +err: + for (i = i - 1; i >= 0; i--) { + ar = ab->pdevs[i].ar; + cfr = &ar->cfr; + + if (!cfr->enabled) + continue; + + ath11k_cfr_ring_free(ar); + + spin_lock_bh(&cfr->lut_lock); + kfree(cfr->lut); + cfr->lut = NULL; + cfr->enabled = false; + spin_unlock_bh(&cfr->lut_lock); + } + return ret; +} diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h new file mode 100644 index 0000000000000..3534176c3e013 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH11K_CFR_H +#define ATH11K_CFR_H + +#include "dbring.h" +#include "wmi.h" + +#define ATH11K_CFR_NUM_RESP_PER_EVENT 1 +#define ATH11K_CFR_EVENT_TIMEOUT_MS 1 +#define ATH11K_CFR_NUM_RING_ENTRIES 1 + +#define CFR_MAX_LUT_ENTRIES 136 + +#define HOST_MAX_CHAINS 8 + +struct ath11k_cfr_dma_hdr { + u16 info0; + u16 info1; + u16 sw_peer_id; + u16 phy_ppdu_id; +}; + +struct ath11k_look_up_table { + bool dbr_recv; + bool tx_recv; + u8 *data; + u32 data_len; + u16 dbr_ppdu_id; + u16 tx_ppdu_id; + dma_addr_t dbr_address; + struct ath11k_cfr_dma_hdr hdr; + u64 txrx_tstamp; + u64 dbr_tstamp; + u32 header_length; + u32 payload_length; + struct ath11k_dbring_element *buff; +}; + +struct ath11k_cfr { + struct ath11k_dbring rx_ring; + /* Protects cfr data */ + spinlock_t lock; + /* Protect for lut entries */ + spinlock_t lut_lock; + struct ath11k_look_up_table *lut; + u32 lut_num; + u64 tx_evt_cnt; + u64 dbr_evt_cnt; + u64 release_cnt; + u64 tx_peer_status_cfr_fail; + u64 tx_evt_status_cfr_fail; + u64 tx_dbr_lookup_fail; + u64 last_success_tstamp; + u64 flush_dbr_cnt; + u64 clear_txrx_event; + u64 cfr_dma_aborts; + bool enabled; +}; + +#ifdef CONFIG_ATH11K_CFR +int ath11k_cfr_init(struct ath11k_base *ab); +void ath11k_cfr_deinit(struct ath11k_base *ab); +void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, + u32 buf_id); +#else +static inline int ath11k_cfr_init(struct ath11k_base *ab) +{ + return 0; +} + +static inline void ath11k_cfr_deinit(struct ath11k_base *ab) +{ +} + +static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar, + dma_addr_t paddr, u32 buf_id) +{ +} +#endif /* CONFIG_ATH11K_CFR */ +#endif /* ATH11K_CFR_H */ diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 06b4df2370e95..7fcab1cb88005 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ @@ -126,6 +125,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .smp2p_wow_exit = false, .support_dual_stations = false, .pdev_suspend = false, + .cfr_support = true, + .cfr_num_stream_bufs = 255, + .cfr_stream_buf_size = 8200, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -211,6 +213,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = false, .support_dual_stations = false, .pdev_suspend = false, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .name = "qca6390 hw2.0", @@ -301,6 +306,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = true, .support_dual_stations = true, .pdev_suspend = false, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .name = "qcn9074 hw1.0", @@ -385,6 +393,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = false, .support_dual_stations = false, .pdev_suspend = false, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .name = "wcn6855 hw2.0", @@ -475,6 +486,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = true, .support_dual_stations = true, .pdev_suspend = false, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .name = "wcn6855 hw2.1", @@ -563,6 +577,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = true, .support_dual_stations = true, .pdev_suspend = false, + .cfr_support = true, + .cfr_num_stream_bufs = 255, + .cfr_stream_buf_size = 8200, }, { .name = "wcn6750 hw1.0", @@ -646,6 +663,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = true, .support_dual_stations = false, .pdev_suspend = true, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .hw_rev = ATH11K_HW_IPQ5018_HW10, @@ -729,6 +749,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = false, .support_dual_stations = false, .pdev_suspend = false, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .name = "qca2066 hw2.1", @@ -818,6 +841,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .smp2p_wow_exit = false, .support_fw_mac_sequence = true, .support_dual_stations = true, + .cfr_support = false, + .cfr_num_stream_bufs = 0, + .cfr_stream_buf_size = 0, }, { .name = "qca6698aq hw2.1", @@ -906,6 +932,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = true, .support_dual_stations = true, .pdev_suspend = false, + .cfr_support = true, + .cfr_num_stream_bufs = 255, + .cfr_stream_buf_size = 8200, }, }; @@ -2014,8 +2043,16 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) goto err_thermal_unregister; } + ret = ath11k_cfr_init(ab); + if (ret) { + ath11k_err(ab, "failed to init cfr %d\n", ret); + goto err_spectral_unregister; + } + return 0; +err_spectral_unregister: + ath11k_spectral_deinit(ab); err_thermal_unregister: ath11k_thermal_unregister(ab); err_mac_unregister: @@ -2065,6 +2102,7 @@ static void ath11k_core_pdev_suspend_target(struct ath11k_base *ab) static void ath11k_core_pdev_destroy(struct ath11k_base *ab) { + ath11k_cfr_deinit(ab); ath11k_spectral_deinit(ab); ath11k_thermal_unregister(ab); ath11k_mac_unregister(ab); @@ -2277,6 +2315,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) mutex_lock(&ab->core_lock); ath11k_thermal_unregister(ab); ath11k_dp_pdev_free(ab); + ath11k_cfr_deinit(ab); ath11k_spectral_deinit(ab); ath11k_ce_cleanup_pipes(ab); ath11k_wmi_detach(ab); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 834988dad591c..fa22c08050b64 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH11K_CORE_H @@ -35,6 +35,7 @@ #include "wow.h" #include "fw.h" #include "coredump.h" +#include "cfr.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -795,6 +796,11 @@ struct ath11k { bool ps_state_enable; bool ps_timekeeper_enable; s8 max_allowed_tx_power; + +#ifdef CONFIG_ATH11K_CFR + struct ath11k_cfr cfr; +#endif + bool cfr_enabled; }; struct ath11k_band_cap { diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c index 520d8b8662a28..ed2b781a6bab6 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.c +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ @@ -37,10 +36,10 @@ static void ath11k_dbring_fill_magic_value(struct ath11k *ar, memset32(buffer, ATH11K_DB_MAGIC_VALUE, size); } -static int ath11k_dbring_bufs_replenish(struct ath11k *ar, - struct ath11k_dbring *ring, - struct ath11k_dbring_element *buff, - enum wmi_direct_buffer_module id) +int ath11k_dbring_bufs_replenish(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_element *buff, + enum wmi_direct_buffer_module id) { struct ath11k_base *ab = ar->ab; struct hal_srng *srng; @@ -80,6 +79,9 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar, goto err_idr_remove; } + if (id == WMI_DIRECT_BUF_CFR) + ath11k_cfr_lut_update_paddr(ar, paddr, buf_id); + buff->paddr = paddr; cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) | @@ -155,12 +157,11 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, enum wmi_direct_buffer_module id) { struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {}; - int ret; + int ret, i; if (id >= WMI_DIRECT_BUF_MAX) return -EINVAL; - param.pdev_id = DP_SW2HW_MACID(ring->pdev_id); param.module_id = id; param.base_paddr_lo = lower_32_bits(ring->refill_srng.paddr); param.base_paddr_hi = upper_32_bits(ring->refill_srng.paddr); @@ -173,10 +174,23 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, param.num_resp_per_event = ring->num_resp_per_event; param.event_timeout_ms = ring->event_timeout_ms; - ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); - if (ret) { - ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); - return ret; + /* For single pdev, 2GHz and 5GHz use one DBR. */ + if (ar->ab->hw_params.single_pdev_only) { + for (i = 0; i < ar->ab->target_pdev_count; i++) { + param.pdev_id = ar->ab->target_pdev_ids[i].pdev_id; + ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); + return ret; + } + } + } else { + param.pdev_id = DP_SW2HW_MACID(ring->pdev_id); + ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); + return ret; + } } return 0; @@ -285,6 +299,10 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, pdev_idx = ev->fixed.pdev_id; module_id = ev->fixed.module_id; + if (ab->hw_params.single_pdev_only && + pdev_idx < ab->target_pdev_count) + pdev_idx = 0; + if (pdev_idx >= ab->num_radios) { ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx); return -EINVAL; diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireless/ath/ath11k/dbring.h index 2f93b78a50df0..0a380120f7a0e 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.h +++ b/drivers/net/wireless/ath/ath11k/dbring.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH11K_DBRING_H @@ -61,6 +61,10 @@ int ath11k_dbring_set_cfg(struct ath11k *ar, u32 event_timeout_ms, int (*handler)(struct ath11k *, struct ath11k_dbring_data *)); +int ath11k_dbring_bufs_replenish(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_element *buff, + enum wmi_direct_buffer_module id); int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, struct ath11k_dbring *ring, enum wmi_direct_buffer_module id); diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index 0c797b8d0a276..e821e5a62c1c0 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -184,7 +183,7 @@ static const struct hal_srng_config hw_srng_config_template[] = { }, { /* RXDMA DIR BUF */ .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, - .max_rings = 1, + .max_rings = 2, .entry_size = 8 >> 2, /* TODO: Define the struct */ .lmac_ring = true, .ring_dir = HAL_SRNG_DIR_SRC, diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 52d9f4c13b136..e13ca02a9d057 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH11K_HW_H @@ -228,6 +228,9 @@ struct ath11k_hw_params { bool support_fw_mac_sequence; bool support_dual_stations; bool pdev_suspend; + bool cfr_support; + u32 cfr_num_stream_bufs; + u32 cfr_stream_buf_size; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 0f0de24a38408..7a55fe0879c08 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -981,6 +981,7 @@ enum wmi_tlv_pdev_param { WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE, WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE, WMI_PDEV_PARAM_MESH_MCAST_ENABLE, + WMI_PDEV_PARAM_PER_PEER_CFR_ENABLE = 0xa8, WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc, WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe, WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6, From 6157ac2ea0f96505e678f067be2efd3555fc096c Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 30 Dec 2025 13:55:16 +0530 Subject: [PATCH 505/659] FROMGIT: wifi: ath11k: Register debugfs for CFR configuration Provide debugfs interfaces support to config CFR from the user space. To enable/disable cfr feature use command, echo > /sys/kernel/debug/ieee80211/phyX/ath11k/enable_cfr where, val: 0 to disable CFR and 1 to enable CFR. To enable CFR capture for associated peers, echo " " > /sys/kernel/debug/ieee80211/phyX/netdev\:wlanx/stations//cfr_capture val: 0 - stop CFR capture 1 - start CFR capture bw: CFR capture bandwidth 0 - 20MHZ 1 - 40MHZ 2 - 80MHZ Periodicity: Periodicity at which hardware is expected to collect CFR dump. 0 - single shot capture. non zero - for Periodic captures (value must be multiple of 10 ms) method: Method used by hardware to collect the CFR dump. 0 - from the ACKs of QOS NULL packets. Also, send the required WMI commands to the firmware based on the CFR configurations. Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Signed-off-by: Qian Zhang Link: https://patch.msgid.link/20251230082520.3401007-3-qian.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/cfr.c | 191 ++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 41 ++++ drivers/net/wireless/ath/ath11k/core.h | 11 + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 142 ++++++++++++- drivers/net/wireless/ath/ath11k/mac.c | 2 + drivers/net/wireless/ath/ath11k/wmi.c | 41 ++++ drivers/net/wireless/ath/ath11k/wmi.h | 50 ++++- 7 files changed, 475 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c index 78e356672ebad..bf0b880e87466 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -14,6 +14,193 @@ static int ath11k_cfr_process_data(struct ath11k *ar, return 0; } +void ath11k_cfr_decrement_peer_count(struct ath11k *ar, + struct ath11k_sta *arsta) +{ + struct ath11k_cfr *cfr = &ar->cfr; + + spin_lock_bh(&cfr->lock); + + if (arsta->cfr_capture.cfr_enable) + cfr->cfr_enabled_peer_cnt--; + + spin_unlock_bh(&cfr->lock); +} + +static enum ath11k_wmi_cfr_capture_bw +ath11k_cfr_bw_to_fw_cfr_bw(enum ath11k_cfr_capture_bw bw) +{ + switch (bw) { + case ATH11K_CFR_CAPTURE_BW_20: + return WMI_PEER_CFR_CAPTURE_BW_20; + case ATH11K_CFR_CAPTURE_BW_40: + return WMI_PEER_CFR_CAPTURE_BW_40; + case ATH11K_CFR_CAPTURE_BW_80: + return WMI_PEER_CFR_CAPTURE_BW_80; + default: + return WMI_PEER_CFR_CAPTURE_BW_MAX; + } +} + +static enum ath11k_wmi_cfr_capture_method +ath11k_cfr_method_to_fw_cfr_method(enum ath11k_cfr_capture_method method) +{ + switch (method) { + case ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME: + return WMI_CFR_CAPTURE_METHOD_NULL_FRAME; + case ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE: + return WMI_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE; + case ATH11K_CFR_CAPTURE_METHOD_PROBE_RESP: + return WMI_CFR_CAPTURE_METHOD_PROBE_RESP; + default: + return WMI_CFR_CAPTURE_METHOD_MAX; + } +} + +int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, + struct ath11k_sta *arsta, + struct ath11k_per_peer_cfr_capture *params, + const u8 *peer_mac) +{ + struct ath11k_cfr *cfr = &ar->cfr; + struct wmi_peer_cfr_capture_conf_arg arg; + enum ath11k_wmi_cfr_capture_bw bw; + enum ath11k_wmi_cfr_capture_method method; + int ret = 0; + + if (cfr->cfr_enabled_peer_cnt >= ATH11K_MAX_CFR_ENABLED_CLIENTS && + !arsta->cfr_capture.cfr_enable) { + ath11k_err(ar->ab, "CFR enable peer threshold reached %u\n", + cfr->cfr_enabled_peer_cnt); + return -ENOSPC; + } + + if (params->cfr_enable == arsta->cfr_capture.cfr_enable && + params->cfr_period == arsta->cfr_capture.cfr_period && + params->cfr_method == arsta->cfr_capture.cfr_method && + params->cfr_bw == arsta->cfr_capture.cfr_bw) + return ret; + + if (!params->cfr_enable && !arsta->cfr_capture.cfr_enable) + return ret; + + bw = ath11k_cfr_bw_to_fw_cfr_bw(params->cfr_bw); + if (bw >= WMI_PEER_CFR_CAPTURE_BW_MAX) { + ath11k_warn(ar->ab, "FW doesn't support configured bw %d\n", + params->cfr_bw); + return -EINVAL; + } + + method = ath11k_cfr_method_to_fw_cfr_method(params->cfr_method); + if (method >= WMI_CFR_CAPTURE_METHOD_MAX) { + ath11k_warn(ar->ab, "FW doesn't support configured method %d\n", + params->cfr_method); + return -EINVAL; + } + + arg.request = params->cfr_enable; + arg.periodicity = params->cfr_period; + arg.bw = bw; + arg.method = method; + + ret = ath11k_wmi_peer_set_cfr_capture_conf(ar, arsta->arvif->vdev_id, + peer_mac, &arg); + if (ret) { + ath11k_warn(ar->ab, + "failed to send cfr capture info: vdev_id %u peer %pM: %d\n", + arsta->arvif->vdev_id, peer_mac, ret); + return ret; + } + + spin_lock_bh(&cfr->lock); + + if (params->cfr_enable && + params->cfr_enable != arsta->cfr_capture.cfr_enable) + cfr->cfr_enabled_peer_cnt++; + else if (!params->cfr_enable) + cfr->cfr_enabled_peer_cnt--; + + spin_unlock_bh(&cfr->lock); + + arsta->cfr_capture.cfr_enable = params->cfr_enable; + arsta->cfr_capture.cfr_period = params->cfr_period; + arsta->cfr_capture.cfr_method = params->cfr_method; + arsta->cfr_capture.cfr_bw = params->cfr_bw; + + return ret; +} + +static ssize_t ath11k_read_file_enable_cfr(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + char buf[32] = {}; + size_t len; + + mutex_lock(&ar->conf_mutex); + len = scnprintf(buf, sizeof(buf), "%d\n", ar->cfr_enabled); + mutex_unlock(&ar->conf_mutex); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t ath11k_write_file_enable_cfr(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + u32 enable_cfr; + int ret; + + if (kstrtouint_from_user(ubuf, count, 0, &enable_cfr)) + return -EINVAL; + + guard(mutex)(&ar->conf_mutex); + + if (ar->state != ATH11K_STATE_ON) + return -ENETDOWN; + + if (enable_cfr > 1) + return -EINVAL; + + if (ar->cfr_enabled == enable_cfr) + return count; + + ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PER_PEER_CFR_ENABLE, + enable_cfr, ar->pdev->pdev_id); + if (ret) { + ath11k_warn(ar->ab, + "Failed to enable/disable per peer cfr %d\n", ret); + return ret; + } + + ar->cfr_enabled = enable_cfr; + + return count; +} + +static const struct file_operations fops_enable_cfr = { + .read = ath11k_read_file_enable_cfr, + .write = ath11k_write_file_enable_cfr, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static void ath11k_cfr_debug_unregister(struct ath11k *ar) +{ + debugfs_remove(ar->cfr.enable_cfr); + ar->cfr.enable_cfr = NULL; +} + +static void ath11k_cfr_debug_register(struct ath11k *ar) +{ + ar->cfr.enable_cfr = debugfs_create_file("enable_cfr", 0600, + ar->debug.debugfs_pdev, ar, + &fops_enable_cfr); +} + void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, u32 buf_id) { @@ -88,6 +275,7 @@ void ath11k_cfr_deinit(struct ath11k_base *ab) if (!cfr->enabled) continue; + ath11k_cfr_debug_unregister(ar); ath11k_cfr_ring_free(ar); spin_lock_bh(&cfr->lut_lock); @@ -146,6 +334,8 @@ int ath11k_cfr_init(struct ath11k_base *ab) cfr->lut_num = num_lut_entries; cfr->enabled = true; + + ath11k_cfr_debug_register(ar); } return 0; @@ -158,6 +348,7 @@ int ath11k_cfr_init(struct ath11k_base *ab) if (!cfr->enabled) continue; + ath11k_cfr_debug_unregister(ar); ath11k_cfr_ring_free(ar); spin_lock_bh(&cfr->lut_lock); diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h index 3534176c3e013..7d161f7f7be84 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -14,10 +14,14 @@ #define ATH11K_CFR_EVENT_TIMEOUT_MS 1 #define ATH11K_CFR_NUM_RING_ENTRIES 1 +#define ATH11K_MAX_CFR_ENABLED_CLIENTS 10 #define CFR_MAX_LUT_ENTRIES 136 #define HOST_MAX_CHAINS 8 +struct ath11k_sta; +struct ath11k_per_peer_cfr_capture; + struct ath11k_cfr_dma_hdr { u16 info0; u16 info1; @@ -48,6 +52,8 @@ struct ath11k_cfr { /* Protect for lut entries */ spinlock_t lut_lock; struct ath11k_look_up_table *lut; + struct dentry *enable_cfr; + u8 cfr_enabled_peer_cnt; u32 lut_num; u64 tx_evt_cnt; u64 dbr_evt_cnt; @@ -62,11 +68,32 @@ struct ath11k_cfr { bool enabled; }; +enum ath11k_cfr_capture_method { + ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME, + ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE, + ATH11K_CFR_CAPTURE_METHOD_PROBE_RESP, + ATH11K_CFR_CAPTURE_METHOD_MAX, +}; + +enum ath11k_cfr_capture_bw { + ATH11K_CFR_CAPTURE_BW_20, + ATH11K_CFR_CAPTURE_BW_40, + ATH11K_CFR_CAPTURE_BW_80, + ATH11K_CFR_CAPTURE_BW_MAX, +}; + #ifdef CONFIG_ATH11K_CFR int ath11k_cfr_init(struct ath11k_base *ab); void ath11k_cfr_deinit(struct ath11k_base *ab); void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, u32 buf_id); +void ath11k_cfr_decrement_peer_count(struct ath11k *ar, + struct ath11k_sta *arsta); +int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, + struct ath11k_sta *arsta, + struct ath11k_per_peer_cfr_capture *params, + const u8 *peer_mac); + #else static inline int ath11k_cfr_init(struct ath11k_base *ab) { @@ -81,5 +108,19 @@ static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, u32 buf_id) { } + +static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar, + struct ath11k_sta *arsta) +{ +} + +static inline int +ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, + struct ath11k_sta *arsta, + struct ath11k_per_peer_cfr_capture *params, + const u8 *peer_mac) +{ + return 0; +} #endif /* CONFIG_ATH11K_CFR */ #endif /* ATH11K_CFR_H */ diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index fa22c08050b64..a0d725923ef24 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -532,6 +532,13 @@ struct ath11k_per_ppdu_tx_stats { DECLARE_EWMA(avg_rssi, 10, 8) +struct ath11k_per_peer_cfr_capture { + enum ath11k_cfr_capture_method cfr_method; + enum ath11k_cfr_capture_bw cfr_bw; + u32 cfr_enable; + u32 cfr_period; +}; + struct ath11k_sta { struct ath11k_vif *arvif; @@ -572,6 +579,10 @@ struct ath11k_sta { bool peer_current_ps_valid; u32 bw_prev; + +#ifdef CONFIG_ATH11K_CFR + struct ath11k_per_peer_cfr_capture cfr_capture; +#endif }; #define ATH11K_MIN_5G_FREQ 4150 diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c index d89d0f28d890b..621a8a8df4b86 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ @@ -240,6 +239,140 @@ static const struct file_operations fops_tx_stats = { .llseek = default_llseek, }; +#ifdef CONFIG_ATH11K_CFR +static ssize_t ath11k_dbg_sta_write_cfr_capture(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ieee80211_sta *sta = file->private_data; + struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); + struct ath11k *ar = arsta->arvif->ar; + struct ath11k_cfr *cfr = &ar->cfr; + struct wmi_peer_cfr_capture_conf_arg arg; + u32 cfr_capture_enable = 0, cfr_capture_bw = 0; + u32 cfr_capture_method = 0, cfr_capture_period = 0; + char buf[64] = {}; + int ret; + + simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); + + guard(mutex)(&ar->conf_mutex); + + if (ar->state != ATH11K_STATE_ON) + return -ENETDOWN; + + if (!ar->cfr_enabled) + return -EINVAL; + + ret = sscanf(buf, "%u %u %u %u", &cfr_capture_enable, &cfr_capture_bw, + &cfr_capture_period, &cfr_capture_method); + + if (ret < 1 || (cfr_capture_enable && ret != 4)) + return -EINVAL; + + if (cfr_capture_enable == arsta->cfr_capture.cfr_enable && + (cfr_capture_period && + cfr_capture_period == arsta->cfr_capture.cfr_period) && + cfr_capture_bw == arsta->cfr_capture.cfr_bw && + cfr_capture_method == arsta->cfr_capture.cfr_method) + return count; + + if (!cfr_capture_enable && + cfr_capture_enable == arsta->cfr_capture.cfr_enable) + return count; + + if (cfr_capture_enable > WMI_PEER_CFR_CAPTURE_ENABLE || + cfr_capture_bw > WMI_PEER_CFR_CAPTURE_BW_80 || + cfr_capture_method > ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE || + cfr_capture_period > WMI_PEER_CFR_PERIODICITY_MAX) + return -EINVAL; + + /* Target expects cfr period in multiple of 10 */ + if (cfr_capture_period % 10) { + ath11k_err(ar->ab, "periodicity should be 10x\n"); + return -EINVAL; + } + + if (ar->cfr.cfr_enabled_peer_cnt >= ATH11K_MAX_CFR_ENABLED_CLIENTS && + !arsta->cfr_capture.cfr_enable) { + ath11k_err(ar->ab, "CFR enable peer threshold reached %u\n", + ar->cfr.cfr_enabled_peer_cnt); + return -EINVAL; + } + + if (!cfr_capture_enable) { + cfr_capture_bw = arsta->cfr_capture.cfr_bw; + cfr_capture_period = arsta->cfr_capture.cfr_period; + cfr_capture_method = arsta->cfr_capture.cfr_method; + } + + arg.request = cfr_capture_enable; + arg.periodicity = cfr_capture_period; + arg.bw = cfr_capture_bw; + arg.method = cfr_capture_method; + + ret = ath11k_wmi_peer_set_cfr_capture_conf(ar, arsta->arvif->vdev_id, + sta->addr, &arg); + if (ret) { + ath11k_warn(ar->ab, + "failed to send cfr capture info: vdev_id %u peer %pM: %d\n", + arsta->arvif->vdev_id, sta->addr, ret); + return ret; + } + + spin_lock_bh(&ar->cfr.lock); + + if (cfr_capture_enable && + cfr_capture_enable != arsta->cfr_capture.cfr_enable) + cfr->cfr_enabled_peer_cnt++; + else if (!cfr_capture_enable) + cfr->cfr_enabled_peer_cnt--; + + spin_unlock_bh(&ar->cfr.lock); + + arsta->cfr_capture.cfr_enable = cfr_capture_enable; + arsta->cfr_capture.cfr_period = cfr_capture_period; + arsta->cfr_capture.cfr_bw = cfr_capture_bw; + arsta->cfr_capture.cfr_method = cfr_capture_method; + + return count; +} + +static ssize_t ath11k_dbg_sta_read_cfr_capture(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ieee80211_sta *sta = file->private_data; + struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); + struct ath11k *ar = arsta->arvif->ar; + char buf[512] = {}; + int len = 0; + + mutex_lock(&ar->conf_mutex); + + len += scnprintf(buf + len, sizeof(buf) - len, "cfr_enabled = %d\n", + arsta->cfr_capture.cfr_enable); + len += scnprintf(buf + len, sizeof(buf) - len, "bandwidth = %d\n", + arsta->cfr_capture.cfr_bw); + len += scnprintf(buf + len, sizeof(buf) - len, "period = %d\n", + arsta->cfr_capture.cfr_period); + len += scnprintf(buf + len, sizeof(buf) - len, "cfr_method = %d\n", + arsta->cfr_capture.cfr_method); + + mutex_unlock(&ar->conf_mutex); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_peer_cfr_capture = { + .write = ath11k_dbg_sta_write_cfr_capture, + .read = ath11k_dbg_sta_read_cfr_capture, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; +#endif /* CONFIG_ATH11K_CFR */ + static ssize_t ath11k_dbg_sta_dump_rx_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -877,6 +1010,13 @@ void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vi debugfs_create_file("htt_peer_stats_reset", 0600, dir, sta, &fops_htt_peer_stats_reset); +#ifdef CONFIG_ATH11K_CFR + if (test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, + ar->ab->wmi_ab.svc_map)) + debugfs_create_file("cfr_capture", 0600, dir, sta, + &fops_peer_cfr_capture); +#endif/* CONFIG_ATH11K_CFR */ + debugfs_create_file("peer_ps_state", 0400, dir, sta, &fops_peer_ps_state); diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 3276fe443502f..4a9db5a6aee2a 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -9979,6 +9979,8 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); + + ath11k_cfr_decrement_peer_count(ar, arsta); } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 110035dae8a61..b14edc0820a24 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -3941,6 +3941,47 @@ int ath11k_wmi_fils_discovery_tmpl(struct ath11k *ar, u32 vdev_id, return 0; } +int ath11k_wmi_peer_set_cfr_capture_conf(struct ath11k *ar, + u32 vdev_id, const u8 *mac_addr, + struct wmi_peer_cfr_capture_conf_arg *arg) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct wmi_peer_cfr_capture_cmd_fixed_param *cmd; + struct sk_buff *skb; + int ret; + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_peer_cfr_capture_cmd_fixed_param *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_PEER_CFR_CAPTURE_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + memcpy(&cmd->mac_addr, mac_addr, ETH_ALEN); + cmd->request = arg->request; + cmd->vdev_id = vdev_id; + cmd->periodicity = arg->periodicity; + cmd->bandwidth = arg->bw; + cmd->capture_method = arg->method; + + ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_PEER_CFR_CAPTURE_CMDID); + if (ret) { + ath11k_warn(ar->ab, + "WMI vdev %d failed to send peer cfr capture cmd: %d\n", + vdev_id, ret); + dev_kfree_skb(skb); + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI peer CFR capture cmd req %u id %u period %u bw %u mode %u\n", + arg->request, vdev_id, arg->periodicity, + arg->bw, arg->method); + + return ret; +} + int ath11k_wmi_probe_resp_tmpl(struct ath11k *ar, u32 vdev_id, struct sk_buff *tmpl) { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 7a55fe0879c08..1562d169ba9ab 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -362,6 +362,10 @@ enum wmi_tlv_cmd_id { WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, WMI_PEER_SET_RX_BLOCKSIZE_CMDID, WMI_PEER_ANTDIV_INFO_REQ_CMDID, + WMI_PEER_RESERVED0_CMDID, + WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, + WMI_PEER_TID_CONFIGURATIONS_CMDID, + WMI_PEER_CFR_CAPTURE_CMDID, WMI_BCN_TX_CMDID = WMI_TLV_CMD(WMI_GRP_MGMT), WMI_PDEV_SEND_BCN_CMDID, WMI_BCN_TMPL_CMDID, @@ -3833,7 +3837,8 @@ struct wmi_scan_prob_req_oui_cmd { #define WMI_TX_PARAMS_DWORD1_BW_MASK GENMASK(14, 8) #define WMI_TX_PARAMS_DWORD1_PREAMBLE_TYPE GENMASK(19, 15) #define WMI_TX_PARAMS_DWORD1_FRAME_TYPE BIT(20) -#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 21) +#define WMI_TX_PARAMS_DWORD1_CFR_CAPTURE BIT(21) +#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 22) struct wmi_mgmt_send_params { u32 tlv_header; @@ -4218,6 +4223,45 @@ enum cc_setting_code { */ }; +enum ath11k_wmi_cfr_capture_bw { + WMI_PEER_CFR_CAPTURE_BW_20, + WMI_PEER_CFR_CAPTURE_BW_40, + WMI_PEER_CFR_CAPTURE_BW_80, + WMI_PEER_CFR_CAPTURE_BW_MAX, +}; + +enum ath11k_wmi_cfr_capture_method { + WMI_CFR_CAPTURE_METHOD_NULL_FRAME, + WMI_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE, + WMI_CFR_CAPTURE_METHOD_PROBE_RESP, + WMI_CFR_CAPTURE_METHOD_MAX, +}; + +struct wmi_peer_cfr_capture_conf_arg { + enum ath11k_wmi_cfr_capture_bw bw; + enum ath11k_wmi_cfr_capture_method method; + u32 request; + u32 periodicity; +}; + +struct wmi_peer_cfr_capture_cmd_fixed_param { + u32 tlv_header; + u32 request; + struct wmi_mac_addr mac_addr; + u32 vdev_id; + u32 periodicity; + /* BW of measurement - of type enum ath11k_wmi_cfr_capture_bw */ + u32 bandwidth; + /* Method used to capture CFR - of type enum ath11k_wmi_cfr_capture_method */ + u32 capture_method; +} __packed; + +#define WMI_PEER_CFR_CAPTURE_ENABLE 1 +#define WMI_PEER_CFR_CAPTURE_DISABLE 0 + +/*periodicity in ms */ +#define WMI_PEER_CFR_PERIODICITY_MAX 600000 + static inline enum cc_setting_code ath11k_wmi_cc_setting_code_to_reg(enum wmi_reg_cc_setting_code status_code) { @@ -6532,5 +6576,7 @@ bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar); int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar, u32 vdev_id, struct ath11k_reg_tpc_power_info *param); - +int ath11k_wmi_peer_set_cfr_capture_conf(struct ath11k *ar, + u32 vdev_id, const u8 *mac, + struct wmi_peer_cfr_capture_conf_arg *arg); #endif From c4105cca6b8b0dbdf1617c6e9f1979caeeb53cc4 Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 30 Dec 2025 13:55:17 +0530 Subject: [PATCH 506/659] FROMGIT: wifi: ath11k: Add support unassociated client CFR Provide debugfs interfaces support to config unassociated client CFR from the user space. To enable CFR capture for unassociated clients, echo " " > /sys/kernel/debug/ieee80211/phyX/ath11k/cfr_unassoc Mac address: mac address of the client. Val: 0 - start CFR capture 1 - stop CFR capture Periodicity: Periodicity at which hardware is expected to collect CFR dump. 0 - single shot capture. non zero - for Periodic captures (value must be multiple of 10 ms) Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Signed-off-by: Qian Zhang Link: https://patch.msgid.link/20251230082520.3401007-4-qian.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/cfr.c | 228 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 33 ++++ drivers/net/wireless/ath/ath11k/mac.c | 15 +- drivers/net/wireless/ath/ath11k/wmi.c | 16 +- drivers/net/wireless/ath/ath11k/wmi.h | 2 +- 5 files changed, 290 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c index bf0b880e87466..e22b0151833ca 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -14,6 +14,60 @@ static int ath11k_cfr_process_data(struct ath11k *ar, return 0; } +/* Helper function to check whether the given peer mac address + * is in unassociated peer pool or not. + */ +bool ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, const u8 *peer_mac) +{ + struct ath11k_cfr *cfr = &ar->cfr; + struct cfr_unassoc_pool_entry *entry; + int i; + + if (!ar->cfr_enabled) + return false; + + spin_lock_bh(&cfr->lock); + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + if (!entry->is_valid) + continue; + + if (ether_addr_equal(peer_mac, entry->peer_mac)) { + spin_unlock_bh(&cfr->lock); + return true; + } + } + + spin_unlock_bh(&cfr->lock); + + return false; +} + +void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar, + const u8 *peer_mac) +{ + struct ath11k_cfr *cfr = &ar->cfr; + struct cfr_unassoc_pool_entry *entry; + int i; + + spin_lock_bh(&cfr->lock); + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + if (!entry->is_valid) + continue; + + if (ether_addr_equal(peer_mac, entry->peer_mac) && + entry->period == 0) { + memset(entry->peer_mac, 0, ETH_ALEN); + entry->is_valid = false; + cfr->cfr_enabled_peer_cnt--; + break; + } + } + + spin_unlock_bh(&cfr->lock); +} + void ath11k_cfr_decrement_peer_count(struct ath11k *ar, struct ath11k_sta *arsta) { @@ -130,6 +184,59 @@ int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, return ret; } +void ath11k_cfr_update_unassoc_pool(struct ath11k *ar, + struct ath11k_per_peer_cfr_capture *params, + u8 *peer_mac) +{ + struct ath11k_cfr *cfr = &ar->cfr; + struct cfr_unassoc_pool_entry *entry; + int available_idx = -1; + int i; + + guard(spinlock_bh)(&cfr->lock); + + if (!params->cfr_enable) { + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + if (ether_addr_equal(peer_mac, entry->peer_mac)) { + memset(entry->peer_mac, 0, ETH_ALEN); + entry->is_valid = false; + cfr->cfr_enabled_peer_cnt--; + break; + } + } + return; + } + + if (cfr->cfr_enabled_peer_cnt >= ATH11K_MAX_CFR_ENABLED_CLIENTS) { + ath11k_info(ar->ab, "Max cfr peer threshold reached\n"); + return; + } + + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + + if (ether_addr_equal(peer_mac, entry->peer_mac)) { + ath11k_info(ar->ab, + "peer entry already present updating params\n"); + entry->period = params->cfr_period; + available_idx = -1; + break; + } + + if (available_idx < 0 && !entry->is_valid) + available_idx = i; + } + + if (available_idx >= 0) { + entry = &cfr->unassoc_pool[available_idx]; + ether_addr_copy(entry->peer_mac, peer_mac); + entry->period = params->cfr_period; + entry->is_valid = true; + cfr->cfr_enabled_peer_cnt++; + } +} + static ssize_t ath11k_read_file_enable_cfr(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -188,10 +295,127 @@ static const struct file_operations fops_enable_cfr = { .llseek = default_llseek, }; +static ssize_t ath11k_write_file_cfr_unassoc(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + struct ath11k_cfr *cfr = &ar->cfr; + struct cfr_unassoc_pool_entry *entry; + char buf[64] = {}; + u8 peer_mac[6]; + u32 cfr_capture_enable; + u32 cfr_capture_period; + int available_idx = -1; + int ret, i; + + simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); + + guard(mutex)(&ar->conf_mutex); + guard(spinlock_bh)(&cfr->lock); + + if (ar->state != ATH11K_STATE_ON) + return -ENETDOWN; + + if (!ar->cfr_enabled) { + ath11k_err(ar->ab, "CFR is not enabled on this pdev %d\n", + ar->pdev_idx); + return -EINVAL; + } + + ret = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %u %u", + &peer_mac[0], &peer_mac[1], &peer_mac[2], &peer_mac[3], + &peer_mac[4], &peer_mac[5], &cfr_capture_enable, + &cfr_capture_period); + + if (ret < 1) + return -EINVAL; + + if (cfr_capture_enable && ret != 8) + return -EINVAL; + + if (!cfr_capture_enable) { + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + if (ether_addr_equal(peer_mac, entry->peer_mac)) { + memset(entry->peer_mac, 0, ETH_ALEN); + entry->is_valid = false; + cfr->cfr_enabled_peer_cnt--; + } + } + + return count; + } + + if (cfr->cfr_enabled_peer_cnt >= ATH11K_MAX_CFR_ENABLED_CLIENTS) { + ath11k_info(ar->ab, "Max cfr peer threshold reached\n"); + return count; + } + + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + + if (available_idx < 0 && !entry->is_valid) + available_idx = i; + + if (ether_addr_equal(peer_mac, entry->peer_mac)) { + ath11k_info(ar->ab, + "peer entry already present updating params\n"); + entry->period = cfr_capture_period; + return count; + } + } + + if (available_idx >= 0) { + entry = &cfr->unassoc_pool[available_idx]; + ether_addr_copy(entry->peer_mac, peer_mac); + entry->period = cfr_capture_period; + entry->is_valid = true; + cfr->cfr_enabled_peer_cnt++; + } + + return count; +} + +static ssize_t ath11k_read_file_cfr_unassoc(struct file *file, + char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + struct ath11k_cfr *cfr = &ar->cfr; + struct cfr_unassoc_pool_entry *entry; + char buf[512] = {}; + int len = 0, i; + + spin_lock_bh(&cfr->lock); + + for (i = 0; i < ATH11K_MAX_CFR_ENABLED_CLIENTS; i++) { + entry = &cfr->unassoc_pool[i]; + if (entry->is_valid) + len += scnprintf(buf + len, sizeof(buf) - len, + "peer: %pM period: %u\n", + entry->peer_mac, entry->period); + } + + spin_unlock_bh(&cfr->lock); + + return simple_read_from_buffer(ubuf, count, ppos, buf, len); +} + +static const struct file_operations fops_configure_cfr_unassoc = { + .write = ath11k_write_file_cfr_unassoc, + .read = ath11k_read_file_cfr_unassoc, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static void ath11k_cfr_debug_unregister(struct ath11k *ar) { debugfs_remove(ar->cfr.enable_cfr); ar->cfr.enable_cfr = NULL; + debugfs_remove(ar->cfr.cfr_unassoc); + ar->cfr.cfr_unassoc = NULL; } static void ath11k_cfr_debug_register(struct ath11k *ar) @@ -199,6 +423,10 @@ static void ath11k_cfr_debug_register(struct ath11k *ar) ar->cfr.enable_cfr = debugfs_create_file("enable_cfr", 0600, ar->debug.debugfs_pdev, ar, &fops_enable_cfr); + + ar->cfr.cfr_unassoc = debugfs_create_file("cfr_unassoc", 0600, + ar->debug.debugfs_pdev, ar, + &fops_configure_cfr_unassoc); } void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h index 7d161f7f7be84..e7b69e98cbf53 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -45,6 +45,12 @@ struct ath11k_look_up_table { struct ath11k_dbring_element *buff; }; +struct cfr_unassoc_pool_entry { + u8 peer_mac[ETH_ALEN]; + u32 period; + bool is_valid; +}; + struct ath11k_cfr { struct ath11k_dbring rx_ring; /* Protects cfr data */ @@ -53,6 +59,7 @@ struct ath11k_cfr { spinlock_t lut_lock; struct ath11k_look_up_table *lut; struct dentry *enable_cfr; + struct dentry *cfr_unassoc; u8 cfr_enabled_peer_cnt; u32 lut_num; u64 tx_evt_cnt; @@ -66,6 +73,7 @@ struct ath11k_cfr { u64 clear_txrx_event; u64 cfr_dma_aborts; bool enabled; + struct cfr_unassoc_pool_entry unassoc_pool[ATH11K_MAX_CFR_ENABLED_CLIENTS]; }; enum ath11k_cfr_capture_method { @@ -89,6 +97,13 @@ void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, u32 buf_id); void ath11k_cfr_decrement_peer_count(struct ath11k *ar, struct ath11k_sta *arsta); +void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar, + const u8 *peer_mac); +bool ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, + const u8 *peer_mac); +void ath11k_cfr_update_unassoc_pool(struct ath11k *ar, + struct ath11k_per_peer_cfr_capture *params, + u8 *peer_mac); int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, struct ath11k_sta *arsta, struct ath11k_per_peer_cfr_capture *params, @@ -114,6 +129,24 @@ static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar, { } +static inline void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar, + const u8 *peer_mac) +{ +} + +static inline bool +ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, const u8 *peer_mac) +{ + return false; +} + +static inline void +ath11k_cfr_update_unassoc_pool(struct ath11k *ar, + struct ath11k_per_peer_cfr_capture *params, + u8 *peer_mac) +{ +} + static inline int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, struct ath11k_sta *arsta, diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 4a9db5a6aee2a..aeea58f3fac02 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6186,6 +6186,8 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif, dma_addr_t paddr; int buf_id; int ret; + bool tx_params_valid = false; + bool peer_in_unassoc_pool; ATH11K_SKB_CB(skb)->ar = ar; @@ -6224,7 +6226,18 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif, ATH11K_SKB_CB(skb)->paddr = paddr; - ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); + peer_in_unassoc_pool = ath11k_cfr_peer_is_in_cfr_unassoc_pool(ar, hdr->addr1); + + if (ar->cfr_enabled && + ieee80211_is_probe_resp(hdr->frame_control) && + peer_in_unassoc_pool) + tx_params_valid = true; + + if (peer_in_unassoc_pool) + ath11k_cfr_update_unassoc_pool_entry(ar, hdr->addr1); + + ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb, + tx_params_valid); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); goto err_unmap_buf; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index b14edc0820a24..b40a31414a471 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -651,11 +651,12 @@ static u32 ath11k_wmi_mgmt_get_freq(struct ath11k *ar, } int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, - struct sk_buff *frame) + struct sk_buff *frame, bool tx_params_valid) { struct ath11k_pdev_wmi *wmi = ar->wmi; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame); struct wmi_mgmt_send_cmd *cmd; + struct wmi_mgmt_send_params *params; struct wmi_tlv *frame_tlv; struct sk_buff *skb; u32 buf_len; @@ -665,6 +666,8 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, frame->len : WMI_MGMT_SEND_DOWNLD_LEN; len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4); + if (tx_params_valid) + len += sizeof(*params); skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); if (!skb) @@ -680,7 +683,7 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr); cmd->frame_len = frame->len; cmd->buf_len = buf_len; - cmd->tx_params_valid = 0; + cmd->tx_params_valid = !!tx_params_valid; frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | @@ -690,6 +693,15 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, ath11k_ce_byte_swap(frame_tlv->value, buf_len); + if (tx_params_valid) { + params = + (struct wmi_mgmt_send_params *)(skb->data + (len - sizeof(*params))); + params->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TX_SEND_PARAMS) | + FIELD_PREP(WMI_TLV_LEN, + sizeof(*params) - TLV_HDR_SIZE); + params->tx_params_dword1 |= WMI_TX_PARAMS_DWORD1_CFR_CAPTURE; + } + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_MGMT_TX_SEND_CMDID); if (ret) { ath11k_warn(ar->ab, diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 1562d169ba9ab..afc78fa4389bc 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -6391,7 +6391,7 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, - struct sk_buff *frame); + struct sk_buff *frame, bool tx_params_valid); int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id, const u8 *p2p_ie); int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, From ee81c4b4d4fe15fa2a584e8db823bfdde7506a3f Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 30 Dec 2025 13:55:18 +0530 Subject: [PATCH 507/659] FROMGIT: wifi: ath11k: Register relayfs entries for CFR dump Provide a relayfs interface to collect the CFR dump from the user space. '/sys/kernel/debug/ieee80211/phyX/ath11k/cfr_capture' is exposed to user space to get CFR data. CFR format to user space: ___________________________________________ | CFR header | CFR payload | CFR tail data | |____________|_____________|_______________| CFR header contains the following fields, * Start magic number 0xDEADBEAF - 4 bytes * vendor id - 4 bytes * cfr metadata version - 1 byte * cfr data version - 1 byte * device type - 1 byte * platform type - 1 byte * CFR metadata length - 4 bytes * metadata - 92 bytes peer mac - 6 bytes capture status - 1 byte (1 for success 0 for failure) capture_bw - 1 byte channel_bw - 1 byte phy_mode - 1 byte prim20_chan - 2 bytes center_freq1 - 2 bytes center_freq2 - 2 bytes capture_mode - 1 byte capture_type - 1 byte sts_count - 1 byte num_rx_chain - 1 byte timestamp - 4 bytes length - 4 bytes chain_rssi - 32 bytes (4 bytes for each chain) chain_phase - 16 bytes (2 bytes for each chain) cfo_measurement - 4 bytes agc_gain - 8 bytes (1 bytes for each chain) rx_start_ts - 4 bytes CFR payload: CFR payload contains 8bytes of ucode header followed by the tone information. Tone order is positive tones, followed by PHY memory garbage, followed by negative tones. Dummy tones are uploaded to make number of tones always integer number of 64. Number of tones is not preamble type dependent. Each CFR tone has 14-bit I component and 14-bit Q component and is sign extended to 16-bit I/Q. Two tones are packed into one 64-bit unit as: [63:0] = [Tone1_Q(63:48) Tone1_I(47:32) Tone0_Q(31:16) Tone0_I(15:0)] CFR tail: end magic number 0xBEAFDEAD Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Signed-off-by: Qian Zhang Link: https://patch.msgid.link/20251230082520.3401007-5-qian.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/cfr.c | 35 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 1 + 2 files changed, 36 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c index e22b0151833ca..495b2c6742aaf 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -416,10 +416,45 @@ static void ath11k_cfr_debug_unregister(struct ath11k *ar) ar->cfr.enable_cfr = NULL; debugfs_remove(ar->cfr.cfr_unassoc); ar->cfr.cfr_unassoc = NULL; + + relay_close(ar->cfr.rfs_cfr_capture); + ar->cfr.rfs_cfr_capture = NULL; } +static struct dentry *ath11k_cfr_create_buf_file_handler(const char *filename, + struct dentry *parent, + umode_t mode, + struct rchan_buf *buf, + int *is_global) +{ + struct dentry *buf_file; + + buf_file = debugfs_create_file(filename, mode, parent, buf, + &relay_file_operations); + *is_global = 1; + return buf_file; +} + +static int ath11k_cfr_remove_buf_file_handler(struct dentry *dentry) +{ + debugfs_remove(dentry); + + return 0; +} + +static const struct rchan_callbacks rfs_cfr_capture_cb = { + .create_buf_file = ath11k_cfr_create_buf_file_handler, + .remove_buf_file = ath11k_cfr_remove_buf_file_handler, +}; + static void ath11k_cfr_debug_register(struct ath11k *ar) { + ar->cfr.rfs_cfr_capture = relay_open("cfr_capture", + ar->debug.debugfs_pdev, + ar->ab->hw_params.cfr_stream_buf_size, + ar->ab->hw_params.cfr_num_stream_bufs, + &rfs_cfr_capture_cb, NULL); + ar->cfr.enable_cfr = debugfs_create_file("enable_cfr", 0600, ar->debug.debugfs_pdev, ar, &fops_enable_cfr); diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h index e7b69e98cbf53..19f136d34c65b 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -60,6 +60,7 @@ struct ath11k_cfr { struct ath11k_look_up_table *lut; struct dentry *enable_cfr; struct dentry *cfr_unassoc; + struct rchan *rfs_cfr_capture; u8 cfr_enabled_peer_cnt; u32 lut_num; u64 tx_evt_cnt; From b51809fdc79edad650105d7bb7efcf9ef57f024d Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 30 Dec 2025 13:55:19 +0530 Subject: [PATCH 508/659] FROMGIT: wifi: ath11k: Register DBR event handler for CFR data Add handler for WMI_PDEV_DMA_RING_BUF_RELEASE_EVENT which indicates CFR data availability in the DB ring. Add CFR data processing from DB ring buffers. Use correlate_and_relay API to match CFR data with metadata from WMI_PEER_CFR_CAPTURE_EVENT. Release buffer to userspace through relayfs on successful correlation, otherwise hold buffer waiting for matching WMI event from firmware. Add new debug masks: - ATH11K_DBG_CFR: Enables CFR-related debug logs. - ATH11K_DBG_CFR_DUMP: Enables detailed CFR data dump for analysis. Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Signed-off-by: Qian Zhang Link: https://patch.msgid.link/20251230082520.3401007-6-qian.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/cfr.c | 240 ++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/cfr.h | 82 ++++++++ drivers/net/wireless/ath/ath11k/dbring.c | 10 +- drivers/net/wireless/ath/ath11k/dbring.h | 2 + drivers/net/wireless/ath/ath11k/debug.h | 8 +- 5 files changed, 339 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c index 495b2c6742aaf..ee7626bd4b1a5 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -8,10 +8,248 @@ #include "core.h" #include "debug.h" +struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar) +{ + if (ar->cfr_enabled) + return &ar->cfr.rx_ring; + + return NULL; +} + +static int ath11k_cfr_calculate_tones_from_dma_hdr(struct ath11k_cfr_dma_hdr *hdr) +{ + u8 bw = FIELD_GET(CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW, hdr->info1); + u8 preamble = FIELD_GET(CFIR_DMA_HDR_INFO1_PREAMBLE_TYPE, hdr->info1); + + switch (preamble) { + case ATH11K_CFR_PREAMBLE_TYPE_LEGACY: + fallthrough; + case ATH11K_CFR_PREAMBLE_TYPE_VHT: + switch (bw) { + case 0: + return TONES_IN_20MHZ; + case 1: /* DUP40/VHT40 */ + return TONES_IN_40MHZ; + case 2: /* DUP80/VHT80 */ + return TONES_IN_80MHZ; + case 3: /* DUP160/VHT160 */ + return TONES_IN_160MHZ; + default: + return TONES_INVALID; + } + case ATH11K_CFR_PREAMBLE_TYPE_HT: + switch (bw) { + case 0: + return TONES_IN_20MHZ; + case 1: + return TONES_IN_40MHZ; + default: + return TONES_INVALID; + } + default: + return TONES_INVALID; + } +} + +void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut) +{ + memset(lut, 0, sizeof(*lut)); +} + +static void ath11k_cfr_rfs_write(struct ath11k *ar, const void *head, + u32 head_len, const void *data, u32 data_len, + const void *tail, int tail_data) +{ + struct ath11k_cfr *cfr = &ar->cfr; + + if (!cfr->rfs_cfr_capture) + return; + + relay_write(cfr->rfs_cfr_capture, head, head_len); + relay_write(cfr->rfs_cfr_capture, data, data_len); + relay_write(cfr->rfs_cfr_capture, tail, tail_data); + relay_flush(cfr->rfs_cfr_capture); +} + +static void ath11k_cfr_free_pending_dbr_events(struct ath11k *ar) +{ + struct ath11k_cfr *cfr = &ar->cfr; + struct ath11k_look_up_table *lut; + int i; + + if (!cfr->lut) + return; + + for (i = 0; i < cfr->lut_num; i++) { + lut = &cfr->lut[i]; + if (lut->dbr_recv && !lut->tx_recv && + lut->dbr_tstamp < cfr->last_success_tstamp) { + ath11k_dbring_bufs_replenish(ar, &cfr->rx_ring, lut->buff, + WMI_DIRECT_BUF_CFR); + ath11k_cfr_release_lut_entry(lut); + cfr->flush_dbr_cnt++; + } + } +} + +/** + * ath11k_cfr_correlate_and_relay() - Correlate and relay CFR events + * @ar: Pointer to ath11k structure + * @lut: Lookup table for correlation + * @event_type: Type of event received (TX or DBR) + * + * Correlates WMI_PDEV_DMA_RING_BUF_RELEASE_EVENT (DBR) and + * WMI_PEER_CFR_CAPTURE_EVENT (TX capture) by PPDU ID. If both events + * are present and the PPDU IDs match, returns CORRELATE_STATUS_RELEASE + * to relay thecorrelated data to userspace. Otherwise returns + * CORRELATE_STATUS_HOLD to wait for the other event. + * + * Also checks pending DBR events and clears them when no corresponding TX + * capture event is received for the PPDU. + * + * Return: CORRELATE_STATUS_RELEASE or CORRELATE_STATUS_HOLD + */ + +static enum ath11k_cfr_correlate_status +ath11k_cfr_correlate_and_relay(struct ath11k *ar, + struct ath11k_look_up_table *lut, + u8 event_type) +{ + enum ath11k_cfr_correlate_status status; + struct ath11k_cfr *cfr = &ar->cfr; + u64 diff; + + if (event_type == ATH11K_CORRELATE_TX_EVENT) { + if (lut->tx_recv) + cfr->cfr_dma_aborts++; + cfr->tx_evt_cnt++; + lut->tx_recv = true; + } else if (event_type == ATH11K_CORRELATE_DBR_EVENT) { + cfr->dbr_evt_cnt++; + lut->dbr_recv = true; + } + + if (lut->dbr_recv && lut->tx_recv) { + if (lut->dbr_ppdu_id == lut->tx_ppdu_id) { + /* + * 64-bit counters make wraparound highly improbable, + * wraparound handling is omitted. + */ + cfr->last_success_tstamp = lut->dbr_tstamp; + if (lut->dbr_tstamp > lut->txrx_tstamp) { + diff = lut->dbr_tstamp - lut->txrx_tstamp; + ath11k_dbg(ar->ab, ATH11K_DBG_CFR, + "txrx event -> dbr event delay = %u ms", + jiffies_to_msecs(diff)); + } else if (lut->txrx_tstamp > lut->dbr_tstamp) { + diff = lut->txrx_tstamp - lut->dbr_tstamp; + ath11k_dbg(ar->ab, ATH11K_DBG_CFR, + "dbr event -> txrx event delay = %u ms", + jiffies_to_msecs(diff)); + } + + ath11k_cfr_free_pending_dbr_events(ar); + + cfr->release_cnt++; + status = ATH11K_CORRELATE_STATUS_RELEASE; + } else { + /* + * Discard TXRX event on PPDU ID mismatch because multiple PPDUs + * may share the same DMA address due to ucode aborts. + */ + + ath11k_dbg(ar->ab, ATH11K_DBG_CFR, + "Received dbr event twice for the same lut entry"); + lut->tx_recv = false; + lut->tx_ppdu_id = 0; + cfr->clear_txrx_event++; + cfr->cfr_dma_aborts++; + status = ATH11K_CORRELATE_STATUS_HOLD; + } + } else { + status = ATH11K_CORRELATE_STATUS_HOLD; + } + + return status; +} + static int ath11k_cfr_process_data(struct ath11k *ar, struct ath11k_dbring_data *param) { - return 0; + u32 end_magic = ATH11K_CFR_END_MAGIC; + struct ath11k_csi_cfr_header *header; + struct ath11k_cfr_dma_hdr *dma_hdr; + struct ath11k_cfr *cfr = &ar->cfr; + struct ath11k_look_up_table *lut; + struct ath11k_base *ab = ar->ab; + u32 buf_id, tones, length; + u8 num_chains; + int status; + u8 *data; + + data = param->data; + buf_id = param->buf_id; + + if (param->data_sz < sizeof(*dma_hdr)) + return -EINVAL; + + dma_hdr = (struct ath11k_cfr_dma_hdr *)data; + + tones = ath11k_cfr_calculate_tones_from_dma_hdr(dma_hdr); + if (tones == TONES_INVALID) { + ath11k_warn(ar->ab, "Number of tones received is invalid\n"); + return -EINVAL; + } + + num_chains = FIELD_GET(CFIR_DMA_HDR_INFO1_NUM_CHAINS, + dma_hdr->info1); + + length = sizeof(*dma_hdr); + length += tones * (num_chains + 1); + + spin_lock_bh(&cfr->lut_lock); + + if (!cfr->lut) { + spin_unlock_bh(&cfr->lut_lock); + return -EINVAL; + } + + lut = &cfr->lut[buf_id]; + + ath11k_dbg_dump(ab, ATH11K_DBG_CFR_DUMP, "data_from_buf_rel:", "", + data, length); + + lut->buff = param->buff; + lut->data = data; + lut->data_len = length; + lut->dbr_ppdu_id = dma_hdr->phy_ppdu_id; + lut->dbr_tstamp = jiffies; + + memcpy(&lut->hdr, dma_hdr, sizeof(*dma_hdr)); + + header = &lut->header; + header->meta_data.channel_bw = FIELD_GET(CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW, + dma_hdr->info1); + header->meta_data.length = length; + + status = ath11k_cfr_correlate_and_relay(ar, lut, + ATH11K_CORRELATE_DBR_EVENT); + if (status == ATH11K_CORRELATE_STATUS_RELEASE) { + ath11k_dbg(ab, ATH11K_DBG_CFR, + "releasing CFR data to user space"); + ath11k_cfr_rfs_write(ar, &lut->header, + sizeof(struct ath11k_csi_cfr_header), + lut->data, lut->data_len, + &end_magic, sizeof(u32)); + ath11k_cfr_release_lut_entry(lut); + } else if (status == ATH11K_CORRELATE_STATUS_HOLD) { + ath11k_dbg(ab, ATH11K_DBG_CFR, + "tx event is not yet received holding the buf"); + } + + spin_unlock_bh(&cfr->lut_lock); + + return status; } /* Helper function to check whether the given peer mac address diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h index 19f136d34c65b..c8e5086674d28 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -19,9 +19,78 @@ #define HOST_MAX_CHAINS 8 +enum ath11k_cfr_correlate_event_type { + ATH11K_CORRELATE_DBR_EVENT, + ATH11K_CORRELATE_TX_EVENT, +}; + struct ath11k_sta; struct ath11k_per_peer_cfr_capture; +#define ATH11K_CFR_END_MAGIC 0xBEAFDEAD + +enum ath11k_cfr_correlate_status { + ATH11K_CORRELATE_STATUS_RELEASE, + ATH11K_CORRELATE_STATUS_HOLD, + ATH11K_CORRELATE_STATUS_ERR, +}; + +enum ath11k_cfr_preamble_type { + ATH11K_CFR_PREAMBLE_TYPE_LEGACY, + ATH11K_CFR_PREAMBLE_TYPE_HT, + ATH11K_CFR_PREAMBLE_TYPE_VHT, +}; + +struct cfr_metadata { + u8 peer_addr[ETH_ALEN]; + u8 status; + u8 capture_bw; + u8 channel_bw; + u8 phy_mode; + u16 prim20_chan; + u16 center_freq1; + u16 center_freq2; + u8 capture_mode; + u8 capture_type; + u8 sts_count; + u8 num_rx_chain; + u32 timestamp; + u32 length; + u32 chain_rssi[HOST_MAX_CHAINS]; + u16 chain_phase[HOST_MAX_CHAINS]; + u32 cfo_measurement; + u8 agc_gain[HOST_MAX_CHAINS]; + u32 rx_start_ts; +} __packed; + +struct ath11k_csi_cfr_header { + u32 start_magic_num; + u32 vendorid; + u8 cfr_metadata_version; + u8 cfr_data_version; + u8 chip_type; + u8 platform_type; + u32 reserved; + struct cfr_metadata meta_data; +} __packed; + +#define TONES_IN_20MHZ 256 +#define TONES_IN_40MHZ 512 +#define TONES_IN_80MHZ 1024 +#define TONES_IN_160MHZ 2048 /* 160 MHz isn't supported yet */ +#define TONES_INVALID 0 + +#define CFIR_DMA_HDR_INFO0_TAG GENMASK(7, 0) +#define CFIR_DMA_HDR_INFO0_LEN GENMASK(13, 8) + +#define CFIR_DMA_HDR_INFO1_UPLOAD_DONE GENMASK(0, 0) +#define CFIR_DMA_HDR_INFO1_CAPTURE_TYPE GENMASK(3, 1) +#define CFIR_DMA_HDR_INFO1_PREAMBLE_TYPE GENMASK(5, 4) +#define CFIR_DMA_HDR_INFO1_NSS GENMASK(8, 6) +#define CFIR_DMA_HDR_INFO1_NUM_CHAINS GENMASK(11, 9) +#define CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW GENMASK(14, 12) +#define CFIR_DMA_HDR_INFO1_SW_PEER_ID_VALID GENMASK(15, 15) + struct ath11k_cfr_dma_hdr { u16 info0; u16 info1; @@ -37,6 +106,7 @@ struct ath11k_look_up_table { u16 dbr_ppdu_id; u16 tx_ppdu_id; dma_addr_t dbr_address; + struct ath11k_csi_cfr_header header; struct ath11k_cfr_dma_hdr hdr; u64 txrx_tstamp; u64 dbr_tstamp; @@ -109,6 +179,8 @@ int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, struct ath11k_sta *arsta, struct ath11k_per_peer_cfr_capture *params, const u8 *peer_mac); +struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar); +void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut); #else static inline int ath11k_cfr_init(struct ath11k_base *ab) @@ -156,5 +228,15 @@ ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, { return 0; } + +static inline void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut) +{ +} + +static inline +struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar) +{ + return NULL; +} #endif /* CONFIG_ATH11K_CFR */ #endif /* ATH11K_CFR_H */ diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c index ed2b781a6bab6..d6994ce6ebff4 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.c +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -295,6 +295,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, int size; dma_addr_t paddr; int ret = 0; + int status; pdev_idx = ev->fixed.pdev_id; module_id = ev->fixed.module_id; @@ -328,6 +329,9 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, case WMI_DIRECT_BUF_SPECTRAL: ring = ath11k_spectral_get_dbring(ar); break; + case WMI_DIRECT_BUF_CFR: + ring = ath11k_cfr_get_dbring(ar); + break; default: ring = NULL; ath11k_warn(ab, "Recv dma buffer release ev on unsupp module %d\n", @@ -378,8 +382,12 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, handler_data.data = PTR_ALIGN(vaddr_unalign, ring->buf_align); handler_data.data_sz = ring->buf_sz; + handler_data.buff = buff; + handler_data.buf_id = buf_id; - ring->handler(ar, &handler_data); + status = ring->handler(ar, &handler_data); + if (status == ATH11K_CORRELATE_STATUS_HOLD) + continue; } buff->paddr = 0; diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireless/ath/ath11k/dbring.h index 0a380120f7a0e..e5f244dfa9631 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.h +++ b/drivers/net/wireless/ath/ath11k/dbring.h @@ -21,6 +21,8 @@ struct ath11k_dbring_data { void *data; u32 data_sz; struct wmi_dma_buf_release_meta_data meta; + struct ath11k_dbring_element *buff; + u32 buf_id; }; struct ath11k_dbring_buf_release_event { diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h index cc8934d156977..aaa0034527a59 100644 --- a/drivers/net/wireless/ath/ath11k/debug.h +++ b/drivers/net/wireless/ath/ath11k/debug.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef _ATH11K_DEBUG_H_ @@ -27,6 +27,8 @@ enum ath11k_debug_mask { ATH11K_DBG_DP_TX = 0x00002000, ATH11K_DBG_DP_RX = 0x00004000, ATH11K_DBG_CE = 0x00008000, + ATH11K_DBG_CFR = 0x00010000, + ATH11K_DBG_CFR_DUMP = 0x00020000, }; static inline const char *ath11k_dbg_str(enum ath11k_debug_mask mask) @@ -64,6 +66,10 @@ static inline const char *ath11k_dbg_str(enum ath11k_debug_mask mask) return "dp_rx"; case ATH11K_DBG_CE: return "ce"; + case ATH11K_DBG_CFR: + return "cfr"; + case ATH11K_DBG_CFR_DUMP: + return "cfr_dump"; /* no default handler to allow compiler to check that the * enum is fully handled From d2fe1557d39e99aa09dd7702f5979ba5f0c43158 Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 30 Dec 2025 13:55:20 +0530 Subject: [PATCH 509/659] FROMGIT: wifi: ath11k: Register handler for CFR capture event Firmware sends CFR meta data through the WMI event WMI_PEER_CFR_CAPTURE_EVENT. Parse the meta data coming from the firmware and invoke correlate_and_relay function to correlate the CFR meta data with the CFR payload coming from the other WMI event WMI_PDEV_DMA_RING_BUF_RELEASE_EVENT. Release the buffer to user space once correlate and relay return success. Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Signed-off-by: Qian Zhang Link: https://patch.msgid.link/20251230082520.3401007-7-qian.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/cfr.c | 161 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 70 ++++++++++- drivers/net/wireless/ath/ath11k/mac.c | 2 + drivers/net/wireless/ath/ath11k/wmi.c | 90 ++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 44 +++++++ 5 files changed, 365 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c index ee7626bd4b1a5..61bf1c0884f72 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -252,6 +252,160 @@ static int ath11k_cfr_process_data(struct ath11k *ar, return status; } +static void ath11k_cfr_fill_hdr_info(struct ath11k *ar, + struct ath11k_csi_cfr_header *header, + struct ath11k_cfr_peer_tx_param *params) +{ + struct ath11k_cfr *cfr; + + cfr = &ar->cfr; + header->cfr_metadata_version = ATH11K_CFR_META_VERSION_4; + header->cfr_data_version = ATH11K_CFR_DATA_VERSION_1; + header->cfr_metadata_len = sizeof(struct cfr_metadata); + header->chip_type = ar->ab->hw_rev; + header->meta_data.status = FIELD_GET(WMI_CFR_PEER_CAPTURE_STATUS, + params->status); + header->meta_data.capture_bw = params->bandwidth; + + /* + * FW reports phymode will always be HE mode. + * Replace it with cached phy mode during peer assoc + */ + header->meta_data.phy_mode = cfr->phymode; + + header->meta_data.prim20_chan = params->primary_20mhz_chan; + header->meta_data.center_freq1 = params->band_center_freq1; + header->meta_data.center_freq2 = params->band_center_freq2; + + /* + * CFR capture is triggered by the ACK of a QoS Null frame: + * - 20 MHz: Legacy ACK + * - 40/80/160 MHz: DUP Legacy ACK + */ + header->meta_data.capture_mode = params->bandwidth ? + ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK : ATH11K_CFR_CAPTURE_LEGACY_ACK; + header->meta_data.capture_type = params->capture_method; + header->meta_data.num_rx_chain = ar->num_rx_chains; + header->meta_data.sts_count = params->spatial_streams; + header->meta_data.timestamp = params->timestamp_us; + ether_addr_copy(header->meta_data.peer_addr, params->peer_mac_addr); + memcpy(header->meta_data.chain_rssi, params->chain_rssi, + sizeof(params->chain_rssi)); + memcpy(header->meta_data.chain_phase, params->chain_phase, + sizeof(params->chain_phase)); + memcpy(header->meta_data.agc_gain, params->agc_gain, + sizeof(params->agc_gain)); +} + +int ath11k_process_cfr_capture_event(struct ath11k_base *ab, + struct ath11k_cfr_peer_tx_param *params) +{ + struct ath11k_look_up_table *lut = NULL; + u32 end_magic = ATH11K_CFR_END_MAGIC; + struct ath11k_csi_cfr_header *header; + struct ath11k_dbring_element *buff; + struct ath11k_cfr *cfr; + dma_addr_t buf_addr; + struct ath11k *ar; + u8 tx_status; + int status; + int i; + + rcu_read_lock(); + ar = ath11k_mac_get_ar_by_vdev_id(ab, params->vdev_id); + if (!ar) { + rcu_read_unlock(); + ath11k_warn(ab, "Failed to get ar for vdev id %d\n", + params->vdev_id); + return -ENOENT; + } + + cfr = &ar->cfr; + rcu_read_unlock(); + + if (WMI_CFR_CAPTURE_STATUS_PEER_PS & params->status) { + ath11k_warn(ab, "CFR capture failed as peer %pM is in powersave", + params->peer_mac_addr); + return -EINVAL; + } + + if (!(WMI_CFR_PEER_CAPTURE_STATUS & params->status)) { + ath11k_warn(ab, "CFR capture failed for the peer : %pM", + params->peer_mac_addr); + cfr->tx_peer_status_cfr_fail++; + return -EINVAL; + } + + tx_status = FIELD_GET(WMI_CFR_FRAME_TX_STATUS, params->status); + if (tx_status != WMI_FRAME_TX_STATUS_OK) { + ath11k_warn(ab, "WMI tx status %d for the peer %pM", + tx_status, params->peer_mac_addr); + cfr->tx_evt_status_cfr_fail++; + return -EINVAL; + } + + buf_addr = (((u64)FIELD_GET(WMI_CFR_CORRELATION_INFO2_BUF_ADDR_HIGH, + params->correlation_info_2)) << 32) | + params->correlation_info_1; + + spin_lock_bh(&cfr->lut_lock); + + if (!cfr->lut) { + spin_unlock_bh(&cfr->lut_lock); + return -EINVAL; + } + + for (i = 0; i < cfr->lut_num; i++) { + struct ath11k_look_up_table *temp = &cfr->lut[i]; + + if (temp->dbr_address == buf_addr) { + lut = &cfr->lut[i]; + break; + } + } + + if (!lut) { + spin_unlock_bh(&cfr->lut_lock); + ath11k_warn(ab, "lut failure to process tx event\n"); + cfr->tx_dbr_lookup_fail++; + return -EINVAL; + } + + lut->tx_ppdu_id = FIELD_GET(WMI_CFR_CORRELATION_INFO2_PPDU_ID, + params->correlation_info_2); + lut->txrx_tstamp = jiffies; + + header = &lut->header; + header->start_magic_num = ATH11K_CFR_START_MAGIC; + header->vendorid = VENDOR_QCA; + header->platform_type = PLATFORM_TYPE_ARM; + + ath11k_cfr_fill_hdr_info(ar, header, params); + + status = ath11k_cfr_correlate_and_relay(ar, lut, + ATH11K_CORRELATE_TX_EVENT); + if (status == ATH11K_CORRELATE_STATUS_RELEASE) { + ath11k_dbg(ab, ATH11K_DBG_CFR, + "Releasing CFR data to user space"); + ath11k_cfr_rfs_write(ar, &lut->header, + sizeof(struct ath11k_csi_cfr_header), + lut->data, lut->data_len, + &end_magic, sizeof(u32)); + buff = lut->buff; + ath11k_cfr_release_lut_entry(lut); + + ath11k_dbring_bufs_replenish(ar, &cfr->rx_ring, buff, + WMI_DIRECT_BUF_CFR); + } else if (status == ATH11K_CORRELATE_STATUS_HOLD) { + ath11k_dbg(ab, ATH11K_DBG_CFR, + "dbr event is not yet received holding buf\n"); + } + + spin_unlock_bh(&cfr->lut_lock); + + return 0; +} + /* Helper function to check whether the given peer mac address * is in unassociated peer pool or not. */ @@ -711,6 +865,13 @@ void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, cfr->lut[buf_id].dbr_address = paddr; } +void ath11k_cfr_update_phymode(struct ath11k *ar, enum wmi_phy_mode phymode) +{ + struct ath11k_cfr *cfr = &ar->cfr; + + cfr->phymode = phymode; +} + static void ath11k_cfr_ring_free(struct ath11k *ar) { struct ath11k_cfr *cfr = &ar->cfr; diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h index c8e5086674d28..94fcb706f2ef2 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -27,8 +27,37 @@ enum ath11k_cfr_correlate_event_type { struct ath11k_sta; struct ath11k_per_peer_cfr_capture; +#define ATH11K_CFR_START_MAGIC 0xDEADBEAF #define ATH11K_CFR_END_MAGIC 0xBEAFDEAD +#define VENDOR_QCA 0x8cfdf0 +#define PLATFORM_TYPE_ARM 2 + +enum ath11k_cfr_meta_version { + ATH11K_CFR_META_VERSION_NONE, + ATH11K_CFR_META_VERSION_1, + ATH11K_CFR_META_VERSION_2, + ATH11K_CFR_META_VERSION_3, + ATH11K_CFR_META_VERSION_4, + ATH11K_CFR_META_VERSION_MAX = 0xFF, +}; + +enum ath11k_cfr_data_version { + ATH11K_CFR_DATA_VERSION_NONE, + ATH11K_CFR_DATA_VERSION_1, + ATH11K_CFR_DATA_VERSION_MAX = 0xFF, +}; + +enum ath11k_cfr_capture_ack_mode { + ATH11K_CFR_CAPTURE_LEGACY_ACK, + ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK, + ATH11K_CFR_CAPTURE_HT_ACK, + ATH11K_CFR_CAPTURE_VHT_ACK, + + /*Always keep this at last*/ + ATH11K_CFR_CAPTURE_INVALID_ACK +}; + enum ath11k_cfr_correlate_status { ATH11K_CORRELATE_STATUS_RELEASE, ATH11K_CORRELATE_STATUS_HOLD, @@ -41,6 +70,28 @@ enum ath11k_cfr_preamble_type { ATH11K_CFR_PREAMBLE_TYPE_VHT, }; +struct ath11k_cfr_peer_tx_param { + u32 capture_method; + u32 vdev_id; + u8 peer_mac_addr[ETH_ALEN]; + u32 primary_20mhz_chan; + u32 bandwidth; + u32 phy_mode; + u32 band_center_freq1; + u32 band_center_freq2; + u32 spatial_streams; + u32 correlation_info_1; + u32 correlation_info_2; + u32 status; + u32 timestamp_us; + u32 counter; + u32 chain_rssi[WMI_MAX_CHAINS]; + u16 chain_phase[WMI_MAX_CHAINS]; + u32 cfo_measurement; + u8 agc_gain[HOST_MAX_CHAINS]; + u32 rx_start_ts; +}; + struct cfr_metadata { u8 peer_addr[ETH_ALEN]; u8 status; @@ -70,7 +121,7 @@ struct ath11k_csi_cfr_header { u8 cfr_data_version; u8 chip_type; u8 platform_type; - u32 reserved; + u32 cfr_metadata_len; struct cfr_metadata meta_data; } __packed; @@ -144,6 +195,7 @@ struct ath11k_cfr { u64 clear_txrx_event; u64 cfr_dma_aborts; bool enabled; + enum wmi_phy_mode phymode; struct cfr_unassoc_pool_entry unassoc_pool[ATH11K_MAX_CFR_ENABLED_CLIENTS]; }; @@ -181,8 +233,15 @@ int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, const u8 *peer_mac); struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar); void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut); - +int ath11k_process_cfr_capture_event(struct ath11k_base *ab, + struct ath11k_cfr_peer_tx_param *params); +void ath11k_cfr_update_phymode(struct ath11k *ar, enum wmi_phy_mode phymode); #else +static inline void ath11k_cfr_update_phymode(struct ath11k *ar, + enum wmi_phy_mode phymode) +{ +} + static inline int ath11k_cfr_init(struct ath11k_base *ab) { return 0; @@ -238,5 +297,12 @@ struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar) { return NULL; } + +static inline +int ath11k_process_cfr_capture_event(struct ath11k_base *ab, + struct ath11k_cfr_peer_tx_param *params) +{ + return 0; +} #endif /* CONFIG_ATH11K_CFR */ #endif /* ATH11K_CFR_H */ diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index aeea58f3fac02..1b5a391138727 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2911,6 +2911,8 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, arg->peer_phymode = phymode; WARN_ON(phymode == MODE_UNKNOWN); + + ath11k_cfr_update_phymode(ar, phymode); } static void ath11k_peer_assoc_prepare(struct ath11k *ar, diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index b40a31414a471..451cc4c719aec 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8805,6 +8805,93 @@ static void ath11k_wmi_p2p_noa_event(struct ath11k_base *ab, kfree(tb); } +static void ath11k_wmi_tlv_cfr_capture_event_fixed_param(const void *ptr, + void *data) +{ + struct ath11k_cfr_peer_tx_param *tx_params = data; + const struct ath11k_wmi_cfr_peer_tx_event_param *params = ptr; + + tx_params->capture_method = params->capture_method; + tx_params->vdev_id = params->vdev_id; + ether_addr_copy(tx_params->peer_mac_addr, params->mac_addr.addr); + tx_params->primary_20mhz_chan = params->chan_mhz; + tx_params->bandwidth = params->bandwidth; + tx_params->phy_mode = params->phy_mode; + tx_params->band_center_freq1 = params->band_center_freq1; + tx_params->band_center_freq2 = params->band_center_freq2; + tx_params->spatial_streams = params->sts_count; + tx_params->correlation_info_1 = params->correlation_info_1; + tx_params->correlation_info_2 = params->correlation_info_2; + tx_params->status = params->status; + tx_params->timestamp_us = params->timestamp_us; + tx_params->counter = params->counter; + tx_params->rx_start_ts = params->rx_start_ts; + + memcpy(tx_params->chain_rssi, params->chain_rssi, + sizeof(tx_params->chain_rssi)); + + if (WMI_CFR_CFO_MEASUREMENT_VALID & params->cfo_measurement) + tx_params->cfo_measurement = FIELD_GET(WMI_CFR_CFO_MEASUREMENT_RAW_DATA, + params->cfo_measurement); +} + +static void ath11k_wmi_tlv_cfr_capture_phase_fixed_param(const void *ptr, + void *data) +{ + struct ath11k_cfr_peer_tx_param *tx_params = data; + const struct ath11k_wmi_cfr_peer_tx_event_phase_param *params = ptr; + int i; + + for (i = 0; i < WMI_MAX_CHAINS; i++) { + tx_params->chain_phase[i] = params->chain_phase[i]; + tx_params->agc_gain[i] = params->agc_gain[i]; + } +} + +static int ath11k_wmi_tlv_cfr_capture_evt_parse(struct ath11k_base *ab, + u16 tag, u16 len, + const void *ptr, void *data) +{ + switch (tag) { + case WMI_TAG_PEER_CFR_CAPTURE_EVENT: + ath11k_wmi_tlv_cfr_capture_event_fixed_param(ptr, data); + break; + case WMI_TAG_CFR_CAPTURE_PHASE_PARAM: + ath11k_wmi_tlv_cfr_capture_phase_fixed_param(ptr, data); + break; + default: + ath11k_warn(ab, "Invalid tag received tag %d len %d\n", + tag, len); + return -EINVAL; + } + + return 0; +} + +static void ath11k_wmi_parse_cfr_capture_event(struct ath11k_base *ab, + struct sk_buff *skb) +{ + struct ath11k_cfr_peer_tx_param params = {}; + int ret; + + ath11k_dbg_dump(ab, ATH11K_DBG_CFR_DUMP, "cfr_dump:", "", + skb->data, skb->len); + + ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, + ath11k_wmi_tlv_cfr_capture_evt_parse, + ¶ms); + if (ret) { + ath11k_warn(ab, "failed to parse cfr capture event tlv %d\n", + ret); + return; + } + + ret = ath11k_process_cfr_capture_event(ab, ¶ms); + if (ret) + ath11k_dbg(ab, ATH11K_DBG_CFR, + "failed to process cfr capture ret = %d\n", ret); +} + static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) { struct wmi_cmd_hdr *cmd_hdr; @@ -8935,6 +9022,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) case WMI_P2P_NOA_EVENTID: ath11k_wmi_p2p_noa_event(ab, skb); break; + case WMI_PEER_CFR_CAPTURE_EVENTID: + ath11k_wmi_parse_cfr_capture_event(ab, skb); + break; default: ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id); break; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index afc78fa4389bc..baed501b640b4 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -1889,6 +1889,8 @@ enum wmi_tlv_tag { WMI_TAG_NDP_EVENT, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD = 0x301, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO, + WMI_TAG_PEER_CFR_CAPTURE_EVENT = 0x317, + WMI_TAG_CFR_CAPTURE_PHASE_PARAM = 0x33b, WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344, WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b, WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, @@ -4237,6 +4239,48 @@ enum ath11k_wmi_cfr_capture_method { WMI_CFR_CAPTURE_METHOD_MAX, }; +#define WMI_CFR_FRAME_TX_STATUS GENMASK(1, 0) +#define WMI_CFR_CAPTURE_STATUS_PEER_PS BIT(30) +#define WMI_CFR_PEER_CAPTURE_STATUS BIT(31) + +#define WMI_CFR_CORRELATION_INFO2_BUF_ADDR_HIGH GENMASK(3, 0) +#define WMI_CFR_CORRELATION_INFO2_PPDU_ID GENMASK(31, 16) + +#define WMI_CFR_CFO_MEASUREMENT_VALID BIT(0) +#define WMI_CFR_CFO_MEASUREMENT_RAW_DATA GENMASK(14, 1) + +struct ath11k_wmi_cfr_peer_tx_event_param { + u32 capture_method; + u32 vdev_id; + struct wmi_mac_addr mac_addr; + u32 chan_mhz; + u32 bandwidth; + u32 phy_mode; + u32 band_center_freq1; + u32 band_center_freq2; + u32 sts_count; + u32 correlation_info_1; + u32 correlation_info_2; + u32 status; + u32 timestamp_us; + u32 counter; + u32 chain_rssi[WMI_MAX_CHAINS]; + u32 cfo_measurement; + u32 rx_start_ts; +} __packed; + +struct ath11k_wmi_cfr_peer_tx_event_phase_param { + u32 chain_phase[WMI_MAX_CHAINS]; + u8 agc_gain[WMI_MAX_CHAINS]; +} __packed; + +enum ath11k_wmi_frame_tx_status { + WMI_FRAME_TX_STATUS_OK, + WMI_FRAME_TX_STATUS_XRETRY, + WMI_FRAME_TX_STATUS_DROP, + WMI_FRAME_TX_STATUS_FILTERED, +}; + struct wmi_peer_cfr_capture_conf_arg { enum ath11k_wmi_cfr_capture_bw bw; enum ath11k_wmi_cfr_capture_method method; From 3ed4de54ec41932134bbd9462342e41b226f64f5 Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Wed, 12 Nov 2025 20:18:11 +0530 Subject: [PATCH 510/659] 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. LVDS Disabled by default. we can enable it through weston. Signed-off-by: Yi Zhang Signed-off-by: Gopi Botlagunta Link: https://lore.kernel.org/lkml/20251112-add-lt9211c-bridge-for-rb3gen2-industrial-mezzanine-v1-1-6eab844ec3ac@oss.qualcomm.com/ --- .../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 a926ab54617884735079f1419e46f9e21452f74e Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 29 Jan 2026 15:52:47 +0530 Subject: [PATCH 511/659] 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 591ac9212b0dd0ef9038b9ce9b617aa4f8c3952b Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Wed, 28 Jan 2026 00:56:39 +0530 Subject: [PATCH 512/659] 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 c37377fe7ad90..af93864d8d548 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1416,7 +1416,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 87b2ee20bdeded599a4852c25cc7e5a8b7b97045 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 27 Oct 2025 23:28:14 -0700 Subject: [PATCH 513/659] FROMLIST: arm64: dts: qcom: x1e80100: add Coresight nodes for APSS debug block Add below Coresight devices for APSS debug block: -ETM -TMC ETF -Funnel -Replicator Link: https://lore.kernel.org/all/20251027-cpu_cluster_component_pm-v1-12-31355ac588c2@oss.qualcomm.com/ Signed-off-by: Yuanfang Zhang Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 885 ++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/purwa.dtsi | 12 + 2 files changed, 897 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index a17900eacb203..22b269ae63a93 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -6864,6 +6864,14 @@ }; }; + port@4 { + reg = <4>; + + funnel1_in4: endpoint { + remote-endpoint = <&apss_funnel_out>; + }; + }; + port@5 { reg = <5>; @@ -8154,6 +8162,883 @@ }; }; + 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>; + }; + }; + }; + }; + + etm@13021000 { + 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@13121000 { + 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@13221000 { + 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@13321000 { + 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>; + }; + }; + }; + }; + + funnel@13401000 { + compatible = "arm,coresight-cpu-funnel"; + reg = <0x0 0x13401000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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,coresight-cpu-tmc"; + reg = <0x0 0x13409000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x13490000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x134a0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x134b0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x134c0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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,coresight-cpu-funnel"; + reg = <0x0 0x134d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd0>; + + 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>; + }; + }; + }; + }; + + etm@13521000 { + 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@13621000 { + 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@13721000 { + 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@13821000 { + 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>; + }; + }; + }; + }; + + funnel@13901000 { + compatible = "arm,coresight-cpu-funnel"; + reg = <0x0 0x13901000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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,coresight-cpu-tmc"; + reg = <0x0 0x13909000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x13990000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x139a0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x139b0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x139c0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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,coresight-cpu-funnel"; + reg = <0x0 0x139d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd1>; + + 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>; + }; + }; + }; + }; + + etm8: etm@13a21000 { + 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@13b21000 { + 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@13c21000 { + 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@13d21000 { + 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>; + }; + }; + }; + }; + + cluster2_funnel_l2: funnel@13e01000 { + compatible = "arm,coresight-cpu-funnel"; + reg = <0x0 0x13e01000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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,coresight-cpu-tmc"; + reg = <0x0 0x13e09000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x13e90000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x13ea0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x13eb0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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,coresight-cpu-replicator"; + reg = <0x0 0x13ec0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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,coresight-cpu-funnel"; + reg = <0x0 0x13ed0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + power-domains = <&cluster_pd2>; + + 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 044da063603dfb7d008563a36576a7cbafc857e6 Mon Sep 17 00:00:00 2001 From: Yongxing Mou Date: Thu, 16 Oct 2025 18:28:57 +0800 Subject: [PATCH 514/659] FROMLIST: arm64: dts: qcom: Add backlight support for eDP panel Previously, the eDP panel backlight was enabled via UEFI. Added backlight control node in kernel DTS due to some meta may not enable the backlight. Aligned with other x1e80100-based platforms: the PWM signal is controlled by PMK8550, and the backlight enable signal is handled by PMC8380. Link: https://lore.kernel.org/all/20251028-hamoa_dvt_backlight-v1-1-97ecb8d0ad01@oss.qualcomm.com/ Signed-off-by: Yongxing Mou --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 36dd6599402b4..fda1b3a3c7673 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -17,6 +17,16 @@ 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"; @@ -183,6 +193,22 @@ 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-names = "default"; + pinctrl-0 = <&edp_bl_reg_en>; + + regulator-boot-on; + }; + vreg_nvme: regulator-nvme { compatible = "regulator-fixed"; @@ -819,6 +845,8 @@ aux-bus { panel { compatible = "edp-panel"; + + backlight = <&backlight>; power-supply = <&vreg_edp_3p3>; port { @@ -879,6 +907,22 @@ }; }; +&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"; + }; + +}; + &pmc8380_5_gpios { usb0_pwr_1p15_reg_en: usb0-pwr-1p15-reg-en-state { pins = "gpio8"; @@ -890,6 +934,17 @@ }; }; +&pmk8550_gpios { + edp_bl_pwm: edp-bl-pwm-state { + pins = "gpio5"; + function = "func3"; + }; +}; + +&pmk8550_pwm { + status = "okay"; +}; + &smb2360_0 { status = "okay"; }; From bba29114d026ee0878501be29bec981fa13651b0 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Tue, 4 Nov 2025 15:36:13 +0800 Subject: [PATCH 515/659] 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/20251104-enable-etr-and-ctcu-for-hamoa-v1-2-af552cfb902c@oss.qualcomm.com/ 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 22b269ae63a93..6eef36bc319ce 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -6713,6 +6713,35 @@ }; }; + ctcu@10001000 { + compatible = "qcom,hamoa-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>, @@ -6935,6 +6964,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>; @@ -7248,7 +7393,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 4f2a89f8b33d0d68548852c0f53a90109e5ac6dd Mon Sep 17 00:00:00 2001 From: Khalid Faisal Ansari Date: Tue, 11 Nov 2025 21:10:52 +0530 Subject: [PATCH 516/659] FROMLIST: arm64: dts: qcom: hamoa-iot-evk: Enable TPM (ST33) on SPI11 Enable ST33HTPM TPM over SPI11 on the Hamoa IoT EVK by adding the required SPI and TPM nodes. Link: https://lore.kernel.org/all/20251112-arm64-dts-qcom-hamoa-iot-evk-enable-st33-tpm-on-spi11-v3-1-39b19eb55cc3@oss.qualcomm.com/ Signed-off-by: Khalid Faisal Ansari --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index fda1b3a3c7673..97af19f3d25ff 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -972,6 +972,16 @@ 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"; From 1d6cb91dfd11b03af4b10bc100545d4cb6afbb1d Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Mon, 22 Sep 2025 15:55:06 +0800 Subject: [PATCH 517/659] FROMLIST: arm64: dts: qcom: Add PCIe3 and PCIe5 support for HAMOA-IOT-SOM platform HAMOA IoT SOM requires PCIe3 and PCIe5 connectivity for SATA controller and SDX65. Add the required sideband signals (PERST#, WAKE#, CLKREQ#), pinctrl states and power supply properties in the device tree, which PCIe3 and PCIe5 require. Link: https://lore.kernel.org/all/20251112090316.936187-2-ziyue.zhang@oss.qualcomm.com/ Signed-off-by: Ziyue Zhang Reviewed-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi | 79 +++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi index 4a69852e91760..1a9e930c0496b 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi @@ -390,6 +390,22 @@ firmware-name = "qcom/x1e80100/gen70500_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>; @@ -407,6 +423,23 @@ 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>; @@ -453,6 +486,29 @@ &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"; @@ -476,6 +532,29 @@ }; }; + 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"; From 05d3f7697acbe16ca4bdd2da0f0fef8975160779 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Mon, 22 Sep 2025 15:55:07 +0800 Subject: [PATCH 518/659] FROMLIST: arm64: dts: qcom: Add PCIe3 and PCIe5 regulators for HAMAO-IOT-EVK board HAMAO IoT EVK uses PCIe5 to connect an SDX65 module for WWAN functionality and PCIe3 to connect a SATA controller. These interfaces require multiple voltage rails: PCIe5 needs 3.3V supplied by vreg_wwan, while PCIe3 requires 12V, 3.3V, and 3.3V AUX rails, controlled via PMIC GPIOs. Add the required fixed regulators with related pin configuration, and connect them to the PCIe3 and PCIe5 ports to ensure proper power for the SDX65 module and SATA controller. Link: https://lore.kernel.org/all/20251112090316.936187-3-ziyue.zhang@oss.qualcomm.com/ Signed-off-by: Ziyue Zhang Reviewed-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 97af19f3d25ff..33e247d7cb79e 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -225,6 +225,48 @@ 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"; @@ -872,6 +914,16 @@ status = "okay"; }; +&pcie3_port { + vpcie12v-supply = <&vreg_pcie_12v>; + vpcie3v3-supply = <&vreg_pcie_3v3>; + vpcie3v3aux-supply = <&vreg_pcie_3v3_aux>; +}; + +&pcie5 { + vddpe-3v3-supply = <&vreg_wwan>; +}; + &pcie6a { vddpe-3v3-supply = <&vreg_nvme>; }; @@ -896,6 +948,17 @@ }; }; +&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"; @@ -921,6 +984,23 @@ function = "normal"; }; + pm_sde7_aux_3p3_en: pcie-aux-3p3-default-state { + pins = "gpio8"; + function = "normal"; + output-enable; + output-high; + bias-pull-down; + power-source = <0>; + }; + + pm_sde7_main_3p3_en: pcie-main-3p3-default-state { + pins = "gpio6"; + function = "normal"; + output-enable; + output-high; + bias-pull-down; + power-source = <0>; + }; }; &pmc8380_5_gpios { From e2c4cb7ea1349dc073597d4ac52485f27daf541d Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Thu, 27 Nov 2025 14:37:04 +0530 Subject: [PATCH 519/659] FROMLIST: arm64: dts: qcom: x1e80100: Add crypto engine On X Elite, there is a crypto engine IP block similar to ones found on SM8x50 platforms. Describe the crypto engine and its BAM. Signed-off-by: Harshal Dev Link: https://lore.kernel.org/lkml/20251127-crypto_dt_node_x1e80100-v3-1-29722003fe83@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 6eef36bc319ce..2cbecbe091c38 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -3060,6 +3060,30 @@ }; }; + cryptobam: dma-controller@1dc4000 { + compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0"; + reg = <0x0 0x01dc4000 0x0 0x28000>; + interrupts = ; + #dma-cells = <1>; + iommus = <&apps_smmu 0x480 0x0000>, + <&apps_smmu 0x481 0x0000>; + qcom,ee = <0>; + qcom,controlled-remotely; + num-channels = <20>; + qcom,num-ees = <4>; + }; + + crypto: crypto@1dfa000 { + compatible = "qcom,x1e80100-qce", "qcom,sm8150-qce", "qcom,qce"; + reg = <0x0 0x01dfa000 0x0 0x6000>; + dmas = <&cryptobam 4>, <&cryptobam 5>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu 0x480 0x0000>, + <&apps_smmu 0x481 0x0000>; + interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "memory"; + }; + cnoc_main: interconnect@1500000 { compatible = "qcom,x1e80100-cnoc-main"; reg = <0 0x01500000 0 0x14400>; From 978b9ee14ff31d326c16fb15b022b62f8bcd1947 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Mon, 8 Dec 2025 14:21:52 +0530 Subject: [PATCH 520/659] FROMLIST: arm64: dts: qcom: hamoa-iot-evk: Add vbus regulator support for Type-A ports The Multiport controller on Hamoa EVK platform is connected to Two Type-A ports. VBUS for each of these ports are provided by a TPS2559QWDRCTQ1 regulator, controlled from PMIC GPIOs. Add the necessary regulators and GPIO configuration to power these. Link: https://lore.kernel.org/all/20251208085152.2597818-1-krishna.kurapati@oss.qualcomm.com/ Signed-off-by: Krishna Kurapati Signed-off-by: Xin Liu --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 33e247d7cb79e..893fb0ed45954 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "hamoa-iot-som.dtsi" +#include / { model = "Qualcomm Technologies, Inc. Hamoa IoT EVK"; @@ -177,6 +178,26 @@ }; }; + 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 { + 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; + }; + vreg_edp_3p3: regulator-edp-3p3 { compatible = "regulator-fixed"; @@ -968,6 +989,22 @@ 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>; + }; }; &pmc8380_3_gpios { From 143d1b8912efca6b4d102bcc5eaeeae0c3885989 Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Thu, 4 Dec 2025 16:50:01 +0800 Subject: [PATCH 521/659] FROMLIST: arm64: dts: qcom: hamoa-iot-evk: Add WLAN node for hamoa iot evk board WLAN card is connected to PCIe4 on hamoa iot evk board. Add WLAN node to support power sequence for this WLAN card. Link: https://lore.kernel.org/all/20251209115924.848165-1-yingying.tang@oss.qualcomm.com Signed-off-by: Yingying Tang --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 893fb0ed45954..f352cd3c0dcd1 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -623,7 +623,7 @@ bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&wcn_bt_en>; + pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; pinctrl-names = "default"; regulators { @@ -941,6 +941,23 @@ vpcie3v3aux-supply = <&vreg_pcie_3v3_aux>; }; +&pcie4_port0 { + 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>; }; @@ -1325,6 +1342,13 @@ 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"; From b8a0b98127acbdb1313bc6f2e4708b1790f348f3 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Mon, 24 Nov 2025 21:29:43 +0530 Subject: [PATCH 522/659] FROMLIST: dt-bindings: crypto: qcom,prng: document x1e80100 Document x1e80100 compatible for the True Random Number Generator. Signed-off-by: Harshal Dev Link: https://lore.kernel.org/lkml/20251124-trng_dt_binding_x1e80100-v1-1-b4eafa0f1077@oss.qualcomm.com/ --- Documentation/devicetree/bindings/crypto/qcom,prng.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/crypto/qcom,prng.yaml b/Documentation/devicetree/bindings/crypto/qcom,prng.yaml index 597441d94cf1e..ef8831ff22730 100644 --- a/Documentation/devicetree/bindings/crypto/qcom,prng.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom,prng.yaml @@ -30,6 +30,7 @@ properties: - qcom,sm8550-trng - qcom,sm8650-trng - qcom,sm8750-trng + - qcom,x1e80100-trng - const: qcom,trng reg: From d7b3d8f9cc6b4faaee66911ee6dd93d99576a146 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Mon, 24 Nov 2025 21:34:42 +0530 Subject: [PATCH 523/659] FROMLIST: arm64: dts: qcom: x1e80100: add TRNG node The x1e80100 SoC has a True Random Number Generator, add the node with the correct compatible set. Signed-off-by: Harshal Dev Link: https://lore.kernel.org/lkml/20251124-trng_dt_binding_x1e80100-v1-2-b4eafa0f1077@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 2cbecbe091c38..8e9f2220dac00 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -3084,6 +3084,11 @@ interconnect-names = "memory"; }; + rng: rng@10c3000 { + compatible = "qcom,x1e80100-trng", "qcom,trng"; + reg = <0x0 0x10c3000 0x0 0x1000>; + }; + cnoc_main: interconnect@1500000 { compatible = "qcom,x1e80100-cnoc-main"; reg = <0 0x01500000 0 0x14400>; From cf43dfaf601a3c86cf00f8363386562cb080a6ff Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:45 +0800 Subject: [PATCH 524/659] 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 d84bd3bca2010..5797bbfac9a28 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -1089,6 +1089,12 @@ properties: - const: qcom,hamoa-iot-som - const: qcom,x1e80100 + - items: + - enum: + - qcom,purwa-iot-evk + - const: qcom,purwa-iot-som + - const: qcom,x1p42100 + - items: - enum: - asus,zenbook-a14-ux3407qa-lcd From e58115b2eaaf85e9658458a6cbff6cdf4ddfe62e Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:46 +0800 Subject: [PATCH 525/659] 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 1a6f85e463e06..1fed7a81bd292 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2010,6 +2010,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 e71d406caee5d0f5b089e51ca597d6e5e2219593 Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:47 +0800 Subject: [PATCH 526/659] 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 5c4a7dd59b2790b53479af5c9593600dc83e9d16 Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Mon, 2 Feb 2026 15:35:48 +0800 Subject: [PATCH 527/659] 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 Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Signed-off-by: Yijie Yang Link: https://lore.kernel.org/all/20260202073555.1345260-4-yijie.yang@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/Makefile | 1 + arch/arm64/boot/dts/qcom/purwa-iot-evk.dts | 1486 ++++++++++++++++++++ 2 files changed, 1487 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 6f34d5ed331c4..803a525093e77 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -123,6 +123,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..6ac37ac280631 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts @@ -0,0 +1,1486 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#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"; + }; + + 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>; + }; + }; + }; + }; + }; + + 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 { + 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; + }; + + 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-names = "default"; + pinctrl-0 = <&edp_bl_reg_en>; + + 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; + }; + + 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_port { + vpcie12v-supply = <&vreg_pcie_12v>; + vpcie3v3-supply = <&vreg_pcie_3v3>; + vpcie3v3aux-supply = <&vreg_pcie_3v3_aux>; +}; + +&pcie4_port0 { + 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>; +}; + +&pcie6a { + vddpe-3v3-supply = <&vreg_nvme>; +}; + +&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>; + }; +}; + +&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; + output-high; + bias-pull-down; + power-source = <0>; + }; + + pm_sde7_main_3p3_en: pcie-main-3p3-default-state { + pins = "gpio6"; + function = "normal"; + output-enable; + output-high; + 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 2c90cffc8f1af67d7281c12968a26e3f9fb9e796 Mon Sep 17 00:00:00 2001 From: Yijie Yang Date: Thu, 15 Jan 2026 10:30:10 +0800 Subject: [PATCH 528/659] QCLINUX: arm64: dts: qcom: workaround for TPM pins Purwa will crash if HLOS attempts to access or configure the TPM pins, as these operations require higher privilege levels. Therefore, the TPM pins should be reserved in the DTS until NHLOS provides proper support. Signed-off-by: Yijie Yang --- arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi index 71770a8504cf3..238e38b5dd739 100644 --- a/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi @@ -483,7 +483,8 @@ }; &tlmm { - gpio-reserved-ranges = <34 2>; /* TPM LP & INT */ + gpio-reserved-ranges = <34 2>, /* TPM LP & INT */ + <44 4>; /* SPI (TPM) */ pcie3_default: pcie3-default-state { clkreq-n-pins { From 3b0e6753d2fe8adeedb0cbf78416e879eff17d73 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Wed, 4 Feb 2026 21:40:53 +0530 Subject: [PATCH 529/659] 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 0b154d57ba24e..5e0347e2b792e 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -8471,8 +8471,7 @@ , , , - , - ; + ; interrupt-names = "msi0", "msi1", "msi2", @@ -8480,8 +8479,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 2b9347cdf09a237d6d8e00bc2d87a3a18617bcc1 Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Wed, 4 Feb 2026 01:08:48 +0530 Subject: [PATCH 530/659] 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 56efd90b7a5e6..99f292ec8e79d 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -41,6 +41,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) += monaco-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.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 b4eb3a0a71e23cabfeba2671027911aa9310bf30 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 5 Feb 2026 15:35:49 +0530 Subject: [PATCH 531/659] 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 afd391fb74f2b..84394f8a866c6 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 e249fa5f1f2c346bfc537494a06e9dc227419639 Mon Sep 17 00:00:00 2001 From: Vishnu Santhosh Date: Thu, 5 Feb 2026 13:51:31 +0530 Subject: [PATCH 532/659] 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 00c51cf693f3d..a1c16269d745c 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 a5f139ef98c4f13cd27d12c6b8030c334b161325 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Fri, 28 Nov 2025 16:02:40 +0530 Subject: [PATCH 533/659] 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 534/659] 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 535/659] 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 536/659] 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 537/659] 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 538/659] 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 539/659] 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 540/659] 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 541/659] 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 542/659] 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 543/659] 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 544/659] 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 545/659] 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 546/659] 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 547/659] 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 548/659] 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 549/659] 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 550/659] 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 551/659] 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 646c7c034503373782427e4bb0060fdc42946ce7 Mon Sep 17 00:00:00 2001 From: Kumari Pallavi Date: Fri, 26 Dec 2025 12:35:31 +0530 Subject: [PATCH 552/659] BACKPORT: dt-bindings: misc: qcom,fastrpc: Add compatible for Kaanapali Kaanapali introduces changes in DSP IOVA layout and CDSP DMA addressing that differ from previous SoCs. The SID field moves within the physical address, and CDSP now supports a wider DMA range, requiring updated sid_pos and DMA mask handling in the driver. Link: https://lore.kernel.org/all/20251226070534.602021-2-kumari.pallavi@oss.qualcomm.com/ Signed-off-by: Kumari Pallavi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Vinayak Katoch --- Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml index 3f6199fc9ae6a..d8e47db677ccc 100644 --- a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml +++ b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml @@ -18,7 +18,9 @@ description: | properties: compatible: - const: qcom,fastrpc + enum: + - qcom,kaanapali-fastrpc + - qcom,fastrpc label: enum: From dc927980ff2b25c95c0a4f7344618be48cbfdfdc Mon Sep 17 00:00:00 2001 From: Kumari Pallavi Date: Fri, 9 Jan 2026 13:53:09 +0530 Subject: [PATCH 553/659] BACKPORT: misc: fastrpc: Rename phys to dma_addr for clarity The fields buf->phys and map->phys currently store DMA addresses returned by dma_map_*() APIs, not physical addresses. This naming is misleading and may lead to incorrect assumptions about the address type and its translation. Rename these fields from phys to dma_addr to improve code clarity and align with kernel conventions for dma_addr_t usage. Link: https://lore.kernel.org/all/20251226070534.602021-3-kumari.pallavi@oss.qualcomm.com/ Signed-off-by: Kumari Pallavi Reviewed-by: Dmitry Baryshkov Signed-off-by: Vinayak Katoch --- drivers/misc/fastrpc.c | 94 ++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index d95d31d27b826..bf58b088ff03b 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -116,7 +116,7 @@ #define FASTRPC_POLL_MAX_TIMEOUT_US (10000) struct fastrpc_phy_page { - u64 addr; /* physical address */ + dma_addr_t addr; /* dma address */ u64 size; /* size of contiguous region */ }; @@ -181,7 +181,7 @@ struct fastrpc_msg { u64 ctx; /* invoke caller context */ u32 handle; /* handle to invoke */ u32 sc; /* scalars structure describing the data */ - u64 addr; /* physical address */ + dma_addr_t addr; /* dma address */ u64 size; /* size of contiguous region */ }; @@ -204,7 +204,7 @@ struct fastrpc_buf { struct dma_buf *dmabuf; struct device *dev; void *virt; - u64 phys; + dma_addr_t dma_addr; u64 size; /* Lock for dma buf attachments */ struct mutex lock; @@ -227,7 +227,7 @@ struct fastrpc_map { struct dma_buf *buf; struct sg_table *table; struct dma_buf_attachment *attach; - u64 phys; + dma_addr_t dma_addr; u64 size; void *va; u64 len; @@ -339,11 +339,12 @@ static void fastrpc_free_map(struct kref *ref) perm.vmid = QCOM_SCM_VMID_HLOS; perm.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(map->phys, map->len, - &src_perms, &perm, 1); + err = qcom_scm_assign_mem(map->dma_addr, map->len, + &src_perms, &perm, 1); if (err) { - dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - map->phys, map->len, err); + dev_err(map->fl->sctx->dev, + "Failed to assign memory dma_addr %pad size 0x%llx err %d\n", + &map->dma_addr, map->len, err); return; } } @@ -408,7 +409,7 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, static void fastrpc_buf_free(struct fastrpc_buf *buf) { dma_free_coherent(buf->dev, buf->size, buf->virt, - FASTRPC_PHYS(buf->phys)); + FASTRPC_PHYS(buf->dma_addr)); kfree(buf); } @@ -427,12 +428,12 @@ static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, buf->fl = fl; buf->virt = NULL; - buf->phys = 0; + buf->dma_addr = 0; buf->size = size; buf->dev = dev; buf->raddr = 0; - buf->virt = dma_alloc_coherent(dev, buf->size, (dma_addr_t *)&buf->phys, + buf->virt = dma_alloc_coherent(dev, buf->size, &buf->dma_addr, GFP_KERNEL); if (!buf->virt) { mutex_destroy(&buf->lock); @@ -458,7 +459,7 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, buf = *obuf; if (fl->sctx && fl->sctx->sid) - buf->phys += ((u64)fl->sctx->sid << 32); + buf->dma_addr += ((u64)fl->sctx->sid << 32); return 0; } @@ -703,7 +704,7 @@ static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf, return -ENOMEM; ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt, - FASTRPC_PHYS(buffer->phys), buffer->size); + FASTRPC_PHYS(buffer->dma_addr), buffer->size); if (ret < 0) { dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); kfree(a); @@ -752,7 +753,7 @@ static int fastrpc_mmap(struct dma_buf *dmabuf, dma_resv_assert_held(dmabuf->resv); return dma_mmap_coherent(buf->dev, vma, buf->virt, - FASTRPC_PHYS(buf->phys), size); + FASTRPC_PHYS(buf->dma_addr), size); } static const struct dma_buf_ops fastrpc_dma_buf_ops = { @@ -804,10 +805,10 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, map->table = table; if (attr & FASTRPC_ATTR_SECUREMAP) { - map->phys = sg_phys(map->table->sgl); + map->dma_addr = sg_phys(map->table->sgl); } else { - map->phys = sg_dma_address(map->table->sgl); - map->phys += ((u64)fl->sctx->sid << 32); + map->dma_addr = sg_dma_address(map->table->sgl); + map->dma_addr += ((u64)fl->sctx->sid << 32); } for_each_sg(map->table->sgl, sgl, map->table->nents, sgl_index) @@ -834,10 +835,11 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, dst_perms[1].vmid = fl->cctx->vmperms[0].vmid; dst_perms[1].perm = QCOM_SCM_PERM_RWX; map->attr = attr; - err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2); + err = qcom_scm_assign_mem(map->dma_addr, (u64)map->len, &src_perms, dst_perms, 2); if (err) { - dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", - map->phys, map->len, err); + dev_err(sess->dev, + "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n", + &map->dma_addr, map->len, err); goto map_err; } } @@ -1031,7 +1033,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) struct vm_area_struct *vma = NULL; rpra[i].buf.pv = (u64) ctx->args[i].ptr; - pages[i].addr = ctx->maps[i]->phys; + pages[i].addr = ctx->maps[i]->dma_addr; mmap_read_lock(current->mm); vma = find_vma(current->mm, ctx->args[i].ptr); @@ -1058,7 +1060,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) goto bail; rpra[i].buf.pv = args - ctx->olaps[oix].offset; - pages[i].addr = ctx->buf->phys - + pages[i].addr = ctx->buf->dma_addr - ctx->olaps[oix].offset + (pkt_size - rlen); pages[i].addr = pages[i].addr & PAGE_MASK; @@ -1090,7 +1092,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) list[i].num = ctx->args[i].length ? 1 : 0; list[i].pgidx = i; if (ctx->maps[i]) { - pages[i].addr = ctx->maps[i]->phys; + pages[i].addr = ctx->maps[i]->dma_addr; pages[i].size = ctx->maps[i]->size; } rpra[i].dma.fd = ctx->args[i].fd; @@ -1164,7 +1166,7 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, msg->ctx = ctx->ctxid | fl->pd; msg->handle = handle; msg->sc = ctx->sc; - msg->addr = ctx->buf ? ctx->buf->phys : 0; + msg->addr = ctx->buf ? ctx->buf->dma_addr : 0; msg->size = roundup(ctx->msg_sz, PAGE_SIZE); fastrpc_context_get(ctx); @@ -1398,13 +1400,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, if (fl->cctx->vmcount) { u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, - &src_perms, - fl->cctx->vmperms, fl->cctx->vmcount); + err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr, + (u64)fl->cctx->remote_heap->size, + &src_perms, fl->cctx->vmperms, + fl->cctx->vmcount); if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + dev_err(fl->sctx->dev, + "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n", + &fl->cctx->remote_heap->dma_addr, + fl->cctx->remote_heap->size, err); goto err_map; } scm_done = true; @@ -1424,7 +1428,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, args[1].length = inbuf.namelen; args[1].fd = -1; - pages[0].addr = fl->cctx->remote_heap->phys; + pages[0].addr = fl->cctx->remote_heap->dma_addr; pages[0].size = fl->cctx->remote_heap->size; args[2].ptr = (u64)(uintptr_t) pages; @@ -1453,12 +1457,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, dst_perms.vmid = QCOM_SCM_VMID_HLOS; dst_perms.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, - &src_perms, &dst_perms, 1); + err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr, + (u64)fl->cctx->remote_heap->size, + &src_perms, &dst_perms, 1); if (err) - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + dev_err(fl->sctx->dev, "Failed to assign memory dma_addr %pad size 0x%llx err %d\n", + &fl->cctx->remote_heap->dma_addr, fl->cctx->remote_heap->size, err); } err_map: fastrpc_buf_free(fl->cctx->remote_heap); @@ -1547,7 +1551,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, args[2].length = inbuf.filelen; args[2].fd = init.filefd; - pages[0].addr = imem->phys; + pages[0].addr = imem->dma_addr; pages[0].size = imem->size; args[3].ptr = (u64)(uintptr_t) pages; @@ -2029,7 +2033,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - pages.addr = buf->phys; + pages.addr = buf->dma_addr; pages.size = buf->size; args[1].ptr = (u64) (uintptr_t) &pages; @@ -2057,11 +2061,13 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, - &src_perms, fl->cctx->vmperms, fl->cctx->vmcount); + err = qcom_scm_assign_mem(buf->dma_addr, (u64)buf->size, + &src_perms, fl->cctx->vmperms, + fl->cctx->vmcount); if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", - buf->phys, buf->size, err); + dev_err(fl->sctx->dev, + "Failed to assign memory dma_addr %pad size 0x%llx err %d", + &buf->dma_addr, buf->size, err); goto err_assign; } } @@ -2175,7 +2181,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - pages.addr = map->phys; + pages.addr = map->dma_addr; pages.size = map->len; args[1].ptr = (u64) (uintptr_t) &pages; @@ -2457,7 +2463,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) src_perms = BIT(QCOM_SCM_VMID_HLOS); qcom_scm_assign_mem(res.start, resource_size(&res), &src_perms, - data->vmperms, data->vmcount); + data->vmperms, data->vmcount); } } From 87246f5946c0f68578893fec6c1c9decad859f14 Mon Sep 17 00:00:00 2001 From: Kumari Pallavi Date: Fri, 9 Jan 2026 16:06:07 +0530 Subject: [PATCH 554/659] BACKPORT: misc: fastrpc: Add support for new DSP IOVA formatting Implement the new IOVA formatting required by the DSP architecture change on Kaanapali SoC. Place the SID for DSP DMA transactions at bit 56 in the physical address. This placement is necessary for the DSPs to correctly identify streams and operate as intended. To address this, set SID position to bit 56 via OF matching on the fastrpc node; otherwise, default to legacy 32-bit placement. This change ensures consistent SID placement across DSPs. Link: https://lore.kernel.org/all/20251226070534.602021-4-kumari.pallavi@oss.qualcomm.com/ Signed-off-by: Kumari Pallavi Reviewed-by: Dmitry Baryshkov Signed-off-by: Vinayak Katoch --- drivers/misc/fastrpc.c | 62 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index bf58b088ff03b..3176896c7fb57 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -25,6 +25,7 @@ #include #include #include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -36,7 +37,6 @@ #define FASTRPC_ALIGN 128 #define FASTRPC_MAX_FDLIST 16 #define FASTRPC_MAX_CRCLIST 64 -#define FASTRPC_PHYS(p) ((p) & 0xffffffff) #define FASTRPC_CTX_MAX (256) #define FASTRPC_INIT_HANDLE 1 #define FASTRPC_DSP_UTILITIES_HANDLE 2 @@ -274,6 +274,10 @@ struct fastrpc_session_ctx { bool valid; }; +struct fastrpc_soc_data { + u32 sid_pos; +}; + struct fastrpc_channel_ctx { int domain_id; int sesscount; @@ -295,6 +299,7 @@ struct fastrpc_channel_ctx { bool secure; bool unsigned_support; u64 dma_mask; + const struct fastrpc_soc_data *soc_data; }; struct fastrpc_device { @@ -324,6 +329,24 @@ struct fastrpc_user { struct mutex mutex; }; +/* Extract SMMU PA from consolidated IOVA */ +static inline dma_addr_t fastrpc_ipa_to_dma_addr(struct fastrpc_channel_ctx *cctx, dma_addr_t iova) +{ + if (!cctx->soc_data->sid_pos) + return 0; + return iova & GENMASK_ULL(cctx->soc_data->sid_pos - 1, 0); +} + +/* + * Prepare the consolidated iova to send to DSP by prepending the SID + * to smmu PA at the appropriate position + */ +static inline u64 fastrpc_sid_offset(struct fastrpc_channel_ctx *cctx, + struct fastrpc_session_ctx *sctx) +{ + return (u64)sctx->sid << cctx->soc_data->sid_pos; +} + static void fastrpc_free_map(struct kref *ref) { struct fastrpc_map *map; @@ -409,7 +432,7 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, static void fastrpc_buf_free(struct fastrpc_buf *buf) { dma_free_coherent(buf->dev, buf->size, buf->virt, - FASTRPC_PHYS(buf->dma_addr)); + fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr)); kfree(buf); } @@ -459,7 +482,7 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, buf = *obuf; if (fl->sctx && fl->sctx->sid) - buf->dma_addr += ((u64)fl->sctx->sid << 32); + buf->dma_addr += fastrpc_sid_offset(fl->cctx, fl->sctx); return 0; } @@ -704,7 +727,8 @@ static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf, return -ENOMEM; ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt, - FASTRPC_PHYS(buffer->dma_addr), buffer->size); + fastrpc_ipa_to_dma_addr(buffer->fl->cctx, buffer->dma_addr), + buffer->size); if (ret < 0) { dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); kfree(a); @@ -753,7 +777,7 @@ static int fastrpc_mmap(struct dma_buf *dmabuf, dma_resv_assert_held(dmabuf->resv); return dma_mmap_coherent(buf->dev, vma, buf->virt, - FASTRPC_PHYS(buf->dma_addr), size); + fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr), size); } static const struct dma_buf_ops fastrpc_dma_buf_ops = { @@ -766,6 +790,11 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = { .release = fastrpc_release, }; +static dma_addr_t fastrpc_compute_dma_addr(struct fastrpc_user *fl, dma_addr_t sg_dma_addr) +{ + return sg_dma_addr + fastrpc_sid_offset(fl->cctx, fl->sctx); +} + static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, u64 len, u32 attr, struct fastrpc_map **ppmap) { @@ -804,12 +833,10 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, } map->table = table; - if (attr & FASTRPC_ATTR_SECUREMAP) { + if (attr & FASTRPC_ATTR_SECUREMAP) map->dma_addr = sg_phys(map->table->sgl); - } else { - map->dma_addr = sg_dma_address(map->table->sgl); - map->dma_addr += ((u64)fl->sctx->sid << 32); - } + else + map->dma_addr = fastrpc_compute_dma_addr(fl, sg_dma_address(map->table->sgl)); for_each_sg(map->table->sgl, sgl, map->table->nents, sgl_index) map->size += sg_dma_len(sgl); @@ -2410,6 +2437,14 @@ static int fastrpc_get_domain_id(const char *domain) return -EINVAL; } +static const struct fastrpc_soc_data kaanapali_soc_data = { + .sid_pos = 56, +}; + +static const struct fastrpc_soc_data default_soc_data = { + .sid_pos = 32, +}; + static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) { struct device *rdev = &rpdev->dev; @@ -2418,6 +2453,9 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) const char *domain; bool secure_dsp; unsigned int vmids[FASTRPC_MAX_VMIDS]; + const struct fastrpc_soc_data *soc_data; + + soc_data = device_get_match_data(rdev); err = of_property_read_string(rdev->of_node, "label", &domain); if (err) { @@ -2470,6 +2508,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain")); data->secure = secure_dsp; + data->soc_data = soc_data; switch (domain_id) { case ADSP_DOMAIN_ID: @@ -2608,7 +2647,8 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, } static const struct of_device_id fastrpc_rpmsg_of_match[] = { - { .compatible = "qcom,fastrpc" }, + { .compatible = "qcom,kaanapali-fastrpc", .data = &kaanapali_soc_data }, + { .compatible = "qcom,fastrpc", .data = &default_soc_data }, { }, }; MODULE_DEVICE_TABLE(of, fastrpc_rpmsg_of_match); From 02c8ae97aa2e858df75258267c5dce446c22d606 Mon Sep 17 00:00:00 2001 From: Kumari Pallavi Date: Fri, 9 Jan 2026 16:14:59 +0530 Subject: [PATCH 555/659] BACKPORT: misc: fastrpc: Update dma_bits for CDSP support on Kaanapali SoC DSP currently supports 32-bit IOVA (32-bit PA + 4-bit SID) for both Q6 and user DMA (uDMA) access. This is being upgraded to 34-bit PA + 4-bit SID due to a hardware revision in CDSP for Kaanapali SoC, which expands the DMA addressable range. Update DMA bits configuration in the driver to support CDSP on Kaanapali SoC. Set the default `dma_bits` to 32-bit and update it to 34-bit based on CDSP and OF matching on the fastrpc node. Link: https://lore.kernel.org/all/20251226070534.602021-5-kumari.pallavi@oss.qualcomm.com/ Signed-off-by: Kumari Pallavi Reviewed-by: Dmitry Baryshkov Signed-off-by: Vinayak Katoch --- drivers/misc/fastrpc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 3176896c7fb57..9ef4e182aad7a 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -276,6 +276,8 @@ struct fastrpc_session_ctx { struct fastrpc_soc_data { u32 sid_pos; + u32 dma_addr_bits_cdsp; + u32 dma_addr_bits_default; }; struct fastrpc_channel_ctx { @@ -2317,6 +2319,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev) int i, sessions = 0; unsigned long flags; int rc; + u32 dma_bits; cctx = dev_get_drvdata(dev->parent); if (!cctx) @@ -2330,12 +2333,16 @@ static int fastrpc_cb_probe(struct platform_device *pdev) spin_unlock_irqrestore(&cctx->lock, flags); return -ENOSPC; } + dma_bits = cctx->soc_data->dma_addr_bits_default; sess = &cctx->session[cctx->sesscount++]; sess->used = false; sess->valid = true; sess->dev = dev; dev_set_drvdata(dev, sess); + if (cctx->domain_id == CDSP_DOMAIN_ID) + dma_bits = cctx->soc_data->dma_addr_bits_cdsp; + if (of_property_read_u32(dev->of_node, "reg", &sess->sid)) dev_info(dev, "FastRPC Session ID not specified in DT\n"); @@ -2350,9 +2357,9 @@ static int fastrpc_cb_probe(struct platform_device *pdev) } } spin_unlock_irqrestore(&cctx->lock, flags); - rc = dma_set_mask(dev, DMA_BIT_MASK(32)); + rc = dma_set_mask(dev, DMA_BIT_MASK(dma_bits)); if (rc) { - dev_err(dev, "32-bit DMA enable failed\n"); + dev_err(dev, "%u-bit DMA enable failed\n", dma_bits); return rc; } @@ -2439,10 +2446,14 @@ static int fastrpc_get_domain_id(const char *domain) static const struct fastrpc_soc_data kaanapali_soc_data = { .sid_pos = 56, + .dma_addr_bits_cdsp = 34, + .dma_addr_bits_default = 32, }; static const struct fastrpc_soc_data default_soc_data = { .sid_pos = 32, + .dma_addr_bits_cdsp = 32, + .dma_addr_bits_default = 32, }; static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) From b67e2b690d732374a0d8843384ef663d60c76539 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 7 Feb 2026 17:55:39 +0530 Subject: [PATCH 556/659] 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 80c0b49f30b01..d22e26354a2a0 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -118,7 +118,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 29fddf62d51cc41b8a89929fa8d08f93a1e3cad8 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 13:44:34 +0800 Subject: [PATCH 557/659] 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 35750b18e0d6129d99f5310adfc7b36c0e71c686 Mon Sep 17 00:00:00 2001 From: Qingqing Zhou Date: Wed, 21 Jan 2026 03:35:52 +0530 Subject: [PATCH 558/659] 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 --- 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 2e617ddad5b23..6c83abcfd6020 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -1849,6 +1849,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 4fbec4457ac6b56f42f6cc7b700c6cec021fda96 Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Wed, 21 Jan 2026 03:35:53 +0530 Subject: [PATCH 559/659] 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 --- 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 6c83abcfd6020..265b234d7e892 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -657,6 +657,11 @@ reg = <0x0 0x95900000 0x0 0x1e00000>; no-map; }; + + pil_gpu_mem: pil-gpu@97715000 { + reg = <0x0 0x97715000 0x0 0x2000>; + no-map; + }; }; soc: soc@0 { @@ -1836,6 +1841,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 2a2c18b5084d4c97ea6fd0d68d20a25090f5c87f Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 21 Jan 2026 03:35:54 +0530 Subject: [PATCH 560/659] 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 --- 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 265b234d7e892..4e877a948f9a3 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>; @@ -4964,12 +4965,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 4b6a4e3dc285dbb9c26132f25187fc9acb2aef65 Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Wed, 21 Jan 2026 03:35:55 +0530 Subject: [PATCH 561/659] 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 --- 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 ff3e20608d857d2ab75d26d5b87b879bc9657c74 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:25 +0530 Subject: [PATCH 562/659] 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 4e877a948f9a3..9a470a501ecaf 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -3696,6 +3696,14 @@ }; }; }; + + cooling { + compatible = "qcom,qmi-cooling-cdsp"; + cdsp_sw: cdsp_sw { + label = "cdsp_sw"; + #cooling-cells = <2>; + }; + }; }; pmu@90b6300 { @@ -4990,12 +4998,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 88e8e7e85eca2560c8c886c583a42c05435ac2b4 Mon Sep 17 00:00:00 2001 From: Shivendra Pratap Date: Sun, 28 Dec 2025 22:50:28 +0530 Subject: [PATCH 563/659] 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 9a470a501ecaf..fb6773ef7e909 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -624,6 +624,11 @@ &cluster_sleep_1 &cluster_sleep_2>; }; + + reboot-mode { + mode-bootloader = <0x80010001 0x2>; + mode-edl = <0x80000000 0x1>; + }; }; reserved-memory { From 319291a9c3aa92ff670af624069aa404fb81798d Mon Sep 17 00:00:00 2001 From: Sudarshan Shetty Date: Wed, 14 Jan 2026 15:30:41 +0530 Subject: [PATCH 564/659] 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/20260114100043.1310164-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 d84bd3bca2010..d4b9c09404087 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -870,6 +870,7 @@ properties: - items: - enum: - qcom,qcs615-ride + - qcom,talos-evk - const: qcom,qcs615 - const: qcom,sm6150 From 2e639f183cfef10663e43fabd85943e0527a38c8 Mon Sep 17 00:00:00 2001 From: Sudarshan Shetty Date: Wed, 14 Jan 2026 15:30:42 +0530 Subject: [PATCH 565/659] FROMLIST: arm64: dts: qcom: talos/qcs615-ride: Fix inconsistent USB PHY node naming The USB PHY nodes has inconsistent labels as 'usb_1_hspy' 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/20260114100043.1310164-3-tessolveupstream@gmail.com/ Reviewed-by: Dmitry Baryshkov Signed-off-by: Sudarshan Shetty Signed-off-by: Jie Gan --- 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..e28dabac0a7d1 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -647,7 +647,7 @@ }; }; -&usb_1_hsphy { +&usb_hsphy_1 { 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 fb6773ef7e909..5d3a7fdebf6a3 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -4547,7 +4547,7 @@ #interconnect-cells = <1>; }; - usb_1_hsphy: phy@88e2000 { + usb_hsphy_1: phy@88e2000 { compatible = "qcom,qcs615-qusb2-phy"; reg = <0x0 0x88e2000 0x0 0x180>; @@ -4681,7 +4681,7 @@ iommus = <&apps_smmu 0x140 0x0>; interrupts = ; - phys = <&usb_1_hsphy>, <&usb_qmpphy>; + phys = <&usb_hsphy_1>, <&usb_qmpphy>; phy-names = "usb2-phy", "usb3-phy"; snps,dis-u1-entry-quirk; From e1205e90534cdec30c1b9e6c95ca60b2c29ac40f Mon Sep 17 00:00:00 2001 From: Sudarshan Shetty Date: Wed, 14 Jan 2026 15:30:43 +0530 Subject: [PATCH 566/659] 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. 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/20260114100043.1310164-4-tessolveupstream@gmail.com/ Reviewed-by: Dmitry Baryshkov Signed-off-by: Sudarshan Shetty Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/Makefile | 4 + .../qcom/talos-evk-lvds-auo,g133han01.dtso | 131 ++++ arch/arm64/boot/dts/qcom/talos-evk-som.dtsi | 616 ++++++++++++++++++ arch/arm64/boot/dts/qcom/talos-evk.dts | 139 ++++ 4 files changed, 890 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.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 6f34d5ed331c4..ae952a993baf2 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -322,6 +322,10 @@ 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-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..e63f88da8ff6f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi @@ -0,0 +1,616 @@ +// 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 { + mmc0 = &sdhc_1; + serial0 = &uart0; + serial1 = &uart7; + }; + + 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"; + }; + }; + }; + + wifi_1p8v: regulator-wifi-1p8v { + compatible = "regulator-fixed"; + regulator-name = "wifi_1p8v"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&tlmm 91 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&wifi_reg_en_pins_state>; + pinctrl-names = "default"; + regulator-boot-on; + regulator-always-on; + }; + + wifi_3p85v: regulator-wifi-3p85v { + compatible = "regulator-fixed"; + regulator-name = "wifi_3p85v"; + regulator-min-microvolt = <3850000>; + regulator-max-microvolt = <3850000>; + gpio = <&tlmm 91 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&wifi_reg_en_pins_state>; + pinctrl-names = "default"; + regulator-boot-on; + regulator-always-on; + }; +}; + +&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-disable; + }; + + 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-down; + output-low; + }; +}; + +&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>; + }; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "host"; +}; + +&usb_hsphy_1 { + 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_hsphy_2 { + 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.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 652b5d5256241442f372701395605d50727310fd Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Fri, 23 Jan 2026 14:45:54 +0800 Subject: [PATCH 567/659] 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/20260123-enable-etr-and-ctcu-devices-v1-1-5fbb3423a2d7@oss.qualcomm.com/ 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 5d3a7fdebf6a3..90a9743d09b12 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -2400,6 +2400,14 @@ #address-cells = <1>; #size-cells = <0>; + port@0 { + reg = <0>; + + replicator0_out0: endpoint { + remote-endpoint = <&tmc_etr_in>; + }; + }; + port@1 { reg = <1>; @@ -2434,6 +2442,25 @@ }; }; + tmc_etr: 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 bc95dc4f46850cc1cd7e69bea5af832216f9b118 Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:52 +0800 Subject: [PATCH 568/659] 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 90a9743d09b12..753e9485d256a 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -3971,6 +3971,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 3f1beff5d01e94a87ae653b515934905ed9d3bee Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:54 +0800 Subject: [PATCH 569/659] 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 753e9485d256a..ef62db4bb7673 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -1570,6 +1570,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"; @@ -3971,6 +3987,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 4f46c14e6183208f6ed0088dddb91a088f6e94df Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:55 +0800 Subject: [PATCH 570/659] 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 ef62db4bb7673..43a84f74f78ff 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -1570,6 +1570,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 9bcb94e77adecf4142ff3b7a6dd5f19ecf965e3a Mon Sep 17 00:00:00 2001 From: Wenmeng Liu Date: Thu, 22 Jan 2026 18:48:56 +0800 Subject: [PATCH 571/659] 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 ae952a993baf2..c5ab055b2710a 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -323,8 +323,11 @@ 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 +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-camera-imx577.dtbo +talos-evk-camera-imx577-dtbs := talos-evk.dtb talos-evk-camera-imx577.dtbo 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 85d9f147285d92b749b3769669bb80e71fd5620b Mon Sep 17 00:00:00 2001 From: Le Qi Date: Tue, 27 Jan 2026 20:26:11 +0800 Subject: [PATCH 572/659] 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 43a84f74f78ff..1018a551a42af 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>; @@ -1570,6 +1571,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"; @@ -5147,6 +5155,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 08e909b98b09c37bb834824e05e16038572cdd2f Mon Sep 17 00:00:00 2001 From: Le Qi Date: Tue, 27 Jan 2026 20:30:18 +0800 Subject: [PATCH 573/659] 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 105f20e3fb028f754d667cb73bc51824239b2e5e Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 19 Jan 2026 14:24:54 +0530 Subject: [PATCH 574/659] 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 c5ab055b2710a..6e9945a36ec8f 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -130,6 +130,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 5aa28ddd5b8244606b3aae0ad6266db68a7611d4 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:20 +0100 Subject: [PATCH 575/659] dt-bindings: vendor-prefixes: Add Arduino name Add entry for Arduino SRL (https://arduino.cc) Signed-off-by: Riccardo Mereu Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251120155825.121483-2-r.mereu.kernel@arduino.cc --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index c7591b2aec2a7..209fad9642713 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -158,6 +158,8 @@ patternProperties: description: Arctic Sand "^arcx,.*": description: arcx Inc. / Archronix Inc. + "^arduino,.*": + description: Arduino SRL "^argon40,.*": description: Argon 40 Technologies Limited "^ariaboard,.*": From cb338e68a33baf51902f5ffef5558d24cedf8fe0 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:23 +0100 Subject: [PATCH 576/659] dt-bindings: arm: qcom: Add arduino imola, UnoQ codename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document Arduino imola, UnoQ codename. Arduino UnoQ combines Qualcomm Dragonwing™ QRB2210 microprocessor with STMicroelectronics STM32U585 microcontroller. Signed-off-by: Riccardo Mereu Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251120155825.121483-5-r.mereu.kernel@arduino.cc --- 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 d84bd3bca2010..1af19245b1d59 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -336,6 +336,7 @@ properties: - description: Qualcomm Technologies, Inc. Robotics RB1 items: - enum: + - arduino,imola - qcom,qrb2210-rb1 - const: qcom,qrb2210 - const: qcom,qcm2290 From 4e4b5e2b8b6d13cfd7d8880926a508feca46684c Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:24 +0100 Subject: [PATCH 577/659] arm64: dts: qcom: agatti: add uart2 node uart2 is used in Arduino UnoQ as an interface between microprocessor and microcontroller. Signed-off-by: Riccardo Mereu Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251120155825.121483-6-r.mereu.kernel@arduino.cc --- arch/arm64/boot/dts/qcom/agatti.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi index 8bf5c5583fc22..992a157c571fc 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -562,6 +562,13 @@ bias-disable; }; + qup_uart2_default: qup-uart2-default-state { + pins = "gpio6", "gpio7", "gpio71", "gpio80"; + function = "qup2"; + drive-strength = <2>; + bias-disable; + }; + qup_uart3_default: qup-uart3-default-state { pins = "gpio8", "gpio9", "gpio10", "gpio11"; function = "qup3"; @@ -1315,6 +1322,23 @@ status = "disabled"; }; + uart2: serial@4a88000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x04a88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + pinctrl-0 = <&qup_uart2_default>; + pinctrl-names = "default"; + interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG + &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, + <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG + &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>; + interconnect-names = "qup-core", + "qup-config"; + status = "disabled"; + }; + i2c3: i2c@4a8c000 { compatible = "qcom,geni-i2c"; reg = <0x0 0x04a8c000 0x0 0x4000>; From fdb4eeda2216188cb8a2de5470d987d37db66183 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:25 +0100 Subject: [PATCH 578/659] arm64: dts: qcom: qrb2210: add dts for Arduino unoq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Arduino UnoQ is a single-board computer combining Qualcomm Dragonwing™ QRB2210 microprocessor with STMicroelectronics STM32U585 microcontroller. Support to a simply boot to shell environment includes: - UART, I2C, SPI - onboard LEDS - eMMC - WLAN and BT Signed-off-by: Riccardo Mereu Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251120155825.121483-7-r.mereu.kernel@arduino.cc --- arch/arm64/boot/dts/qcom/Makefile | 1 + .../boot/dts/qcom/qrb2210-arduino-imola.dts | 459 ++++++++++++++++++ 2 files changed, 460 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 6f34d5ed331c4..9f98a7f2cbb4f 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -143,6 +143,7 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb +dtb-$(CONFIG_ARCH_QCOM) += qrb2210-arduino-imola.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb5165-rb5.dtb diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts new file mode 100644 index 0000000000000..197ab6eb1666f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2025, Arduino SRL + */ + +/dts-v1/; + +#include +#include "agatti.dtsi" +#include "pm4125.dtsi" + +/delete-node/ &cont_splash_memory; + +/ { + model = "Arduino UnoQ"; + compatible = "arduino,imola", "qcom,qrb2210", "qcom,qcm2290"; + chassis-type = "embedded"; + + aliases { + serial0 = &uart4; + serial1 = &uart2; + serial2 = &uart3; + sdhc1 = &sdhc_1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + label = "gpio-keys"; + pinctrl-0 = <&key_volp_n>, <&key_vold_n>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = ; + gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + + key-volume-down { + label = "Volume Down"; + linux,code = ; + gpios = <&tlmm 36 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + }; + + leds: leds { + compatible = "gpio-leds"; + + led-bt { + label = "unoq:bt-blue2"; + function = LED_FUNCTION_BLUETOOTH; + color = ; + gpios = <&tlmm 47 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "bluetooth-power"; + default-state = "off"; + }; + + led-panic { + label = "unoq:panic-red2"; + function = LED_FUNCTION_INDICATOR; + color = ; + gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + default-state = "off"; + panic-indicator; + }; + + led-wlan { + label = "unoq:wlan-green2"; + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&tlmm 40 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tx"; + default-state = "off"; + }; + + ledb: led-user-blue { + label = "unoq:user-blue1"; + gpios = <&tlmm 60 GPIO_ACTIVE_HIGH>; + color = ; + }; + + ledg: led-user-green { + label = "unoq:user-green1"; + gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>; + color = ; + }; + + ledr: led-user-red { + label = "unoq:user-red1"; + gpios = <&tlmm 41 GPIO_ACTIVE_HIGH>; + color = ; + }; + }; + + multi-led { + compatible = "leds-group-multicolor"; + color = ; + function = LED_FUNCTION_INDICATOR; + leds = <&ledr>, <&ledg>, <&ledb>; + }; + + /* PM4125 charger out, supplied by VBAT */ + 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; + }; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/qcm2290/a702_zap.mbn"; +}; + +&i2c0 { + clock-frequency = <100000>; + + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + + status = "okay"; +}; + +&pm4125_vbus { + regulator-min-microamp = <500000>; + regulator-max-microamp = <500000>; + + status = "okay"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/qcm2290/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_mpss { + firmware-name = "qcom/qcm2290/modem.mbn"; + + status = "okay"; +}; + +&rpm_requests { + regulators { + compatible = "qcom,rpm-pm2250-regulators"; + vdd_s3-supply = <&vph_pwr>; + vdd_s4-supply = <&vph_pwr>; + vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm4125_s3>; + vdd_l4_l17_l18_l19_l20_l21_l22-supply = <&vph_pwr>; + vdd_l13_l14_l15_l16-supply = <&pm4125_s4>; + + pm4125_s3: s3 { + /* 0.4V-1.6625V -> 1.3V (Power tree requirements) */ + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + regulator-boot-on; + }; + + pm4125_s4: s4 { + /* 1.2V-2.35V -> 2.05V (Power tree requirements) */ + regulator-min-microvolt = <2072000>; + regulator-max-microvolt = <2072000>; + regulator-boot-on; + }; + + pm4125_l2: l2 { + /* LPDDR4X VDD2 */ + regulator-min-microvolt = <1136000>; + regulator-max-microvolt = <1136000>; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l3: l3 { + /* LPDDR4X VDDQ */ + regulator-min-microvolt = <616000>; + regulator-max-microvolt = <616000>; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l4: l4 { + /* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2700000>; + regulator-allow-set-load; + }; + + pm4125_l5: l5 { + /* CSI/DSI */ + regulator-min-microvolt = <1232000>; + regulator-max-microvolt = <1232000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l6: l6 { + /* DRAM PLL */ + regulator-min-microvolt = <928000>; + regulator-max-microvolt = <928000>; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l7: l7 { + /* Wi-Fi CX */ + regulator-min-microvolt = <664000>; + regulator-max-microvolt = <664000>; + }; + + pm4125_l10: l10 { + /* Wi-Fi RFA */ + regulator-min-microvolt = <1304000>; + regulator-max-microvolt = <1304000>; + }; + + pm4125_l11: l11 { + /* ANX7625 DVDD1P0V/AVDD1P0V */ + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-boot-on; + regulator-always-on; + }; + + pm4125_l12: l12 { + /* USB PHYs */ + regulator-min-microvolt = <928000>; + regulator-max-microvolt = <928000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l13: l13 { + /* USB/QFPROM/PLLs */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l14: l14 { + /* SDHCI1 EMMC VCCQ */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + /* Broken hardware, never turn it off! */ + regulator-always-on; + }; + + pm4125_l15: l15 { + /* VDDIO */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l20: l20 { + /* SDHCI1 EMMC */ + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3600000>; + regulator-allow-set-load; + }; + + pm4125_l21: l21 { + /* USB HS */ + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <3300000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l22: l22 { + /* Wi-Fi VDD */ + regulator-min-microvolt = <3312000>; + regulator-max-microvolt = <3312000>; + }; + }; +}; + +&sdhc_1 { + vmmc-supply = <&pm4125_l20>; + vqmmc-supply = <&pm4125_l14>; + pinctrl-0 = <&sdc1_state_on>; + pinctrl-1 = <&sdc1_state_off>; + pinctrl-names = "default", "sleep"; + mmc-hs400-1_8v; + mmc-hs200-1_8v; + non-removable; + supports-cqe; + no-sdio; + no-sd; + + status = "okay"; +}; + +&spi5 { + status = "okay"; + + spidev@0 { + reg = <0>; + compatible = "arduino,unoq-mcu"; + pinctrl-0 = <&spidev_cs>; + pinctrl-names = "default"; + }; +}; + +&tlmm { + spidev_cs: spidev-cs-state { + pins = "gpio17"; + function = "gpio"; + drive-strength = <16>; + }; + + jmisc_gpio18: jmisc-gpio18-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio28: jmisc-gpio28-state { + pins = "gpio28"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + key_vold_n: key-vold-n-state { + pins = "gpio36"; + function = "gpio"; + bias-pull-up; + output-disable; + }; + + key_volp_n: key-volp-n-state { + pins = "gpio96"; + function = "gpio"; + bias-pull-up; + output-disable; + }; + + jmisc_gpio98: jmisc-gpio98-state { + pins = "gpio98"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio99: jmisc-gpio99-state { + pins = "gpio99"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio100: jmisc-gpio100-state { + pins = "gpio100"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio101: jmisc-gpio101-state { + pins = "gpio101"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; +}; + +&uart2 { + status = "okay"; +}; + +/* UART connected to Bluetooth */ +&uart3 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn3988-bt"; + + vddio-supply = <&pm4125_l15>; + vddxo-supply = <&pm4125_l13>; + vddrf-supply = <&pm4125_l10>; + vddch0-supply = <&pm4125_l22>; + enable-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; + max-speed = <3000000>; + }; +}; + +/* UART exposed in JCTL */ +&uart4 { + compatible = "qcom,geni-debug-uart"; + + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&usb_hsphy { + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + + status = "okay"; +}; + +&wifi { + vdd-0.8-cx-mx-supply = <&pm4125_l7>; + vdd-1.8-xo-supply = <&pm4125_l13>; + vdd-1.3-rfa-supply = <&pm4125_l10>; + vdd-3.3-ch0-supply = <&pm4125_l22>; + qcom,ath10k-calibration-variant = "ArduinoImola"; + firmware-name = "qcm2290"; + + status = "okay"; +}; + +&xo_board { + clock-frequency = <38400000>; +}; From 261808860d46de42434af53f4339b13da4f7e7bc Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:45 +0200 Subject: [PATCH 579/659] 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://lore.kernel.org/r/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 41946842fec63be5ce6fa1c75bb6355f0a67fa82 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:46 +0200 Subject: [PATCH 580/659] 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://lore.kernel.org/r/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 6f3fdcb6afdb9..9fa95b5623157 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 c24b0d5e294a4c5a7b347f1966aae5a3de20530a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:47 +0200 Subject: [PATCH 581/659] 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://lore.kernel.org/r/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 9fa95b5623157..0d90887cd5ab4 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 0c79a8ea4160035b3f9521e4d77a3e0b9d112b04 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Thu, 18 Dec 2025 16:13:07 +0100 Subject: [PATCH 582/659] drm/bridge: anx7625: Fix invalid EDID size DRM checks EDID block count against allocated size in drm_edid_valid function. We have to allocate the right EDID size instead of the max size to prevent the EDID to be reported as invalid. Cc: stable@kernel.org Fixes: 7c585f9a71aa ("drm/bridge: anx7625: use struct drm_edid more") Reviewed-by: Dmitry Baryshkov Signed-off-by: Loic Poulain Link: https://lore.kernel.org/r/20251218151307.95491-1-loic.poulain@oss.qualcomm.com --- drivers/gpu/drm/bridge/analogix/anx7625.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 0d90887cd5ab4..c43519097a457 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1984,7 +1984,7 @@ static const struct drm_edid *anx7625_edid_read(struct anx7625_data *ctx) return NULL; } - ctx->cached_drm_edid = drm_edid_alloc(edid_buf, FOUR_BLOCK_SIZE); + ctx->cached_drm_edid = drm_edid_alloc(edid_buf, edid_num * ONE_BLOCK_SIZE); kfree(edid_buf); out: From 313032daa95c37f0042539c7de034d1e723b2904 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 22 Jan 2026 17:40:40 +0530 Subject: [PATCH 583/659] 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://lore.kernel.org/r/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 0ff6c8a7a015361324ef8e11584934eb92d9073e Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 22 Jan 2026 17:40:41 +0530 Subject: [PATCH 584/659] 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://lore.kernel.org/r/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 0864412b62e7f8cf4cd2458af3c9c5f59733724f Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 22 Jan 2026 17:40:42 +0530 Subject: [PATCH 585/659] 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://lore.kernel.org/r/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 992a157c571fc..46f7cd521690d 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -1637,8 +1637,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>; @@ -1919,8 +1918,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 @@ -2363,10 +2361,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 9d4ee0308d4f910c2d290984d51d0d4ea369e374 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 22 Oct 2025 07:47:14 +0100 Subject: [PATCH 586/659] arm64: dts: arduino-imola: add support for sound Add support for sound on Arduino UNO Q board, which includes - Headset playback and record. - Lineout Along with this add support in the SoC level dts for soundwire controllers and pm4125 codec. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/agatti.dtsi | 170 ++++++++++++++++++ .../boot/dts/qcom/qrb2210-arduino-imola.dts | 124 +++++++++++++ 2 files changed, 294 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi index 46f7cd521690d..07f129009b106 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -730,6 +730,94 @@ 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; + }; + }; + + }; + + 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>; + + #sound-dai-cells = <1>; + #address-cells = <2>; + #size-cells = <0>; }; gcc: clock-controller@1400000 { @@ -742,6 +830,88 @@ #power-domain-cells = <1>; }; + 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>; + + #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>; + }; + usb_hsphy: phy@1613000 { compatible = "qcom,qcm2290-qusb2-phy"; reg = <0x0 0x01613000 0x0 0x180>; diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index 197ab6eb1666f..e7e5c4b768ddb 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -109,6 +109,83 @@ 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>; + }; + }; + + 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"; @@ -424,6 +501,53 @@ status = "okay"; }; +&spmi_bus { + pmic@0 { + pmic4125_codec: audio-codec@f3db{ + compatible = "qcom,pm4125-codec"; + reg =<0xf3db>; + 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,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>; */ + + 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>; + }; +}; + &usb { status = "okay"; }; From 0470a0914268fc822b19f5626cdac07fda281bb0 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 14:10:29 +0800 Subject: [PATCH 587/659] 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 dee3d2155d3fc834b4d38feda73f9243096b9f7c Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 14:58:04 +0800 Subject: [PATCH 588/659] 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 3ac8d13a4115dabe6ac0a8ebdb8aebadb108481a Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 15:16:19 +0800 Subject: [PATCH 589/659] 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 fb6e530fb739fa2a3321615a158fd1c3de8a5b61 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 15:32:10 +0800 Subject: [PATCH 590/659] 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 7fc440765b19f217c84d3cceef13f158f9338821 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 9 Feb 2026 15:45:31 +0800 Subject: [PATCH 591/659] 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 d02d17363623cf15ba4ea228c8d7753d8675571e Mon Sep 17 00:00:00 2001 From: Mohd Ayaan Anwar Date: Sun, 14 Sep 2025 20:36:48 +0530 Subject: [PATCH 592/659] 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 a6ce790e0668cc6f98549c390017c5d1be5d983d Mon Sep 17 00:00:00 2001 From: Udit Tiwari Date: Thu, 20 Nov 2025 11:54:43 +0530 Subject: [PATCH 593/659] 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 ecedde1ec29a3b61eb279e91e2320aadfa9ae29d Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Mon, 2 Feb 2026 14:30:57 +0800 Subject: [PATCH 594/659] 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 6da26a5babc21..764b5b9effb14 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 93be5e1da22add744318e1fdb20387fac4c2e83f Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Tue, 10 Feb 2026 11:24:45 +0800 Subject: [PATCH 595/659] 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 a32ee9f8061af..6995de7761df3 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(sizeof(*elem), GFP_ATOMIC); if (!elem) return -ENOMEM; From 7b47af6e432d377b4ad9dee6a2d5ac83f693e931 Mon Sep 17 00:00:00 2001 From: Janaki Ramaiah Thota Date: Tue, 3 Feb 2026 12:48:07 +0530 Subject: [PATCH 596/659] 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 7c34815632cdccc6e60628ce1efb3c710eff7989 Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Tue, 10 Feb 2026 16:08:21 +0530 Subject: [PATCH 597/659] 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 7721c4cfd578d..ab1633d3a54c9 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -46,6 +46,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 b37ec075a9d8f4e78f0c1054c913eadfc8e18312 Mon Sep 17 00:00:00 2001 From: Ronak Raheja Date: Tue, 21 Oct 2025 23:50:27 -0700 Subject: [PATCH 598/659] FROMLIST: dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Add Kaanapali QMP PHY Document QMP combo PHY for Kaanapali. Use fallback to indicate the compatibility of the QMP PHY on the Kaanapali with that on the SM8750. Signed-off-by: Ronak Raheja Co-developed-by: Jingyi Wang Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/linux-usb/20251021-knp-usb-v2-1-a2809fffcfab@oss.qualcomm.com/ --- .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml index e0ec45b96bf5d..6b2bec4b90321 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml @@ -15,22 +15,27 @@ description: properties: compatible: - enum: - - qcom,sar2130p-qmp-usb3-dp-phy - - qcom,sc7180-qmp-usb3-dp-phy - - qcom,sc7280-qmp-usb3-dp-phy - - qcom,sc8180x-qmp-usb3-dp-phy - - qcom,sc8280xp-qmp-usb43dp-phy - - qcom,sdm845-qmp-usb3-dp-phy - - qcom,sm6350-qmp-usb3-dp-phy - - qcom,sm8150-qmp-usb3-dp-phy - - qcom,sm8250-qmp-usb3-dp-phy - - qcom,sm8350-qmp-usb3-dp-phy - - qcom,sm8450-qmp-usb3-dp-phy - - qcom,sm8550-qmp-usb3-dp-phy - - qcom,sm8650-qmp-usb3-dp-phy - - qcom,sm8750-qmp-usb3-dp-phy - - qcom,x1e80100-qmp-usb3-dp-phy + oneOf: + - items: + - enum: + - qcom,kaanapali-qmp-usb3-dp-phy + - const: qcom,sm8750-qmp-usb3-dp-phy + - enum: + - qcom,sar2130p-qmp-usb3-dp-phy + - qcom,sc7180-qmp-usb3-dp-phy + - qcom,sc7280-qmp-usb3-dp-phy + - qcom,sc8180x-qmp-usb3-dp-phy + - qcom,sc8280xp-qmp-usb43dp-phy + - qcom,sdm845-qmp-usb3-dp-phy + - qcom,sm6350-qmp-usb3-dp-phy + - qcom,sm8150-qmp-usb3-dp-phy + - qcom,sm8250-qmp-usb3-dp-phy + - qcom,sm8350-qmp-usb3-dp-phy + - qcom,sm8450-qmp-usb3-dp-phy + - qcom,sm8550-qmp-usb3-dp-phy + - qcom,sm8650-qmp-usb3-dp-phy + - qcom,sm8750-qmp-usb3-dp-phy + - qcom,x1e80100-qmp-usb3-dp-phy reg: maxItems: 1 @@ -194,14 +199,15 @@ allOf: - if: properties: compatible: - enum: - - qcom,sar2130p-qmp-usb3-dp-phy - - qcom,sc8280xp-qmp-usb43dp-phy - - qcom,sm6350-qmp-usb3-dp-phy - - qcom,sm8550-qmp-usb3-dp-phy - - qcom,sm8650-qmp-usb3-dp-phy - - qcom,sm8750-qmp-usb3-dp-phy - - qcom,x1e80100-qmp-usb3-dp-phy + contains: + enum: + - qcom,sar2130p-qmp-usb3-dp-phy + - qcom,sc8280xp-qmp-usb43dp-phy + - qcom,sm6350-qmp-usb3-dp-phy + - qcom,sm8550-qmp-usb3-dp-phy + - qcom,sm8650-qmp-usb3-dp-phy + - qcom,sm8750-qmp-usb3-dp-phy + - qcom,x1e80100-qmp-usb3-dp-phy then: required: - power-domains From 1da82f2cacb4caf69992b976d1d234a93ece20a2 Mon Sep 17 00:00:00 2001 From: Ronak Raheja Date: Tue, 21 Oct 2025 23:50:28 -0700 Subject: [PATCH 599/659] FROMLIST: dt-bindings: phy: qcom,m31-eusb2-phy: Document M31 eUSB2 PHY for Kaanapali Document M31 eUSB2 PHY for Kaanapali which handles the USB2 path. Use fallback to indicate the compatibility of the M31 eUSB2 PHY on the Kaanapali with that on the SM8750. Signed-off-by: Ronak Raheja Co-developed-by: Jingyi Wang Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/linux-usb/20251021-knp-usb-v2-2-a2809fffcfab@oss.qualcomm.com/ --- .../devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml index c84c62d0e8cbd..ab1cdedac05c1 100644 --- a/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml @@ -15,7 +15,11 @@ description: properties: compatible: - items: + oneOf: + - items: + - enum: + - qcom,kaanapali-m31-eusb2-phy + - const: qcom,sm8750-m31-eusb2-phy - enum: - qcom,sm8750-m31-eusb2-phy From 16fac6ba2609f902e7fca7017b0dc0c01dccc9c6 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 11 Dec 2025 11:41:01 -0800 Subject: [PATCH 600/659] 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/ --- .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml index 6b2bec4b90321..3d537b7f99859 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml @@ -21,6 +21,7 @@ properties: - qcom,kaanapali-qmp-usb3-dp-phy - const: qcom,sm8750-qmp-usb3-dp-phy - enum: + - qcom,glymur-qmp-usb3-dp-phy - qcom,sar2130p-qmp-usb3-dp-phy - qcom,sc7180-qmp-usb3-dp-phy - qcom,sc7280-qmp-usb3-dp-phy @@ -68,6 +69,8 @@ properties: vdda-pll-supply: true + refgen-supply: true + "#clock-cells": const: 1 description: @@ -201,6 +204,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-usb3-dp-phy - qcom,sar2130p-qmp-usb3-dp-phy - qcom,sc8280xp-qmp-usb43dp-phy - qcom,sm6350-qmp-usb3-dp-phy @@ -215,6 +219,18 @@ allOf: properties: power-domains: false + - if: + properties: + compatible: + enum: + - qcom,glymur-qmp-usb3-dp-phy + then: + required: + - refgen-supply + else: + properties: + refgen-supply: false + additionalProperties: false examples: From 23d8518e1c253b257dfba234ea796617fe81897c Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Dec 2025 14:53:08 -0800 Subject: [PATCH 601/659] FROMLIST: dt-bindings: phy: qcom,qmp-usb: Add Glymur USB UNI PHY compatible The Glymur USB subsystem contains a multiport controller, which utilizes two QMP UNI PHYs. Add the proper compatible string for the Glymur SoC, and the required clkref clock name. Acked-by: Rob Herring (Arm) Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-2-42133596bda0@oss.qualcomm.com/ --- .../phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml index 863a1a446739e..623c2f8c7d220 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml @@ -16,6 +16,7 @@ description: properties: compatible: enum: + - qcom,glymur-qmp-usb3-uni-phy - qcom,ipq5424-qmp-usb3-phy - qcom,ipq6018-qmp-usb3-phy - qcom,ipq8074-qmp-usb3-phy @@ -61,6 +62,8 @@ properties: vdda-pll-supply: true + refgen-supply: true + "#clock-cells": const: 0 @@ -113,6 +116,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-usb3-uni-phy - qcom,qcs8300-qmp-usb3-uni-phy - qcom,qdu1000-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy @@ -156,6 +160,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy - qcom,sc8180x-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy @@ -164,6 +169,19 @@ allOf: required: - power-domains + - if: + properties: + compatible: + contains: + enum: + - qcom,glymur-qmp-usb3-uni-phy + then: + required: + - refgen-supply + else: + properties: + refgen-supply: false + additionalProperties: false examples: From acc44ce6c2fc6b53c1f752b95acff68677f80f3f Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 11 Dec 2025 11:47:27 -0800 Subject: [PATCH 602/659] 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/ --- Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml index ab1cdedac05c1..a0acfd9f6c279 100644 --- a/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml @@ -18,6 +18,7 @@ properties: oneOf: - items: - enum: + - qcom,glymur-m31-eusb2-phy - qcom,kaanapali-m31-eusb2-phy - const: qcom,sm8750-m31-eusb2-phy - enum: From 4e3c95bdcc2186a334431d0ffbbf5f173c2aaa47 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Dec 2025 14:53:10 -0800 Subject: [PATCH 603/659] FROMLIST: dt-bindings: phy: qcom,snps-eusb2-repeater: Add SMB2370 compatible Add the compatible string for identifying a SMB2370 USB repeater device. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-4-42133596bda0@oss.qualcomm.com/ --- .../devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml index 5bf0d6c9c0256..0f015a4c23423 100644 --- a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml @@ -24,6 +24,7 @@ properties: - qcom,pm8550b-eusb2-repeater - qcom,pmiv0104-eusb2-repeater - qcom,smb2360-eusb2-repeater + - qcom,smb2370-eusb2-repeater reg: maxItems: 1 From efecdddd9da4c7075f744f423442b40ef04f6ab6 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Dec 2025 14:53:11 -0800 Subject: [PATCH 604/659] FROMLIST: phy: qualcomm: eusb2-repeater: Add SMB2370 eUSB2 repeater support Introduce support for the SMB2370 based eUSB2 repeater. Configure the proper repeater tuning settings, as if this is not done correctly, it can lead to instability on the USB2 link, which leads to USB2 enumeration failures, or random disconnects. Reviewed-by: Dmitry Baryshkov Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-5-42133596bda0@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c index 651a12b59bc8c..441996480a67f 100644 --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c @@ -75,6 +75,13 @@ static const struct eusb2_repeater_init_tbl_reg smb2360_init_tbl[] = { { EUSB2_TUNE_USB2_PREEM, 0x2 }, }; +static const struct eusb2_repeater_init_tbl_reg smb2370_init_tbl[] = { + { EUSB2_TUNE_IUSB2, 0x4 }, + { EUSB2_TUNE_SQUELCH_U, 0x3 }, + { EUSB2_TUNE_USB2_SLEW, 0x7 }, + { EUSB2_TUNE_USB2_PREEM, 0x0 }, +}; + static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { .init_tbl = pm8550b_init_tbl, .init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl), @@ -97,6 +104,13 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), }; +static const struct eusb2_repeater_cfg smb2370_eusb2_cfg = { + .init_tbl = smb2370_init_tbl, + .init_tbl_num = ARRAY_SIZE(smb2370_init_tbl), + .vreg_list = pm8550b_vreg_l, + .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), +}; + static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr) { int num = rptr->cfg->num_vregs; @@ -278,6 +292,10 @@ static const struct of_device_id eusb2_repeater_of_match_table[] = { .compatible = "qcom,smb2360-eusb2-repeater", .data = &smb2360_eusb2_cfg, }, + { + .compatible = "qcom,smb2370-eusb2-repeater", + .data = &smb2370_eusb2_cfg, + }, { }, }; MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table); From ce3e5f15c66444a1d7a315fafcf0d0e9108f8106 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Dec 2025 14:53:12 -0800 Subject: [PATCH 605/659] FROMLIST: phy: qualcomm: qmp-usb: Add support for Glymur USB UNI PHY Glymur contains a USB multiport controller which supports a QMP UNI PHY. These ports do not have typeC capability, so it needs to be differentiated in this manner. Update the QMP PHY sequence required to bring up the UNI PHY for Glymur. The UNI PHY follows mostly the same register field definitions as previous SoCs. Reviewed-by: Dmitry Baryshkov Signed-off-by: Wesley Cheng Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-6-42133596bda0@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 163 ++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index ed646a7e705ba..d5e9ba783c5e3 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -28,6 +28,7 @@ #include "phy-qcom-qmp-pcs-usb-v5.h" #include "phy-qcom-qmp-pcs-usb-v6.h" #include "phy-qcom-qmp-pcs-usb-v7.h" +#include "phy-qcom-qmp-pcs-usb-v8.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 @@ -109,6 +110,139 @@ static const unsigned int qmp_v7_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V7_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, }; +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x75), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE1, 0x25), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE0, 0x00), + + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0x75), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE0, 0x25), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_BUF_ENABLE, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_ADDITIONAL_MISC, 0x0c), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG1, 0xc4), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG2, 0x89), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG3, 0x20), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG6, 0x13), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_REFGEN_REQ_CONFIG1, 0x21), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RX_SIGDET_LVL, 0x55), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_CDR_RESET_TIME, 0x0a), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG1, 0xd4), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG2, 0x30), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_PCS_TX_RX_CONFIG, 0x0c), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG1, 0x4b), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG5, 0x10), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_TX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_RX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_TX, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_RX, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_1, 0xf5), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_4, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_5, 0x5f), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RCV_DETECT_LVL_2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_PI_QEC_CTRL, 0x21), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FO_GAIN, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_GAIN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_PI_CONTROLS, 0x99), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH2, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_AUX_DATA_TCOARSE_TFINE, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL1, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL2, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_GM_CAL, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_LOW, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_HIGH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_ENABLES, 0x0c), + + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CNTRL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_DEGLITCH_CNTRL, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_LOW, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH3, 0xdf), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH4, 0xed), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_LOW, 0x19), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH2, 0x91), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH3, 0xb7), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH4, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_EN_TIMER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DCC_CTRL1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VTH_CODE, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_CTRL1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_TRIM, 0x08), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_usb_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_WAIT_TIME, 0x75), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RCVR_DTCT_DLY_U3_L, 0x40), +}; + static const struct qmp_phy_init_tbl ipq9574_usb3_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a), QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), @@ -1403,6 +1537,14 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v7 = { .rx = 0x1000, }; +static const struct qmp_usb_offsets qmp_usb_offsets_v8 = { + .serdes = 0, + .pcs = 0x0400, + .pcs_usb = 0x1200, + .tx = 0x0e00, + .rx = 0x1000, +}; + static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = { .offsets = &qmp_usb_offsets_v3, @@ -1704,6 +1846,24 @@ static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = { .regs = qmp_v7_usb3phy_regs_layout, }; +static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = { + .offsets = &qmp_usb_offsets_v8, + + .serdes_tbl = glymur_usb3_uniphy_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_serdes_tbl), + .tx_tbl = glymur_usb3_uniphy_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_tx_tbl), + .rx_tbl = glymur_usb3_uniphy_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_rx_tbl), + .pcs_tbl = glymur_usb3_uniphy_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_tbl), + .pcs_usb_tbl = glymur_usb3_uniphy_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_usb_tbl), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = qmp_v7_usb3phy_regs_layout, +}; + static int qmp_usb_serdes_init(struct qmp_usb *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -2302,6 +2462,9 @@ static int qmp_usb_probe(struct platform_device *pdev) static const struct of_device_id qmp_usb_of_match_table[] = { { + .compatible = "qcom,glymur-qmp-usb3-uni-phy", + .data = &glymur_usb3_uniphy_cfg, + }, { .compatible = "qcom,ipq5424-qmp-usb3-phy", .data = &ipq9574_usb3phy_cfg, }, { From 056be26d5724cf0cc105800f208eb4da6d7ffda5 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Dec 2025 14:53:13 -0800 Subject: [PATCH 606/659] FROMLIST: phy: qualcomm: Update the QMP clamp register for V6 QMP combo phy V6 and above use the clamp register from the PCS always on (AON) address space. Update the driver accordingly. Reviewed-by: Dmitry Baryshkov Signed-off-by: Elson Roy Serrao Signed-off-by: Wesley Cheng Reviewed-by: Abel Vesa Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-7-42133596bda0@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 38 ++++++++++++++++--- .../phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h | 12 ++++++ .../phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h | 12 ++++++ 3 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 9e2a6c5d0f586..59a8c6a535eeb 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -30,7 +30,10 @@ #include "phy-qcom-qmp-common.h" #include "phy-qcom-qmp.h" +#include "phy-qcom-qmp-pcs-aon-v6.h" #include "phy-qcom-qmp-pcs-misc-v3.h" +#include "phy-qcom-qmp-pcs-misc-v4.h" +#include "phy-qcom-qmp-pcs-misc-v5.h" #include "phy-qcom-qmp-pcs-usb-v4.h" #include "phy-qcom-qmp-pcs-usb-v5.h" #include "phy-qcom-qmp-pcs-usb-v6.h" @@ -79,6 +82,7 @@ enum qphy_reg_layout { QPHY_PCS_AUTONOMOUS_MODE_CTRL, QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, QPHY_PCS_POWER_DOWN_CONTROL, + QPHY_PCS_CLAMP_ENABLE, QPHY_COM_RESETSM_CNTRL, QPHY_COM_C_READY_STATUS, @@ -106,6 +110,8 @@ static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V3_PCS_MISC_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V3_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V3_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V3_COM_CMN_STATUS, @@ -131,6 +137,8 @@ static const unsigned int qmp_v45_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V4_PCS_MISC_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V4_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V4_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V4_COM_CMN_STATUS, @@ -156,6 +164,8 @@ static const unsigned int qmp_v5_5nm_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V5_PCS_MISC_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V5_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V5_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V5_COM_CMN_STATUS, @@ -181,6 +191,8 @@ static const unsigned int qmp_v6_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, @@ -206,6 +218,8 @@ static const unsigned int qmp_v6_n4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, @@ -1771,6 +1785,7 @@ struct qmp_combo_offsets { u16 usb3_serdes; u16 usb3_pcs_misc; u16 usb3_pcs; + u16 usb3_pcs_aon; u16 usb3_pcs_usb; u16 dp_serdes; u16 dp_txa; @@ -1852,6 +1867,7 @@ struct qmp_combo { void __iomem *tx2; void __iomem *rx2; void __iomem *pcs_misc; + void __iomem *pcs_aon; void __iomem *pcs_usb; void __iomem *dp_serdes; @@ -1976,6 +1992,7 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = { .usb3_serdes = 0x1000, .usb3_pcs_misc = 0x1c00, .usb3_pcs = 0x1e00, + .usb3_pcs_aon = 0x2000, .usb3_pcs_usb = 0x2100, .dp_serdes = 0x3000, .dp_txa = 0x3400, @@ -3361,6 +3378,7 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp) const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; void __iomem *pcs_misc = qmp->pcs_misc; + void __iomem *pcs_aon = qmp->pcs_aon; u32 intr_mask; if (qmp->phy_mode == PHY_MODE_USB_HOST_SS || @@ -3380,9 +3398,14 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp) /* Enable required PHY autonomous mode interrupts */ qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask); - /* Enable i/o clamp_n for autonomous mode */ - if (pcs_misc) - qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); + /* + * Enable i/o clamp_n for autonomous mode + * V6 and later versions use pcs aon clamp register + */ + if (pcs_aon) + qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); + else if (pcs_misc) + qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); } static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp) @@ -3390,10 +3413,13 @@ static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp) const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; void __iomem *pcs_misc = qmp->pcs_misc; + void __iomem *pcs_aon = qmp->pcs_aon; /* Disable i/o clamp_n on resume for normal mode */ - if (pcs_misc) - qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); + if (pcs_aon) + qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); + else if (pcs_misc) + qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN); @@ -4058,6 +4084,8 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp) qmp->serdes = base + offs->usb3_serdes; qmp->pcs_misc = base + offs->usb3_pcs_misc; qmp->pcs = base + offs->usb3_pcs; + if (offs->usb3_pcs_aon) + qmp->pcs_aon = base + offs->usb3_pcs_aon; qmp->pcs_usb = base + offs->usb3_pcs_usb; qmp->dp_serdes = base + offs->dp_serdes; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h new file mode 100644 index 0000000000000..52db31a7cf22e --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_AON_V6_H_ +#define QCOM_PHY_QMP_PCS_AON_V6_H_ + +/* Only for QMP V6 PHY - PCS_AON registers */ +#define QPHY_V6_PCS_AON_CLAMP_ENABLE 0x00 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h new file mode 100644 index 0000000000000..77d04c6a1644c --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_MISC_V5_H_ +#define QCOM_PHY_QMP_PCS_MISC_V5_H_ + +/* Only for QMP V5 PHY - PCS_MISC registers */ +#define QPHY_V5_PCS_MISC_CLAMP_ENABLE 0x0c + +#endif From 18c585be02273d71df12f1c97fd3b59d0aae6a2f Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Dec 2025 14:53:14 -0800 Subject: [PATCH 607/659] FROMLIST: phy: qualcomm: qmp-combo: Update QMP PHY with Glymur settings For SuperSpeed USB to work properly, there is a set of HW settings that need to be programmed into the USB blocks within the QMP PHY. Ensure that these settings follow the latest settings mentioned in the HW programming guide. The QMP USB PHY on Glymur is a USB43 based PHY that will have some new ways to define certain registers, such as the replacement of TXA/RXA and TXB/RXB register sets. This was replaced with the LALB register set. There are also some PHY init updates to modify the PCS MISC register space. Without these, the QMP PHY PLL locking fails. Reviewed-by: Dmitry Baryshkov Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-8-42133596bda0@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 285 ++++++++ .../phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h | 17 + .../phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h | 12 + .../qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h | 639 ++++++++++++++++++ .../phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h | 33 + .../phy-qcom-qmp-usb43-qserdes-com-v8.h | 224 ++++++ drivers/phy/qualcomm/phy-qcom-qmp.h | 2 + 7 files changed, 1212 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 59a8c6a535eeb..32a3f3a4ab05f 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -31,9 +31,11 @@ #include "phy-qcom-qmp.h" #include "phy-qcom-qmp-pcs-aon-v6.h" +#include "phy-qcom-qmp-pcs-aon-v8.h" #include "phy-qcom-qmp-pcs-misc-v3.h" #include "phy-qcom-qmp-pcs-misc-v4.h" #include "phy-qcom-qmp-pcs-misc-v5.h" +#include "phy-qcom-qmp-pcs-misc-v8.h" #include "phy-qcom-qmp-pcs-usb-v4.h" #include "phy-qcom-qmp-pcs-usb-v5.h" #include "phy-qcom-qmp-pcs-usb-v6.h" @@ -47,6 +49,8 @@ #include "phy-qcom-qmp-dp-phy-v5.h" #include "phy-qcom-qmp-dp-phy-v6.h" +#include "phy-qcom-qmp-usb43-pcs-v8.h" + /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */ /* DP PHY soft reset */ #define SW_DPPHY_RESET BIT(0) @@ -98,6 +102,7 @@ enum qphy_reg_layout { QPHY_TX_HIGHZ_DRVR_EN, QPHY_TX_TRANSCEIVER_BIAS_EN, + QPHY_AON_TOGGLE_ENABLE, /* Keep last to ensure regs_layout arrays are properly initialized */ QPHY_LAYOUT_SIZE }; @@ -260,6 +265,233 @@ static const unsigned int qmp_v8_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_TX_TRANSCEIVER_BIAS_EN, }; +static const unsigned int qmp_v8_n3_usb43dpphy_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V8_USB43_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V8_USB43_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V8_USB43_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL, + + /* In PCS_USB */ + [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V8_PCS_USB_AUTONOMOUS_MODE_CTRL, + [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V8_PCS_USB_LFPS_RXTERM_IRQ_CLEAR, + + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE, + [QPHY_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE, + + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V8_COM_RESETSM_CNTRL, + [QPHY_COM_C_READY_STATUS] = QSERDES_V8_COM_C_READY_STATUS, + [QPHY_COM_CMN_STATUS] = QSERDES_V8_COM_CMN_STATUS, + [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, + + [QPHY_TX_TX_DRV_LVL] = QSERDES_V8_LALB_TX0_DRV_LVL, + [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V8_LALB_TX0_EMP_POST1_LVL, + [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V8_LALB_HIGHZ_DRVR_EN, + [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1, 0xe1), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1, 0x4d), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x95), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0xe1), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0x4d), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO_MODE1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x76), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x33), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xaf), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1, 0x01), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1, 0xc4), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2, 0x89), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3, 0x20), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6, 0x13), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1, 0x21), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_SIGDET_LVL, 0x55), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME, 0xa4), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_CONFIG, 0x0a), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_DLY_TIME, 0x04), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1, 0xd4), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2, 0x30), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG, 0x0c), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG1, 0x4b), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG5, 0x10), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_usb_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_lalb_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x81), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4, 0x8D), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_4, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1, 0xa2), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2, 0x6e), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3, 0x51), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7, 0x2a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B0, 0x4c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B1, 0xc4), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B2, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B3, 0x64), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B4, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B5, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B6, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B7, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_0_1, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_2_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2, 0x22), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3, 0x22), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2, 0x85), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3, 0x45), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_ENABLES, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CNTRL, 0xa3), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_LVL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_TRIM, 0x66), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2, 0x32), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01, 0x76), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23, 0x67), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1, 0x33), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3, 0x43), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3, 0x51), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123, 0xe5), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123, 0xf5), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL, 0xd0), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_EN, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE0_1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE2_3, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_AUX_CLK_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_EOM_CTRL1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2, 0x77), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1, 0xdd), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123, 0x1C), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DIG_BKUP_CTRL16, 0x37), +}; + static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), @@ -1663,6 +1895,12 @@ static struct regulator_bulk_data qmp_phy_vreg_l[] = { { .supply = "vdda-pll", .init_load_uA = 36000, }, }; +static struct regulator_bulk_data qmp_phy_vreg_refgen[] = { + { .supply = "vdda-phy", .init_load_uA = 21800 }, + { .supply = "vdda-pll", .init_load_uA = 36000 }, + { .supply = "refgen", .init_load_uA = 3270 }, +}; + static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = { { 0x00, 0x0c, 0x15, 0x1a }, { 0x02, 0x0e, 0x16, 0xff }, @@ -1807,6 +2045,8 @@ struct qmp_phy_cfg { int pcs_tbl_num; const struct qmp_phy_init_tbl *pcs_usb_tbl; int pcs_usb_tbl_num; + const struct qmp_phy_init_tbl *pcs_misc_tbl; + int pcs_misc_tbl_num; const struct qmp_phy_init_tbl *dp_serdes_tbl; int dp_serdes_tbl_num; @@ -2000,6 +2240,19 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = { .dp_dp_phy = 0x3c00, }; +static const struct qmp_combo_offsets qmp_combo_usb43dp_offsets_v8 = { + .com = 0x0000, + .usb3_pcs_aon = 0x0100, + .usb3_serdes = 0x1000, + .usb3_pcs_misc = 0x1400, + .usb3_pcs = 0x1600, + .usb3_pcs_usb = 0x1900, + .dp_serdes = 0x2000, + .dp_dp_phy = 0x2400, + .txa = 0x4000, + .txb = 0x5000, +}; + static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = { .offsets = &qmp_combo_offsets_v3, @@ -2544,6 +2797,27 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = { .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), }; +static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = { + .offsets = &qmp_combo_usb43dp_offsets_v8, + + .serdes_tbl = glymur_usb43dp_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(glymur_usb43dp_serdes_tbl), + .tx_tbl = glymur_usb43dp_lalb_tbl, + .tx_tbl_num = ARRAY_SIZE(glymur_usb43dp_lalb_tbl), + .pcs_tbl = glymur_usb43dp_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_tbl), + .pcs_usb_tbl = glymur_usb43dp_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_usb_tbl), + .pcs_misc_tbl = glymur_usb43dp_pcs_misc_tbl, + .pcs_misc_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_misc_tbl), + + .regs = qmp_v8_n3_usb43dpphy_regs_layout, + .reset_list = msm8996_usb3phy_reset_l, + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), + .vreg_list = qmp_phy_vreg_refgen, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_refgen), +}; + static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -3040,6 +3314,7 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) { const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *com = qmp->com; + void __iomem *pcs_aon = qmp->pcs_aon; int ret; u32 val; @@ -3075,6 +3350,10 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); + /* override hardware control for reset of qmp phy */ + if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) + qphy_clrbits(pcs_aon, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1); + /* Use software based port select and switch on typec orientation */ val = SW_PORTSELECT_MUX; if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) @@ -3252,6 +3531,8 @@ static int qmp_combo_usb_power_on(struct phy *phy) qmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); + qmp_configure(qmp->dev, qmp->pcs_misc, cfg->pcs_misc_tbl, cfg->pcs_misc_tbl_num); + if (pcs_usb) qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl, @@ -4347,6 +4628,10 @@ static int qmp_combo_probe(struct platform_device *pdev) } static const struct of_device_id qmp_combo_of_match_table[] = { + { + .compatible = "qcom,glymur-qmp-usb3-dp-phy", + .data = &glymur_usb3dpphy_cfg, + }, { .compatible = "qcom,sar2130p-qmp-usb3-dp-phy", .data = &sar2130p_usb3dpphy_cfg, diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h new file mode 100644 index 0000000000000..f6a275c0938ff --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_AON_V8_H_ +#define QCOM_PHY_QMP_PCS_AON_V8_H_ + +/* Only for QMP V8 PHY - PCS_AON registers */ +#define QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE 0x00 +#define QPHY_V8_PCS_AON_USB4_AON_CLAMP_ENABLE 0x04 +#define QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE 0x08 +#define QPHY_V8_PCS_AON_USB4_AON_TOGGLE_ENABLE 0x0c +#define QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE 0x10 +#define QPHY_V8_PCS_AON_DUMMY_STATUS 0x14 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h new file mode 100644 index 0000000000000..a93ef2faa894a --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_MISC_V8_H_ +#define QCOM_PHY_QMP_PCS_MISC_V8_H_ + +/* Only for QMP V8 PHY - PCS_MISC registers */ +#define QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1 0x08 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h new file mode 100644 index 0000000000000..60ba730620f82 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h @@ -0,0 +1,639 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_V8_LALBH_ +#define QCOM_PHY_QMP_QSERDES_V8_LALBH_ + +#define QSERDES_V8_LALB_BIST_MODE_LANENO 0x0 +#define QSERDES_V8_LALB_BIST_INVERT 0x4 +#define QSERDES_V8_LALB_PERL_LENGTH1 0x8 +#define QSERDES_V8_LALB_PERL_LENGTH2 0xc +#define QSERDES_V8_LALB_BIST_PATTERN1 0x10 +#define QSERDES_V8_LALB_BIST_PATTERN2 0x14 +#define QSERDES_V8_LALB_BIST_PATTERN3 0x18 +#define QSERDES_V8_LALB_BIST_PATTERN4 0x1c +#define QSERDES_V8_LALB_BIST_PATTERN5 0x20 +#define QSERDES_V8_LALB_BIST_PATTERN6 0x24 +#define QSERDES_V8_LALB_BIST_PATTERN7 0x28 +#define QSERDES_V8_LALB_BIST_PATTERN8 0x2c +#define QSERDES_V8_LALB_PRBS_SEED1 0x30 +#define QSERDES_V8_LALB_PRBS_SEED2 0x34 +#define QSERDES_V8_LALB_PRBS_SEED3 0x38 +#define QSERDES_V8_LALB_PRBS_SEED4 0x3c +#define QSERDES_V8_LALB_PRBS_SEED5 0x40 +#define QSERDES_V8_LALB_PRBS_SEED6 0x44 +#define QSERDES_V8_LALB_PRBS_SEED7 0x48 +#define QSERDES_V8_LALB_SW_RESET_PWRDNB 0x4c +#define QSERDES_V8_LALB_RESET_GEN 0x50 +#define QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL 0x54 +#define QSERDES_V8_LALB_CDR_EN_RXEQ_RESET 0x58 +#define QSERDES_V8_LALB_CLKBUF_ENABLE 0x5c +#define QSERDES_V8_LALB_TX0_EMP_POST1_LVL 0x60 +#define QSERDES_V8_LALB_TX1_EMP_POST1_LVL 0x64 +#define QSERDES_V8_LALB_TX0_IDLE_CTRL 0x68 +#define QSERDES_V8_LALB_TX1_IDLE_CTRL 0x6c +#define QSERDES_V8_LALB_TX0_DRV_LVL 0x70 +#define QSERDES_V8_LALB_TX0_DRV_LVL_OFFSET 0x74 +#define QSERDES_V8_LALB_TX1_DRV_LVL 0x78 +#define QSERDES_V8_LALB_TX1_DRV_LVL_OFFSET 0x7c +#define QSERDES_V8_LALB_TRAN_DRVR_EMP_EN 0x80 +#define QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL 0x84 +#define QSERDES_V8_LALB_TX0_PRE1_EMPH 0x88 +#define QSERDES_V8_LALB_TX1_PRE1_EMPH 0x8c +#define QSERDES_V8_LALB_TX0_PRE2_EMPH 0x90 +#define QSERDES_V8_LALB_TX1_PRE2_EMPH 0x94 +#define QSERDES_V8_LALB_STALL_LDO_BOOST_EN 0x98 +#define QSERDES_V8_LALB_PRE_EMPH_EN_CTRL 0x9c +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1 0xa0 +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2 0xa4 +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3 0xa8 +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4 0xac +#define QSERDES_V8_LALB_TRANSMITTER_EN_CTRL 0xb0 +#define QSERDES_V8_LALB_HIGHZ_DRVR_EN 0xb4 +#define QSERDES_V8_LALB_TX_MISC_CTRL1 0xb8 +#define QSERDES_V8_LALB_LPB_EN_CTRL1 0xbc +#define QSERDES_V8_LALB_LBP_EN_CTRL2 0xc0 +#define QSERDES_V8_LALB_TX0_SERDES_BYP_CTRL 0xc4 +#define QSERDES_V8_LALB_TX1_SERDES_BYP_CTRL 0xc8 +#define QSERDES_V8_LALB_LANE_MODE_1 0xcc +#define QSERDES_V8_LALB_LANE_MODE_2 0xd0 +#define QSERDES_V8_LALB_LANE_MODE_3 0xd4 +#define QSERDES_V8_LALB_LANE_MODE_4 0xd8 +#define QSERDES_V8_LALB_ATB_SEL1 0xdc +#define QSERDES_V8_LALB_ATB_SEL2 0xe0 +#define QSERDES_V8_LALB_TX0_RES_CODE_LANE 0xe4 +#define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_OVRD 0xe8 +#define QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL 0xec +#define QSERDES_V8_LALB_TX0_RESTRIM_INIT_CODE 0xf0 +#define QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET 0xf4 +#define QSERDES_V8_LALB_TX1_RES_CODE_LANE 0xf8 +#define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_OVRD 0xfc +#define QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL 0x100 +#define QSERDES_V8_LALB_TX1_RESTRIM_INIT_CODE 0x104 +#define QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET 0x108 +#define QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL 0x10c +#define QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL 0x110 +#define QSERDES_V8_LALB_VMODE_CTRL1 0x114 +#define QSERDES_V8_LALB_SLEW_CNTL_RATE01 0x118 +#define QSERDES_V8_LALB_SLEW_CNTL_RATE23 0x11c +#define QSERDES_V8_LALB_SLEW_CNTL_RATE4 0x120 +#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT1 0x124 +#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT2 0x128 +#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT3 0x12c +#define QSERDES_V8_LALB_PCS_INTERFACE_SELECT1 0x130 +#define QSERDES_V8_LALB_PCS_INTERFACE_SELECT2 0x134 +#define QSERDES_V8_LALB_LDO_TIMER_CTRL 0x138 +#define QSERDES_V8_LALB_AC_JTAG_ENABLE 0x13c +#define QSERDES_V8_LALB_AC_JTAG_INITP 0x140 +#define QSERDES_V8_LALB_AC_JTAG_INITN 0x144 +#define QSERDES_V8_LALB_AC_JTAG_LVL 0x148 +#define QSERDES_V8_LALB_AC_JTAG_MODE 0x14c +#define QSERDES_V8_LALB_AC_JTAG_RESET 0x150 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0 0x154 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1 0x158 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2 0x15c +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3 0x160 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4 0x164 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5 0x168 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6 0x16c +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7 0x170 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B0 0x174 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B1 0x178 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B2 0x17c +#define QSERDES_V8_LALB_RX_MODE_RATE2_B3 0x180 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B4 0x184 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B5 0x188 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B6 0x18c +#define QSERDES_V8_LALB_RX_MODE_RATE2_B7 0x190 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B0 0x194 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B1 0x198 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B2 0x19c +#define QSERDES_V8_LALB_RX_MODE_RATE3_B3 0x1a0 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B4 0x1a4 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B5 0x1a8 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B6 0x1ac +#define QSERDES_V8_LALB_RX_MODE_RATE3_B7 0x1b0 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B0 0x1b4 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B1 0x1b8 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B2 0x1bc +#define QSERDES_V8_LALB_RX_MODE_RATE4_B3 0x1c0 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B4 0x1c4 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B5 0x1c8 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B6 0x1cc +#define QSERDES_V8_LALB_RX_MODE_RATE4_B7 0x1d0 +#define QSERDES_V8_LALB_TX_DCC_ANA_CTRL1 0x1d4 +#define QSERDES_V8_LALB_TX_DCC_ANA_CTRL2 0x1d8 +#define QSERDES_V8_LALB_CMUX_DCC_CTRL1 0x1dc +#define QSERDES_V8_LALB_CMUX_DCC_POSTCAL_OFFSET 0x1e0 +#define QSERDES_V8_LALB_CMUX_DCC_OVRD 0x1e4 +#define QSERDES_V8_LALB_TX_DCC_CTRL 0x1e8 +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_CONFIG 0x1ec +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_POSTCAL_OFFSET 0x1f0 +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_OVRD 0x1f4 +#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_CONFIG 0x1f8 +#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x1fc +#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_CONFIG 0x200 +#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x204 +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_CONFIG 0x208 +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_POSTCAL_OFFSET 0x20c +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_OVRD 0x210 +#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_CONFIG 0x214 +#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x218 +#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_CONFIG 0x21c +#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x220 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CTRL 0x224 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE0 0x228 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE1 0x22c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE2 0x230 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE3 0x234 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE4 0x238 +#define QSERDES_V8_LALB_CDR_VCO_CAL_CTRL 0x23c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE0 0x240 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE0 0x244 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1 0x248 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1 0x24c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2 0x250 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2 0x254 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE3 0x258 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE3 0x25c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE4 0x260 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE4 0x264 +#define QSERDES_V8_LALB_CDR_VCTRL_RATE_0_1 0x268 +#define QSERDES_V8_LALB_CDR_VCTRL_RATE_2_3 0x26c +#define QSERDES_V8_LALB_CDR_VCTRL_RATE_4 0x270 +#define QSERDES_V8_LALB_KVCO_INIT_RATE_0_1 0x274 +#define QSERDES_V8_LALB_KVCO_INIT_RATE_2_3 0x278 +#define QSERDES_V8_LALB_KVCO_INIT_RATE_4 0x27c +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE0 0x280 +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1 0x284 +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2 0x288 +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE3 0x28c +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE4 0x290 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_0_1 0x294 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_2_3 0x298 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_4 0x29c +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_0_1 0x2a0 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_2_3 0x2a4 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_4 0x2a8 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE0 0x2ac +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE0 0x2b0 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1 0x2b4 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1 0x2b8 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2 0x2bc +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2 0x2c0 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE3 0x2c4 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE3 0x2c8 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE4 0x2cc +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE4 0x2d0 +#define QSERDES_V8_LALB_KP_CDR_UP_DN 0x2d4 +#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_0_1 0x2d8 +#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3 0x2dc +#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE4 0x2e0 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE0 0x2e4 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE0 0x2e8 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1 0x2ec +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1 0x2f0 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2 0x2f4 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2 0x2f8 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE3 0x2fc +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE3 0x300 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE4 0x304 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE4 0x308 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE0 0x30c +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1 0x310 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2 0x314 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE3 0x318 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE4 0x31c +#define QSERDES_V8_LALB_CDR_KVCO_KP_CAL_FREQ_MEAS_CTRL 0x320 +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CTRL 0x324 +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT1 0x328 +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT2 0x32c +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT3 0x330 +#define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123 0x334 +#define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_4 0x338 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE0 0x33c +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1 0x340 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2 0x344 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE3 0x348 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE4 0x34c +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL1 0x350 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2 0x354 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3 0x358 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL4 0x35c +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE0 0x360 +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1 0x364 +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2 0x368 +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE3 0x36c +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE4 0x370 +#define QSERDES_V8_LALB_RX_IDAC_I0_DC_OFFSETS 0x374 +#define QSERDES_V8_LALB_RX_IDAC_I0BAR_DC_OFFSETS 0x378 +#define QSERDES_V8_LALB_RX_IDAC_I1_DC_OFFSETS 0x37c +#define QSERDES_V8_LALB_RX_IDAC_I1BAR_DC_OFFSETS 0x380 +#define QSERDES_V8_LALB_RX_IDAC_Q_DC_OFFSETS 0x384 +#define QSERDES_V8_LALB_RX_IDAC_QBAR_DC_OFFSETS 0x388 +#define QSERDES_V8_LALB_RX_IDAC_A_DC_OFFSETS 0x38c +#define QSERDES_V8_LALB_RX_IDAC_ABAR_DC_OFFSETS 0x390 +#define QSERDES_V8_LALB_RX_IDAC_EN 0x394 +#define QSERDES_V8_LALB_DATA_SLICER_INIT_TIMER_CTRL 0x398 +#define QSERDES_V8_LALB_RX_IDAC_ENABLES 0x39c +#define QSERDES_V8_LALB_RX_IDAC_SIGN 0x3a0 +#define QSERDES_V8_LALB_RX_IDAC_TSETTLE 0x3a4 +#define QSERDES_V8_LALB_SIGDET_ENABLES 0x3a8 +#define QSERDES_V8_LALB_SIGDET_CNTRL 0x3ac +#define QSERDES_V8_LALB_SIGDET_LVL 0x3b0 +#define QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL 0x3b4 +#define QSERDES_V8_LALB_SIGDET_CAL_CTRL1 0x3b8 +#define QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE 0x3bc +#define QSERDES_V8_LALB_SIGDET_CAL_TRIM 0x3c0 +#define QSERDES_V8_LALB_IA_OFFSET_CENTER_CAL_CTRL 0x3c4 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE0 0x3c8 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1 0x3cc +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2 0x3d0 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE3 0x3d4 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE4 0x3d8 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE0 0x3dc +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE1 0x3e0 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE2 0x3e4 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE3 0x3e8 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE4 0x3ec +#define QSERDES_V8_LALB_CDR_LOCK_CTRL 0x3f0 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE0 0x3f4 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1 0x3f8 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2 0x3fc +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE3 0x400 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE4 0x404 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE0 0x408 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1 0x40c +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2 0x410 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE3 0x414 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE4 0x418 +#define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123 0x41c +#define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE4 0x420 +#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01 0x424 +#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23 0x428 +#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE4 0x42c +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1 0x430 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3 0x434 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE4 0x438 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1 0x43c +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3 0x440 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE4 0x444 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1 0x448 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3 0x44c +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE4 0x450 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123 0x454 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE4 0x458 +#define QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG 0x45c +#define QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ 0x460 +#define QSERDES_V8_LALB_CDR_FAST_SLOW_VCO_OVRD 0x464 +#define QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL 0x468 +#define QSERDES_V8_LALB_CDR_FAST_LOCK_EN_CTRL 0x46c +#define QSERDES_V8_LALB_RX_RCVR_EN 0x470 +#define QSERDES_V8_LALB_LANE_RATE_CTRL 0x474 +#define QSERDES_V8_LALB_RX_TERM_RCVR_CTRL 0x478 +#define QSERDES_V8_LALB_REC_DETECT_CTRL 0x47c +#define QSERDES_V8_LALB_RCV_DETECT_LVL 0x480 +#define QSERDES_V8_LALB_GM_CAL_EN 0x484 +#define QSERDES_V8_LALB_GM_CAL_RES_RATE0_1 0x488 +#define QSERDES_V8_LALB_GM_CAL_RES_RATE2_3 0x48c +#define QSERDES_V8_LALB_GM_CAL_RES_RATE4 0x490 +#define QSERDES_V8_LALB_RX_TERM_BW_RATE_0123 0x494 +#define QSERDES_V8_LALB_RX_TERM_BW_RATE4 0x498 +#define QSERDES_V8_LALB_AUX_CLK_CTRL 0x49c +#define QSERDES_V8_LALB_AUX_OFFSET_CONTROL 0x4a0 +#define QSERDES_V8_LALB_AUXDATA_TB 0x4a4 +#define QSERDES_V8_LALB_EOM_CTRL1 0x4a8 +#define QSERDES_V8_LALB_EOM_CTRL2 0x4ac +#define QSERDES_V8_LALB_EOM_CTRL3 0x4b0 +#define QSERDES_V8_LALB_EOM_CTRL4 0x4b4 +#define QSERDES_V8_LALB_DFE_EN_TIMER 0x4b8 +#define QSERDES_V8_LALB_RX_EQ_OFFSET_LSB 0x4bc +#define QSERDES_V8_LALB_RX_EQ_OFFSET_MSB 0x4c0 +#define QSERDES_V8_LALB_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x4c4 +#define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL2 0x4c8 +#define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL3 0x4cc +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL1 0x4d0 +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2 0x4d4 +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3 0x4d8 +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4 0x4dc +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL5 0x4e0 +#define QSERDES_V8_LALB_RX_EQU_KEQ_UP_LSB 0x4e4 +#define QSERDES_V8_LALB_RX_EQU_KEQ_UP_MSB 0x4e8 +#define QSERDES_V8_LALB_RX_EQU_KEQ_DN_LSB 0x4ec +#define QSERDES_V8_LALB_RX_EQU_KEQ_DN_MSB 0x4f0 +#define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_0_1_2 0x4f4 +#define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_3_4 0x4f8 +#define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2 0x4fc +#define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_3_4 0x500 +#define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK1 0x504 +#define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK2 0x508 +#define QSERDES_V8_LALB_VGA_CAL_CNTRL1 0x50c +#define QSERDES_V8_LALB_VGA_CAL_CNTRL2 0x510 +#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1 0x514 +#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3 0x518 +#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE4 0x51c +#define QSERDES_V8_LALB_KVGA_CTRL1 0x520 +#define QSERDES_V8_LALB_KVGA_CTRL2 0x524 +#define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL1 0x528 +#define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL2 0x52c +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE0 0x530 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE1 0x534 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE2 0x538 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE3 0x53c +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE4 0x540 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_CAL_PAM3 0x544 +#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_0_1 0x548 +#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_2_3 0x54c +#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE4 0x550 +#define QSERDES_V8_LALB_DFE_TAP1_CTRL 0x554 +#define QSERDES_V8_LALB_DFE_TAP1_MANVAL_KTAP 0x558 +#define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_0_1_2 0x55c +#define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_3_4 0x560 +#define QSERDES_V8_LALB_DFE_TAP2_CTRL 0x564 +#define QSERDES_V8_LALB_DFE_TAP2_MANVAL_KTAP 0x568 +#define QSERDES_V8_LALB_DFE_TAP3_CTRL 0x56c +#define QSERDES_V8_LALB_DFE_TAP3_MANVAL_KTAP 0x570 +#define QSERDES_V8_LALB_DFE_TAP4_CTRL 0x574 +#define QSERDES_V8_LALB_DFE_TAP4_MANVAL_KTAP 0x578 +#define QSERDES_V8_LALB_DFE_TAP5_CTRL 0x57c +#define QSERDES_V8_LALB_DFE_TAP5_MANVAL_KTAP 0x580 +#define QSERDES_V8_LALB_DFE_TAP6_CTRL 0x584 +#define QSERDES_V8_LALB_DFE_TAP6_MANVAL_KTAP 0x588 +#define QSERDES_V8_LALB_DFE_TAP7_CTRL 0x58c +#define QSERDES_V8_LALB_DFE_TAP7_MANVAL_KTAP 0x590 +#define QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE 0x594 +#define QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE 0x598 +#define QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE 0x59c +#define QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE 0x5a0 +#define QSERDES_V8_LALB_CDR_IQTUNE_CTRL 0x5a4 +#define QSERDES_V8_LALB_CDR_IQTUNE_GAIN 0x5a8 +#define QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX 0x5ac +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL1 0x5b0 +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL2 0x5b4 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE0 0x5b8 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE1 0x5bc +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE2 0x5c0 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE3 0x5c4 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE4 0x5c8 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE0 0x5cc +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE1 0x5d0 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE2 0x5d4 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE3 0x5d8 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE4 0x5dc +#define QSERDES_V8_LALB_CDR_IQTUNE_ANA_CTRL 0x5e0 +#define QSERDES_V8_LALB_CDR_IQTUNE_VDCC_CTRL 0x5e4 +#define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123 0x5e8 +#define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE4 0x5ec +#define QSERDES_V8_LALB_BLW_CTRL 0x5f0 +#define QSERDES_V8_LALB_BLW_ANA_VER_CTRL 0x5f4 +#define QSERDES_V8_LALB_BLW_GAIN_CAL_CTRL 0x5f8 +#define QSERDES_V8_LALB_BLW_GAIN_FORCE_CODE 0x5fc +#define QSERDES_V8_LALB_BLW_MAN_VAL_RATE3 0x600 +#define QSERDES_V8_LALB_BLW_MAN_VAL_RATE4 0x604 +#define QSERDES_V8_LALB_IVTH_CAL_CTRL1 0x608 +#define QSERDES_V8_LALB_IVTH_CAL_CTRL2 0x60c +#define QSERDES_V8_LALB_IVTH_CAL_CTRL3 0x610 +#define QSERDES_V8_LALB_VTH_I_UP_CNTRL_VAL 0x614 +#define QSERDES_V8_LALB_VTH_I_DN_CNTRL_VAL 0x618 +#define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_VAL 0x61c +#define QSERDES_V8_LALB_IVTH_CAL_VAL_OVRD_MUX 0x620 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES 0x624 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE0 0x628 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE1 0x62c +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE2 0x630 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE3 0x634 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE4 0x638 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE0 0x63c +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE1 0x640 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE2 0x644 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE3 0x648 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE4 0x64c +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE0 0x650 +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE1 0x654 +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE2 0x658 +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE3 0x65c +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE4 0x660 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE0 0x664 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE1 0x668 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE2 0x66c +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE3 0x670 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE4 0x674 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE0 0x678 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE1 0x67c +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE2 0x680 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE3 0x684 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE4 0x688 +#define QSERDES_V8_LALB_DEBUG_BUS_SEL 0x68c +#define QSERDES_V8_LALB_BIST_STATUS 0x690 +#define QSERDES_V8_LALB_BIST_ERROR_COUNT1 0x694 +#define QSERDES_V8_LALB_BIST_ERROR_COUNT2 0x698 +#define QSERDES_V8_LALB_AC_JTAG_OUTP 0x69c +#define QSERDES_V8_LALB_AC_JTAG_OUTN 0x6a0 +#define QSERDES_V8_LALB_DATA_SLICER_DEBUG_STATUS 0x6a4 +#define QSERDES_V8_LALB_DATA_SLICER_TIMER1_STATUS 0x6a8 +#define QSERDES_V8_LALB_DATA_SLICER_TIMER2_STATUS 0x6ac +#define QSERDES_V8_LALB_TX0_RESTRIM_CODE_STATUS 0x6b0 +#define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_CODE_STATUS 0x6b4 +#define QSERDES_V8_LALB_TX0_RESTRIM_CAL_STATUS 0x6b8 +#define QSERDES_V8_LALB_TX1_RESTRIM_CODE_STATUS 0x6bc +#define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_CODE_STATUS 0x6c0 +#define QSERDES_V8_LALB_TX1_RESTRIM_CAL_STATUS 0x6c4 +#define QSERDES_V8_LALB_CMUX_DCC_CAL_FSM_STATUS 0x6c8 +#define QSERDES_V8_LALB_CMUX_DCC_READCODE_STATUS 0x6cc +#define QSERDES_V8_LALB_TX_DCC_CAL_ANA_STATUS 0x6d0 +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_FSM_DEBUG_STATUS 0x6d4 +#define QSERDES_V8_LALB_TX0_COARSE_DCC_READCODE_STATUS 0x6d8 +#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6dc +#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6e0 +#define QSERDES_V8_LALB_TX0_FINE_DCC_READCODE_STATUS 0x6e4 +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_FSM_DEBUG_STATUS 0x6e8 +#define QSERDES_V8_LALB_TX1_COARSE_DCC_READCODE_STATUS 0x6ec +#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6f0 +#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6f4 +#define QSERDES_V8_LALB_TX1_FINE_DCC_READCODE_STATUS 0x6f8 +#define QSERDES_V8_LALB_CDR_VCO_CAL_STATUS 0x6fc +#define QSERDES_V8_LALB_CDR_VCTRL_STATUS 0x700 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_STATUS 0x704 +#define QSERDES_V8_LALB_KVCO_CAL_DEBUG1_STATUS 0x708 +#define QSERDES_V8_LALB_KVCO_CAL_DEBUG2_STATUS 0x70c +#define QSERDES_V8_LALB_KP_CAL_DEBUG1_STATUS 0x710 +#define QSERDES_V8_LALB_KP_CAL_DEBUG2_STATUS 0x714 +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG1_STATUS 0x718 +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG2_STATUS 0x71c +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG3_STATUS 0x720 +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG4_STATUS 0x724 +#define QSERDES_V8_LALB_IVCM_CAL_STATUS 0x728 +#define QSERDES_V8_LALB_IVCM_CAL_DEBUG_STATUS 0x72c +#define QSERDES_V8_LALB_IDAC_STATUS_I0 0x730 +#define QSERDES_V8_LALB_IDAC_STATUS_I0BAR 0x734 +#define QSERDES_V8_LALB_IDAC_STATUS_I1 0x738 +#define QSERDES_V8_LALB_IDAC_STATUS_I1BAR 0x73c +#define QSERDES_V8_LALB_IDAC_STATUS_Q 0x740 +#define QSERDES_V8_LALB_IDAC_STATUS_QBAR 0x744 +#define QSERDES_V8_LALB_IDAC_STATUS_A 0x748 +#define QSERDES_V8_LALB_IDAC_STATUS_ABAR 0x74c +#define QSERDES_V8_LALB_IDAC_STATUS_SM_ON 0x750 +#define QSERDES_V8_LALB_IDAC_STATUS_SIGNERROR 0x754 +#define QSERDES_V8_LALB_RX_SIGDET_STATUS 0x758 +#define QSERDES_V8_LALB_SIGDET_CAL_CODE_STATUS 0x75c +#define QSERDES_V8_LALB_SIGDET_CAL_FSM_DEBUG_STATUS 0x760 +#define QSERDES_V8_LALB_CDR_FREQ_LOCK_CNT_STATUS 0x764 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_STATUS 0x768 +#define QSERDES_V8_LALB_CDR_LOCK_DEBUG_STATUS 0x76c +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS1 0x770 +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS2 0x774 +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS3 0x778 +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS4 0x77c +#define QSERDES_V8_LALB_IDATA_LOW_STATUS1 0x780 +#define QSERDES_V8_LALB_IDATA_LOW_STATUS2 0x784 +#define QSERDES_V8_LALB_IDATA_LOW_STATUS3 0x788 +#define QSERDES_V8_LALB_IDATA_LOW_STATUS4 0x78c +#define QSERDES_V8_LALB_QDATA_STATUS1 0x790 +#define QSERDES_V8_LALB_QDATA_STATUS2 0x794 +#define QSERDES_V8_LALB_QDATA_STATUS3 0x798 +#define QSERDES_V8_LALB_QDATA_STATUS4 0x79c +#define QSERDES_V8_LALB_IA_ERROR_COUNTER_LOW 0x7a0 +#define QSERDES_V8_LALB_IA_ERROR_COUNTER_HIGH 0x7a4 +#define QSERDES_V8_LALB_EOM_ERR_CNT_LSB_STATUS 0x7a8 +#define QSERDES_V8_LALB_EOM_ERR_CNT_MSB_STATUS 0x7ac +#define QSERDES_V8_LALB_EOM_OP_STATUS 0x7b0 +#define QSERDES_V8_LALB_AUX_MIXER_INDEX_STATUS 0x7b4 +#define QSERDES_V8_LALB_AUX_OFFSET_STATUS 0x7b8 +#define QSERDES_V8_LALB_AUXDATA_TB_STATUS 0x7bc +#define QSERDES_V8_LALB_AUX_MIXER_CTRL_0_STATUS 0x7c0 +#define QSERDES_V8_LALB_AUX_MIXER_CTRL_90_STATUS 0x7c4 +#define QSERDES_V8_LALB_AUX_MIXER_CTRL_180_STATUS 0x7c8 +#define QSERDES_V8_LALB_IQ_MIXER_INDEX_STATUS 0x7cc +#define QSERDES_V8_LALB_IQTUNE_FLTR_INDEX_STATUS 0x7d0 +#define QSERDES_V8_LALB_IQ_MIXER_CTRL_0_STATUS 0x7d4 +#define QSERDES_V8_LALB_IQ_MIXER_CTRL_90_STATUS 0x7d8 +#define QSERDES_V8_LALB_IQ_MIXER_CTRL_180_STATUS 0x7dc +#define QSERDES_V8_LALB_READ_EQCODE 0x7e0 +#define QSERDES_V8_LALB_READ_OFFSETCODE 0x7e4 +#define QSERDES_V8_LALB_VGA_READ_CODE 0x7e8 +#define QSERDES_V8_LALB_VTHRESH_READ_CODE 0x7ec +#define QSERDES_V8_LALB_DFE_TAP1_READ_CODE 0x7f0 +#define QSERDES_V8_LALB_DFE_TAP2_READ_CODE 0x7f4 +#define QSERDES_V8_LALB_DFE_TAP3_READ_CODE 0x7f8 +#define QSERDES_V8_LALB_DFE_TAP4_READ_CODE 0x7fc +#define QSERDES_V8_LALB_DFE_TAP5_READ_CODE 0x800 +#define QSERDES_V8_LALB_DFE_TAP6_READ_CODE 0x804 +#define QSERDES_V8_LALB_DFE_TAP7_READ_CODE 0x808 +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_BIN_CODE 0x80c +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK0_CODE 0x810 +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK90_CODE 0x814 +#define QSERDES_V8_LALB_BLW_READ_CODE 0x818 +#define QSERDES_V8_LALB_IA_OFFSET_CAL_DEBUG_STATUS 0x81c +#define QSERDES_V8_LALB_IA_OFFSET_CAL_STATUS 0x820 +#define QSERDES_V8_LALB_IVTH_CAL_STATUS 0x824 +#define QSERDES_V8_LALB_IVTH_NRZ_EYE_HEIGHT_STATUS 0x828 +#define QSERDES_V8_LALB_IVTH_UPPER_EYE_MAX_STATUS 0x82c +#define QSERDES_V8_LALB_IVTH_UPPER_EYE_MIN_STATUS 0x830 +#define QSERDES_V8_LALB_IVTH_LOWER_EYE_MAX_STATUS 0x834 +#define QSERDES_V8_LALB_IVTH_LOWER_EYE_MIN_STATUS 0x838 +#define QSERDES_V8_LALB_IVTH_UP_INIT_CTR_STATUS 0x83c +#define QSERDES_V8_LALB_VTH_I_UP_CNTRL_STATUS 0x840 +#define QSERDES_V8_LALB_VTH_I_DN_CNTRL_STATUS 0x844 +#define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_STATUS 0x848 +#define QSERDES_V8_LALB_DEBUG_BUS0 0x84c +#define QSERDES_V8_LALB_DEBUG_BUS1 0x850 +#define QSERDES_V8_LALB_DEBUG_BUS2 0x854 +#define QSERDES_V8_LALB_DEBUG_BUS3 0x858 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL1 0x85c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL2 0x860 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL3 0x864 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL4 0x868 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL5 0x86c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL6 0x870 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL7 0x874 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL8 0x878 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL9 0x87c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL10 0x880 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL11 0x884 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL12 0x888 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL13 0x88c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL14 0x890 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL15 0x894 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL16 0x898 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL17 0x89c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL18 0x8a0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL19 0x8a4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL20 0x8a8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL21 0x8ac +#define QSERDES_V8_LALB_DIG_BKUP_CTRL22 0x8b0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL23 0x8b4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL24 0x8b8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL25 0x8bc +#define QSERDES_V8_LALB_DIG_BKUP_CTRL26 0x8c0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL27 0x8c4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL28 0x8c8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL29 0x8cc +#define QSERDES_V8_LALB_DIG_BKUP_CTRL30 0x8d0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL31 0x8d4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL32 0x8d8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_1 0x8dc +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_2 0x8e0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_3 0x8e4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_4 0x8e8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_5 0x8ec +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS1 0x8f0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS2 0x8f4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS3 0x8f8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS4 0x8fc +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS5 0x900 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS6 0x904 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS7 0x908 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS8 0x90c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS9 0x910 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS10 0x914 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS11 0x918 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS12 0x91c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS13 0x920 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS14 0x924 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS15 0x928 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS16 0x92c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS17 0x930 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS18 0x934 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS19 0x938 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS20 0x93c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS21 0x940 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS22 0x944 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS23 0x948 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS24 0x94c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS25 0x950 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS26 0x954 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS27 0x958 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS28 0x95c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS29 0x960 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS30 0x964 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS31 0x968 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS32 0x96c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS1 0x970 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS2 0x974 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS3 0x978 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS4 0x97c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS5 0x980 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS6 0x984 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS7 0x988 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS8 0x98c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS9 0x990 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS10 0x994 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS11 0x998 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS12 0x99c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS13 0x9a0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS14 0x9a4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS15 0x9a8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS16 0x9ac +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS17 0x9b0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS18 0x9b4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS19 0x9b8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS20 0x9bc +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS21 0x9c0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS22 0x9c4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS23 0x9c8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS24 0x9cc +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS25 0x9d0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS26 0x9d4 +#endif /* QCOM_PHY_QMP_QSERDES_V8_LALBH_ */ diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h new file mode 100644 index 0000000000000..4f387c8ed9e55 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_USB43_PCS_V8_H_ +#define QCOM_PHY_QMP_USB43_PCS_V8_H_ + +#define QPHY_V8_USB43_PCS_SW_RESET 0x000 +#define QPHY_V8_USB43_PCS_PCS_STATUS1 0x014 +#define QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL 0x040 +#define QPHY_V8_USB43_PCS_START_CONTROL 0x044 +#define QPHY_V8_USB43_PCS_POWER_STATE_CONFIG1 0x090 +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1 0x0c4 +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2 0x0c8 +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3 0x0cc +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6 0x0d8 +#define QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1 0x0dc +#define QPHY_V8_USB43_PCS_RX_SIGDET_LVL 0x188 +#define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 +#define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 +#define QPHY_V8_USB43_PCS_RATE_SLEW_CNTRL1 0x198 +#define QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME 0x1ac +#define QPHY_V8_USB43_PCS_RX_CONFIG 0x1b0 +#define QPHY_V8_USB43_PCS_TSYNC_DLY_TIME 0x1b4 +#define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1 0x1c0 +#define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2 0x1c4 +#define QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG 0x1d0 +#define QPHY_V8_USB43_PCS_EQ_CONFIG1 0x1dc +#define QPHY_V8_USB43_PCS_EQ_CONFIG2 0x1e0 +#define QPHY_V8_USB43_PCS_EQ_CONFIG5 0x1ec + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h new file mode 100644 index 0000000000000..e9c743fce9d1b --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_ +#define QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_ + +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1 0x000 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1 0x004 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE1 0x008 +#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE1 0x00c +#define QSERDES_V8_USB43_COM_CP_CTRL_MODE1 0x010 +#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1 0x014 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1 0x018 +#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1 0x01c +#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1 0x020 +#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1 0x024 +#define QSERDES_V8_USB43_COM_DEC_START_MODE1 0x028 +#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1 0x02c +#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1 0x030 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1 0x034 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1 0x038 +#define QSERDES_V8_USB43_COM_HSCLK_SEL_1 0x03c +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1 0x040 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE1 0x044 +#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1 0x048 +#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1 0x04c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x050 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x054 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0 0x060 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0 0x064 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE0 0x068 +#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE0 0x06c +#define QSERDES_V8_USB43_COM_CP_CTRL_MODE0 0x070 +#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0 0x074 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0 0x078 +#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0 0x07c +#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0 0x080 +#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0 0x084 +#define QSERDES_V8_USB43_COM_DEC_START_MODE0 0x088 +#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0 0x08c +#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0 0x090 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0 0x094 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0 0x098 +#define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1 0x09c +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 +#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0 0x0a8 +#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0 0x0ac +#define QSERDES_V8_USB43_COM_ATB_SEL1 0x0b0 +#define QSERDES_V8_USB43_COM_ATB_SEL2 0x0b4 +#define QSERDES_V8_USB43_COM_FREQ_UPDATE 0x0b8 +#define QSERDES_V8_USB43_COM_BG_TIMER 0x0bc +#define QSERDES_V8_USB43_COM_SSC_EN_CENTER 0x0c0 +#define QSERDES_V8_USB43_COM_SSC_ADJ_PER1 0x0c4 +#define QSERDES_V8_USB43_COM_SSC_ADJ_PER2 0x0c8 +#define QSERDES_V8_USB43_COM_SSC_PER1 0x0cc +#define QSERDES_V8_USB43_COM_SSC_PER2 0x0d0 +#define QSERDES_V8_USB43_COM_POST_DIV 0x0d4 +#define QSERDES_V8_USB43_COM_POST_DIV_MUX 0x0d8 +#define QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define QSERDES_V8_USB43_COM_CLK_ENABLE1 0x0e0 +#define QSERDES_V8_USB43_COM_SYS_CLK_CTRL 0x0e4 +#define QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE 0x0e8 +#define QSERDES_V8_USB43_COM_PLL_EN 0x0ec +#define QSERDES_V8_USB43_COM_DEBUG_BUS_OVRD 0x0f0 +#define QSERDES_V8_USB43_COM_PLL_IVCO 0x0f4 +#define QSERDES_V8_USB43_COM_PLL_IVCO_MODE1 0x0f8 +#define QSERDES_V8_USB43_COM_CMN_IETRIM 0x0fc +#define QSERDES_V8_USB43_COM_CMN_IPTRIM 0x100 +#define QSERDES_V8_USB43_COM_EP_CLOCK_DETECT_CTRL 0x104 +#define QSERDES_V8_USB43_COM_PLL_CNTRL 0x108 +#define QSERDES_V8_USB43_COM_BIAS_EN_CTRL_BY_PSM 0x10c +#define QSERDES_V8_USB43_COM_SYSCLK_EN_SEL 0x110 +#define QSERDES_V8_USB43_COM_CML_SYSCLK_SEL 0x114 +#define QSERDES_V8_USB43_COM_RESETSM_CNTRL 0x118 +#define QSERDES_V8_USB43_COM_RESETSM_CNTRL2 0x11c +#define QSERDES_V8_USB43_COM_LOCK_CMP_EN 0x120 +#define QSERDES_V8_USB43_COM_LOCK_CMP_CFG 0x124 +#define QSERDES_V8_USB43_COM_INTEGLOOP_INITVAL 0x128 +#define QSERDES_V8_USB43_COM_INTEGLOOP_EN 0x12c +#define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN0 0x130 +#define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN1 0x134 +#define QSERDES_V8_USB43_COM_VCOCAL_DEADMAN_CTRL 0x138 +#define QSERDES_V8_USB43_COM_VCO_TUNE_CTRL 0x13c +#define QSERDES_V8_USB43_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL1 0x144 +#define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL2 0x148 +#define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL1 0x14c +#define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL2 0x150 +#define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL1 0x154 +#define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL2 0x158 +#define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER1 0x15c +#define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER2 0x160 +#define QSERDES_V8_USB43_COM_CLK_SELECT 0x164 +#define QSERDES_V8_USB43_COM_PLL_ANALOG 0x168 +#define QSERDES_V8_USB43_COM_SW_RESET 0x16c +#define QSERDES_V8_USB43_COM_CORE_CLK_EN 0x170 +#define QSERDES_V8_USB43_COM_CMN_CONFIG_1 0x174 +#define QSERDES_V8_USB43_COM_CMN_CONFIG_3 0x178 +#define QSERDES_V8_USB43_COM_CMN_RATE_OVERRIDE 0x17c +#define QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL 0x180 +#define QSERDES_V8_USB43_COM_DEBUG_BUS_SEL 0x184 +#define QSERDES_V8_USB43_COM_CMN_MISC1 0x188 +#define QSERDES_V8_USB43_COM_CMN_MODE 0x18c +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD 0x190 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD1 0x194 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD2 0x198 +#define QSERDES_V8_USB43_COM_VCO_DC_LEVEL_CTRL 0x19c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1 0x1a0 +#define QSERDES_V8_USB43_COM_ADDITIONAL_CTRL_1 0x1a4 +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a8 +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_2 0x1ac +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_3 0x1b0 +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_4 0x1b4 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC 0x1b8 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_2 0x1bc +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_3 0x1c0 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_4 0x1c4 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_5 0x1c8 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE2 0x1cc +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE2 0x1d0 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE2 0x1d4 +#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE2 0x1d8 +#define QSERDES_V8_USB43_COM_CP_CTRL_MODE2 0x1dc +#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE2 0x1e0 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE2 0x1e4 +#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE2 0x1e8 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE2 0x1ec +#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE2 0x1f0 +#define QSERDES_V8_USB43_COM_DEC_START_MODE2 0x1f4 +#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE2 0x1f8 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE2 0x1fc +#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE2 0x200 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE2 0x204 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE2 0x208 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE2 0x20c +#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE2 0x210 +#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE2 0x214 +#define QSERDES_V8_USB43_COM_PLL_IVCO_MODE2 0x218 +#define QSERDES_V8_USB43_COM_HSCLK_SEL_2 0x21c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE2 0x220 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE2 0x224 +#define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_2 0x228 +#define QSERDES_V8_USB43_COM_CMN_CONFIG_2 0x22c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_2 0x230 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_0 0x234 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_1 0x238 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_2 0x23c +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_3 0x240 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_4 0x244 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_5 0x248 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE0 0x24c +#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE0 0x250 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE1 0x254 +#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE1 0x258 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE2 0x25c +#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE2 0x260 +#define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_0 0x264 +#define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_1 0x268 +#define QSERDES_V8_USB43_COM_ADAPTIVE_ANALOG_CONFIG 0x26c +#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE0 0x270 +#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE0 0x274 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE0 0x278 +#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE1 0x27c +#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE1 0x280 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE1 0x284 +#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE2 0x288 +#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE2 0x28c +#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE2 0x290 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD3 0x294 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD4 0x298 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD5 0x29c +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD6 0x2a0 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_6 0x2a4 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_7 0x2a8 +#define QSERDES_V8_USB43_COM_VCO_WAIT_CYCLES 0x2ac +#define QSERDES_V8_USB43_COM_BIAS_WAIT_CYCLES 0x2b0 +#define QSERDES_V8_USB43_COM_AUX_CLK_PSM_ENABLE 0x2b4 +#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO 0x2b8 +#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_1 0x2bc +#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_2 0x2c0 +#define QSERDES_V8_USB43_COM_LDO_CAL_1 0x2c4 +#define QSERDES_V8_USB43_COM_LDO_CAL_2 0x2c8 +#define QSERDES_V8_USB43_COM_LDO_CAL_3 0x2cc +#define QSERDES_V8_USB43_COM_LDO_CAL_4 0x2d0 +#define QSERDES_V8_USB43_COM_LDO_CAL_5 0x2d4 +#define QSERDES_V8_USB43_COM_DCC_CAL_1 0x2d8 +#define QSERDES_V8_USB43_COM_DCC_CAL_2 0x2dc +#define QSERDES_V8_USB43_COM_DCC_CAL_3 0x2e0 +#define QSERDES_V8_USB43_COM_DCC_CAL_4 0x2e4 +#define QSERDES_V8_USB43_COM_DCC_CAL_5 0x2e8 +#define QSERDES_V8_USB43_COM_DCC_CAL_6 0x2ec +#define QSERDES_V8_USB43_COM_PSM_CAL_EN 0x2f0 +#define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1 0x2f4 +#define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_2 0x2f8 +#define QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL 0x2fc +#define QSERDES_V8_USB43_COM_DCC_CAL_7 0x300 +#define QSERDES_V8_USB43_COM_DCC_CAL_8 0x304 +#define QSERDES_V8_USB43_COM_DCC_CAL_9 0x308 +#define QSERDES_V8_USB43_COM_MODE_OPERATION_STATUS 0x30c +#define QSERDES_V8_USB43_COM_SYSCLK_DET_COMP_STATUS 0x310 +#define QSERDES_V8_USB43_COM_CMN_STATUS 0x314 +#define QSERDES_V8_USB43_COM_RESET_SM_STATUS 0x318 +#define QSERDES_V8_USB43_COM_RESTRIM_CODE_STATUS 0x31c +#define QSERDES_V8_USB43_COM_PLLCAL_CODE1_STATUS 0x320 +#define QSERDES_V8_USB43_COM_PLLCAL_CODE2_STATUS 0x324 +#define QSERDES_V8_USB43_COM_INTEGLOOP_BINCODE_STATUS 0x328 +#define QSERDES_V8_USB43_COM_DEBUG_BUS0 0x32c +#define QSERDES_V8_USB43_COM_DEBUG_BUS1 0x330 +#define QSERDES_V8_USB43_COM_DEBUG_BUS2 0x334 +#define QSERDES_V8_USB43_COM_DEBUG_BUS3 0x338 +#define QSERDES_V8_USB43_COM_C_READY_STATUS 0x33c +#define QSERDES_V8_USB43_COM_READ_DUMMY_1 0x340 +#define QSERDES_V8_USB43_COM_READ_DUMMY_2 0x344 +#define QSERDES_V8_USB43_COM_READ_DUMMY_3 0x348 +#define QSERDES_V8_USB43_COM_IVCO_CAL_CODE_STATUS 0x34c +#define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_2 0x350 +#define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_3 0x354 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index da2a7ad2cdcce..e4060edc81387 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -32,7 +32,9 @@ #include "phy-qcom-qmp-qserdes-txrx-v7.h" #include "phy-qcom-qmp-qserdes-com-v8.h" +#include "phy-qcom-qmp-usb43-qserdes-com-v8.h" #include "phy-qcom-qmp-qserdes-txrx-v8.h" +#include "phy-qcom-qmp-qserdes-lalb-v8.h" #include "phy-qcom-qmp-qserdes-pll.h" From e41df78f005cf8236460b611a2f23c3f66db11ed Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 9 Dec 2025 14:53:15 -0800 Subject: [PATCH 608/659] FROMLIST: phy: qualcomm: qmp-combo: Add DP offsets and settings for Glymur platforms Starting with Glymur, the PCIe and DP PHYs qserdes register offsets differ for the same version number. So in order to be able to differentiate between them, add these ones with DP prefix. Add the necessary PHY setting tables for enabling the DP path within the QMP subsystem. Introduced some new callbacks for v8 specific sequences, such as for clock configurations based on the different link speeds. Wesley Cheng added some updated settings from the hardware programming guides on existing PHY tables and clock settings. Reviewed-by: Dmitry Baryshkov Co-developed-by: Wesley Cheng Signed-off-by: Abel Vesa Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-9-42133596bda0@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 355 +++++++++++++++++- drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h | 25 ++ .../qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h | 52 +++ 3 files changed, 428 insertions(+), 4 deletions(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 32a3f3a4ab05f..97c6ff46c3735 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -48,6 +48,7 @@ #include "phy-qcom-qmp-dp-phy-v4.h" #include "phy-qcom-qmp-dp-phy-v5.h" #include "phy-qcom-qmp-dp-phy-v6.h" +#include "phy-qcom-qmp-dp-phy-v8.h" #include "phy-qcom-qmp-usb43-pcs-v8.h" @@ -103,6 +104,7 @@ enum qphy_reg_layout { QPHY_TX_TRANSCEIVER_BIAS_EN, QPHY_AON_TOGGLE_ENABLE, + QPHY_DP_AON_TOGGLE_ENABLE, /* Keep last to ensure regs_layout arrays are properly initialized */ QPHY_LAYOUT_SIZE }; @@ -277,12 +279,16 @@ static const unsigned int qmp_v8_n3_usb43dpphy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_CLAMP_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE, [QPHY_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE, + [QPHY_DP_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE, [QPHY_COM_RESETSM_CNTRL] = QSERDES_V8_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V8_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V8_COM_CMN_STATUS, [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, + [QPHY_DP_PHY_STATUS] = QSERDES_V8_DP_PHY_STATUS, + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V8_DP_PHY_VCO_DIV, + [QPHY_TX_TX_DRV_LVL] = QSERDES_V8_LALB_TX0_DRV_LVL, [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V8_LALB_TX0_EMP_POST1_LVL, [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V8_LALB_HIGHZ_DRVR_EN, @@ -1378,6 +1384,38 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), }; +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x56), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x01), +}; + static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40), QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30), @@ -1405,6 +1443,33 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_tx_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TX_BAND, 0x1), }; +static const struct qmp_phy_init_tbl qmp_v8_n3p_dp_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VMODE_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x50), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRAN_DRVR_EMP_EN, 0x5f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_EMP_POST1_LVL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_EMP_POST1_LVL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_PRE1_EMPH, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_PRE1_EMPH, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_DRV_LVL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_DRV_LVL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_HIGHZ_DRVR_EN, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x50), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x51), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET, 0x10), +}; + static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = { QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05), QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), @@ -1521,6 +1586,109 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr3[] = { QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), }; +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_rbr[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x7a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x83), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x37), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xfe), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa4), +}; + +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x21), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa3), +}; + +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr2[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xf6), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_RESETSM_CNTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f), +}; + +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr3[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x63), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a), + + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x4f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x6b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c), + + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0x84), +}; + static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01), QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31), @@ -2070,6 +2238,7 @@ struct qmp_phy_cfg { const u8 (*pre_emphasis_hbr3_hbr2)[4][4]; /* DP PHY callbacks */ + int (*configure_dp_clocks)(struct qmp_combo *qmp); int (*configure_dp_phy)(struct qmp_combo *qmp); void (*configure_dp_tx)(struct qmp_combo *qmp); int (*calibrate_dp_phy)(struct qmp_combo *qmp); @@ -2147,6 +2316,7 @@ struct qmp_combo { static void qmp_v3_dp_aux_init(struct qmp_combo *qmp); static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp); +static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp); static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp); static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp); @@ -2155,6 +2325,10 @@ static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp); static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp); static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp); +static void qmp_v8_dp_aux_init(struct qmp_combo *qmp); +static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp); +static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp); + static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) { u32 reg; @@ -2288,6 +2462,7 @@ static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2423,6 +2598,7 @@ static const struct qmp_phy_cfg sc8180x_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2469,6 +2645,7 @@ static const struct qmp_phy_cfg sc8280xp_usb43dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2514,6 +2691,7 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2602,6 +2780,7 @@ static const struct qmp_phy_cfg sm8250_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2650,6 +2829,7 @@ static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2697,6 +2877,7 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2742,6 +2923,7 @@ static const struct qmp_phy_cfg sm8650_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2787,6 +2969,7 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2811,6 +2994,31 @@ static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = { .pcs_misc_tbl = glymur_usb43dp_pcs_misc_tbl, .pcs_misc_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_misc_tbl), + .dp_serdes_tbl = qmp_v8_dp_serdes_tbl, + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl), + .dp_tx_tbl = qmp_v8_n3p_dp_tx_tbl, + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v8_n3p_dp_tx_tbl), + + .serdes_tbl_rbr = qmp_v8_dp_serdes_tbl_rbr, + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_rbr), + .serdes_tbl_hbr = qmp_v8_dp_serdes_tbl_hbr, + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr), + .serdes_tbl_hbr2 = qmp_v8_dp_serdes_tbl_hbr2, + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr2), + .serdes_tbl_hbr3 = qmp_v8_dp_serdes_tbl_hbr3, + .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr3), + + .swing_hbr_rbr = &qmp_dp_v6_voltage_swing_hbr_rbr, + .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr, + .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2, + .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2, + + .dp_aux_init = qmp_v8_dp_aux_init, + .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v8_configure_dp_clocks, + .configure_dp_phy = qmp_v8_configure_dp_phy, + .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, + .regs = qmp_v8_n3_usb43dpphy_regs_layout, .reset_list = msm8996_usb3phy_reset_l, .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), @@ -2980,7 +3188,7 @@ static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp) return reverse; } -static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp) +static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp) { const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; u32 phy_vco_div; @@ -3027,7 +3235,7 @@ static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp) writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL); writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL); - ret = qmp_combo_configure_dp_clocks(qmp); + ret = qmp_v3_configure_dp_clocks(qmp); if (ret) return ret; @@ -3113,6 +3321,35 @@ static void qmp_v4_dp_aux_init(struct qmp_combo *qmp) qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); } +static void qmp_v8_dp_aux_init(struct qmp_combo *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + /* Turn on BIAS current for PHY/PLL */ + writel(0x1c, qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]); + + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); + writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); + writel(0x06, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); + writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); + writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); + qmp->dp_aux_cfg = 0; + + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | + PHY_AUX_REQ_ERR_MASK, + qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); +} + static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -3127,6 +3364,58 @@ static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp) qmp_combo_configure_dp_swing(qmp); } +static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp) +{ + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + u32 phy_vco_div; + unsigned long pixel_freq; + const struct qmp_phy_cfg *cfg = qmp->cfg; + + switch (dp_opts->link_rate) { + case 1620: + phy_vco_div = 0x4; + pixel_freq = 1620000000UL / 2; + break; + case 2700: + phy_vco_div = 0x2; + pixel_freq = 2700000000UL / 2; + break; + case 5400: + phy_vco_div = 0x4; + pixel_freq = 5400000000UL / 4; + break; + case 8100: + phy_vco_div = 0x3; + pixel_freq = 8100000000UL / 6; + break; + default: + /* Other link rates aren't supported */ + return -EINVAL; + } + writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]); + + /* disable core reset tsync */ + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + writel(0x04, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC); + writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC); + writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_CYC); + writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD); + + writel(0x3e, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TSYNC_OVRD); + writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL); + writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL); + writel(0x01, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_CFG1); + writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD); + writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN0_DRV_LVL); + writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN1_DRV_LVL); + + clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); + clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); + + return 0; +} + static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -3143,7 +3432,7 @@ static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp) writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL); writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL); - ret = qmp_combo_configure_dp_clocks(qmp); + ret = qmp->cfg->configure_dp_clocks(qmp); if (ret) return ret; @@ -3257,6 +3546,62 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp) return 0; } +static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + u32 bias0_en, drvr0_en, bias1_en, drvr1_en; + u32 status; + int ret; + + ret = qmp_v456_configure_dp_phy(qmp); + if (ret < 0) + return ret; + + if (dp_opts->lanes == 1) { + bias0_en = reverse ? 0x3e : 0x15; + bias1_en = reverse ? 0x15 : 0x3e; + drvr0_en = reverse ? 0x13 : 0x10; + drvr1_en = reverse ? 0x10 : 0x13; + } else if (dp_opts->lanes == 2) { + bias0_en = reverse ? 0x3f : 0x15; + bias1_en = reverse ? 0x15 : 0x3f; + drvr0_en = 0x10; + drvr1_en = 0x10; + } else { + bias0_en = 0x3f; + bias1_en = 0x3f; + drvr0_en = 0x34; + drvr1_en = 0x34; + } + + writel(drvr0_en, qmp->dp_tx + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); + writel(bias0_en, qmp->dp_tx + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); + writel(drvr1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); + writel(bias1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); + + writel(0x08, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + udelay(100); + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + udelay(500); + + if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], + status, + ((status & BIT(1)) > 0), + 500, + 10000)) + return -ETIMEDOUT; + + writel(0x00, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]); + writel(0x00, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]); + + writel(0x2b, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); + writel(0x2b, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); + + return 0; +} + /* * We need to calibrate the aux setting here as many times * as the caller tries @@ -3351,8 +3696,10 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); /* override hardware control for reset of qmp phy */ - if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) + if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) { qphy_clrbits(pcs_aon, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1); + qphy_clrbits(pcs_aon, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1); + } /* Use software based port select and switch on typec orientation */ val = SW_PORTSELECT_MUX; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h new file mode 100644 index 0000000000000..b6a8ab59c2ff4 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V8_H_ +#define QCOM_PHY_QMP_DP_PHY_V8_H_ + +/* Only for QMP V8 PHY - DP PHY registers */ +#define QSERDES_V8_DP_PHY_VCO_DIV 0x070 +#define QSERDES_V8_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0 +#define QSERDES_V8_DP_PHY_TSYNC_OVRD 0x074 +#define QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL 0x078 +#define QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL 0x0bc +#define QSERDES_V8_DP_PHY_AUXLESS_CFG1 0x0c8 +#define QSERDES_V8_DP_PHY_LFPS_PERIOD 0x0d0 +#define QSERDES_V8_DP_PHY_LFPS_CYC 0x0d4 +#define QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC 0x0d8 +#define QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC 0x0d8 +#define QSERDES_V8_DP_PHY_LN0_DRV_LVL 0x0e0 +#define QSERDES_V8_DP_PHY_LN1_DRV_LVL 0x0e4 +#define QSERDES_V8_DP_PHY_STATUS 0x114 + + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h new file mode 100644 index 0000000000000..2bef1eecdc56a --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025 Linaro Ltd. + */ + +#ifndef QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_ +#define QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_ + +/* Only for DP QMP V8 PHY - QSERDES COM registers */ +#define DP_QSERDES_V8_COM_HSCLK_SEL_1 0x03c +#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 +#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c +#define DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0 0x060 +#define DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0 0x064 +#define DP_QSERDES_V8_COM_CP_CTRL_MODE0 0x070 +#define DP_QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 +#define DP_QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 +#define DP_QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c +#define DP_QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 +#define DP_QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 +#define DP_QSERDES_V8_COM_DEC_START_MODE0 0x088 +#define DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 +#define DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 +#define DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 +#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 +#define DP_QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 +#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 +#define DP_QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac +#define DP_QSERDES_V8_COM_BG_TIMER 0x0bc +#define DP_QSERDES_V8_COM_SSC_EN_CENTER 0x0c0 +#define DP_QSERDES_V8_COM_SSC_ADJ_PER1 0x0c4 +#define DP_QSERDES_V8_COM_SSC_PER1 0x0cc +#define DP_QSERDES_V8_COM_SSC_PER2 0x0d0 +#define DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define DP_QSERDES_V8_COM_CLK_ENABLE1 0x0e0 +#define DP_QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 +#define DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 +#define DP_QSERDES_V8_COM_PLL_IVCO 0x0f4 +#define DP_QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 +#define DP_QSERDES_V8_COM_RESETSM_CNTRL 0x118 +#define DP_QSERDES_V8_COM_LOCK_CMP_EN 0x120 +#define DP_QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c +#define DP_QSERDES_V8_COM_VCO_TUNE_MAP 0x140 +#define DP_QSERDES_V8_COM_CLK_SELECT 0x164 +#define DP_QSERDES_V8_COM_CORE_CLK_EN 0x170 +#define DP_QSERDES_V8_COM_CMN_CONFIG_1 0x174 +#define DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL 0x180 +#define DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1 0x2f4 +#define DP_QSERDES_V8_COM_CMN_STATUS 0x314 +#define DP_QSERDES_V8_COM_C_READY_STATUS 0x33c + +#endif From 905baada512b64b904b7558cd4dc0572374438f9 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:35 +0530 Subject: [PATCH 609/659] 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 41360a7591e56..bde303b820d7e 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 c1462be5526d5..7706a04f2630f 100644 --- a/drivers/usb/misc/onboard_usb_dev.h +++ b/drivers/usb/misc/onboard_usb_dev.h @@ -140,6 +140,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 373f7fe1434d68146cc9a791fccf6fbbca7e526f Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:34 +0530 Subject: [PATCH 610/659] 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 8bcf72e971d89279e5196e6483d052d13111dfde Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 25 Sep 2025 12:02:09 +0530 Subject: [PATCH 611/659] 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/20260205-upstream_v3_glymur_introduction-v7-1-849e7a9e6888@oss.qualcomm.com/ Signed-off-by: Pankaj Patil Signed-off-by: Sibi Sankar 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 d84bd3bca2010..b6398bc8c5887 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: - microsoft,dempsey From 4022b9fff0dfda1c88ddf3a92e915bd59f142e76 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 25 Sep 2025 12:02:11 +0530 Subject: [PATCH 612/659] 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/20260205-upstream_v3_glymur_introduction-v7-3-849e7a9e6888@oss.qualcomm.com/ 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 Signed-off-by: Pankaj Patil 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 38803458ca086fa7e3b3ba8978e63507f0b71dd5 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 11 Dec 2025 18:39:53 +0530 Subject: [PATCH 613/659] 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/20260205-upstream_v3_glymur_introduction-v7-4-849e7a9e6888@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 6f34d5ed331c4..6ff911cca06cc 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 e668e9874abc96706bcba6968ab78e2282a7f837 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 13 Jan 2026 14:33:05 +0200 Subject: [PATCH 614/659] 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/all/20260113-dts-qcom-glymur-add-usb-support-v1-2-98d6d387df01@oss.qualcomm.com/#r Signed-off-by: Wesley Cheng Co-developed-by: Abel Vesa Signed-off-by: Abel Vesa Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur.dtsi | 667 ++++++++++++++++++++++++++- 1 file changed, 662 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index e269cec7942c8..b0df806d3367d 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 */ + <&usb1_ss0_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb1_ss1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb1_ss2_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,253 @@ }; }; + usb_mp_hsphy0: phy@fa1000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0 0x00fa1000 0 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 = <0 0x00fa2000 0 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 = <0 0x00fa3000 0 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 = <0 0x00fa5000 0 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"; + }; + + usb1_ss0_hsphy: phy@fd3000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0 0x00fd3000 0 0x29c>; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + + status = "disabled"; + }; + + usb1_ss0_qmpphy: phy@fd5000 { + compatible = "qcom,glymur-qmp-usb3-dp-phy"; + reg = <0 0x00fd5000 0 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>; + + usb1_ss0_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb1_ss0_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb1_ss0_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb_dp_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + usb1_ss1_hsphy: phy@fdd000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0 0x00fdd000 0 0x29c>; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + + status = "disabled"; + }; + + usb1_ss1_qmpphy: phy@fde000 { + compatible = "qcom,glymur-qmp-usb3-dp-phy"; + reg = <0 0x00fde000 0 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>; + + usb1_ss1_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb1_ss1_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb1_ss1_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb1_ss1_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + usb_2_hsphy: phy@fa0000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + reg = <0 0x00fa0000 0 0x154>; + #phy-cells = <0>; + + clocks = <&tcsr TCSR_USB2_1_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_USB20_HS_BCR>; + + status = "disabled"; + }; + + cnoc_main: interconnect@1500000 { compatible = "qcom,glymur-cnoc-main"; reg = <0x0 0x01500000 0x0 0x17080>; @@ -3367,6 +3614,416 @@ #interconnect-cells = <2>; }; + usb1_ss2_hsphy: phy@88e0000 { + compatible = "qcom,glymur-m31-eusb2-phy", + "qcom,sm8750-m31-eusb2-phy"; + + reg = <0 0x088e0000 0 0x29c>; + #phy-cells = <0>; + + clocks = <&tcsr TCSR_USB2_4_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_TERT_BCR>; + + status = "disabled"; + }; + + usb1_ss2_qmpphy: phy@88e1000 { + compatible = "qcom,glymur-qmp-usb3-dp-phy"; + reg = <0 0x088e1000 0 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>; + + usb1_ss2_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb1_ss2_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb1_ss2_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb1_ss2_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + usb1_ss0: usb@a600000 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0 0x0a600000 0 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 = <&usb1_ss0_hsphy>, + <&usb1_ss0_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,dis_u3_susphy_quirk; + snps,usb2-lpm-disable; + + usb-role-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb1_ss0_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb1_ss0_dwc3_ss: endpoint { + remote-endpoint = <&usb1_ss0_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + usb1_ss1: usb@a800000 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0 0x0a800000 0 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 = <&usb1_ss1_hsphy>, + <&usb1_ss1_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,dis_u3_susphy_quirk; + snps,usb2-lpm-disable; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb1_ss1_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb1_ss1_dwc3_ss: endpoint { + remote-endpoint = <&usb1_ss1_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + usb1_ss2: usb@a000000 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0 0x0a000000 0 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 = <&usb1_ss2_hsphy>, + <&usb1_ss2_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,dis_u3_susphy_quirk; + snps,usb2-lpm-disable; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb1_ss2_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb1_ss2_dwc3_ss: endpoint { + remote-endpoint = <&usb1_ss2_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + usb_2: usb@a2f8800 { + compatible = "qcom,glymur-dwc3", "qcom,snps-dwc3"; + reg = <0 0x0a200000 0 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_2_hsphy>; + phy-names = "usb2-phy"; + + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,dis_u2_susphy_quirk; + snps,dis_u3_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 = <0 0x0a400000 0 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,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,usb3_lpm_capable; + snps,dis_u3_susphy_quirk; + snps,usb2-lpm-disable; + + dr_mode = "host"; + + status = "disabled"; + }; + + dispcc: clock-controller@af00000 { compatible = "qcom,glymur-dispcc"; reg = <0x0 0x0af00000 0x0 0x20000>; From 28a78ca04fa0c35caecb33e4607134cabb45cd29 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 20 Jan 2026 11:45:10 +0530 Subject: [PATCH 615/659] 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 combo 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 SMB2360 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/all/20260113-dts-qcom-glymur-add-usb-support-v1-3-98d6d387df01@oss.qualcomm.com/ Signed-off-by: Wesley Cheng Co-developed-by: Abel Vesa Signed-off-by: Abel Vesa Signed-off-by: Pradyot Kumar Nayak --- arch/arm64/boot/dts/qcom/glymur-crd.dts | 283 ++++++++++++++++++++++++ 1 file changed, 283 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 8779453190122..43f86f841cc27 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 = <&usb1_ss0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb1_ss0_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 = <&usb1_ss1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in1: endpoint { + remote-endpoint = <&usb1_ss1_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 = <&usb1_ss2_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in2: endpoint { + remote-endpoint = <&usb1_ss2_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,138 @@ bias-disable; }; }; + +&usb1_ss0_hsphy { + vdd-supply = <&vreg_l3f_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_j_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb1_ss0_qmpphy { + vdda-phy-supply = <&vreg_l4h_e0_1p2>; + vdda-pll-supply = <&vreg_l3f_e0_0p72>; + refgen-supply = <&vreg_l2f_e0_0p82>; + + status = "okay"; +}; + +&usb1_ss0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb1_ss0_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb1_ss0 { + status = "okay"; +}; + +&usb1_ss1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in1>; +}; + +&usb1_ss1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in1>; +}; + +&usb1_ss1_hsphy { + vdd-supply = <&vreg_l3f_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_k_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb1_ss1_qmpphy { + vdda-phy-supply = <&vreg_l4h_e0_1p2>; + vdda-pll-supply = <&vreg_l1h_e0_0p89>; + refgen-supply = <&vreg_l2f_e0_0p82>; + + status = "okay"; +}; + +&usb1_ss1 { + status = "okay"; +}; + +&usb1_ss2_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in2>; +}; + +&usb1_ss2_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in2>; +}; + +&usb1_ss2_hsphy { + vdd-supply = <&vreg_l4c_e1_0p72>; + vdda12-supply = <&vreg_l4f_e1_1p08>; + + phys = <&smb2370_l_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb1_ss2_qmpphy { + vdda-phy-supply = <&vreg_l4f_e1_1p08>; + vdda-pll-supply = <&vreg_l4c_e1_0p72>; + refgen-supply = <&vreg_l1c_e1_0p82>; + + status = "okay"; +}; + +&usb1_ss2 { + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_hsphy { + phys = <&ptn3222_2>; + + 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"; +}; + +&usb_mp { + status = "okay"; +}; From 8570a13288d29f82003faf1e9bdfe50f7e8c35aa Mon Sep 17 00:00:00 2001 From: Pradyot Kumar Nayak Date: Tue, 10 Feb 2026 23:37:59 +0530 Subject: [PATCH 616/659] 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 b0df806d3367d..ea6e95dd0f303 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -3593,6 +3593,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>; @@ -5349,6 +5465,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 95ce79d01c2e816c393bd45611b216b116979187 Mon Sep 17 00:00:00 2001 From: Pradyot Kumar Nayak Date: Tue, 10 Feb 2026 23:40:07 +0530 Subject: [PATCH 617/659] 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 43f86f841cc27..130bb9f801b5f 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 74e83f399b94405c00c80e819c5d3cc2aaa4af40 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Wed, 11 Feb 2026 13:59:53 +0800 Subject: [PATCH 618/659] FROMLIST: arm64: dts: qcom: glymur: add coresight nodes Add CoreSight nodes to enable trace paths like TPDM->ETF/STM->ETF. These devices are part of the AOSS, CDSP, QDSS, PCIe5, TraceNoc and some small subsystems, such as GCC, IPCC, PMU and so on. Link: https://lore.kernel.org/all/20251230-add-coresight-nodes-for-glymur-v1-1-103b6d24f1ca@oss.qualcomm.com/ Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/glymur.dtsi | 1549 ++++++++++++++++++++++---- 1 file changed, 1345 insertions(+), 204 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index ea6e95dd0f303..d775352f23939 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -341,6 +341,18 @@ }; }; + dummy-sink { + compatible = "arm,coresight-dummy-sink"; + + in-ports { + port { + eud_in: endpoint { + remote-endpoint = <&swao_rep_out1>; + }; + }; + }; + }; + firmware { scm: scm { compatible = "qcom,scm-glymur", "qcom,scm"; @@ -5052,259 +5064,1362 @@ }; }; - 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 = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + stm: stm@10002000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0x0 0x10002000 0x0 0x1000>, + <0x0 0x16280000 0x0 0x180000>; + reg-names = "stm-base", + "stm-stimulus-base"; - dma-coherent; - }; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - 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>; + out-ports { + port { + stm_out: endpoint { + remote-endpoint = <&funnel0_in7>; + }; + }; + }; }; - intc: interrupt-controller@17000000 { - compatible = "arm,gic-v3"; - reg = <0x0 0x17000000 0x0 0x10000>, - <0x0 0x17080000 0x0 0x480000>; + tpda@10004000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x10004000 0x0 0x1000>; - interrupts = ; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - #interrupt-cells = <3>; - interrupt-controller; + in-ports { + #address-cells = <1>; + #size-cells = <0>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + port@1 { + reg = <1>; - gic_its: msi-controller@17040000 { - compatible = "arm,gic-v3-its"; - reg = <0x0 0x17040000 0x0 0x40000>; + qdss_tpda_in1: endpoint { + remote-endpoint = <&spdm_tpdm_out>; + }; + }; + }; - msi-controller; - #msi-cells = <1>; + out-ports { + port { + qdss_tpda_out: endpoint { + remote-endpoint = <&funnel0_in6>; + }; + }; }; }; - watchdog@17600000 { - compatible = "qcom,apss-wdt-glymur", "qcom,kpss-wdt"; - reg = <0x0 0x17600000 0x0 0x1000>; - clocks = <&sleep_clk>; - interrupts = ; - }; + tpdm@1000f000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1000f000 0x0 0x1000>; - 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>; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + spdm_tpdm_out: endpoint { + remote-endpoint = <&qdss_tpda_in1>; + }; + }; + }; }; - timer@17810000 { - compatible = "arm,armv7-timer-mem"; - reg = <0x0 0x17810000 0x0 0x1000>; - #address-cells = <2>; - #size-cells = <1>; - ranges = <0x0 0x0 0x0 0x0 0x20000000>; + funnel@10041000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x10041000 0x0 0x1000>; - frame@17811000 { - reg = <0x0 0x17811000 0x1000>, - <0x0 0x17812000 0x1000>; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - interrupts = , - ; + in-ports { + #address-cells = <1>; + #size-cells = <0>; - frame-number = <0>; - }; + port@0 { + reg = <0>; - frame@17813000 { - reg = <0x0 0x17813000 0x1000>; + funnel0_in0: endpoint { + remote-endpoint = <&tn_ag_out>; + }; + }; - interrupts = ; + port@6 { + reg = <6>; - frame-number = <1>; + funnel0_in6: endpoint { + remote-endpoint = <&qdss_tpda_out>; + }; + }; - status = "disabled"; + port@7 { + reg = <7>; + + funnel0_in7: endpoint { + remote-endpoint = <&stm_out>; + }; + }; }; - frame@17815000 { - reg = <0x0 0x17815000 0x1000>; + out-ports { + port { + funnel0_out: endpoint { + remote-endpoint = <&aoss_funnel_in6>; + }; + }; + }; + }; - interrupts = ; + tpdm@1102c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1102c000 0x0 0x1000>; - frame-number = <2>; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - status = "disabled"; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + gcc_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in36>; + }; + }; }; + }; - frame@17817000 { - reg = <0x0 0x17817000 0x1000>; + cti@11161000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x11161000 0x0 0x1000>; - interrupts = ; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; - frame-number = <3>; + cti@11162000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x11162000 0x0 0x1000>; - status = "disabled"; - }; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; - frame@17819000 { - reg = <0x0 0x17819000 0x1000>; + tpdm@11180000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11180000 0x0 0x1000>; - interrupts = ; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - frame-number = <4>; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; - status = "disabled"; + out-ports { + port { + cdsp_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_in0>; + }; + }; }; + }; - frame@1781b000 { - reg = <0x0 0x1781b000 0x1000>; + tpdm@11183000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11183000 0x0 0x1000>; - interrupts = ; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - frame-number = <5>; + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; - status = "disabled"; + out-ports { + port { + cdsp_cmsr_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_in3>; + }; + }; }; + }; - frame@1781d000 { - reg = <0x0 0x1781d000 0x1000>; + tpdm@11184000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11184000 0x0 0x1000>; - interrupts = ; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - frame-number = <6>; + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; - status = "disabled"; + out-ports { + port { + cdsp_cmsr2_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_in4>; + }; + }; }; }; - apps_rsc: rsc@18900000 { + 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>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + cdsp_dpm1_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_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>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + cdsp_dpm2_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_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>; + + cdsp_tpda_in0: endpoint { + remote-endpoint = <&cdsp_tpdm_out>; + }; + }; + + port@1 { + reg = <1>; + + cdsp_tpda_in1: endpoint { + remote-endpoint = <&cdsp_llm_tpdm_out>; + }; + }; + + port@2 { + reg = <2>; + + cdsp_tpda_in2: endpoint { + remote-endpoint = <&cdsp_llm2_tpdm_out>; + }; + }; + + port@3 { + reg = <3>; + + cdsp_tpda_in3: endpoint { + remote-endpoint = <&cdsp_cmsr_tpdm_out>; + }; + }; + + port@4 { + reg = <4>; + + cdsp_tpda_in4: endpoint { + remote-endpoint = <&cdsp_cmsr2_tpdm_out>; + }; + }; + + port@5 { + reg = <5>; + + cdsp_tpda_in5: endpoint { + remote-endpoint = <&cdsp_dpm1_tpdm_out>; + }; + }; + + port@6 { + reg = <6>; + + cdsp_tpda_in6: endpoint { + remote-endpoint = <&cdsp_dpm2_tpdm_out>; + }; + }; + }; + + out-ports { + port { + cdsp_tpda_out: endpoint { + remote-endpoint = <&cdsp_funnel_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 { + cdsp_funnel_in0: endpoint { + remote-endpoint = <&cdsp_tpda_out>; + }; + }; + }; + + out-ports { + port { + cdsp_funnel_out: endpoint { + remote-endpoint = <&tn_ag_in53>; + }; + }; + }; + }; + + cti@11193000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x11193000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + cti@111ab000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x111ab000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + tpdm@111d0000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x111d0000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + qm_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in35>; + }; + }; + }; + }; + + tn@11200000 { + compatible = "qcom,coresight-tnoc", "arm,primecell"; + reg = <0x0 0x11200000 0x0 0x4200>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@6 { + reg = <6>; + + tn_ag_in6: endpoint { + remote-endpoint = <&mm_dsb_tpdm_out>; + }; + }; + + port@10 { + reg = <0x10>; + + tn_ag_in16: endpoint { + remote-endpoint = <&east_dsb_tpdm_out>; + }; + }; + + port@21 { + reg = <0x21>; + + tn_ag_in33: endpoint { + remote-endpoint = <&west_dsb_tpdm_out>; + }; + }; + + port@23 { + reg = <0x23>; + + tn_ag_in35: endpoint { + remote-endpoint = <&qm_tpdm_out>; + }; + }; + + port@24 { + reg = <0x24>; + + tn_ag_in36: endpoint { + remote-endpoint = <&gcc_tpdm_out>; + }; + }; + + port@32 { + reg = <0x32>; + + tn_ag_in50: endpoint { + remote-endpoint = <&pcie_rscc_tpda_out>; + }; + }; + + port@35 { + reg = <0x35>; + + tn_ag_in53: endpoint { + remote-endpoint = <&cdsp_funnel_out>; + }; + }; + + port@3f { + reg = <0x3f>; + + tn_ag_in63: endpoint { + remote-endpoint = <¢er_dsb_tpdm_out>; + }; + }; + + port@40 { + reg = <0x40>; + + tn_ag_in64: endpoint { + remote-endpoint = <&ipcc_cmb_tpdm_out>; + }; + }; + + port@41 { + reg = <0x41>; + + tn_ag_in65: endpoint { + remote-endpoint = <&qrng_tpdm_out>; + }; + }; + + port@42 { + reg = <0x42>; + + tn_ag_in66: endpoint { + remote-endpoint = <&pmu_tpdm_out>; + }; + }; + + port@43 { + reg = <0x43>; + + tn_ag_in67: endpoint { + remote-endpoint = <&rdpm_west_cmb0_tpdm_out>; + }; + }; + + port@44 { + reg = <0x44>; + + tn_ag_in68: endpoint { + remote-endpoint = <&rdpm_west_cmb1_tpdm_out>; + }; + }; + + port@45 { + reg = <0x45>; + + tn_ag_in69: endpoint { + remote-endpoint = <&rdpm_west_cmb2_tpdm_out>; + }; + }; + + port@4b { + reg = <0x4b>; + + tn_ag_in75: endpoint { + remote-endpoint = <&south_dsb2_tpdm_out>; + }; + }; + + port@52 { + reg = <0x52>; + + tn_ag_in82: endpoint { + remote-endpoint = <&south_dsb_tpdm_out>; + }; + }; + + port@53 { + reg = <0x53>; + + tn_ag_in83: endpoint { + remote-endpoint = <¢er_dsb1_tpdm_out>; + }; + }; + }; + + out-ports { + port { + tn_ag_out: endpoint { + remote-endpoint = <&funnel0_in0>; + }; + }; + }; + }; + + tpdm@11207000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11207000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + mm_dsb_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in6>; + }; + }; + }; + }; + + tpdm@1120b000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1120b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + east_dsb_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in16>; + }; + }; + }; + }; + + tpdm@11213000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11213000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + west_dsb_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in33>; + }; + }; + }; + }; + + tpdm@11219000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11219000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + center_dsb_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in63>; + }; + }; + }; + }; + + tpdm@1121a000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1121a000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + ipcc_cmb_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in64>; + }; + }; + }; + }; + + tpdm@1121b000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1121b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + qrng_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in65>; + }; + }; + }; + }; + + tpdm@1121c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1121c000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + pmu_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in66>; + }; + }; + }; + }; + + tpdm@1121d000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1121d000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + rdpm_west_cmb0_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in67>; + }; + }; + }; + }; + + tpdm@1121e000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1121e000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + rdpm_west_cmb1_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in68>; + }; + }; + }; + }; + + tpdm@1121f000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x1121f000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + rdpm_west_cmb2_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in69>; + }; + }; + }; + }; + + tpdm@11220000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11220000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + center_dsb1_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in83>; + }; + }; + }; + }; + + tpdm@11224000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11224000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + south_dsb2_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in75>; + }; + }; + }; + }; + + tpdm@11228000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11228000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + south_dsb_tpdm_out: endpoint { + remote-endpoint = <&tn_ag_in82>; + }; + }; + }; + }; + + tpdm@11470000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11470000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + pcie_rscc_tpdm_out: endpoint { + remote-endpoint = <&pcie_rscc_tpda_in0>; + }; + }; + }; + }; + + tpda@11471000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x11471000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + pcie_rscc_tpda_in0: endpoint { + remote-endpoint = <&pcie_rscc_tpdm_out>; + }; + }; + }; + + out-ports { + port { + pcie_rscc_tpda_out: endpoint { + remote-endpoint = <&tn_ag_in50>; + }; + }; + }; + }; + + tpdm@11c03000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11c03000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio4_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in4>; + }; + }; + }; + }; + + funnel@11c04000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x11c04000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@5 { + reg = <5>; + + aoss_funnel_in5: endpoint { + remote-endpoint = <&aoss_tpda_out>; + }; + }; + + port@6 { + reg = <6>; + + aoss_funnel_in6: endpoint { + remote-endpoint = <&funnel0_out>; + }; + }; + }; + + out-ports { + port { + aoss_funnel_out: endpoint { + remote-endpoint = <&etf0_in>; + }; + }; + }; + }; + + tmc_etf: tmc@11c05000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x11c05000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + etf0_in: endpoint { + remote-endpoint = <&aoss_funnel_out>; + }; + }; + }; + + out-ports { + port { + etf0_out: endpoint { + remote-endpoint = <&swao_rep_in>; + }; + }; + }; + }; + + replicator@11c06000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x11c06000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + swao_rep_in: endpoint { + remote-endpoint = <&etf0_out>; + }; + }; + }; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + swao_rep_out1: endpoint { + remote-endpoint = <&eud_in>; + }; + }; + }; + }; + + tpda@11c08000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x11c08000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + aoss_tpda_in0: endpoint { + remote-endpoint = <&swao_prio0_tpdm_out>; + }; + }; + + port@1 { + reg = <1>; + + aoss_tpda_in1: endpoint { + remote-endpoint = <&swao_prio1_tpdm_out>; + }; + }; + + port@2 { + reg = <2>; + + aoss_tpda_in2: endpoint { + remote-endpoint = <&swao_prio2_tpdm_out>; + }; + }; + + port@3 { + reg = <3>; + + aoss_tpda_in3: endpoint { + remote-endpoint = <&swao_prio3_tpdm_out>; + }; + }; + + port@4 { + reg = <4>; + + aoss_tpda_in4: endpoint { + remote-endpoint = <&swao_prio4_tpdm_out>; + }; + }; + + port@5 { + reg = <5>; + + aoss_tpda_in5: endpoint { + remote-endpoint = <&swao_tpdm_out>; + }; + }; + }; + + out-ports { + port { + aoss_tpda_out: endpoint { + remote-endpoint = <&aoss_funnel_in5>; + }; + }; + }; + }; + + tpdm@11c09000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11c09000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio0_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in0>; + }; + }; + }; + }; + + tpdm@11c0a000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11c0a000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio1_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in1>; + }; + }; + }; + }; + + tpdm@11c0b000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11c0b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio2_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in2>; + }; + }; + }; + }; + + tpdm@11c0c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11c0c000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio3_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in3>; + }; + }; + }; + }; + + cti@11c42000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x11c42000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + cti@11c4b000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x11c4b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + tpdm@11c0d000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x11c0d000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + swao_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in5>; + }; + }; + }; + }; + + 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>, @@ -6853,4 +7968,30 @@ }; }; }; + + tpdm-cdsp-llm { + compatible = "qcom,coresight-static-tpdm"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + cdsp_llm_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_in1>; + }; + }; + }; + }; + + tpdm-cdsp-llm2 { + compatible = "qcom,coresight-static-tpdm"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + cdsp_llm2_tpdm_out: endpoint { + remote-endpoint = <&cdsp_tpda_in2>; + }; + }; + }; + }; }; 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 619/659] 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 98e337d73e91592479c85518c29445ced7106ff5 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:20 +0530 Subject: [PATCH 620/659] 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 e087673237636..fc8fb724aed55 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25961,6 +25961,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 82666a05889f6827fb469aa59c875d86cfff41a6 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Tue, 23 Dec 2025 18:02:22 +0530 Subject: [PATCH 621/659] 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 63a82e7a8bf88..bbc82253f76b3 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml @@ -77,6 +77,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 f02e75e749cc2093690cf8b14ec14f9d6db45dba Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Tue, 23 Dec 2025 18:02:23 +0530 Subject: [PATCH 622/659] 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 9af47570316b56382d744d424d86c16bbb7c758a Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 30 Dec 2025 23:08:36 +0530 Subject: [PATCH 623/659] FROMGIT: arm64: dts: qcom: hamoa: Extend the gcc input clock list The recent dt-bindings were updated for the missing RX/TX symbol clocks for UFS. Extend the existing list to make sure the DT contains the expected amount of 'clocks' entries. Signed-off-by: Taniya Das Reviewed-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/lkml/20251230-ufs_symbol_clk-v1-3-47d46b24c087@oss.qualcomm.com Signed-off-by: Pradeep P V K --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 8e9f2220dac00..93f308d6c948b 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -834,6 +834,9 @@ <0>, <0>, <0>, + <0>, + <0>, + <0>, <0>; power-domains = <&rpmhpd RPMHPD_CX>; From b96ba18d39f4ea7360600491a7f31045050064cf Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Wed, 11 Feb 2026 18:59:25 +0530 Subject: [PATCH 624/659] 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 93f308d6c948b..8bfe6d3c603fb 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -835,9 +835,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>; @@ -3877,6 +3877,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>; + }; + }; + }; + tcsr_mutex: hwlock@1f40000 { compatible = "qcom,tcsr-mutex"; reg = <0 0x01f40000 0 0x20000>; From 288231937cd4fc61d950555139bf88fb58ad40d8 Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Wed, 11 Feb 2026 18:59:26 +0530 Subject: [PATCH 625/659] 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 f352cd3c0dcd1..6578bb2e47613 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -1396,6 +1396,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 2de2c8811b30a7559e85dd2ee348228119610869 Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Wed, 11 Feb 2026 15:00:45 +0530 Subject: [PATCH 626/659] 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 6578bb2e47613..cab8813cb9727 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -1079,6 +1079,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"; }; @@ -1261,6 +1277,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 22ab1d0be514ca0b6e28ba54637c4cb0735170aa Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 25 Nov 2025 17:46:18 +0530 Subject: [PATCH 627/659] FROMLIST: dt-bindings: phy: qcom-edp: Add missing clock for X Elite On X Elite platform, the eDP PHY uses one more clock called ref. The current X Elite devices supported upstream work fine without this clock, because the boot firmware leaves this clock enabled. But we should not rely on that. Also, even though this change breaks the ABI, it is needed in order to make the driver disables this clock along with the other ones, for a proper bring-down of the entire PHY. So attach the this ref clock to the PHY. Cc: stable@vger.kernel.org # v6.10 Fixes: 5d5607861350 ("dt-bindings: phy: qcom-edp: Add X1E80100 PHY compatibles") Link:https://lore.kernel.org/all/20251030-phy-qcom-edp-add-missing-refclk-v5-1-fce8c76f855a@linaro.org/ Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Signed-off-by: Abel Vesa --- .../devicetree/bindings/phy/qcom,edp-phy.yaml | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml index eb97181cbb957..bfc4d75f50ff9 100644 --- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml @@ -37,12 +37,15 @@ properties: - description: PLL register block clocks: - maxItems: 2 + minItems: 2 + maxItems: 3 clock-names: + minItems: 2 items: - const: aux - const: cfg_ahb + - const: ref "#clock-cells": const: 1 @@ -64,6 +67,29 @@ required: - "#clock-cells" - "#phy-cells" +allOf: + - if: + properties: + compatible: + enum: + - qcom,x1e80100-dp-phy + then: + properties: + clocks: + minItems: 3 + maxItems: 3 + clock-names: + minItems: 3 + maxItems: 3 + else: + properties: + clocks: + minItems: 2 + maxItems: 2 + clock-names: + minItems: 2 + maxItems: 2 + additionalProperties: false examples: From 635edc07668276f114474bd1b8fb0b89337ff2df Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 10 Oct 2025 16:30:30 +0530 Subject: [PATCH 628/659] FROMLIST: phy: qcom: edp: Make the number of clocks flexible On X Elite, the DP PHY needs another clock called ref, while all other platforms do not. The current X Elite devices supported upstream work fine without this clock, because the boot firmware leaves this clock enabled. But we should not rely on that. Also, even though this change breaks the ABI, it is needed in order to make the driver disables this clock along with the other ones, for a proper bring-down of the entire PHY. So in order to handle these clocks on different platforms, make the driver get all the clocks regardless of how many there are provided. Cc: stable@vger.kernel.org # v6.10 Fixes: db83c107dc29 ("phy: qcom: edp: Add v6 specific ops and X1E80100 platform support") Link:https://lore.kernel.org/all/20251030-phy-qcom-edp-add-missing-refclk-v5-2-fce8c76f855a@linaro.org/ Reviewed-by: Dmitry Baryshkov Reviewed-by: Bjorn Andersson Signed-off-by: Abel Vesa --- drivers/phy/qualcomm/phy-qcom-edp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c index f1b51018683d5..ca9bb9d70e29e 100644 --- a/drivers/phy/qualcomm/phy-qcom-edp.c +++ b/drivers/phy/qualcomm/phy-qcom-edp.c @@ -103,7 +103,9 @@ struct qcom_edp { struct phy_configure_opts_dp dp_opts; - struct clk_bulk_data clks[2]; + struct clk_bulk_data *clks; + int num_clks; + struct regulator_bulk_data supplies[2]; bool is_edp; @@ -218,7 +220,7 @@ static int qcom_edp_phy_init(struct phy *phy) if (ret) return ret; - ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks); + ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks); if (ret) goto out_disable_supplies; @@ -885,7 +887,7 @@ static int qcom_edp_phy_exit(struct phy *phy) { struct qcom_edp *edp = phy_get_drvdata(phy); - clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks); + clk_bulk_disable_unprepare(edp->num_clks, edp->clks); regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); return 0; @@ -1092,11 +1094,9 @@ static int qcom_edp_phy_probe(struct platform_device *pdev) if (IS_ERR(edp->pll)) return PTR_ERR(edp->pll); - edp->clks[0].id = "aux"; - edp->clks[1].id = "cfg_ahb"; - ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks); - if (ret) - return ret; + edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks); + if (edp->num_clks < 0) + return dev_err_probe(dev, edp->num_clks, "failed to parse clocks\n"); edp->supplies[0].supply = "vdda-phy"; edp->supplies[1].supply = "vdda-pll"; From 7a1aa6c80e821ec06b51115ea5f29bd88987ce79 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Fri, 10 Oct 2025 16:50:16 +0530 Subject: [PATCH 629/659] FROMLIST: dt-bindings: phy: qcom-edp: Add eDP ref clk for sa8775p When the initial contribution of eDP PHY for sa8775p was done, eDP reference clock voting was missed. It worked fine at that time because the clock was already enabled by the UFS PHY driver. After commit 77d2fa54a945 ("scsi: ufs: qcom : Refactor phy_power_on/off calls"), eDP reference clock started getting turned off, leading to 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/20251104114327.27842-2-riteshk@qti.qualcomm.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 bfc4d75f50ff9..ba757b08b9b1b 100644 --- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml @@ -72,6 +72,7 @@ allOf: properties: compatible: enum: + - qcom,sa8775p-edp-phy - qcom,x1e80100-dp-phy then: properties: From 6279762caf7a596aebefedfd20ec52330ad84a96 Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:37 +0800 Subject: [PATCH 630/659] FROMLIST: dt-bindings: phy: Add QMP USB3+DP PHY for QCS615 Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY on QCS615 Platform. This PHY supports both USB3 and DP functionality over USB-C, with PHY mode switching capability. It does not support combo mode. Reviewed-by: Rob Herring (Arm) Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-1-dc5edaac6c2b@oss.qualcomm.com/ --- .../phy/qcom,qcs615-qmp-usb3dp-phy.yaml | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml new file mode 100644 index 0000000000000..efb465c71c1b5 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615) + +maintainers: + - Xiangxu Yin + +description: + The QMP PHY controller supports physical layer functionality for both USB3 + and DisplayPort over USB-C. While it enables mode switching between USB3 and + DisplayPort, but does not support combo mode. + +properties: + compatible: + enum: + - qcom,qcs615-qmp-usb3-dp-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 4 + + clock-names: + items: + - const: aux + - const: ref + - const: cfg_ahb + - const: pipe + + resets: + maxItems: 2 + + reset-names: + items: + - const: phy_phy + - const: dp_phy + + vdda-phy-supply: true + + vdda-pll-supply: true + + "#clock-cells": + const: 1 + description: + See include/dt-bindings/phy/phy-qcom-qmp.h + + "#phy-cells": + const: 1 + description: + See include/dt-bindings/phy/phy-qcom-qmp.h + + qcom,tcsr-reg: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to TCSR hardware block + - description: offset of the VLS CLAMP register + - description: offset of the PHY mode register + description: Clamp and PHY mode register present in the TCSR + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - vdda-phy-supply + - vdda-pll-supply + - "#clock-cells" + - "#phy-cells" + - qcom,tcsr-reg + +additionalProperties: false + +examples: + - | + #include + #include + + phy@88e8000 { + compatible = "qcom,qcs615-qmp-usb3-dp-phy"; + reg = <0x88e8000 0x2000>; + + clocks = <&gcc GCC_USB2_SEC_PHY_AUX_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_CLK>, + <&gcc GCC_AHB2PHY_WEST_CLK>, + <&gcc GCC_USB2_SEC_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "cfg_ahb", + "pipe"; + + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, + <&gcc GCC_USB3_DP_PHY_SEC_BCR>; + reset-names = "phy_phy", + "dp_phy"; + + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + #clock-cells = <1>; + #phy-cells = <1>; + + qcom,tcsr-reg = <&tcsr 0xbff0 0xb24c>; + }; From e68a54f233ca8ac13e2a4613da9d5bc28e1c35ec Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Thu, 13 Nov 2025 16:00:16 +0800 Subject: [PATCH 631/659] FROMLIST: phy: qcom: qmp-usbc: Rename USB-specific ops to prepare for DP support To support following DisplayPort (DP) mode over the Type-C PHY, rename USB-specific functions and ops to clearly separate them from common or DP-related logic. This is a preparatory cleanup to enable USB + DP dual mode. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-2-dc5edaac6c2b@oss.qualcomm.com/ Signed-off-by: Yongxing Mou --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 55 ++++++++++++------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 5e7fcb26744a4..62920dd2aed39 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -342,11 +342,10 @@ struct qmp_usbc { struct mutex phy_mutex; + struct phy *usb_phy; enum phy_mode mode; unsigned int usb_init_count; - struct phy *phy; - struct clk_fixed_rate pipe_clk_fixed; struct typec_switch_dev *sw; @@ -454,7 +453,7 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = { .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; -static int qmp_usbc_init(struct phy *phy) +static int qmp_usbc_com_init(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -504,7 +503,7 @@ static int qmp_usbc_init(struct phy *phy) return ret; } -static int qmp_usbc_exit(struct phy *phy) +static int qmp_usbc_com_exit(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -518,7 +517,7 @@ static int qmp_usbc_exit(struct phy *phy) return 0; } -static int qmp_usbc_power_on(struct phy *phy) +static int qmp_usbc_usb_power_on(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -566,7 +565,7 @@ static int qmp_usbc_power_on(struct phy *phy) return ret; } -static int qmp_usbc_power_off(struct phy *phy) +static int qmp_usbc_usb_power_off(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -587,20 +586,20 @@ static int qmp_usbc_power_off(struct phy *phy) return 0; } -static int qmp_usbc_enable(struct phy *phy) +static int qmp_usbc_usb_enable(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); int ret; mutex_lock(&qmp->phy_mutex); - ret = qmp_usbc_init(phy); + ret = qmp_usbc_com_init(phy); if (ret) goto out_unlock; - ret = qmp_usbc_power_on(phy); + ret = qmp_usbc_usb_power_on(phy); if (ret) { - qmp_usbc_exit(phy); + qmp_usbc_com_exit(phy); goto out_unlock; } @@ -611,19 +610,19 @@ static int qmp_usbc_enable(struct phy *phy) return ret; } -static int qmp_usbc_disable(struct phy *phy) +static int qmp_usbc_usb_disable(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); int ret; qmp->usb_init_count--; - ret = qmp_usbc_power_off(phy); + ret = qmp_usbc_usb_power_off(phy); if (ret) return ret; - return qmp_usbc_exit(phy); + return qmp_usbc_com_exit(phy); } -static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode) +static int qmp_usbc_usb_set_mode(struct phy *phy, enum phy_mode mode, int submode) { struct qmp_usbc *qmp = phy_get_drvdata(phy); @@ -632,10 +631,10 @@ static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode) return 0; } -static const struct phy_ops qmp_usbc_phy_ops = { - .init = qmp_usbc_enable, - .exit = qmp_usbc_disable, - .set_mode = qmp_usbc_set_mode, +static const struct phy_ops qmp_usbc_usb_phy_ops = { + .init = qmp_usbc_usb_enable, + .exit = qmp_usbc_usb_disable, + .set_mode = qmp_usbc_usb_set_mode, .owner = THIS_MODULE, }; @@ -690,7 +689,7 @@ static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev) dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); - if (!qmp->phy->init_count) { + if (!qmp->usb_init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; } @@ -710,7 +709,7 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev) dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); - if (!qmp->phy->init_count) { + if (!qmp->usb_init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; } @@ -865,11 +864,11 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw, qmp->orientation = orientation; if (qmp->usb_init_count) { - qmp_usbc_power_off(qmp->phy); - qmp_usbc_exit(qmp->phy); + qmp_usbc_usb_power_off(qmp->usb_phy); + qmp_usbc_com_exit(qmp->usb_phy); - qmp_usbc_init(qmp->phy); - qmp_usbc_power_on(qmp->phy); + qmp_usbc_com_init(qmp->usb_phy); + qmp_usbc_usb_power_on(qmp->usb_phy); } mutex_unlock(&qmp->phy_mutex); @@ -1097,14 +1096,14 @@ static int qmp_usbc_probe(struct platform_device *pdev) if (ret) goto err_node_put; - qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops); - if (IS_ERR(qmp->phy)) { - ret = PTR_ERR(qmp->phy); + qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops); + if (IS_ERR(qmp->usb_phy)) { + ret = PTR_ERR(qmp->usb_phy); dev_err(dev, "failed to create PHY: %d\n", ret); goto err_node_put; } - phy_set_drvdata(qmp->phy, qmp); + phy_set_drvdata(qmp->usb_phy, qmp); of_node_put(np); From 58b9cdcd788a2e2accc20b1b9e342b81e58e68aa Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:39 +0800 Subject: [PATCH 632/659] FROMLIST: phy: qcom: qmp-usbc: Add DP-related fields for USB/DP switchable PHY Extend qmp_usbc_offsets and qmp_phy_cfg with DP-specific fields, including register offsets, init tables, and callback hooks. Also update qmp_usbc struct to track DP-related resources and state. This enables support for USB/DP switchable Type-C PHYs that operate in either mode. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-3-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 54 ++++++++++++++++++++---- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 62920dd2aed39..de28c3464a40e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -293,13 +293,18 @@ struct qmp_usbc_offsets { /* for PHYs with >= 2 lanes */ u16 tx2; u16 rx2; + + u16 dp_serdes; + u16 dp_txa; + u16 dp_txb; + u16 dp_dp_phy; }; -/* struct qmp_phy_cfg - per-PHY initialization config */ +struct qmp_usbc; struct qmp_phy_cfg { const struct qmp_usbc_offsets *offsets; - /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ + /* Init sequence for USB PHY blocks - serdes, tx, rx, pcs */ const struct qmp_phy_init_tbl *serdes_tbl; int serdes_tbl_num; const struct qmp_phy_init_tbl *tx_tbl; @@ -309,6 +314,27 @@ struct qmp_phy_cfg { const struct qmp_phy_init_tbl *pcs_tbl; int pcs_tbl_num; + /* Init sequence for DP PHY blocks - serdes, tx, rbr, hbr, hbr2 */ + const struct qmp_phy_init_tbl *dp_serdes_tbl; + int dp_serdes_tbl_num; + const struct qmp_phy_init_tbl *dp_tx_tbl; + int dp_tx_tbl_num; + const struct qmp_phy_init_tbl *serdes_tbl_rbr; + int serdes_tbl_rbr_num; + const struct qmp_phy_init_tbl *serdes_tbl_hbr; + int serdes_tbl_hbr_num; + const struct qmp_phy_init_tbl *serdes_tbl_hbr2; + int serdes_tbl_hbr2_num; + + const u8 (*swing_tbl)[4][4]; + const u8 (*pre_emphasis_tbl)[4][4]; + + /* DP PHY callbacks */ + void (*dp_aux_init)(struct qmp_usbc *qmp); + void (*configure_dp_tx)(struct qmp_usbc *qmp); + int (*configure_dp_phy)(struct qmp_usbc *qmp); + int (*calibrate_dp_phy)(struct qmp_usbc *qmp); + /* regulators to be requested */ const char * const *vreg_list; int num_vregs; @@ -329,24 +355,36 @@ struct qmp_usbc { void __iomem *rx; void __iomem *tx2; void __iomem *rx2; - - struct regmap *tcsr_map; - u32 vls_clamp_reg; + void __iomem *dp_dp_phy; + void __iomem *dp_tx; + void __iomem *dp_tx2; + void __iomem *dp_serdes; struct clk *pipe_clk; + struct clk_fixed_rate pipe_clk_fixed; + + struct clk_hw dp_link_hw; + struct clk_hw dp_pixel_hw; struct clk_bulk_data *clks; int num_clks; int num_resets; struct reset_control_bulk_data *resets; struct regulator_bulk_data *vregs; + struct regmap *tcsr_map; + u32 vls_clamp_reg; + u32 dp_phy_mode_reg; + struct mutex phy_mutex; struct phy *usb_phy; enum phy_mode mode; unsigned int usb_init_count; - struct clk_fixed_rate pipe_clk_fixed; + struct phy *dp_phy; + unsigned int dp_aux_cfg; + struct phy_configure_opts_dp dp_opts; + unsigned int dp_init_count; struct typec_switch_dev *sw; enum typec_orientation orientation; @@ -689,7 +727,7 @@ static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev) dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); - if (!qmp->usb_init_count) { + if (!qmp->usb_init_count && !qmp->dp_init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; } @@ -709,7 +747,7 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev) dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); - if (!qmp->usb_init_count) { + if (!qmp->usb_init_count && !qmp->dp_init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; } From 702e0e76df9d67a0da911d37648e9c08e7e3e21e Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:40 +0800 Subject: [PATCH 633/659] FROMLIST: phy: qcom: qmp-usbc: Add regulator init_load support QMP USBC PHY drivers previously did not set init_load_uA for regulators, which could result in incorrect vote levels. This patch introduces regulator definitions with proper init_load_uA values based on each chip's power grid design. QCS615 USB3 PHY was previously reusing qcm2290_usb3phy_cfg, but its regulator requirements differ. A new qcs615_usb3phy_cfg is added to reflect the correct settings. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-4-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 68 ++++++++++++++---------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index de28c3464a40e..3b48c69f9c3cb 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -336,7 +336,7 @@ struct qmp_phy_cfg { int (*calibrate_dp_phy)(struct qmp_usbc *qmp); /* regulators to be requested */ - const char * const *vreg_list; + const struct regulator_bulk_data *vreg_list; int num_vregs; /* array of registers with different offsets */ @@ -428,9 +428,19 @@ static const char * const usb3phy_reset_l[] = { "phy_phy", "phy", }; -/* list of regulators */ -static const char * const qmp_phy_vreg_l[] = { - "vdda-phy", "vdda-pll", +static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 68600 }, + { .supply = "vdda-pll", .init_load_uA = 14200 }, +}; + +static const struct regulator_bulk_data qmp_phy_sm2290_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 66100 }, + { .supply = "vdda-pll", .init_load_uA = 13300 }, +}; + +static const struct regulator_bulk_data qmp_phy_qcs615_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 50000 }, + { .supply = "vdda-pll", .init_load_uA = 20000 }, }; static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = { @@ -454,8 +464,8 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl), .pcs_tbl = msm8998_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = qmp_phy_msm8998_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, }; @@ -470,8 +480,8 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = qmp_phy_sm2290_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_sm2290_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; @@ -486,8 +496,24 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(sdm660_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = qmp_phy_msm8998_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, +}; + +static const struct qmp_phy_cfg qcs615_usb3phy_cfg = { + .offsets = &qmp_usbc_offsets_v3_qcm2290, + + .serdes_tbl = qcm2290_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), + .tx_tbl = qcm2290_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), + .rx_tbl = qcm2290_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), + .pcs_tbl = qcm2290_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + .vreg_list = qmp_phy_qcs615_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; @@ -773,23 +799,6 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = { qmp_usbc_runtime_resume, NULL) }; -static int qmp_usbc_vreg_init(struct qmp_usbc *qmp) -{ - const struct qmp_phy_cfg *cfg = qmp->cfg; - struct device *dev = qmp->dev; - int num = cfg->num_vregs; - int i; - - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); - if (!qmp->vregs) - return -ENOMEM; - - for (i = 0; i < num; i++) - qmp->vregs[i].supply = cfg->vreg_list[i]; - - return devm_regulator_bulk_get(dev, num, qmp->vregs); -} - static int qmp_usbc_reset_init(struct qmp_usbc *qmp, const char *const *reset_list, int num_resets) @@ -1097,7 +1106,8 @@ static int qmp_usbc_probe(struct platform_device *pdev) mutex_init(&qmp->phy_mutex); - ret = qmp_usbc_vreg_init(qmp); + ret = devm_regulator_bulk_get_const(qmp->dev, qmp->cfg->num_vregs, + qmp->cfg->vreg_list, &qmp->vregs); if (ret) return ret; @@ -1163,7 +1173,7 @@ static const struct of_device_id qmp_usbc_of_match_table[] = { .data = &qcm2290_usb3phy_cfg, }, { .compatible = "qcom,qcs615-qmp-usb3-phy", - .data = &qcm2290_usb3phy_cfg, + .data = &qcs615_usb3phy_cfg, }, { .compatible = "qcom,sdm660-qmp-usb3-phy", .data = &sdm660_usb3phy_cfg, From 1e634bd86b4430764e57545e1569dc82035f8b5c Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:41 +0800 Subject: [PATCH 634/659] FROMLIST: phy: qcom: qmp-usbc: Move reset config into PHY cfg The original reset list only works for USB-only PHYs. USB3DP PHYs require different reset names such as "dp_phy", so they need a separate list. Moving reset configuration into qmp_phy_cfg allows per-PHY customization without adding special-case logic in DT parsing. The legacy DT path keeps using the old hardcoded list, while non-legacy paths use cfg->reset_list. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-5-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 3b48c69f9c3cb..f9e20f43435c0 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -335,7 +335,8 @@ struct qmp_phy_cfg { int (*configure_dp_phy)(struct qmp_usbc *qmp); int (*calibrate_dp_phy)(struct qmp_usbc *qmp); - /* regulators to be requested */ + const char * const *reset_list; + int num_resets; const struct regulator_bulk_data *vreg_list; int num_vregs; @@ -464,6 +465,8 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl), .pcs_tbl = msm8998_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), .vreg_list = qmp_phy_msm8998_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, @@ -480,6 +483,8 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), .vreg_list = qmp_phy_sm2290_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_sm2290_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, @@ -496,6 +501,8 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(sdm660_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), .vreg_list = qmp_phy_msm8998_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, @@ -512,6 +519,8 @@ static const struct qmp_phy_cfg qcs615_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), .vreg_list = qmp_phy_qcs615_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, @@ -1051,8 +1060,7 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) "failed to get pipe clock\n"); } - ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l, - ARRAY_SIZE(usb3phy_reset_l)); + ret = qmp_usbc_reset_init(qmp, cfg->reset_list, cfg->num_resets); if (ret) return ret; From 44d0ef8e6b1ee1391b480c9d4d05a1ebfa49c829 Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:42 +0800 Subject: [PATCH 635/659] FROMLIST: phy: qcom: qmp-usbc: add DP link and vco_div clocks for DP PHY USB3DP PHY requires link and vco_div clocks when operating in DP mode. Extend qmp_usbc_register_clocks and the clock provider logic to register these clocks along with the existing pipe clock, to support both USB and DP configurations. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-6-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 210 ++++++++++++++++++++++- 1 file changed, 204 insertions(+), 6 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index f9e20f43435c0..7139f4dab82fd 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "phy-qcom-qmp-common.h" @@ -851,9 +852,23 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp) return devm_clk_bulk_get_optional(dev, num, qmp->clks); } -static void phy_clk_release_provider(void *res) +static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec, void *data) { - of_clk_del_provider(res); + struct qmp_usbc *qmp = data; + + if (clkspec->args_count == 0) + return &qmp->pipe_clk_fixed.hw; + + switch (clkspec->args[0]) { + case QMP_USB43DP_USB3_PIPE_CLK: + return &qmp->pipe_clk_fixed.hw; + case QMP_USB43DP_DP_LINK_CLK: + return &qmp->dp_link_hw; + case QMP_USB43DP_DP_VCO_DIV_CLK: + return &qmp->dp_pixel_hw; + } + + return ERR_PTR(-EINVAL); } /* @@ -878,12 +893,14 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np) { struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; struct clk_init_data init = { }; + char name[64]; int ret; ret = of_property_read_string(np, "clock-output-names", &init.name); if (ret) { - dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); - return ret; + /* Clock name is not mandatory. */ + snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev)); + init.name = name; } init.ops = &clk_fixed_rate_ops; @@ -892,10 +909,184 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np) fixed->fixed_rate = 125000000; fixed->hw.init = &init; - ret = devm_clk_hw_register(qmp->dev, &fixed->hw); + return devm_clk_hw_register(qmp->dev, &fixed->hw); +} + + +/* + * Display Port PLL driver block diagram for branch clocks + * + * +------------------------------+ + * | DP_VCO_CLK | + * | | + * | +-------------------+ | + * | | (DP PLL/VCO) | | + * | +---------+---------+ | + * | v | + * | +----------+-----------+ | + * | | hsclk_divsel_clk_src | | + * | +----------+-----------+ | + * +------------------------------+ + * | + * +---------<---------v------------>----------+ + * | | + * +--------v----------------+ | + * | dp_phy_pll_link_clk | | + * | link_clk | | + * +--------+----------------+ | + * | | + * | | + * v v + * Input to DISPCC block | + * for link clk, crypto clk | + * and interface clock | + * | + * | + * +--------<------------+-----------------+---<---+ + * | | | + * +----v---------+ +--------v-----+ +--------v------+ + * | vco_divided | | vco_divided | | vco_divided | + * | _clk_src | | _clk_src | | _clk_src | + * | | | | | | + * |divsel_six | | divsel_two | | divsel_four | + * +-------+------+ +-----+--------+ +--------+------+ + * | | | + * v---->----------v-------------<------v + * | + * +----------+-----------------+ + * | dp_phy_pll_vco_div_clk | + * +---------+------------------+ + * | + * v + * Input to DISPCC block + * for DP pixel clock + * + */ +static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + switch (req->rate) { + case 1620000000UL / 2: + case 2700000000UL / 2: + /* 5.4 is same link rate as 2.7GHz, i.e. div 4 */ + return 0; + default: + return -EINVAL; + } +} + +static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + const struct qmp_usbc *qmp; + const struct phy_configure_opts_dp *dp_opts; + + qmp = container_of(hw, struct qmp_usbc, dp_pixel_hw); + + dp_opts = &qmp->dp_opts; + + switch (dp_opts->link_rate) { + case 1620: + return 1620000000UL / 2; + case 2700: + return 2700000000UL / 2; + case 5400: + return 5400000000UL / 4; + default: + return 0; + } +} + +static const struct clk_ops qmp_dp_pixel_clk_ops = { + .determine_rate = qmp_dp_pixel_clk_determine_rate, + .recalc_rate = qmp_dp_pixel_clk_recalc_rate, +}; + +static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + switch (req->rate) { + case 162000000: + case 270000000: + case 540000000: + return 0; + default: + return -EINVAL; + } +} + +static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + const struct qmp_usbc *qmp; + const struct phy_configure_opts_dp *dp_opts; + + qmp = container_of(hw, struct qmp_usbc, dp_link_hw); + dp_opts = &qmp->dp_opts; + + switch (dp_opts->link_rate) { + case 1620: + case 2700: + case 5400: + return dp_opts->link_rate * 100000; + default: + return 0; + } +} + +static const struct clk_ops qmp_dp_link_clk_ops = { + .determine_rate = qmp_dp_link_clk_determine_rate, + .recalc_rate = qmp_dp_link_clk_recalc_rate, +}; + +static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *np) +{ + struct clk_init_data init = { }; + char name[64]; + int ret; + + snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev)); + init.ops = &qmp_dp_link_clk_ops; + init.name = name; + qmp->dp_link_hw.init = &init; + ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw); + if (ret < 0) { + dev_err(qmp->dev, "link clk reg fail ret=%d\n", ret); + return ret; + } + + snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev)); + init.ops = &qmp_dp_pixel_clk_ops; + init.name = name; + qmp->dp_pixel_hw.init = &init; + ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw); + if (ret) { + dev_err(qmp->dev, "pxl clk reg fail ret=%d\n", ret); + return ret; + } + + return 0; +} + +static void phy_clk_release_provider(void *res) +{ + of_clk_del_provider(res); +} + +static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np) +{ + struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; + int ret; + + ret = phy_pipe_clk_register(qmp, np); if (ret) return ret; + if (qmp->dp_serdes != 0) { + ret = phy_dp_clks_register(qmp, np); + if (ret) + return ret; + } + + if (np == qmp->dev->of_node) + return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp); + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); if (ret) return ret; @@ -1040,6 +1231,13 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) if (IS_ERR(base)) return PTR_ERR(base); + if (offs->dp_serdes != 0) { + qmp->dp_serdes = base + offs->dp_serdes; + qmp->dp_tx = base + offs->dp_txa; + qmp->dp_tx2 = base + offs->dp_txb; + qmp->dp_dp_phy = base + offs->dp_dp_phy; + } + qmp->serdes = base + offs->serdes; qmp->pcs = base + offs->pcs; if (offs->pcs_misc) @@ -1148,7 +1346,7 @@ static int qmp_usbc_probe(struct platform_device *pdev) */ pm_runtime_forbid(dev); - ret = phy_pipe_clk_register(qmp, np); + ret = qmp_usbc_register_clocks(qmp, np); if (ret) goto err_node_put; From a743d70120ef7f5060a87b3a6ff7d9d559e4c685 Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:43 +0800 Subject: [PATCH 636/659] FROMLIST: phy: qcom: qmp-usbc: Move USB-only init to usb_power_on The current implementation programs USB-specific registers in qmp_usbc_com_init(), which is shared by both USB and DP modes. This causes unnecessary configuration when the PHY is used for DP. Move USB-only register setup from com_init to qmp_usbc_usb_power_on, so it runs only for USB mode. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-7-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 7139f4dab82fd..a971bdc3e7677 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -30,6 +30,8 @@ #include "phy-qcom-qmp-pcs-misc-v3.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 +#define SW_PORTSELECT_VAL BIT(0) +#define SW_PORTSELECT_MUX BIT(1) /* set of registers with offsets different per-PHY */ enum qphy_reg_layout { @@ -531,8 +533,6 @@ static int qmp_usbc_com_init(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; - void __iomem *pcs = qmp->pcs; - u32 val = 0; int ret; ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); @@ -557,16 +557,6 @@ static int qmp_usbc_com_init(struct phy *phy) if (ret) goto err_assert_reset; - qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); - -#define SW_PORTSELECT_VAL BIT(0) -#define SW_PORTSELECT_MUX BIT(1) - /* Use software based port select and switch on typec orientation */ - val = SW_PORTSELECT_MUX; - if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) - val |= SW_PORTSELECT_VAL; - writel(val, qmp->pcs_misc); - return 0; err_assert_reset: @@ -599,6 +589,14 @@ static int qmp_usbc_usb_power_on(struct phy *phy) unsigned int val; int ret; + qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); + + /* Use software based port select and switch on typec orientation */ + val = SW_PORTSELECT_MUX; + if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) + val |= SW_PORTSELECT_VAL; + writel(val, qmp->pcs_misc); + qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl, cfg->serdes_tbl_num); From 8b0e5e1631e7ff997e672fc6cfeefaed5a19919c Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:44 +0800 Subject: [PATCH 637/659] FROMLIST: phy: qcom: qmp-usbc: Add TCSR parsing and PHY mode setting Extend TCSR parsing to read optional dp_phy_mode_reg and add qmp_usbc_set_phy_mode() to switch between USB and DP modes when supported. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-8-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 25 ++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index a971bdc3e7677..fab6ccc4a5f12 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -529,6 +529,12 @@ static const struct qmp_phy_cfg qcs615_usb3phy_cfg = { .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; +static void qmp_usbc_set_phy_mode(struct qmp_usbc *qmp, bool is_dp) +{ + if (qmp->tcsr_map && qmp->dp_phy_mode_reg) + regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, is_dp); +} + static int qmp_usbc_com_init(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); @@ -669,6 +675,8 @@ static int qmp_usbc_usb_enable(struct phy *phy) if (ret) goto out_unlock; + qmp_usbc_set_phy_mode(qmp, false); + ret = qmp_usbc_usb_power_on(phy); if (ret) { qmp_usbc_com_exit(phy); @@ -1113,6 +1121,7 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw, qmp_usbc_com_exit(qmp->usb_phy); qmp_usbc_com_init(qmp->usb_phy); + qmp_usbc_set_phy_mode(qmp, false); qmp_usbc_usb_power_on(qmp->usb_phy); } @@ -1263,15 +1272,16 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) return 0; } -static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) +static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp) { struct of_phandle_args tcsr_args; struct device *dev = qmp->dev; - int ret; + int ret, args_count; - /* for backwards compatibility ignore if there is no property */ - ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0, - &tcsr_args); + args_count = of_property_count_u32_elems(dev->of_node, "qcom,tcsr-reg"); + args_count = args_count - 1; + ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", + args_count, 0, &tcsr_args); if (ret == -ENOENT) return 0; else if (ret < 0) @@ -1284,6 +1294,9 @@ static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) qmp->vls_clamp_reg = tcsr_args.args[0]; + if (args_count > 1) + qmp->dp_phy_mode_reg = tcsr_args.args[1]; + return 0; } @@ -1319,7 +1332,7 @@ static int qmp_usbc_probe(struct platform_device *pdev) if (ret) return ret; - ret = qmp_usbc_parse_vls_clamp(qmp); + ret = qmp_usbc_parse_tcsr(qmp); if (ret) return ret; From 5b1eff04a99fca72e0f485090dd2a56d3076351d Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:45 +0800 Subject: [PATCH 638/659] FROMLIST: phy: qcom: qmp-usbc: Add DP PHY ops for USB/DP switchable Type-C PHYs Define qmp_usbc_dp_phy_ops struct to support DP mode on USB/DP switchable PHYs. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-9-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 194 ++++++++++++++++++++++- 1 file changed, 193 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index fab6ccc4a5f12..3580c19fd62e0 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -29,6 +29,8 @@ #include "phy-qcom-qmp.h" #include "phy-qcom-qmp-pcs-misc-v3.h" +#include "phy-qcom-qmp-dp-phy.h" + #define PHY_INIT_COMPLETE_TIMEOUT 10000 #define SW_PORTSELECT_VAL BIT(0) #define SW_PORTSELECT_MUX BIT(1) @@ -711,6 +713,159 @@ static int qmp_usbc_usb_set_mode(struct phy *phy, enum phy_mode mode, int submod return 0; } +static int qmp_usbc_dp_enable(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + int ret; + + if (qmp->dp_init_count) { + dev_err(qmp->dev, "DP already inited\n"); + return 0; + } + + mutex_lock(&qmp->phy_mutex); + + ret = qmp_usbc_com_init(phy); + if (ret) + goto dp_init_unlock; + + qmp_usbc_set_phy_mode(qmp, true); + + cfg->dp_aux_init(qmp); + + qmp->dp_init_count++; + +dp_init_unlock: + mutex_unlock(&qmp->phy_mutex); + return ret; +} + +static int qmp_usbc_dp_disable(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + + mutex_lock(&qmp->phy_mutex); + + qmp_usbc_com_exit(phy); + + qmp->dp_init_count--; + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static int qmp_usbc_dp_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_dp *dp_opts = &opts->dp; + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + + mutex_lock(&qmp->phy_mutex); + + memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts)); + if (qmp->dp_opts.set_voltages) { + cfg->configure_dp_tx(qmp); + qmp->dp_opts.set_voltages = 0; + } + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static int qmp_usbc_dp_calibrate(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + int ret = 0; + + mutex_lock(&qmp->phy_mutex); + + if (cfg->calibrate_dp_phy) { + ret = cfg->calibrate_dp_phy(qmp); + if (ret) { + dev_err(qmp->dev, "dp calibrate err(%d)\n", ret); + mutex_unlock(&qmp->phy_mutex); + return ret; + } + } + + mutex_unlock(&qmp->phy_mutex); + return 0; +} + +static int qmp_usbc_dp_serdes_init(struct qmp_usbc *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + void __iomem *serdes = qmp->dp_serdes; + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + + qmp_configure(qmp->dev, serdes, cfg->dp_serdes_tbl, + cfg->dp_serdes_tbl_num); + + switch (dp_opts->link_rate) { + case 1620: + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_rbr, + cfg->serdes_tbl_rbr_num); + break; + case 2700: + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr, + cfg->serdes_tbl_hbr_num); + break; + case 5400: + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr2, + cfg->serdes_tbl_hbr2_num); + break; + default: + /* Other link rates aren't supported */ + return -EINVAL; + } + + return 0; +} + +static int qmp_usbc_dp_power_on(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + + void __iomem *tx = qmp->dp_tx; + void __iomem *tx2 = qmp->dp_tx2; + + mutex_lock(&qmp->phy_mutex); + + qmp_usbc_dp_serdes_init(qmp); + + qmp_configure_lane(qmp->dev, tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1); + qmp_configure_lane(qmp->dev, tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2); + + /* Configure special DP tx tunings */ + cfg->configure_dp_tx(qmp); + + /* Configure link rate, swing, etc. */ + cfg->configure_dp_phy(qmp); + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static int qmp_usbc_dp_power_off(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + + mutex_lock(&qmp->phy_mutex); + + /* Assert DP PHY power down */ + writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + static const struct phy_ops qmp_usbc_usb_phy_ops = { .init = qmp_usbc_usb_enable, .exit = qmp_usbc_usb_disable, @@ -718,6 +873,16 @@ static const struct phy_ops qmp_usbc_usb_phy_ops = { .owner = THIS_MODULE, }; +static const struct phy_ops qmp_usbc_dp_phy_ops = { + .init = qmp_usbc_dp_enable, + .exit = qmp_usbc_dp_disable, + .configure = qmp_usbc_dp_configure, + .calibrate = qmp_usbc_dp_calibrate, + .power_on = qmp_usbc_dp_power_on, + .power_off = qmp_usbc_dp_power_off, + .owner = THIS_MODULE, +}; + static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -1300,6 +1465,23 @@ static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp) return 0; } +static struct phy *qmp_usbc_phy_xlate(struct device *dev, const struct of_phandle_args *args) +{ + struct qmp_usbc *qmp = dev_get_drvdata(dev); + + if (args->args_count == 0) + return qmp->usb_phy; + + switch (args->args[0]) { + case QMP_USB43DP_USB3_PHY: + return qmp->usb_phy; + case QMP_USB43DP_DP_PHY: + return qmp->dp_phy ?: ERR_PTR(-ENODEV); + } + + return ERR_PTR(-EINVAL); +} + static int qmp_usbc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1370,9 +1552,19 @@ static int qmp_usbc_probe(struct platform_device *pdev) phy_set_drvdata(qmp->usb_phy, qmp); + if (qmp->dp_serdes != 0) { + qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops); + if (IS_ERR(qmp->dp_phy)) { + ret = PTR_ERR(qmp->dp_phy); + dev_err(dev, "failed to create PHY: %d\n", ret); + goto err_node_put; + } + phy_set_drvdata(qmp->dp_phy, qmp); + } + of_node_put(np); - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate); return PTR_ERR_OR_ZERO(phy_provider); From 550f483feaaf1ff975f02f0a7f093b8f1ce9b6b5 Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:46 +0800 Subject: [PATCH 639/659] FROMLIST: phy: qcom: qmp-usbc: Add USB/DP exclude handling When both USB and DP PHY modes are enabled simultaneously on the same QMP USBC PHY, it can lead to hardware misconfiguration and undefined behavior. This happens because the PHY resources are not designed to operate in both modes at the same time. To prevent this, introduce a mutual exclusion check between USB and DP PHY modes. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-10-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 3580c19fd62e0..d84bf68940043 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -666,6 +666,19 @@ static int qmp_usbc_usb_power_off(struct phy *phy) return 0; } +static int qmp_usbc_check_phy_status(struct qmp_usbc *qmp, bool is_dp) +{ + if ((is_dp && qmp->usb_init_count) || + (!is_dp && qmp->dp_init_count)) { + dev_err(qmp->dev, + "PHY is configured for %s, can not enable %s\n", + is_dp ? "USB" : "DP", is_dp ? "DP" : "USB"); + return -EBUSY; + } + + return 0; +} + static int qmp_usbc_usb_enable(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); @@ -673,6 +686,10 @@ static int qmp_usbc_usb_enable(struct phy *phy) mutex_lock(&qmp->phy_mutex); + ret = qmp_usbc_check_phy_status(qmp, false); + if (ret) + goto out_unlock; + ret = qmp_usbc_com_init(phy); if (ret) goto out_unlock; @@ -726,6 +743,10 @@ static int qmp_usbc_dp_enable(struct phy *phy) mutex_lock(&qmp->phy_mutex); + ret = qmp_usbc_check_phy_status(qmp, true); + if (ret) + goto dp_init_unlock; + ret = qmp_usbc_com_init(phy); if (ret) goto dp_init_unlock; From 61f2e90619c25cad15cebeeb472036c02975422a Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:47 +0800 Subject: [PATCH 640/659] FROMLIST: phy: qcom: qmp: Add DP v2 PHY register definitions Add dedicated headers for DP v2 PHY, including QSERDES COM and TX/RX register definitions. Reviewed-by: Dmitry Baryshkov Signed-off-by: Xiangxu Yin Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-11-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h | 21 ++++ .../qualcomm/phy-qcom-qmp-qserdes-com-v2.h | 106 ++++++++++++++++++ .../qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h | 68 +++++++++++ drivers/phy/qualcomm/phy-qcom-qmp.h | 3 + 4 files changed, 198 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h new file mode 100644 index 0000000000000..8b9572d3cdebb --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V2_H_ +#define QCOM_PHY_QMP_DP_PHY_V2_H_ + +// /* Only for QMP V2 PHY - DP PHY registers */ +#define QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK 0x048 +#define QSERDES_V2_DP_PHY_AUX_INTERRUPT_CLEAR 0x04c +#define QSERDES_V2_DP_PHY_AUX_BIST_CFG 0x050 + +#define QSERDES_V2_DP_PHY_VCO_DIV 0x068 +#define QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL 0x06c +#define QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL 0x088 + +#define QSERDES_V2_DP_PHY_SPARE0 0x0ac +#define QSERDES_V2_DP_PHY_STATUS 0x0c0 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h new file mode 100644 index 0000000000000..3ea1884f35dd5 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_COM_V2_H_ +#define QCOM_PHY_QMP_QSERDES_COM_V2_H_ + +/* Only for QMP V2 PHY - QSERDES COM registers */ +#define QSERDES_V2_COM_ATB_SEL1 0x000 +#define QSERDES_V2_COM_ATB_SEL2 0x004 +#define QSERDES_V2_COM_FREQ_UPDATE 0x008 +#define QSERDES_V2_COM_BG_TIMER 0x00c +#define QSERDES_V2_COM_SSC_EN_CENTER 0x010 +#define QSERDES_V2_COM_SSC_ADJ_PER1 0x014 +#define QSERDES_V2_COM_SSC_ADJ_PER2 0x018 +#define QSERDES_V2_COM_SSC_PER1 0x01c +#define QSERDES_V2_COM_SSC_PER2 0x020 +#define QSERDES_V2_COM_SSC_STEP_SIZE1 0x024 +#define QSERDES_V2_COM_SSC_STEP_SIZE2 0x028 +#define QSERDES_V2_COM_POST_DIV 0x02c +#define QSERDES_V2_COM_POST_DIV_MUX 0x030 +#define QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN 0x034 +#define QSERDES_V2_COM_CLK_ENABLE1 0x038 +#define QSERDES_V2_COM_SYS_CLK_CTRL 0x03c +#define QSERDES_V2_COM_SYSCLK_BUF_ENABLE 0x040 +#define QSERDES_V2_COM_PLL_EN 0x044 +#define QSERDES_V2_COM_PLL_IVCO 0x048 +#define QSERDES_V2_COM_LOCK_CMP1_MODE0 0x04c +#define QSERDES_V2_COM_LOCK_CMP2_MODE0 0x050 +#define QSERDES_V2_COM_LOCK_CMP3_MODE0 0x054 +#define QSERDES_V2_COM_LOCK_CMP1_MODE1 0x058 +#define QSERDES_V2_COM_LOCK_CMP2_MODE1 0x05c +#define QSERDES_V2_COM_LOCK_CMP3_MODE1 0x060 +#define QSERDES_V2_COM_EP_CLOCK_DETECT_CTR 0x068 +#define QSERDES_V2_COM_SYSCLK_DET_COMP_STATUS 0x06c +#define QSERDES_V2_COM_CLK_EP_DIV 0x074 +#define QSERDES_V2_COM_CP_CTRL_MODE0 0x078 +#define QSERDES_V2_COM_CP_CTRL_MODE1 0x07c +#define QSERDES_V2_COM_PLL_RCTRL_MODE0 0x084 +#define QSERDES_V2_COM_PLL_RCTRL_MODE1 0x088 +#define QSERDES_V2_COM_PLL_CCTRL_MODE0 0x090 +#define QSERDES_V2_COM_PLL_CCTRL_MODE1 0x094 +#define QSERDES_V2_COM_PLL_CNTRL 0x09c +#define QSERDES_V2_COM_BIAS_EN_CTRL_BY_PSM 0x0a8 +#define QSERDES_V2_COM_SYSCLK_EN_SEL 0x0ac +#define QSERDES_V2_COM_CML_SYSCLK_SEL 0x0b0 +#define QSERDES_V2_COM_RESETSM_CNTRL 0x0b4 +#define QSERDES_V2_COM_RESETSM_CNTRL2 0x0b8 +#define QSERDES_V2_COM_LOCK_CMP_EN 0x0c8 +#define QSERDES_V2_COM_LOCK_CMP_CFG 0x0cc +#define QSERDES_V2_COM_DEC_START_MODE0 0x0d0 +#define QSERDES_V2_COM_DEC_START_MODE1 0x0d4 +#define QSERDES_V2_COM_VCOCAL_DEADMAN_CTRL 0x0d8 +#define QSERDES_V2_COM_DIV_FRAC_START1_MODE0 0x0dc +#define QSERDES_V2_COM_DIV_FRAC_START2_MODE0 0x0e0 +#define QSERDES_V2_COM_DIV_FRAC_START3_MODE0 0x0e4 +#define QSERDES_V2_COM_DIV_FRAC_START1_MODE1 0x0e8 +#define QSERDES_V2_COM_DIV_FRAC_START2_MODE1 0x0ec +#define QSERDES_V2_COM_DIV_FRAC_START3_MODE1 0x0f0 +#define QSERDES_V2_COM_VCO_TUNE_MINVAL1 0x0f4 +#define QSERDES_V2_COM_VCO_TUNE_MINVAL2 0x0f8 +#define QSERDES_V2_COM_INTEGLOOP_INITVAL 0x100 +#define QSERDES_V2_COM_INTEGLOOP_EN 0x104 +#define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE0 0x108 +#define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE0 0x10c +#define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE1 0x110 +#define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE1 0x114 +#define QSERDES_V2_COM_VCO_TUNE_MAXVAL1 0x118 +#define QSERDES_V2_COM_VCO_TUNE_MAXVAL2 0x11c +#define QSERDES_V2_COM_VCO_TUNE_CTRL 0x124 +#define QSERDES_V2_COM_VCO_TUNE_MAP 0x128 +#define QSERDES_V2_COM_VCO_TUNE1_MODE0 0x12c +#define QSERDES_V2_COM_VCO_TUNE2_MODE0 0x130 +#define QSERDES_V2_COM_VCO_TUNE1_MODE1 0x134 +#define QSERDES_V2_COM_VCO_TUNE2_MODE1 0x138 +#define QSERDES_V2_COM_VCO_TUNE_INITVAL1 0x13c +#define QSERDES_V2_COM_VCO_TUNE_INITVAL2 0x140 +#define QSERDES_V2_COM_VCO_TUNE_TIMER1 0x144 +#define QSERDES_V2_COM_VCO_TUNE_TIMER2 0x148 +#define QSERDES_V2_COM_CMN_STATUS 0x15c +#define QSERDES_V2_COM_RESET_SM_STATUS 0x160 +#define QSERDES_V2_COM_RESTRIM_CODE_STATUS 0x164 +#define QSERDES_V2_COM_PLLCAL_CODE1_STATUS 0x168 +#define QSERDES_V2_COM_PLLCAL_CODE2_STATUS 0x16c +#define QSERDES_V2_COM_CLK_SELECT 0x174 +#define QSERDES_V2_COM_HSCLK_SEL 0x178 +#define QSERDES_V2_COM_INTEGLOOP_BINCODE_STATUS 0x17c +#define QSERDES_V2_COM_PLL_ANALOG 0x180 +#define QSERDES_V2_COM_CORECLK_DIV 0x184 +#define QSERDES_V2_COM_SW_RESET 0x188 +#define QSERDES_V2_COM_CORE_CLK_EN 0x18c +#define QSERDES_V2_COM_C_READY_STATUS 0x190 +#define QSERDES_V2_COM_CMN_CONFIG 0x194 +#define QSERDES_V2_COM_CMN_RATE_OVERRIDE 0x198 +#define QSERDES_V2_COM_SVS_MODE_CLK_SEL 0x19c +#define QSERDES_V2_COM_DEBUG_BUS0 0x1a0 +#define QSERDES_V2_COM_DEBUG_BUS1 0x1a4 +#define QSERDES_V2_COM_DEBUG_BUS2 0x1a8 +#define QSERDES_V2_COM_DEBUG_BUS3 0x1ac +#define QSERDES_V2_COM_DEBUG_BUS_SEL 0x1b0 +#define QSERDES_V2_COM_CMN_MISC1 0x1b4 +#define QSERDES_V2_COM_CMN_MISC2 0x1b8 +#define QSERDES_V2_COM_CORECLK_DIV_MODE1 0x1bc + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h new file mode 100644 index 0000000000000..34919720b7bc4 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V2_H_ +#define QCOM_PHY_QMP_QSERDES_TXRX_V2_H_ + +/* Only for QMP V2 PHY - TX registers */ +#define QSERDES_V2_TX_BIST_MODE_LANENO 0x000 +#define QSERDES_V2_TX_CLKBUF_ENABLE 0x008 +#define QSERDES_V2_TX_TX_EMP_POST1_LVL 0x00c +#define QSERDES_V2_TX_TX_DRV_LVL 0x01c +#define QSERDES_V2_TX_RESET_TSYNC_EN 0x024 +#define QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN 0x028 +#define QSERDES_V2_TX_TX_BAND 0x02c +#define QSERDES_V2_TX_SLEW_CNTL 0x030 +#define QSERDES_V2_TX_INTERFACE_SELECT 0x034 +#define QSERDES_V2_TX_RES_CODE_LANE_TX 0x03c +#define QSERDES_V2_TX_RES_CODE_LANE_RX 0x040 +#define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX 0x044 +#define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX 0x048 +#define QSERDES_V2_TX_DEBUG_BUS_SEL 0x058 +#define QSERDES_V2_TX_TRANSCEIVER_BIAS_EN 0x05c +#define QSERDES_V2_TX_HIGHZ_DRVR_EN 0x060 +#define QSERDES_V2_TX_TX_POL_INV 0x064 +#define QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN 0x068 +#define QSERDES_V2_TX_LANE_MODE_1 0x08c +#define QSERDES_V2_TX_LANE_MODE_2 0x090 +#define QSERDES_V2_TX_LANE_MODE_3 0x094 +#define QSERDES_V2_TX_RCV_DETECT_LVL_2 0x0a4 +#define QSERDES_V2_TX_TRAN_DRVR_EMP_EN 0x0c0 +#define QSERDES_V2_TX_TX_INTERFACE_MODE 0x0c4 +#define QSERDES_V2_TX_VMODE_CTRL1 0x0f0 + +/* Only for QMP V2 PHY - RX registers */ +#define QSERDES_V2_RX_UCDR_FO_GAIN 0x008 +#define QSERDES_V2_RX_UCDR_SO_GAIN_HALF 0x00c +#define QSERDES_V2_RX_UCDR_SO_GAIN 0x014 +#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_HALF 0x024 +#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028 +#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN 0x02c +#define QSERDES_V2_RX_UCDR_FASTLOCK_FO_GAIN 0x030 +#define QSERDES_V2_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 +#define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c +#define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040 +#define QSERDES_V2_RX_UCDR_PI_CONTROLS 0x044 +#define QSERDES_V2_RX_RX_TERM_BW 0x07c +#define QSERDES_V2_RX_VGA_CAL_CNTRL1 0x0bc +#define QSERDES_V2_RX_VGA_CAL_CNTRL2 0x0c0 +#define QSERDES_V2_RX_RX_EQ_GAIN2_LSB 0x0c8 +#define QSERDES_V2_RX_RX_EQ_GAIN2_MSB 0x0cc +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL1 0x0d0 +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d4 +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL3 0x0d8 +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL4 0x0dc +#define QSERDES_V2_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x0f8 +#define QSERDES_V2_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x0fc +#define QSERDES_V2_RX_SIGDET_ENABLES 0x100 +#define QSERDES_V2_RX_SIGDET_CNTRL 0x104 +#define QSERDES_V2_RX_SIGDET_LVL 0x108 +#define QSERDES_V2_RX_SIGDET_DEGLITCH_CNTRL 0x10c +#define QSERDES_V2_RX_RX_BAND 0x110 +#define QSERDES_V2_RX_RX_INTERFACE_MODE 0x11c +#define QSERDES_V2_RX_RX_MODE_00 0x164 +#define QSERDES_V2_RX_RX_MODE_01 0x168 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index da2a7ad2cdcce..836a222a2e786 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -9,6 +9,9 @@ #include "phy-qcom-qmp-qserdes-com.h" #include "phy-qcom-qmp-qserdes-txrx.h" +#include "phy-qcom-qmp-qserdes-com-v2.h" +#include "phy-qcom-qmp-qserdes-txrx-v2.h" + #include "phy-qcom-qmp-qserdes-com-v3.h" #include "phy-qcom-qmp-qserdes-txrx-v3.h" From 39fdd2b0c212d1b9a34e2033b7c447c19fe647c2 Mon Sep 17 00:00:00 2001 From: Xiangxu Yin Date: Fri, 26 Sep 2025 15:25:48 +0800 Subject: [PATCH 641/659] FROMLIST: phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support Add QCS615-specific configuration for USB/DP PHY, including DP init routines, voltage swing tables, and platform data. Add compatible "qcs615-qmp-usb3-dp-phy". Note: SW_PORTSELECT handling for orientation flip is not implemented due to QCS615 fixed-orientation design and non-standard lane mapping. Signed-off-by: Xiangxu Yin Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-12-dc5edaac6c2b@oss.qualcomm.com/ --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 413 +++++++++++++++++++++++ 1 file changed, 413 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index d84bf68940043..105cc0f4b8ddd 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -30,6 +30,7 @@ #include "phy-qcom-qmp-pcs-misc-v3.h" #include "phy-qcom-qmp-dp-phy.h" +#include "phy-qcom-qmp-dp-phy-v2.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 #define SW_PORTSELECT_VAL BIT(0) @@ -289,6 +290,83 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88), }; +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x37), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_COM_BG_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x08), + QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x05), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x02), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_rbr[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x2c), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x21), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_hbr[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x24), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x38), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_hbr2[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x8c), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x70), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TRANSCEIVER_BIAS_EN, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_VMODE_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_INTERFACE_SELECT, 0x3d), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_CLKBUF_ENABLE, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RESET_TSYNC_EN, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TRAN_DRVR_EMP_EN, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_INTERFACE_MODE, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_EMP_POST1_LVL, 0x2b), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_DRV_LVL, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_BAND, 0x4), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX, 0x12), +}; + struct qmp_usbc_offsets { u16 serdes; u16 pcs; @@ -434,6 +512,10 @@ static const char * const usb3phy_reset_l[] = { "phy_phy", "phy", }; +static const char * const usb3dpphy_reset_l[] = { + "phy_phy", "dp_phy", +}; + static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = { { .supply = "vdda-phy", .init_load_uA = 68600 }, { .supply = "vdda-pll", .init_load_uA = 14200 }, @@ -459,6 +541,34 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = { .rx2 = 0x800, }; +static const struct qmp_usbc_offsets qmp_usbc_usb3dp_offsets_qcs615 = { + .serdes = 0x0, + .pcs = 0xc00, + .pcs_misc = 0xa00, + .tx = 0x200, + .rx = 0x400, + .tx2 = 0x600, + .rx2 = 0x800, + .dp_serdes = 0x1c00, + .dp_txa = 0x1400, + .dp_txb = 0x1800, + .dp_dp_phy = 0x1000, +}; + +static const u8 qmp_v2_dp_pre_emphasis_hbr2_rbr[4][4] = { + {0x00, 0x0b, 0x12, 0xff}, + {0x00, 0x0a, 0x12, 0xff}, + {0x00, 0x0c, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff} +}; + +static const u8 qmp_v2_dp_voltage_swing_hbr2_rbr[4][4] = { + {0x07, 0x0f, 0x14, 0xff}, + {0x11, 0x1d, 0x1f, 0xff}, + {0x18, 0x1f, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff} +}; + static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .offsets = &qmp_usbc_offsets_v3_qcm2290, @@ -531,6 +641,51 @@ static const struct qmp_phy_cfg qcs615_usb3phy_cfg = { .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; +static void qmp_v2_dp_aux_init(struct qmp_usbc *qmp); +static void qmp_v2_configure_dp_tx(struct qmp_usbc *qmp); +static int qmp_v2_configure_dp_phy(struct qmp_usbc *qmp); +static int qmp_v2_calibrate_dp_phy(struct qmp_usbc *qmp); + +static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = { + .offsets = &qmp_usbc_usb3dp_offsets_qcs615, + + .serdes_tbl = qcm2290_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), + .tx_tbl = qcm2290_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), + .rx_tbl = qcm2290_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), + .pcs_tbl = qcm2290_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, + + .dp_serdes_tbl = qmp_v2_dp_serdes_tbl, + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl), + .dp_tx_tbl = qmp_v2_dp_tx_tbl, + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v2_dp_tx_tbl), + + .serdes_tbl_rbr = qmp_v2_dp_serdes_tbl_rbr, + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_rbr), + .serdes_tbl_hbr = qmp_v2_dp_serdes_tbl_hbr, + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_hbr), + .serdes_tbl_hbr2 = qmp_v2_dp_serdes_tbl_hbr2, + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_hbr2), + + .swing_tbl = &qmp_v2_dp_voltage_swing_hbr2_rbr, + .pre_emphasis_tbl = &qmp_v2_dp_pre_emphasis_hbr2_rbr, + + .dp_aux_init = qmp_v2_dp_aux_init, + .configure_dp_tx = qmp_v2_configure_dp_tx, + .configure_dp_phy = qmp_v2_configure_dp_phy, + .calibrate_dp_phy = qmp_v2_calibrate_dp_phy, + + .reset_list = usb3dpphy_reset_l, + .num_resets = ARRAY_SIZE(usb3dpphy_reset_l), + .vreg_list = qmp_phy_qcs615_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), +}; + static void qmp_usbc_set_phy_mode(struct qmp_usbc *qmp, bool is_dp) { if (qmp->tcsr_map && qmp->dp_phy_mode_reg) @@ -589,6 +744,253 @@ static int qmp_usbc_com_exit(struct phy *phy) return 0; } +static void qmp_v2_dp_aux_init(struct qmp_usbc *qmp) +{ + writel(DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN, + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN, + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); + writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); + writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); + writel(0xbb, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); + qmp->dp_aux_cfg = 0; + + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | + PHY_AUX_REQ_ERR_MASK, + qmp->dp_dp_phy + QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK); +} + +static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + void __iomem *tx = qmp->dp_tx; + void __iomem *tx2 = qmp->dp_tx2; + unsigned int v_level = 0, p_level = 0; + u8 voltage_swing_cfg, pre_emphasis_cfg; + int i; + + if (dp_opts->lanes > 4) { + dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes); + return -EINVAL; + } + + for (i = 0; i < dp_opts->lanes; i++) { + v_level = max(v_level, dp_opts->voltage[i]); + p_level = max(p_level, dp_opts->pre[i]); + } + + if (v_level > 4 || p_level > 4) { + dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n", + v_level, p_level); + return -EINVAL; + } + + voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level]; + pre_emphasis_cfg = (*cfg->pre_emphasis_tbl)[v_level][p_level]; + + voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN; + pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN; + + if (voltage_swing_cfg == 0xff && pre_emphasis_cfg == 0xff) + return -EINVAL; + + writel(voltage_swing_cfg, tx + QSERDES_V2_TX_TX_DRV_LVL); + writel(pre_emphasis_cfg, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL); + writel(voltage_swing_cfg, tx2 + QSERDES_V2_TX_TX_DRV_LVL); + writel(pre_emphasis_cfg, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL); + + return 0; +} + +static void qmp_usbc_configure_dp_mode(struct qmp_usbc *qmp) +{ + bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); + u32 val; + + val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN; + + writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + if (reverse) + writel(0xc9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); + else + writel(0xd9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); +} + +static int qmp_usbc_configure_dp_clocks(struct qmp_usbc *qmp) +{ + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + u32 phy_vco_div; + unsigned long pixel_freq; + + switch (dp_opts->link_rate) { + case 1620: + phy_vco_div = 0x1; + pixel_freq = 1620000000UL / 2; + break; + case 2700: + phy_vco_div = 0x1; + pixel_freq = 2700000000UL / 2; + break; + case 5400: + phy_vco_div = 0x2; + pixel_freq = 5400000000UL / 4; + break; + default: + dev_err(qmp->dev, "link rate:%d not supported\n", dp_opts->link_rate); + return -EINVAL; + } + writel(phy_vco_div, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_VCO_DIV); + + clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); + clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); + + return 0; +} + +static void qmp_v2_configure_dp_tx(struct qmp_usbc *qmp) +{ + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + void __iomem *tx = qmp->dp_tx; + void __iomem *tx2 = qmp->dp_tx2; + + /* program default setting first */ + writel(0x2a, tx + QSERDES_V2_TX_TX_DRV_LVL); + writel(0x20, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL); + writel(0x2a, tx2 + QSERDES_V2_TX_TX_DRV_LVL); + writel(0x20, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL); + + if (dp_opts->link_rate >= 2700) { + writel(0xc4, tx + QSERDES_V2_TX_LANE_MODE_1); + writel(0xc4, tx2 + QSERDES_V2_TX_LANE_MODE_1); + } else { + writel(0xc6, tx + QSERDES_V2_TX_LANE_MODE_1); + writel(0xc6, tx2 + QSERDES_V2_TX_LANE_MODE_1); + } + + qmp_v2_configure_dp_swing(qmp); +} + +static int qmp_v2_configure_dp_phy(struct qmp_usbc *qmp) +{ + u32 status; + int ret; + + qmp_usbc_configure_dp_mode(qmp); + + writel(0x05, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL); + writel(0x05, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL); + + ret = qmp_usbc_configure_dp_clocks(qmp); + if (ret) + return ret; + + writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + writel(0x20, qmp->dp_serdes + QSERDES_COM_RESETSM_CNTRL); + + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_C_READY_STATUS, + status, + ((status & BIT(0)) > 0), + 500, + 10000)) { + dev_err(qmp->dev, "C_READY not ready\n"); + return -ETIMEDOUT; + } + + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS, + status, + ((status & BIT(0)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "FREQ_DONE not ready\n"); + return -ETIMEDOUT; + } + + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS, + status, + ((status & BIT(1)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "PLL_LOCKED not ready\n"); + return -ETIMEDOUT; + } + + writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, + status, + ((status & BIT(0)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "TSYNC_DONE not ready\n"); + return -ETIMEDOUT; + } + + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, + status, + ((status & BIT(1)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "PHY_READY not ready\n"); + return -ETIMEDOUT; + } + + writel(0x3f, qmp->dp_tx + QSERDES_V2_TX_TRANSCEIVER_BIAS_EN); + writel(0x10, qmp->dp_tx + QSERDES_V2_TX_HIGHZ_DRVR_EN); + writel(0x0a, qmp->dp_tx + QSERDES_V2_TX_TX_POL_INV); + writel(0x3f, qmp->dp_tx2 + QSERDES_V2_TX_TRANSCEIVER_BIAS_EN); + writel(0x10, qmp->dp_tx2 + QSERDES_V2_TX_HIGHZ_DRVR_EN); + writel(0x0a, qmp->dp_tx2 + QSERDES_V2_TX_TX_POL_INV); + + writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, + status, + ((status & BIT(1)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "PHY_READY not ready\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int qmp_v2_calibrate_dp_phy(struct qmp_usbc *qmp) +{ + static const u8 cfg1_settings[] = {0x13, 0x23, 0x1d}; + u8 val; + + qmp->dp_aux_cfg++; + qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings); + val = cfg1_settings[qmp->dp_aux_cfg]; + + writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); + + return 0; +} + static int qmp_usbc_usb_power_on(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); @@ -855,6 +1257,14 @@ static int qmp_usbc_dp_power_on(struct phy *phy) void __iomem *tx = qmp->dp_tx; void __iomem *tx2 = qmp->dp_tx2; + /* + * FIXME: SW_PORTSELECT handling for DP orientation flip is not implemented. + * Expected: + * - For standard lane mapping: configure SW_PORTSELECT in QSERDES_DP_PHY_CFG_1. + * - For non-standard mapping: pass orientation to dp_ctrl and handle flip + * via logical2physical lane remapping. + */ + mutex_lock(&qmp->phy_mutex); qmp_usbc_dp_serdes_init(qmp); @@ -1601,6 +2011,9 @@ static const struct of_device_id qmp_usbc_of_match_table[] = { }, { .compatible = "qcom,qcm2290-qmp-usb3-phy", .data = &qcm2290_usb3phy_cfg, + }, { + .compatible = "qcom,qcs615-qmp-usb3-dp-phy", + .data = &qcs615_usb3dp_phy_cfg, }, { .compatible = "qcom,qcs615-qmp-usb3-phy", .data = &qcs615_usb3phy_cfg, From d988effbfbed9e96258b4605b45daf415612b97d Mon Sep 17 00:00:00 2001 From: Mani Chandana Ballary Kuntumalla Date: Tue, 23 Sep 2025 17:34:02 +0530 Subject: [PATCH 642/659] FROMLIST: drm/msm/dp: Update msm_dp_controller IDs for sa8775p The Qualcomm SA8775P platform comes with 2 DisplayPort controllers for each mdss. Update controller id for DPTX0 and DPTX1 of mdss1. Fixes: dcb380d19e58 ("drm/msm/dp: Add DisplayPort controller for SA8775P") Signed-off-by: Mani Chandana Ballary Kuntumalla Link: https://lore.kernel.org/all/20251125105622.1755651-2-quic_mkuntuma@quicinc.com/ --- drivers/gpu/drm/msm/dp/dp_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 9bd9cd5c1e03c..a082f4d3ebe27 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -141,8 +141,8 @@ static const struct msm_dp_desc msm_dp_desc_glymur[] = { static const struct msm_dp_desc msm_dp_desc_sa8775p[] = { { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0af5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, - { .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, - { .io_start = 0x2215c000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true }, + { .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, + { .io_start = 0x2215c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, {} }; From 569d07f9b355b25b74203a1169bf45b480fce739 Mon Sep 17 00:00:00 2001 From: Yuanjie Yang Date: Thu, 23 Oct 2025 16:06:04 +0800 Subject: [PATCH 643/659] FROMLIST: drm/panel: Set sufficient voltage for panel nt37801 The NT37801 Sepc V1.0 chapter "5.7.1 Power On Sequence" states VDDI=1.65V~1.95V, so set sufficient voltage for panel nt37801. Signed-off-by: Yongxing Mou Signed-off-by: Yuanjie Yang Link: https://lore.kernel.org/all/20251023080609.1212-2-yuanjie.yang@oss.qualcomm.com/#r Signed-off-by: Yash Gupta --- drivers/gpu/drm/panel/panel-novatek-nt37801.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt37801.c b/drivers/gpu/drm/panel/panel-novatek-nt37801.c index d6a37d7e0cc63..7eda16e0c1f94 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt37801.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt37801.c @@ -267,6 +267,11 @@ static int novatek_nt37801_probe(struct mipi_dsi_device *dsi) if (ret < 0) return ret; + ret = regulator_set_voltage(ctx->supplies[0].consumer, + 1650000, 1950000); + if (ret < 0) + return ret; + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), From f4e46d393ec161de902608df1f4d8fff08b72ff3 Mon Sep 17 00:00:00 2001 From: Gopi Botlagunta Date: Fri, 21 Nov 2025 19:12:06 +0530 Subject: [PATCH 644/659] 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 38fb8776c0f44..6f2b72fba598e 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -382,7 +382,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 cef50c3ad1af7105c981e90fdd68b521b3960e7e Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Tue, 25 Nov 2025 07:03:00 +0530 Subject: [PATCH 645/659] FROMLIST: dt-bindings: display: msm: document DSI controller and phy on QCS8300 Document DSI controller and phy on QCS8300 platform. Signed-off-by: Ayushi Makhija Link: https://lore.kernel.org/all/20251125013302.3835909-4-quic_amakhija@quicinc.com/ Signed-off-by: Arpit Saini --- .../display/msm/qcom,qcs8300-mdss.yaml | 102 +++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml index e96baaae9ba9e..c41a86203e78a 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml @@ -53,13 +53,23 @@ patternProperties: contains: const: qcom,qcs8300-dp + "^dsi@[0-9a-f]+$": + type: object + additionalProperties: true + properties: + compatible: + contains: + const: qcom,qcs8300-dsi-ctrl + "^phy@[0-9a-f]+$": type: object additionalProperties: true properties: compatible: contains: - const: qcom,qcs8300-edp-phy + enum: + - qcom,qcs8300-dsi-phy-5nm + - qcom,qcs8300-edp-phy required: - compatible @@ -71,6 +81,7 @@ examples: #include #include #include + #include #include #include #include @@ -142,6 +153,13 @@ examples: remote-endpoint = <&mdss_dp0_in>; }; }; + + port@1 { + reg = <1>; + dpu_intf1_out: endpoint { + remote-endpoint = <&mdss_dsi0_in>; + }; + }; }; mdp_opp_table: opp-table { @@ -169,6 +187,88 @@ examples: }; }; + dsi@ae94000 { + compatible = "qcom,qcs8300-dsi-ctrl", + "qcom,sa8775p-dsi-ctrl", + "qcom,mdss-dsi-ctrl"; + reg = <0x0ae94000 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 0>, <&mdss_dsi0_phy 1>; + phys = <&mdss_dsi0_phy>; + + operating-points-v2 = <&dsi0_opp_table>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + + vdda-supply = <&vreg_l5a>; + + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdss0_dsi0_in: endpoint { + remote-endpoint = <&dpu_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + mdss0_dsi0_out: endpoint { }; + }; + }; + + dsi0_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 = <0x0ae94400 0x200>, + <0x0ae94600 0x280>, + <0x0ae94900 0x27c>; + 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"; + + vdds-supply = <&vreg_l4a>; + }; + mdss_dp0_phy: phy@aec2a00 { compatible = "qcom,qcs8300-edp-phy", "qcom,sa8775p-edp-phy"; From f0f870d10b6b1b0dfdd7aa506d9b043137bf6ef3 Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Tue, 25 Nov 2025 07:02:59 +0530 Subject: [PATCH 646/659] FROMLIST: dt-bindings: msm: dsi-controller-main: document the QCS8300 DSI CTRL Document the DSI CTRL on the QCS8300 Platform. Signed-off-by: Ayushi Makhija Link: https://lore.kernel.org/all/20251125013302.3835909-3-quic_amakhija@quicinc.com/ Signed-off-by: Arpit Saini --- .../devicetree/bindings/display/msm/dsi-controller-main.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml index 4400d4cce0722..6276350e582f7 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml @@ -45,6 +45,11 @@ properties: - qcom,sm8650-dsi-ctrl - qcom,sm8750-dsi-ctrl - const: qcom,mdss-dsi-ctrl + - items: + - enum: + - qcom,qcs8300-dsi-ctrl + - const: qcom,sa8775p-dsi-ctrl + - const: qcom,mdss-dsi-ctrl - enum: - qcom,dsi-ctrl-6g-qcm2290 - qcom,mdss-dsi-ctrl # This should always come with an SoC-specific compatible From 615bb7836e318ffd525e3fa466b4ea7a4b37ff18 Mon Sep 17 00:00:00 2001 From: Ayushi Makhija Date: Tue, 25 Nov 2025 07:02:58 +0530 Subject: [PATCH 647/659] FROMLIST: dt-bindings: display: msm-dsi-phy-7nm: document the QCS8300 DSI PHY Document the DSI PHY on the QCS8300 Platform. Signed-off-by: Ayushi Makhija Link: https://lore.kernel.org/all/20251125013302.3835909-2-quic_amakhija@quicinc.com/ Signed-off-by: Arpit Saini --- .../bindings/display/msm/dsi-phy-7nm.yaml | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml index 1ca820a500b72..7a83387502da1 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml @@ -14,18 +14,24 @@ allOf: properties: compatible: - enum: - - qcom,dsi-phy-7nm - - qcom,dsi-phy-7nm-8150 - - qcom,sa8775p-dsi-phy-5nm - - qcom,sar2130p-dsi-phy-5nm - - qcom,sc7280-dsi-phy-7nm - - qcom,sm6375-dsi-phy-7nm - - qcom,sm8350-dsi-phy-5nm - - qcom,sm8450-dsi-phy-5nm - - qcom,sm8550-dsi-phy-4nm - - qcom,sm8650-dsi-phy-4nm - - qcom,sm8750-dsi-phy-3nm + oneOf: + - items: + - enum: + - qcom,dsi-phy-7nm + - qcom,dsi-phy-7nm-8150 + - qcom,sa8775p-dsi-phy-5nm + - qcom,sar2130p-dsi-phy-5nm + - qcom,sc7280-dsi-phy-7nm + - qcom,sm6375-dsi-phy-7nm + - qcom,sm8350-dsi-phy-5nm + - qcom,sm8450-dsi-phy-5nm + - qcom,sm8550-dsi-phy-4nm + - qcom,sm8650-dsi-phy-4nm + - qcom,sm8750-dsi-phy-3nm + - items: + - enum: + - qcom,qcs8300-dsi-phy-5nm + - const: qcom,sa8775p-dsi-phy-5nm reg: items: From f6fdae2e8c421d92998ab63c19e6afd1ac3b2c0a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 14 May 2025 02:30:00 +0300 Subject: [PATCH 648/659] FROMLIST: drm/msm/dpu: enable virtual planes by default Turn on the switch and use virtual planes by default, enhancing utilisation of the display pipelines. It is still possible to use legacy implementation by using `msm.dpu_use_virtual_planes=false` kernel boot parameter. Link:https://lore.kernel.org/all/20250514-dpu-enable-virt-planes-v1-1-bf5ba0088007@oss.qualcomm.com/ Signed-off-by: Dmitry Baryshkov Signed-off-by: Mahadevan P --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index f4c9767c418d3..70cdc7f03645d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -52,7 +52,7 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" -bool dpu_use_virtual_planes; +bool dpu_use_virtual_planes = true; module_param(dpu_use_virtual_planes, bool, 0); static int dpu_kms_hw_init(struct msm_kms *kms); From 92d7cbcc2a01c262e6dae85c7e5cea528e6d102f Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Mon, 24 Nov 2025 19:57:01 +0530 Subject: [PATCH 649/659] FROMLIST: drm/msm/disp/dpu: add merge3d support for sc7280 Add support for the merge3d block on sc7280 which will allow merge of streams coming from two layer mixers routed to single non DSC interface. This change helps to support larger buffer width which exceeds max_linewidth of 2400. Link:https://lore.kernel.org/all/20251124-merge3d-sc7280-v1-1-798d94211626@oss.qualcomm.com/ Fixes: 591e34a091d1 ("drm/msm/disp/dpu1: add support for display for SC7280 target") Signed-off-by: Mahadevan P --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 8f978b9c34520..2f8688224f343 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -13,6 +13,7 @@ static const struct dpu_caps sc7280_dpu_caps = { .has_dim_layer = true, .has_idle_pc = true, .max_linewidth = 2400, + .has_3d_merge = true, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; @@ -134,17 +135,24 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { .name = "pingpong_2", .id = PINGPONG_2, .base = 0x6b000, .len = 0, .sblk = &sc7280_pp_sblk, - .merge_3d = 0, + .merge_3d = MERGE_3D_1, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), }, { .name = "pingpong_3", .id = PINGPONG_3, .base = 0x6c000, .len = 0, .sblk = &sc7280_pp_sblk, - .merge_3d = 0, + .merge_3d = MERGE_3D_1, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), }, }; +static const struct dpu_merge_3d_cfg sc7280_merge_3d[] = { + { + .name = "merge_3d_1", .id = MERGE_3D_1, + .base = 0x4f000, .len = 0x8, + }, +}; + /* NOTE: sc7280 only has one DSC hard slice encoder */ static const struct dpu_dsc_cfg sc7280_dsc[] = { { @@ -247,6 +255,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), .pingpong = sc7280_pp, + .merge_3d_count = ARRAY_SIZE(sc7280_merge_3d), + .merge_3d = sc7280_merge_3d, .dsc_count = ARRAY_SIZE(sc7280_dsc), .dsc = sc7280_dsc, .wb_count = ARRAY_SIZE(sc7280_wb), From 5d007ceba5a05b89e3b10346ceda089c7f6acfcb Mon Sep 17 00:00:00 2001 From: Nilesh Laad Date: Wed, 26 Nov 2025 17:01:18 +0530 Subject: [PATCH 650/659] 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 6f2b72fba598e..d0273a55687de 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -89,7 +89,9 @@ static const struct regmap_config lt9611uxc_regmap_config = { struct lt9611uxc_mode { u16 hdisplay; + u16 htotal; u16 vdisplay; + u16 vtotal; u8 vrefresh; }; @@ -98,22 +100,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) @@ -237,7 +239,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 034ab71fd7e65e4f42926dfce3850b7fbc254f48 Mon Sep 17 00:00:00 2001 From: Nilesh Laad Date: Wed, 26 Nov 2025 18:52:37 +0530 Subject: [PATCH 651/659] 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 d0273a55687de..d8ab95bb3a612 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -100,6 +100,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 f7e7c937fb7e0249538d80c9d879c28105c12615 Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sun, 28 Dec 2025 17:10:39 +0530 Subject: [PATCH 652/659] 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 b5923dc55102c20bda21079a2c83e52689ef092c Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Sun, 28 Dec 2025 17:10:40 +0530 Subject: [PATCH 653/659] 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 a250afd8d6622..7fef383ed7cb7 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -184,6 +184,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 c7dc03182e592..07eeb13fa4978 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -16,6 +16,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 c1f076e849990a89040ca0d769a9b890f76675ae Mon Sep 17 00:00:00 2001 From: Prahlad Valluru Date: Tue, 25 Nov 2025 20:55:07 +0530 Subject: [PATCH 654/659] 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 c5e1d2016bcca..4033809ff8237 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 c609893765eccf058561f29931f4ee99e0ca8f37 Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Fri, 23 Jan 2026 15:54:56 +0530 Subject: [PATCH 655/659] 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 dd3d695253322ef39b33553501fafaa29cdef6a0 Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Wed, 28 Jan 2026 15:13:23 +0530 Subject: [PATCH 656/659] 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 900c5680354394d0e55710f77740d69e8fe6e9b9 Mon Sep 17 00:00:00 2001 From: Nilesh Laad Date: Wed, 28 Jan 2026 18:28:20 +0530 Subject: [PATCH 657/659] 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 d8ab95bb3a612..875893f617ade 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -174,6 +174,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 7b7585189222388a7d5ecde56447bf353eb9d4c6 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Thu, 12 Feb 2026 16:11:35 +0530 Subject: [PATCH 658/659] FROMLIST: drm/bridge: anx7625: Fix invalid EDID size DRM checks EDID block count against allocated size in drm_edid_valid function. We have to allocate the right EDID size instead of the max size to prevent the EDID to be reported as invalid. Cc: stable@kernel.org Fixes: 7c585f9 ("drm/bridge: anx7625: use struct drm_edid more") Reviewed-by: Dmitry Baryshkov Signed-off-by: Loic Poulain Link: https://lore.kernel.org/r/20251218151307.95491-1-loic.poulain@oss.qualcomm.com --- drivers/gpu/drm/bridge/analogix/anx7625.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 6f3fdcb6afdb9..4e49e4f28d552 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1801,7 +1801,7 @@ static const struct drm_edid *anx7625_edid_read(struct anx7625_data *ctx) return NULL; } - ctx->cached_drm_edid = drm_edid_alloc(edid_buf, FOUR_BLOCK_SIZE); + ctx->cached_drm_edid = drm_edid_alloc(edid_buf, edid_num * ONE_BLOCK_SIZE); kfree(edid_buf); out: From a59723ab8bfd542c0d931b0dbb142061c7e9e8fe Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Thu, 12 Feb 2026 16:44:06 +0530 Subject: [PATCH 659/659] Add qcom-next log files for 20260212 Adding merge log file and topic_SHA1 file Signed-off-by: Salendarsingh Gaud --- qcom-next/merge.log | 438 +++++++++++++++++++++++++++++++++++++++++++ qcom-next/topic_SHA1 | 46 +++++ 2 files changed, 484 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..3928617a14986 --- /dev/null +++ b/qcom-next/merge.log @@ -0,0 +1,438 @@ +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/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 68 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/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 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b +Done, updated baseline. +Latest tag is 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b +Create a new integration branch based on 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b +Merging topic branches... +------------------------------------------ + ** Merging topic branch: tech/bsp/clk/tech/bsp/clk +Merge successful : tech/bsp/clk : 4a0d4ec7f50e2e2609856e3b72af981e45419792 : 30 +------------------------------------------ + ** 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 failed, manual merge +No files need merging +[qcom-next 43d6ed7ef787] Merge remote-tracking branch tech/bsp/soc-infra into qcom-next +Merge successful : tech/bsp/soc-infra : c6c4df7b49310ee2948d4e32b1c73a71e2e8df02 : 11 +------------------------------------------ + ** 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 : d9f9599c6801d504ef3e87e8d83aa67fec64496b : 8 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/mhi/tech/bus/pci/mhi +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/pci/phy/tech/bus/pci/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** 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 : 373f7fe1434d68146cc9a791fccf6fbbca7e526f : 13 +------------------------------------------ + ** 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 : ca9a1762361f8aefa943924a351d0959ff4b030b : 29 +------------------------------------------ + ** 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 : eaefc127fa1a2d81319bfa675e198c9d5f60e3d7 : 20 +------------------------------------------ + ** 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 : e2e878598fd2f5ac7bcb564f35853d849aa5b9c4 : 6 +------------------------------------------ + ** 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 : 84e6e6d35e5160bf676c70f2cfeb6456d8cff150 : 14 +------------------------------------------ + ** Merging topic branch: tech/mm/drm/tech/mm/drm +Merge successful : tech/mm/drm : 7b7585189222388a7d5ecde56447bf353eb9d4c6 : 32 +------------------------------------------ + ** Merging topic branch: tech/mm/fastrpc/tech/mm/fastrpc +Merge successful : tech/mm/fastrpc : 02c8ae97aa2e858df75258267c5dce446c22d606 : 8 +------------------------------------------ + ** 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 : 48714170dc4a486d6c17c502c203178d3bf31f22 : 16 +------------------------------------------ + ** Merging topic branch: tech/mm/gpu/tech/mm/gpu +Merge successful : tech/mm/gpu : 4bb11fd3175d4d89a067411371d2d5d0e05fdb5f : 7 +------------------------------------------ + ** Merging topic branch: tech/mproc/rpmsg/tech/mproc/rpmsg +Merge successful : tech/mproc/rpmsg : c3875d91bc790317fbfd048810402ebd4fa406b2 : 1 +------------------------------------------ + ** 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 : 93be5e1da22add744318e1fdb20387fac4c2e83f : 144 +------------------------------------------ + ** Merging topic branch: tech/net/eth/tech/net/eth +Merge successful : tech/net/eth : c280d7e86faa86b16d3c1e313e95207503cf3770 : 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 : e249fa5f1f2c346bfc537494a06e9dc227419639 : 1 +------------------------------------------ + ** Merging topic branch: tech/net/phy/tech/net/phy +Merge successful : tech/net/phy : d02d17363623cf15ba4ea228c8d7753d8675571e : 1 +------------------------------------------ + ** Merging topic branch: tech/net/bluetooth/tech/net/bluetooth +Merge successful : tech/net/bluetooth : b85467e8227775774b42430aa9b057f7c0d6406c : 7 +------------------------------------------ + ** 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 : 7b7e77956157470a1c0925cdec114a0f1a423877 : 7 +------------------------------------------ + ** Merging topic branch: tech/pm/thermal/tech/pm/thermal +Merge successful : tech/pm/thermal : f02e75e749cc2093690cf8b14ec14f9d6db45dba : 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 : 5c53b58f4ebbdc2b97f442b6758fb74df96884dc : 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 : 7b47af6e432d377b4ad9dee6a2d5ac83f693e931 : 9 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs9100/tech/all/dt/qcs9100 +Merge successful : tech/all/dt/qcs9100 : 2b9347cdf09a237d6d8e00bc2d87a3a18617bcc1 : 21 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs8300/tech/all/dt/qcs8300 +Merge successful : tech/all/dt/qcs8300 : 7c34815632cdccc6e60628ce1efb3c710eff7989 : 32 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs615/tech/all/dt/qcs615 +Merge successful : tech/all/dt/qcs615 : 105f20e3fb028f754d667cb73bc51824239b2e5e : 22 +------------------------------------------ + ** Merging topic branch: tech/all/dt/hamoa/tech/all/dt/hamoa +Merge successful : tech/all/dt/hamoa : 2de2c8811b30a7559e85dd2ee348228119610869 : 20 +------------------------------------------ + ** Merging topic branch: tech/all/dt/glymur/tech/all/dt/glymur +Merge successful : tech/all/dt/glymur : 74e83f399b94405c00c80e819c5d3cc2aaa4af40 : 8 +------------------------------------------ + ** Merging topic branch: tech/all/dt/kaanapali/tech/all/dt/kaanapali +Merge failed, manual merge +No files need merging +[qcom-next eff62a6fe7e0] Merge remote-tracking branch tech/all/dt/kaanapali into qcom-next +Merge successful : tech/all/dt/kaanapali : c3ff3fc9f8f2aab4813819282b72298763d547eb : 17 +------------------------------------------ + ** Merging topic branch: tech/all/dt/pakala/tech/all/dt/pakala +Merge successful : tech/all/dt/pakala : 12287e54c6772afe134ba5df936177e1a033fac9 : 10 +------------------------------------------ + ** Merging topic branch: tech/all/config/tech/all/config +Merge successful : tech/all/config : 591ac9212b0dd0ef9038b9ce9b617aa4f8c3952b : 43 +------------------------------------------ + ** Merging topic branch: tech/overlay/dt/tech/overlay/dt +Merge failed, manual merge +No files need merging +[qcom-next afacba0903d6] Merge remote-tracking branch tech/overlay/dt into qcom-next +Merge successful : tech/overlay/dt : ba99ff10a2448f95028e534842ceb4b1ae57067d : 21 +------------------------------------------ + ** Merging topic branch: tech/all/workaround/tech/all/workaround +Merge failed, manual merge +No files need merging +[qcom-next 0a6e3759f28a] Merge remote-tracking branch tech/all/workaround into qcom-next +Merge successful : tech/all/workaround : b67e2b690d732374a0d8843384ef663d60c76539 : 6 +------------------------------------------ + ** Merging topic branch: tech/mproc/all/tech/mproc/all +Merge successful : tech/mproc/all : d19a4c1bd3a5c85722d13d63aa5e2542accfc2a0 : 5 +------------------------------------------ + ** Merging topic branch: tech/noup/debug/all/tech/noup/debug/all +Merge successful : tech/noup/debug/all : 7fc440765b19f217c84d3cceef13f158f9338821 : 12 +------------------------------------------ + ** Merging topic branch: tech/hwe/unoq/tech/hwe/unoq +Merge successful : tech/hwe/unoq : 9d4ee0308d4f910c2d290984d51d0d4ea369e374 : 12 +Done, merged 44 topic(s). diff --git a/qcom-next/topic_SHA1 b/qcom-next/topic_SHA1 new file mode 100644 index 0000000000000..f3b9bab9862c1 --- /dev/null +++ b/qcom-next/topic_SHA1 @@ -0,0 +1,46 @@ +Name SHA Commits +------------------------------------------------------------------------------------ +tech/bsp/clk 4a0d4ec7f50e2e2609856e3b72af981e45419792 30 +tech/bsp/interconnect e9171e9aefb18c3343ba123d70c676de820b7ac5 3 +tech/security/firmware-smc a50984a91bb9d551ee48136ee2db90eca0929979 2 +tech/bsp/soc-infra c6c4df7b49310ee2948d4e32b1c73a71e2e8df02 11 +tech/bsp/remoteproc 53b8ced13b8fbbf3e2e4547648cbc647e408b7e0 19 +tech/bus/peripherals 486bcf7a4a94e54abf5fd9e6cc6bf68eea22a5d6 1 +tech/bus/pci/all d9f9599c6801d504ef3e87e8d83aa67fec64496b 8 +tech/bus/usb/dwc 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 2 +tech/bus/usb/phy 373f7fe1434d68146cc9a791fccf6fbbca7e526f 13 +tech/debug/hwtracing ca9a1762361f8aefa943924a351d0959ff4b030b 29 +tech/pmic/misc eaefc127fa1a2d81319bfa675e198c9d5f60e3d7 20 +tech/pmic/regulator 81fc8fbf0f0a02a7b2d855aee574b88bd7d59107 6 +tech/mem/iommu 4cff31be02c7cce3434b096cb6cba4c11fc7f3c7 3 +tech/mm/audio/all e2e878598fd2f5ac7bcb564f35853d849aa5b9c4 6 +tech/mm/camss 84e6e6d35e5160bf676c70f2cfeb6456d8cff150 14 +tech/mm/drm 7b7585189222388a7d5ecde56447bf353eb9d4c6 32 +tech/mm/fastrpc 02c8ae97aa2e858df75258267c5dce446c22d606 8 +tech/mm/video 48714170dc4a486d6c17c502c203178d3bf31f22 16 +tech/mm/gpu 4bb11fd3175d4d89a067411371d2d5d0e05fdb5f 7 +tech/mproc/rpmsg c3875d91bc790317fbfd048810402ebd4fa406b2 1 +tech/net/ath 93be5e1da22add744318e1fdb20387fac4c2e83f 144 +tech/net/eth c280d7e86faa86b16d3c1e313e95207503cf3770 1 +tech/net/qrtr e249fa5f1f2c346bfc537494a06e9dc227419639 1 +tech/net/phy d02d17363623cf15ba4ea228c8d7753d8675571e 1 +tech/net/bluetooth b85467e8227775774b42430aa9b057f7c0d6406c 7 +tech/pm/power 7b7e77956157470a1c0925cdec114a0f1a423877 7 +tech/pm/thermal f02e75e749cc2093690cf8b14ec14f9d6db45dba 3 +tech/security/crypto a6ce790e0668cc6f98549c390017c5d1be5d983d 12 +tech/security/ice 5c53b58f4ebbdc2b97f442b6758fb74df96884dc 12 +tech/storage/all e254daed78f7b24bf852df097b78455ca142666a 1 +tech/all/dt/qcs6490 7b47af6e432d377b4ad9dee6a2d5ac83f693e931 9 +tech/all/dt/qcs9100 2b9347cdf09a237d6d8e00bc2d87a3a18617bcc1 21 +tech/all/dt/qcs8300 7c34815632cdccc6e60628ce1efb3c710eff7989 32 +tech/all/dt/qcs615 105f20e3fb028f754d667cb73bc51824239b2e5e 22 +tech/all/dt/hamoa 2de2c8811b30a7559e85dd2ee348228119610869 20 +tech/all/dt/glymur 74e83f399b94405c00c80e819c5d3cc2aaa4af40 8 +tech/all/dt/kaanapali c3ff3fc9f8f2aab4813819282b72298763d547eb 17 +tech/all/dt/pakala 12287e54c6772afe134ba5df936177e1a033fac9 10 +tech/all/config 591ac9212b0dd0ef9038b9ce9b617aa4f8c3952b 43 +tech/overlay/dt ba99ff10a2448f95028e534842ceb4b1ae57067d 21 +tech/all/workaround b67e2b690d732374a0d8843384ef663d60c76539 6 +tech/mproc/all d19a4c1bd3a5c85722d13d63aa5e2542accfc2a0 5 +tech/noup/debug/all 7fc440765b19f217c84d3cceef13f158f9338821 12 +tech/hwe/unoq 9d4ee0308d4f910c2d290984d51d0d4ea369e374 12