2018-06-29 21:21:45

by David Dai

[permalink] [raw]
Subject: [RFC PATCH v1 0/2] Add QCOM SDM845 interconnect provider driver

Hi,

This patch series adds a driver and DT binding using the interconnect (ICC)
framework [1] to describe the Qualcomm SDM845 platform's topology of its
interconnected buses and internal aggregation nodes known as
Bus Clock Managers(BCM). The SDM845 ICC provider driver would aggregate and
satisfy consumer requests accross the SoC by generating commands that
communicate with the BCM through the Resource Power Manager (RPMh) driver [2]
interface. The SDM845 ICC driver also configures QoS settings specific to each
node to ensure clients have proper priority.

The SDM845 interconnect provider has dependencies on the RPMh driver
and Command DB driver [3] which are under review.

Changes since v0 [4]:
- Addressed review feedback from Georgi D. and Evan G.
- Removed proposal to modify ICC aggregate callback interface
- Moved BCM aggregation into provider set function
- Added devicetree binding documentation
- Fixed logic in generating TCS command list
- Added keepalive flags for resources that are critical to platform operation
- Added various comments to clarify intent
- Removed unused types and struct definitions

[1]: https://lkml.org/lkml/2018/6/20/453
[2]: https://lkml.org/lkml/2018/5/9/729
[3]: https://lkml.org/lkml/2018/3/14/787
[4]: https://patchwork.kernel.org/patch/10428167/

Summary of the patches:
Patch 1 creates the Qualcomm SDM845 Specific provider driver.
Patch 2 Adds dt binding for SDM845 provider

TODO:
* Expand aggregation/provider to handle clients with active only requirements.
* Add Network-on-Chip (NoC) objects to encapsulate logical nodes for QoS.
* Add QoS configuration specific to each NoC.

David Dai (2):
interconnect: qcom: Add sdm845 interconnect provider driver
arm64: dts: sdm845: Add interconnect provider DT nodes

.../bindings/interconnect/qcom-sdm845.txt | 22 +
arch/arm64/boot/dts/qcom/sdm845.dtsi | 5 +
drivers/interconnect/qcom/Kconfig | 8 +
drivers/interconnect/qcom/Makefile | 1 +
drivers/interconnect/qcom/qcom-icc-ids.h | 142 ++++
drivers/interconnect/qcom/sdm845.c | 826 +++++++++++++++++++++
6 files changed, 1004 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt
create mode 100644 drivers/interconnect/qcom/qcom-icc-ids.h
create mode 100644 drivers/interconnect/qcom/sdm845.c

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



2018-06-29 21:20:19

by David Dai

[permalink] [raw]
Subject: [RFC PATCH v1 2/2] arm64: dts: sdm845: Add interconnect provider DT nodes

Add RSC(Resource State Coordinator) provider
dictating network-on-chip interconnect bus performance
found on SDM845-based platforms.

Change-Id: I58f0bfc3ed484d7b45064dceb94dcfda507e9333
Signed-off-by: David Dai <[email protected]>
---
arch/arm64/boot/dts/qcom/sdm845.dtsi | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 228d502..c2a5309 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1091,6 +1091,11 @@

pmi8998_bob: bob {};
};
+
+ qnoc: qnoc-rsc-hlos{
+ compatible = "qcom,sdm845-rsc-hlos";
+ status = "okay";
+ };
};

intc: interrupt-controller@17a00000 {
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


2018-06-29 21:20:27

by David Dai

[permalink] [raw]
Subject: [RFC PATCH v1 1/2] interconnect: qcom: Add sdm845 interconnect provider driver

Introduce Qualcomm SDM845 specific provider driver using the
interconnect framework.

Change-Id: I716b39068b4a211b8203b2a52d3037a5b84594ea
Signed-off-by: David Dai <[email protected]>
---
.../bindings/interconnect/qcom-sdm845.txt | 22 +
drivers/interconnect/qcom/Kconfig | 8 +
drivers/interconnect/qcom/Makefile | 1 +
drivers/interconnect/qcom/qcom-icc-ids.h | 142 ++++
drivers/interconnect/qcom/sdm845.c | 826 +++++++++++++++++++++
5 files changed, 999 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt
create mode 100644 drivers/interconnect/qcom/qcom-icc-ids.h
create mode 100644 drivers/interconnect/qcom/sdm845.c

diff --git a/Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt
new file mode 100644
index 0000000..6248523
--- /dev/null
+++ b/Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt
@@ -0,0 +1,22 @@
+Qualcomm SDM845 Network-On-Chip interconnect driver binding
+----------------------------------------------------
+
+SDM845 interconnect providers support system bandwidth requirements through
+RPMh hardware accelerators known as Bus Clock Manager(BCM). The provider is able
+to communicate with the BCM through the Resource State Coordinator(RSC)
+associated with each execution environment. Provider nodes must reside within
+an RPMh device node pertaining to their RSC and each provider maps to
+a single RPMh resource.
+
+Required properties :
+- compatible : shall contain only one of the following:
+ "qcom,sdm845-rsc-hlos"
+
+Examples:
+
+apps_rsc: rsc {
+ qnoc: qnoc-rsc-hlos {
+ compatible = "qcom,sdm845-rsc-hlos";
+ };
+};
+
diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
index c858218..2cd3603 100644
--- a/drivers/interconnect/qcom/Kconfig
+++ b/drivers/interconnect/qcom/Kconfig
@@ -17,3 +17,11 @@ config INTERCONNECT_QCOM_MSM8916
help
This is a driver for the Qualcomm Network-on-Chip on msm8916-based
platforms.
+
+config INTERCONNECT_QCOM_SDM845
+ tristate "Qualcomm SDM845 interconnect driver"
+ depends on INTERCONNECT_QCOM
+ depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST
+ help
+ This is a driver for the Qualcomm Network-on-Chip on sdm845-based
+ platforms.
diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
index 53f3380..a0a5056 100644
--- a/drivers/interconnect/qcom/Makefile
+++ b/drivers/interconnect/qcom/Makefile
@@ -2,3 +2,4 @@
obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += smd-rpm.o

obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += msm8916.o
+obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += sdm845.o
diff --git a/drivers/interconnect/qcom/qcom-icc-ids.h b/drivers/interconnect/qcom/qcom-icc-ids.h
new file mode 100644
index 0000000..5bd0db2
--- /dev/null
+++ b/drivers/interconnect/qcom/qcom-icc-ids.h
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#ifndef _QCOM_ICC_IDS_H
+#define _QCOM_ICC_IDS_H
+
+#define MASTER_APPSS_PROC 0
+#define MASTER_TCU_0 1
+#define MASTER_IPA_CORE 2
+#define MASTER_LLCC 3
+#define MASTER_GNOC_CFG 4
+#define MASTER_A1NOC_CFG 5
+#define MASTER_A2NOC_CFG 6
+#define MASTER_CNOC_DC_NOC 7
+#define MASTER_MEM_NOC_CFG 8
+#define MASTER_CNOC_MNOC_CFG 9
+#define MASTER_QDSS_BAM 10
+#define MASTER_BLSP_1 11
+#define MASTER_BLSP_2 12
+#define MASTER_SNOC_CFG 13
+#define MASTER_SPDM 14
+#define MASTER_TIC 15
+#define MASTER_TSIF 16
+#define MASTER_A1NOC_SNOC 17
+#define MASTER_A2NOC_SNOC 18
+#define MASTER_GNOC_MEM_NOC 19
+#define MASTER_CNOC_A2NOC 20
+#define MASTER_GNOC_SNOC 21
+#define MASTER_MEM_NOC_SNOC 22
+#define MASTER_MNOC_HF_MEM_NOC 23
+#define MASTER_MNOC_SF_MEM_NOC 24
+#define MASTER_ANOC_PCIE_SNOC 25
+#define MASTER_SNOC_CNOC 26
+#define MASTER_SNOC_GC_MEM_NOC 27
+#define MASTER_SNOC_SF_MEM_NOC 28
+#define MASTER_CAMNOC_HF0 29
+#define MASTER_CAMNOC_HF0_UNCOMP 30
+#define MASTER_CAMNOC_HF1 31
+#define MASTER_CAMNOC_HF1_UNCOMP 32
+#define MASTER_CAMNOC_SF 33
+#define MASTER_CAMNOC_SF_UNCOMP 34
+#define MASTER_CRYPTO 35
+#define MASTER_GFX3D 36
+#define MASTER_IPA 37
+#define MASTER_MDP0 38
+#define MASTER_MDP1 39
+#define MASTER_PIMEM 40
+#define MASTER_ROTATOR 41
+#define MASTER_VIDEO_P0 42
+#define MASTER_VIDEO_P1 43
+#define MASTER_VIDEO_PROC 44
+#define MASTER_GIC 45
+#define MASTER_PCIE_1 46
+#define MASTER_PCIE_0 47
+#define MASTER_QDSS_DAP 48
+#define MASTER_QDSS_ETR 49
+#define MASTER_SDCC_2 50
+#define MASTER_SDCC_4 51
+#define MASTER_UFS_CARD 52
+#define MASTER_UFS_MEM 53
+#define MASTER_USB3_0 54
+#define MASTER_USB3_1 55
+#define SLAVE_EBI1 512
+#define SLAVE_IPA_CORE 513
+#define SLAVE_A1NOC_CFG 514
+#define SLAVE_A2NOC_CFG 515
+#define SLAVE_AOP 516
+#define SLAVE_AOSS 517
+#define SLAVE_APPSS 518
+#define SLAVE_CAMERA_CFG 519
+#define SLAVE_CLK_CTL 520
+#define SLAVE_CDSP_CFG 521
+#define SLAVE_RBCPR_CX_CFG 522
+#define SLAVE_CRYPTO_0_CFG 523
+#define SLAVE_DCC_CFG 524
+#define SLAVE_CNOC_DDRSS 525
+#define SLAVE_DISPLAY_CFG 526
+#define SLAVE_GLM 527
+#define SLAVE_GFX3D_CFG 528
+#define SLAVE_IMEM_CFG 529
+#define SLAVE_IPA_CFG 530
+#define SLAVE_LLCC_CFG 531
+#define SLAVE_MSS_PROC_MS_MPU_CFG 532
+#define SLAVE_MEM_NOC_CFG 533
+#define SLAVE_CNOC_MNOC_CFG 534
+#define SLAVE_PCIE_0_CFG 535
+#define SLAVE_PCIE_1_CFG 536
+#define SLAVE_PDM 537
+#define SLAVE_SOUTH_PHY_CFG 538
+#define SLAVE_PIMEM_CFG 539
+#define SLAVE_PRNG 540
+#define SLAVE_QDSS_CFG 541
+#define SLAVE_BLSP_2 542
+#define SLAVE_BLSP_1 543
+#define SLAVE_SDCC_2 544
+#define SLAVE_SDCC_4 545
+#define SLAVE_SNOC_CFG 546
+#define SLAVE_SPDM_WRAPPER 547
+#define SLAVE_SPSS_CFG 548
+#define SLAVE_TCSR 549
+#define SLAVE_TLMM_NORTH 550
+#define SLAVE_TLMM_SOUTH 551
+#define SLAVE_TSIF 552
+#define SLAVE_UFS_CARD_CFG 553
+#define SLAVE_UFS_MEM_CFG 554
+#define SLAVE_USB3_0 555
+#define SLAVE_USB3_1 556
+#define SLAVE_VENUS_CFG 557
+#define SLAVE_VSENSE_CTRL_CFG 558
+#define SLAVE_MNOC_SF_MEM_NOC 559
+#define SLAVE_A1NOC_SNOC 560
+#define SLAVE_A2NOC_SNOC 561
+#define SLAVE_MEM_NOC_GNOC 562
+#define SLAVE_CAMNOC_UNCOMP 563
+#define SLAVE_SNOC_CNOC 564
+#define SLAVE_CNOC_A2NOC 565
+#define SLAVE_GNOC_SNOC 566
+#define SLAVE_GNOC_MEM_NOC 567
+#define SLAVE_LLCC 568
+#define SLAVE_MNOC_HF_MEM_NOC 569
+#define SLAVE_SNOC_MEM_NOC_GC 570
+#define SLAVE_SNOC_MEM_NOC_SF 571
+#define SLAVE_MEM_NOC_SNOC 572
+#define SLAVE_ANOC_PCIE_A1NOC_SNOC 573
+#define SLAVE_ANOC_PCIE_SNOC 574
+#define SLAVE_IMEM 575
+#define SLAVE_PCIE_0 576
+#define SLAVE_PCIE_1 577
+#define SLAVE_PIMEM 578
+#define SLAVE_SERVICE_A1NOC 579
+#define SLAVE_SERVICE_A2NOC 580
+#define SLAVE_SERVICE_CNOC 581
+#define SLAVE_SERVICE_GNOC 582
+#define SLAVE_SERVICE_MEM_NOC 583
+#define SLAVE_SERVICE_MNOC 584
+#define SLAVE_SERVICE_SNOC 585
+#define SLAVE_QDSS_STM 586
+#define SLAVE_TCU 587
+#endif
diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c
new file mode 100644
index 0000000..c68d5dc
--- /dev/null
+++ b/drivers/interconnect/qcom/sdm845.c
@@ -0,0 +1,826 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/interconnect.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+
+#include <soc/qcom/cmd-db.h>
+#include <soc/qcom/rpmh.h>
+#include <soc/qcom/tcs.h>
+
+#include "qcom-icc-ids.h"
+
+#define BCM_TCS_CMD_COMMIT_SHFT 30
+#define BCM_TCS_CMD_COMMIT_MASK 0x40000000
+#define BCM_TCS_CMD_VALID_SHFT 29
+#define BCM_TCS_CMD_VALID_MASK 0x200010000
+#define BCM_TCS_CMD_VOTE_X_SHFT 14
+#define BCM_TCS_CMD_VOTE_MASK 0x3fff
+#define BCM_TCS_CMD_VOTE_Y_SHFT 0
+#define BCM_TCS_CMD_VOTE_Y_MASK 0xfffc000
+
+#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \
+ ((commit << BCM_TCS_CMD_COMMIT_SHFT) |\
+ (valid << BCM_TCS_CMD_VALID_SHFT) |\
+ ((vote_x & BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) |\
+ ((vote_y & BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_Y_SHFT))
+
+#define to_qcom_provider(_provider) \
+ container_of(_provider, struct qcom_icc_provider, provider)
+
+#define DEFINE_QNODE(_name, _id, _channels, _buswidth, \
+ _numlinks, ...) \
+ static struct qcom_icc_node _name = { \
+ .id = _id, \
+ .name = #_name, \
+ .channels = _channels, \
+ .buswidth = _buswidth, \
+ .num_links = _numlinks, \
+ .links = { __VA_ARGS__ }, \
+ }
+
+#define DEFINE_QBCM(_name, _bcmname, _keepalive, _numnodes, ...) \
+ static struct qcom_icc_bcm _name = { \
+ .name = _bcmname, \
+ .keepalive = _keepalive, \
+ .num_nodes = _numnodes, \
+ .nodes = { __VA_ARGS__ }, \
+ }
+
+struct qcom_icc_provider {
+ struct icc_provider provider;
+ void __iomem *base;
+ struct rpmh_client *rpmh_client;
+ struct qcom_icc_bcm **bcms;
+ size_t num_bcms;
+};
+
+/**
+ * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM)
+ * @unit: bcm threshold values are in magnitudes of this
+ * @width: prototype width
+ * @vcd: virtual clock domain that this bcm belongs to
+ */
+
+struct bcm_db {
+ u32 unit;
+ u16 width;
+ u8 vcd;
+ u8 reserved;
+};
+
+#define SDM845_MAX_LINKS 43
+#define SDM845_MAX_BCMS 30
+#define SDM845_MAX_BCM_PER_NODE 2
+#define SDM845_MAX_VCD 10
+
+/**
+ * struct qcom_icc_node - Qualcomm specific interconnect nodes
+ * @name: the node name used in debugfs
+ * @links: an array of nodes where we can go next while traversing
+ * @id: a unique node identifier
+ * @num_links: the total number of @links
+ * @channels: num of channels at this node
+ * @buswidth: width of the interconnect between a node and the bus
+ * @sum_avg: current sum aggregate value of all avg bw requests
+ * @max_peak: current max aggregate value of all peak bw requests
+ * @bcms: list of bcms associated with this logical node
+ * @num_bcm: num of @bcms
+ */
+struct qcom_icc_node {
+ const char *name;
+ u16 links[SDM845_MAX_LINKS];
+ u16 id;
+ u16 num_links;
+ u16 channels;
+ u16 buswidth;
+ u64 sum_avg;
+ u64 max_peak;
+ struct qcom_icc_bcm *bcms[SDM845_MAX_BCM_PER_NODE];
+ size_t num_bcms;
+};
+
+/**
+ * struct qcom_icc_bcm - Qualcomm specific hardware accelerator nodes
+ * known as Bus Clock Manager(BCM)
+ * @name: the bcm node name used to fetch BCM data from command db
+ * @type: latency or bandwidth bcm
+ * @addr: address offsets used when voting to RPMH
+ * @vote_x: aggregated threshold values, represents sum_bw when @type is bw bcm
+ * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm
+ * @dirty: flag used to indicate whether or bcm needs to be committed
+ * @aux_data: auxiliary data used when calculating threshold values and
+ * communicating with RPMh
+ * @list: used to link to other bcms when compiling lists for commit
+ * @num_nodes: total number of @num_nodes
+ * @nodes: list of qcom_icc_nodes that this BCM encapsulates
+ */
+
+struct qcom_icc_bcm {
+ const char *name;
+ u32 type;
+ u32 addr;
+ u64 vote_x;
+ u64 vote_y;
+ bool dirty;
+ bool keepalive;
+ struct bcm_db aux_data;
+ struct list_head list;
+ size_t num_nodes;
+ struct qcom_icc_node *nodes[];
+};
+
+struct qcom_icc_fabric {
+ struct qcom_icc_node **nodes;
+ size_t num_nodes;
+ u32 base_offset;
+ u32 qos_offset;
+};
+
+struct qcom_icc_desc {
+ struct qcom_icc_node **nodes;
+ size_t num_nodes;
+ struct qcom_icc_bcm **bcms;
+ size_t num_bcms;
+};
+
+DEFINE_QNODE(qhm_a1noc_cfg, MASTER_A1NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A1NOC);
+DEFINE_QNODE(qhm_qup1, MASTER_BLSP_1, 1, 4, 1, SLAVE_A1NOC_SNOC);
+DEFINE_QNODE(qhm_tsif, MASTER_TSIF, 1, 4, 1, SLAVE_A1NOC_SNOC);
+DEFINE_QNODE(xm_sdc2, MASTER_SDCC_2, 1, 8, 1, SLAVE_A1NOC_SNOC);
+DEFINE_QNODE(xm_sdc4, MASTER_SDCC_4, 1, 8, 1, SLAVE_A1NOC_SNOC);
+DEFINE_QNODE(xm_ufs_card, MASTER_UFS_CARD, 1, 8, 1, SLAVE_A1NOC_SNOC);
+DEFINE_QNODE(xm_ufs_mem, MASTER_UFS_MEM, 1, 8, 1, SLAVE_A1NOC_SNOC);
+DEFINE_QNODE(xm_pcie_0, MASTER_PCIE_0, 1, 8, 1, SLAVE_ANOC_PCIE_A1NOC_SNOC);
+DEFINE_QNODE(qhm_a2noc_cfg, MASTER_A2NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A2NOC);
+DEFINE_QNODE(qhm_qdss_bam, MASTER_QDSS_BAM, 1, 4, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(qhm_qup2, MASTER_BLSP_2, 1, 4, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(qnm_cnoc, MASTER_CNOC_A2NOC, 1, 8, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(qxm_crypto, MASTER_CRYPTO, 1, 8, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(qxm_ipa, MASTER_IPA, 1, 8, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(xm_pcie3_1, MASTER_PCIE_1, 1, 8, 1, SLAVE_ANOC_PCIE_SNOC);
+DEFINE_QNODE(xm_qdss_etr, MASTER_QDSS_ETR, 1, 8, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(xm_usb3_0, MASTER_USB3_0, 1, 8, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(xm_usb3_1, MASTER_USB3_1, 1, 8, 1, SLAVE_A2NOC_SNOC);
+DEFINE_QNODE(qxm_camnoc_hf0_uncomp, MASTER_CAMNOC_HF0_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP);
+DEFINE_QNODE(qxm_camnoc_hf1_uncomp, MASTER_CAMNOC_HF1_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP);
+DEFINE_QNODE(qxm_camnoc_sf_uncomp, MASTER_CAMNOC_SF_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP);
+DEFINE_QNODE(qhm_spdm, MASTER_SPDM, 1, 4, 1, SLAVE_CNOC_A2NOC);
+DEFINE_QNODE(qhm_tic, MASTER_TIC, 1, 4, 43, SLAVE_A1NOC_CFG, SLAVE_A2NOC_CFG, SLAVE_AOP, SLAVE_AOSS, SLAVE_CAMERA_CFG, SLAVE_CLK_CTL, SLAVE_CDSP_CFG, SLAVE_RBCPR_CX_CFG, SLAVE_CRYPTO_0_CFG, SLAVE_DCC_CFG, SLAVE_CNOC_DDRSS, SLAVE_DISPLAY_CFG, SLAVE_GLM, SLAVE_GFX3D_CFG, SLAVE_IMEM_CFG, SLAVE_IPA_CFG, SLAVE_CNOC_MNOC_CFG, SLAVE_PCIE_0_CFG, SLAVE_PCIE_1_CFG, SLAVE_PDM, SLAVE_SOUTH_PHY_CFG, SLAVE_PIMEM_CFG, SLAVE_PRNG, SLAVE_QDSS_CFG, SLAVE_BLSP_2, SLAVE_BLSP_1, SLAVE_SDCC_2, SLAVE_SDCC_4, SLAVE_SNOC_CFG, SLAVE_SPDM_WRAPPER, SLAVE_SPSS_CFG, SLAVE_TCSR, SLAVE_TLMM_NORTH, SLAVE_TLMM_SOUTH, SLAVE_TSIF, SLAVE_UFS_CARD_CFG, SLAVE_UFS_MEM_CFG, SLAVE_USB3_0, SLAVE_USB3_1, SLAVE_VENUS_CFG, SLAVE_VSENSE_CTRL_CFG, SLAVE_CNOC_A2NOC, SLAVE_SERVICE_CNOC);
+DEFINE_QNODE(qnm_snoc, MASTER_SNOC_CNOC, 1, 8, 42, SLAVE_A1NOC_CFG, SLAVE_A2NOC_CFG, SLAVE_AOP, SLAVE_AOSS, SLAVE_CAMERA_CFG, SLAVE_CLK_CTL, SLAVE_CDSP_CFG, SLAVE_RBCPR_CX_CFG, SLAVE_CRYPTO_0_CFG, SLAVE_DCC_CFG, SLAVE_CNOC_DDRSS, SLAVE_DISPLAY_CFG, SLAVE_GLM, SLAVE_GFX3D_CFG, SLAVE_IMEM_CFG, SLAVE_IPA_CFG, SLAVE_CNOC_MNOC_CFG, SLAVE_PCIE_0_CFG, SLAVE_PCIE_1_CFG, SLAVE_PDM, SLAVE_SOUTH_PHY_CFG, SLAVE_PIMEM_CFG, SLAVE_PRNG, SLAVE_QDSS_CFG, SLAVE_BLSP_2, SLAVE_BLSP_1, SLAVE_SDCC_2, SLAVE_SDCC_4, SLAVE_SNOC_CFG, SLAVE_SPDM_WRAPPER, SLAVE_SPSS_CFG, SLAVE_TCSR, SLAVE_TLMM_NORTH, SLAVE_TLMM_SOUTH, SLAVE_TSIF, SLAVE_UFS_CARD_CFG, SLAVE_UFS_MEM_CFG, SLAVE_USB3_0, SLAVE_USB3_1, SLAVE_VENUS_CFG, SLAVE_VSENSE_CTRL_CFG, SLAVE_SERVICE_CNOC);
+DEFINE_QNODE(xm_qdss_dap, MASTER_QDSS_DAP, 1, 8, 43, SLAVE_A1NOC_CFG, SLAVE_A2NOC_CFG, SLAVE_AOP, SLAVE_AOSS, SLAVE_CAMERA_CFG, SLAVE_CLK_CTL, SLAVE_CDSP_CFG, SLAVE_RBCPR_CX_CFG, SLAVE_CRYPTO_0_CFG, SLAVE_DCC_CFG, SLAVE_CNOC_DDRSS, SLAVE_DISPLAY_CFG, SLAVE_GLM, SLAVE_GFX3D_CFG, SLAVE_IMEM_CFG, SLAVE_IPA_CFG, SLAVE_CNOC_MNOC_CFG, SLAVE_PCIE_0_CFG, SLAVE_PCIE_1_CFG, SLAVE_PDM, SLAVE_SOUTH_PHY_CFG, SLAVE_PIMEM_CFG, SLAVE_PRNG, SLAVE_QDSS_CFG, SLAVE_BLSP_2, SLAVE_BLSP_1, SLAVE_SDCC_2, SLAVE_SDCC_4, SLAVE_SNOC_CFG, SLAVE_SPDM_WRAPPER, SLAVE_SPSS_CFG, SLAVE_TCSR, SLAVE_TLMM_NORTH, SLAVE_TLMM_SOUTH, SLAVE_TSIF, SLAVE_UFS_CARD_CFG, SLAVE_UFS_MEM_CFG, SLAVE_USB3_0, SLAVE_USB3_1, SLAVE_VENUS_CFG, SLAVE_VSENSE_CTRL_CFG, SLAVE_CNOC_A2NOC, SLAVE_SERVICE_CNOC);
+DEFINE_QNODE(qhm_cnoc, MASTER_CNOC_DC_NOC, 1, 4, 2, SLAVE_LLCC_CFG, SLAVE_MEM_NOC_CFG);
+DEFINE_QNODE(acm_l3, MASTER_APPSS_PROC, 1, 16, 3, SLAVE_GNOC_SNOC, SLAVE_GNOC_MEM_NOC, SLAVE_SERVICE_GNOC);
+DEFINE_QNODE(pm_gnoc_cfg, MASTER_GNOC_CFG, 1, 4, 1, SLAVE_SERVICE_GNOC);
+DEFINE_QNODE(ipa_core_master, MASTER_IPA_CORE, 1, 8, 1, SLAVE_IPA_CORE);
+DEFINE_QNODE(llcc_mc, MASTER_LLCC, 4, 4, 1, SLAVE_EBI1);
+DEFINE_QNODE(acm_tcu, MASTER_TCU_0, 1, 8, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC);
+DEFINE_QNODE(qhm_memnoc_cfg, MASTER_MEM_NOC_CFG, 1, 4, 2, SLAVE_MSS_PROC_MS_MPU_CFG, SLAVE_SERVICE_MEM_NOC);
+DEFINE_QNODE(qnm_apps, MASTER_GNOC_MEM_NOC, 2, 32, 1, SLAVE_LLCC);
+DEFINE_QNODE(qnm_mnoc_hf, MASTER_MNOC_HF_MEM_NOC, 2, 32, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC);
+DEFINE_QNODE(qnm_mnoc_sf, MASTER_MNOC_SF_MEM_NOC, 1, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC);
+DEFINE_QNODE(qnm_snoc_gc, MASTER_SNOC_GC_MEM_NOC, 1, 8, 1, SLAVE_LLCC);
+DEFINE_QNODE(qnm_snoc_sf, MASTER_SNOC_SF_MEM_NOC, 1, 16, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC);
+DEFINE_QNODE(qxm_gpu, MASTER_GFX3D, 2, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC);
+DEFINE_QNODE(qhm_mnoc_cfg, MASTER_CNOC_MNOC_CFG, 1, 4, 1, SLAVE_SERVICE_MNOC);
+DEFINE_QNODE(qxm_camnoc_hf0, MASTER_CAMNOC_HF0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
+DEFINE_QNODE(qxm_camnoc_hf1, MASTER_CAMNOC_HF1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
+DEFINE_QNODE(qxm_camnoc_sf, MASTER_CAMNOC_SF, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
+DEFINE_QNODE(qxm_mdp0, MASTER_MDP0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
+DEFINE_QNODE(qxm_mdp1, MASTER_MDP1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC);
+DEFINE_QNODE(qxm_rot, MASTER_ROTATOR, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
+DEFINE_QNODE(qxm_venus0, MASTER_VIDEO_P0, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
+DEFINE_QNODE(qxm_venus1, MASTER_VIDEO_P1, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC);
+DEFINE_QNODE(qxm_venus_arm9, MASTER_VIDEO_PROC, 1, 8, 1, SLAVE_MNOC_SF_MEM_NOC);
+DEFINE_QNODE(qhm_snoc_cfg, MASTER_SNOC_CFG, 1, 4, 1, SLAVE_SERVICE_SNOC);
+DEFINE_QNODE(qnm_aggre1_noc, MASTER_A1NOC_SNOC, 1, 16, 6, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_SNOC_MEM_NOC_SF, SLAVE_IMEM, SLAVE_PIMEM, SLAVE_QDSS_STM);
+DEFINE_QNODE(qnm_aggre2_noc, MASTER_A2NOC_SNOC, 1, 16, 9, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_SNOC_MEM_NOC_SF, SLAVE_IMEM, SLAVE_PCIE_0, SLAVE_PCIE_1, SLAVE_PIMEM, SLAVE_QDSS_STM, SLAVE_TCU);
+DEFINE_QNODE(qnm_gladiator_sodv, MASTER_GNOC_SNOC, 1, 8, 8, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_IMEM, SLAVE_PCIE_0, SLAVE_PCIE_1, SLAVE_PIMEM, SLAVE_QDSS_STM, SLAVE_TCU);
+DEFINE_QNODE(qnm_memnoc, MASTER_MEM_NOC_SNOC, 1, 8, 5, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_IMEM, SLAVE_PIMEM, SLAVE_QDSS_STM);
+DEFINE_QNODE(qnm_pcie_anoc, MASTER_ANOC_PCIE_SNOC, 1, 16, 5, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_SNOC_MEM_NOC_SF, SLAVE_IMEM, SLAVE_QDSS_STM);
+DEFINE_QNODE(qxm_pimem, MASTER_PIMEM, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM);
+DEFINE_QNODE(xm_gic, MASTER_GIC, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM);
+DEFINE_QNODE(qns_a1noc_snoc, SLAVE_A1NOC_SNOC, 1, 16, 1, MASTER_A1NOC_SNOC);
+DEFINE_QNODE(srvc_aggre1_noc, SLAVE_SERVICE_A1NOC, 1, 4, 0);
+DEFINE_QNODE(qns_pcie_a1noc_snoc, SLAVE_ANOC_PCIE_A1NOC_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC);
+DEFINE_QNODE(qns_a2noc_snoc, SLAVE_A2NOC_SNOC, 1, 16, 1, MASTER_A2NOC_SNOC);
+DEFINE_QNODE(qns_pcie_snoc, SLAVE_ANOC_PCIE_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC);
+DEFINE_QNODE(srvc_aggre2_noc, SLAVE_SERVICE_A2NOC, 1, 4, 0);
+DEFINE_QNODE(qns_camnoc_uncomp, SLAVE_CAMNOC_UNCOMP, 1, 32, 0);
+DEFINE_QNODE(qhs_a1_noc_cfg, SLAVE_A1NOC_CFG, 1, 4, 1, MASTER_A1NOC_CFG);
+DEFINE_QNODE(qhs_a2_noc_cfg, SLAVE_A2NOC_CFG, 1, 4, 1, MASTER_A2NOC_CFG);
+DEFINE_QNODE(qhs_aop, SLAVE_AOP, 1, 4, 0);
+DEFINE_QNODE(qhs_aoss, SLAVE_AOSS, 1, 4, 0);
+DEFINE_QNODE(qhs_camera_cfg, SLAVE_CAMERA_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_clk_ctl, SLAVE_CLK_CTL, 1, 4, 0);
+DEFINE_QNODE(qhs_compute_dsp_cfg, SLAVE_CDSP_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_cpr_cx, SLAVE_RBCPR_CX_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_crypto0_cfg, SLAVE_CRYPTO_0_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_dcc_cfg, SLAVE_DCC_CFG, 1, 4, 1, MASTER_CNOC_DC_NOC);
+DEFINE_QNODE(qhs_ddrss_cfg, SLAVE_CNOC_DDRSS, 1, 4, 0);
+DEFINE_QNODE(qhs_display_cfg, SLAVE_DISPLAY_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_glm, SLAVE_GLM, 1, 4, 0);
+DEFINE_QNODE(qhs_gpuss_cfg, SLAVE_GFX3D_CFG, 1, 8, 0);
+DEFINE_QNODE(qhs_imem_cfg, SLAVE_IMEM_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_ipa, SLAVE_IPA_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_mnoc_cfg, SLAVE_CNOC_MNOC_CFG, 1, 4, 1, MASTER_CNOC_MNOC_CFG);
+DEFINE_QNODE(qhs_pcie0_cfg, SLAVE_PCIE_0_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_pcie_gen3_cfg, SLAVE_PCIE_1_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_pdm, SLAVE_PDM, 1, 4, 0);
+DEFINE_QNODE(qhs_phy_refgen_south, SLAVE_SOUTH_PHY_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_pimem_cfg, SLAVE_PIMEM_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_prng, SLAVE_PRNG, 1, 4, 0);
+DEFINE_QNODE(qhs_qdss_cfg, SLAVE_QDSS_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_qupv3_north, SLAVE_BLSP_2, 1, 4, 0);
+DEFINE_QNODE(qhs_qupv3_south, SLAVE_BLSP_1, 1, 4, 0);
+DEFINE_QNODE(qhs_sdc2, SLAVE_SDCC_2, 1, 4, 0);
+DEFINE_QNODE(qhs_sdc4, SLAVE_SDCC_4, 1, 4, 0);
+DEFINE_QNODE(qhs_snoc_cfg, SLAVE_SNOC_CFG, 1, 4, 1, MASTER_SNOC_CFG);
+DEFINE_QNODE(qhs_spdm, SLAVE_SPDM_WRAPPER, 1, 4, 0);
+DEFINE_QNODE(qhs_spss_cfg, SLAVE_SPSS_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_tcsr, SLAVE_TCSR, 1, 4, 0);
+DEFINE_QNODE(qhs_tlmm_north, SLAVE_TLMM_NORTH, 1, 4, 0);
+DEFINE_QNODE(qhs_tlmm_south, SLAVE_TLMM_SOUTH, 1, 4, 0);
+DEFINE_QNODE(qhs_tsif, SLAVE_TSIF, 1, 4, 0);
+DEFINE_QNODE(qhs_ufs_card_cfg, SLAVE_UFS_CARD_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_ufs_mem_cfg, SLAVE_UFS_MEM_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_usb3_0, SLAVE_USB3_0, 1, 4, 0);
+DEFINE_QNODE(qhs_usb3_1, SLAVE_USB3_1, 1, 4, 0);
+DEFINE_QNODE(qhs_venus_cfg, SLAVE_VENUS_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_vsense_ctrl_cfg, SLAVE_VSENSE_CTRL_CFG, 1, 4, 0);
+DEFINE_QNODE(qns_cnoc_a2noc, SLAVE_CNOC_A2NOC, 1, 8, 1, MASTER_CNOC_A2NOC);
+DEFINE_QNODE(srvc_cnoc, SLAVE_SERVICE_CNOC, 1, 4, 0);
+DEFINE_QNODE(qhs_llcc, SLAVE_LLCC_CFG, 1, 4, 0);
+DEFINE_QNODE(qhs_memnoc, SLAVE_MEM_NOC_CFG, 1, 4, 1, MASTER_MEM_NOC_CFG);
+DEFINE_QNODE(qns_gladiator_sodv, SLAVE_GNOC_SNOC, 1, 8, 1, MASTER_GNOC_SNOC);
+DEFINE_QNODE(qns_gnoc_memnoc, SLAVE_GNOC_MEM_NOC, 2, 32, 1, MASTER_GNOC_MEM_NOC);
+DEFINE_QNODE(srvc_gnoc, SLAVE_SERVICE_GNOC, 1, 4, 0);
+DEFINE_QNODE(ipa_core_slave, SLAVE_IPA_CORE, 1, 8, 0);
+DEFINE_QNODE(ebi, SLAVE_EBI1, 4, 4, 0);
+DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SLAVE_MSS_PROC_MS_MPU_CFG, 1, 4, 0);
+DEFINE_QNODE(qns_apps_io, SLAVE_MEM_NOC_GNOC, 1, 32, 0);
+DEFINE_QNODE(qns_llcc, SLAVE_LLCC, 4, 16, 1, MASTER_LLCC);
+DEFINE_QNODE(qns_memnoc_snoc, SLAVE_MEM_NOC_SNOC, 1, 8, 1, MASTER_MEM_NOC_SNOC);
+DEFINE_QNODE(srvc_memnoc, SLAVE_SERVICE_MEM_NOC, 1, 4, 0);
+DEFINE_QNODE(qns2_mem_noc, SLAVE_MNOC_SF_MEM_NOC, 1, 32, 1, MASTER_MNOC_SF_MEM_NOC);
+DEFINE_QNODE(qns_mem_noc_hf, SLAVE_MNOC_HF_MEM_NOC, 2, 32, 1, MASTER_MNOC_HF_MEM_NOC);
+DEFINE_QNODE(srvc_mnoc, SLAVE_SERVICE_MNOC, 1, 4, 0);
+DEFINE_QNODE(qhs_apss, SLAVE_APPSS, 1, 8, 0);
+DEFINE_QNODE(qns_cnoc, SLAVE_SNOC_CNOC, 1, 8, 1, MASTER_SNOC_CNOC);
+DEFINE_QNODE(qns_memnoc_gc, SLAVE_SNOC_MEM_NOC_GC, 1, 8, 1, MASTER_SNOC_GC_MEM_NOC);
+DEFINE_QNODE(qns_memnoc_sf, SLAVE_SNOC_MEM_NOC_SF, 1, 16, 1, MASTER_SNOC_SF_MEM_NOC);
+DEFINE_QNODE(qxs_imem, SLAVE_IMEM, 1, 8, 0);
+DEFINE_QNODE(qxs_pcie, SLAVE_PCIE_0, 1, 8, 0);
+DEFINE_QNODE(qxs_pcie_gen3, SLAVE_PCIE_1, 1, 8, 0);
+DEFINE_QNODE(qxs_pimem, SLAVE_PIMEM, 1, 8, 0);
+DEFINE_QNODE(srvc_snoc, SLAVE_SERVICE_SNOC, 1, 4, 0);
+DEFINE_QNODE(xs_qdss_stm, SLAVE_QDSS_STM, 1, 4, 0);
+DEFINE_QNODE(xs_sys_tcu_cfg, SLAVE_TCU, 1, 8, 0);
+
+DEFINE_QBCM(bcm_acv, "ACV", false, 1, &ebi);
+DEFINE_QBCM(bcm_mc0, "MC0", true, 1, &ebi);
+DEFINE_QBCM(bcm_sh0, "SH0", true, 1, &qns_llcc);
+DEFINE_QBCM(bcm_mm0, "MM0", false, 1, &qns_mem_noc_hf);
+DEFINE_QBCM(bcm_sh1, "SH1", false, 1, &qns_apps_io);
+DEFINE_QBCM(bcm_mm1, "MM1", false, 7, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, &qxm_camnoc_hf1, &qxm_mdp0, &qxm_mdp1);
+DEFINE_QBCM(bcm_sh2, "SH2", false, 1, &qns_memnoc_snoc);
+DEFINE_QBCM(bcm_mm2, "MM2", false, 1, &qns2_mem_noc);
+DEFINE_QBCM(bcm_sh3, "SH3", false, 1, &acm_tcu);
+DEFINE_QBCM(bcm_mm3, "MM3", false, 5, &qxm_camnoc_sf, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9);
+DEFINE_QBCM(bcm_sh5, "SH5", false, 1, &qnm_apps);
+DEFINE_QBCM(bcm_sn0, "SN0", true, 1, &qns_memnoc_sf);
+DEFINE_QBCM(bcm_ce0, "CE0", false, 1, &qxm_crypto);
+DEFINE_QBCM(bcm_ip0, "IP0", false, 1, &ipa_core_slave);
+DEFINE_QBCM(bcm_cn0, "CN0", false, 47, &qhm_spdm, &qhm_tic, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_aop, &qhs_aoss, &qhs_camera_cfg, &qhs_clk_ctl, &qhs_compute_dsp_cfg, &qhs_cpr_cx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_pcie0_cfg, &qhs_pcie_gen3_cfg, &qhs_pdm, &qhs_phy_refgen_south, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qupv3_north, &qhs_qupv3_south, &qhs_sdc2, &qhs_sdc4, &qhs_snoc_cfg, &qhs_spdm, &qhs_spss_cfg, &qhs_tcsr, &qhs_tlmm_north, &qhs_tlmm_south, &qhs_tsif, &qhs_ufs_card_cfg, &qhs_ufs_mem_cfg, &qhs_usb3_0, &qhs_usb3_1, &qhs_venus_cfg, &qhs_vsense_ctrl_cfg, &qns_cnoc_a2noc, &srvc_cnoc);
+DEFINE_QBCM(bcm_qup0, "QUP0", false, 2, &qhm_qup1, &qhm_qup2);
+DEFINE_QBCM(bcm_sn1, "SN1", false, 1, &qxs_imem);
+DEFINE_QBCM(bcm_sn2, "SN2", false, 1, &qns_memnoc_gc);
+DEFINE_QBCM(bcm_sn3, "SN3", false, 1, &qns_cnoc);
+DEFINE_QBCM(bcm_sn4, "SN4", false, 1, &qxm_pimem);
+DEFINE_QBCM(bcm_sn5, "SN5", false, 1, &xs_qdss_stm);
+DEFINE_QBCM(bcm_sn6, "SN6", false, 3, &qhs_apss, &srvc_snoc, &xs_sys_tcu_cfg);
+DEFINE_QBCM(bcm_sn7, "SN7", false, 1, &qxs_pcie);
+DEFINE_QBCM(bcm_sn8, "SN8", false, 1, &qxs_pcie_gen3);
+DEFINE_QBCM(bcm_sn9, "SN9", false, 2, &srvc_aggre1_noc, &qnm_aggre1_noc);
+DEFINE_QBCM(bcm_sn11, "SN11", false, 2, &srvc_aggre2_noc, &qnm_aggre2_noc);
+DEFINE_QBCM(bcm_sn12, "SN12", false, 2, &qnm_gladiator_sodv, &xm_gic);
+DEFINE_QBCM(bcm_sn14, "SN14", false, 1, &qnm_pcie_anoc);
+DEFINE_QBCM(bcm_sn15, "SN15", false, 1, &qnm_memnoc);
+
+static struct qcom_icc_node *rsc_hlos_nodes[] = {
+ &acm_l3,
+ &acm_tcu,
+ &ipa_core_master,
+ &llcc_mc,
+ &pm_gnoc_cfg,
+ &qhm_a1noc_cfg,
+ &qhm_a2noc_cfg,
+ &qhm_cnoc,
+ &qhm_memnoc_cfg,
+ &qhm_mnoc_cfg,
+ &qhm_qdss_bam,
+ &qhm_qup1,
+ &qhm_qup2,
+ &qhm_snoc_cfg,
+ &qhm_spdm,
+ &qhm_tic,
+ &qhm_tsif,
+ &qnm_aggre1_noc,
+ &qnm_aggre2_noc,
+ &qnm_apps,
+ &qnm_cnoc,
+ &qnm_gladiator_sodv,
+ &qnm_memnoc,
+ &qnm_mnoc_hf,
+ &qnm_mnoc_sf,
+ &qnm_pcie_anoc,
+ &qnm_snoc,
+ &qnm_snoc_gc,
+ &qnm_snoc_sf,
+ &qxm_camnoc_hf0,
+ &qxm_camnoc_hf0_uncomp,
+ &qxm_camnoc_hf1,
+ &qxm_camnoc_hf1_uncomp,
+ &qxm_camnoc_sf,
+ &qxm_camnoc_sf_uncomp,
+ &qxm_crypto,
+ &qxm_gpu,
+ &qxm_ipa,
+ &qxm_mdp0,
+ &qxm_mdp1,
+ &qxm_pimem,
+ &qxm_rot,
+ &qxm_venus0,
+ &qxm_venus1,
+ &qxm_venus_arm9,
+ &xm_gic,
+ &xm_pcie3_1,
+ &xm_pcie_0,
+ &xm_qdss_dap,
+ &xm_qdss_etr,
+ &xm_sdc2,
+ &xm_sdc4,
+ &xm_ufs_card,
+ &xm_ufs_mem,
+ &xm_usb3_0,
+ &xm_usb3_1,
+ &ebi,
+ &ipa_core_slave,
+ &qhs_a1_noc_cfg,
+ &qhs_a2_noc_cfg,
+ &qhs_aop,
+ &qhs_aoss,
+ &qhs_apss,
+ &qhs_camera_cfg,
+ &qhs_clk_ctl,
+ &qhs_compute_dsp_cfg,
+ &qhs_cpr_cx,
+ &qhs_crypto0_cfg,
+ &qhs_dcc_cfg,
+ &qhs_ddrss_cfg,
+ &qhs_display_cfg,
+ &qhs_glm,
+ &qhs_gpuss_cfg,
+ &qhs_imem_cfg,
+ &qhs_ipa,
+ &qhs_llcc,
+ &qhs_mdsp_ms_mpu_cfg,
+ &qhs_memnoc,
+ &qhs_mnoc_cfg,
+ &qhs_pcie0_cfg,
+ &qhs_pcie_gen3_cfg,
+ &qhs_pdm,
+ &qhs_phy_refgen_south,
+ &qhs_pimem_cfg,
+ &qhs_prng,
+ &qhs_qdss_cfg,
+ &qhs_qupv3_north,
+ &qhs_qupv3_south,
+ &qhs_sdc2,
+ &qhs_sdc4,
+ &qhs_snoc_cfg,
+ &qhs_spdm,
+ &qhs_spss_cfg,
+ &qhs_tcsr,
+ &qhs_tlmm_north,
+ &qhs_tlmm_south,
+ &qhs_tsif,
+ &qhs_ufs_card_cfg,
+ &qhs_ufs_mem_cfg,
+ &qhs_usb3_0,
+ &qhs_usb3_1,
+ &qhs_venus_cfg,
+ &qhs_vsense_ctrl_cfg,
+ &qns2_mem_noc,
+ &qns_a1noc_snoc,
+ &qns_a2noc_snoc,
+ &qns_apps_io,
+ &qns_camnoc_uncomp,
+ &qns_cnoc,
+ &qns_cnoc_a2noc,
+ &qns_gladiator_sodv,
+ &qns_gnoc_memnoc,
+ &qns_llcc,
+ &qns_mem_noc_hf,
+ &qns_memnoc_gc,
+ &qns_memnoc_sf,
+ &qns_memnoc_snoc,
+ &qns_pcie_a1noc_snoc,
+ &qns_pcie_snoc,
+ &qxs_imem,
+ &qxs_pcie,
+ &qxs_pcie_gen3,
+ &qxs_pimem,
+ &srvc_aggre1_noc,
+ &srvc_aggre2_noc,
+ &srvc_cnoc,
+ &srvc_gnoc,
+ &srvc_memnoc,
+ &srvc_mnoc,
+ &srvc_snoc,
+ &xs_qdss_stm,
+ &xs_sys_tcu_cfg,
+};
+
+static struct qcom_icc_bcm *rsc_hlos_bcms[] = {
+ &bcm_acv,
+ &bcm_mc0,
+ &bcm_sh0,
+ &bcm_mm0,
+ &bcm_sh1,
+ &bcm_mm1,
+ &bcm_sh2,
+ &bcm_mm2,
+ &bcm_sh3,
+ &bcm_mm3,
+ &bcm_sh5,
+ &bcm_sn0,
+ &bcm_ce0,
+ &bcm_ip0,
+ &bcm_cn0,
+ &bcm_qup0,
+ &bcm_sn1,
+ &bcm_sn2,
+ &bcm_sn3,
+ &bcm_sn4,
+ &bcm_sn5,
+ &bcm_sn6,
+ &bcm_sn7,
+ &bcm_sn8,
+ &bcm_sn9,
+ &bcm_sn11,
+ &bcm_sn12,
+ &bcm_sn14,
+ &bcm_sn15,
+};
+
+static struct qcom_icc_desc sdm845_rsc_hlos = {
+ .nodes = rsc_hlos_nodes,
+ .num_nodes = ARRAY_SIZE(rsc_hlos_nodes),
+ .bcms = rsc_hlos_bcms,
+ .num_bcms = ARRAY_SIZE(rsc_hlos_bcms),
+};
+
+static int qcom_icc_init(struct icc_node *node)
+{
+ /* TODO: init qos and priority */
+
+ return 0;
+}
+
+static int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev)
+{
+ struct qcom_icc_node *qn;
+ int ret, i;
+
+ bcm->addr = cmd_db_read_addr(bcm->name);
+ if (!bcm->addr) {
+ dev_err(dev, "%s could not find RPMh address\n",
+ bcm->name);
+ return -EINVAL;
+ }
+
+ if (!cmd_db_read_aux_data_len(bcm->name)) {
+ dev_err(dev, "%s command db missing aux data\n",
+ bcm->name);
+ return -EINVAL;
+ }
+
+ ret = cmd_db_read_aux_data(bcm->name, (u8 *)&bcm->aux_data,
+ sizeof(struct bcm_db));
+ if (ret < 0) {
+ dev_err(dev, "%s command db read error (%d)\n",
+ bcm->name, ret);
+ return ret;
+ }
+
+ for (i = 0; i < bcm->num_nodes; i++) {
+ qn = bcm->nodes[i];
+ qn->bcms[qn->num_bcms] = bcm;
+ qn->num_bcms++;
+ }
+
+ return 0;
+}
+
+static int qcom_tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x,
+ u64 vote_y, u32 addr, bool commit)
+{
+ int ret = 0;
+ bool valid = true;
+
+ if (!cmd)
+ return ret;
+
+ if (vote_x == 0 && vote_y == 0)
+ valid = false;
+
+ if (vote_x > BCM_TCS_CMD_VOTE_MASK)
+ vote_x = BCM_TCS_CMD_VOTE_MASK;
+
+ if (vote_y > BCM_TCS_CMD_VOTE_MASK)
+ vote_y = BCM_TCS_CMD_VOTE_MASK;
+
+ cmd->addr = addr;
+ cmd->data = BCM_TCS_CMD(commit, valid, vote_x, vote_y);
+
+ /* Set the wait for completion flag on commands that have the commit
+ * set, in order to indicate to the RSC to not release the TCS slot
+ * until hardware has acknowledged that this transaction has completed
+ */
+ if (commit)
+ cmd->wait = true;
+
+ return ret;
+}
+
+static void qcom_tcs_list_gen(struct list_head *bcm_list,
+ struct tcs_cmd *tcs_list, int *n)
+{
+ struct qcom_icc_bcm *bcm;
+ bool commit;
+ size_t idx = 0, batch = 0, cur_vcd_size = 0;
+
+ memset(n, 0, sizeof(int) * SDM845_MAX_VCD);
+
+ list_for_each_entry(bcm, bcm_list, list) {
+ commit = false;
+ cur_vcd_size++;
+ if ((bcm->aux_data.vcd !=
+ list_next_entry(bcm, list)->aux_data.vcd) ||
+ list_is_last(&bcm->list, bcm_list)) {
+ commit = true;
+ cur_vcd_size = 0;
+ }
+ qcom_tcs_cmd_gen(&tcs_list[idx], bcm->vote_x, bcm->vote_y,
+ bcm->addr, commit);
+ idx++;
+ n[batch]++;
+ if (n[batch] >= MAX_RPMH_PAYLOAD) {
+ if (!commit) {
+ n[batch] -= cur_vcd_size;
+ n[batch+1] = cur_vcd_size;
+ }
+ batch++;
+ }
+ }
+}
+
+static void qcom_icc_bcm_aggregate(struct qcom_icc_bcm *bcm)
+{
+ size_t i;
+ u64 agg_avg = 0;
+ u64 agg_peak = 0;
+
+ for (i = 0; i < bcm->num_nodes; i++) {
+ agg_avg = max(agg_avg,
+ bcm->nodes[i]->sum_avg * bcm->aux_data.width /
+ (bcm->nodes[i]->buswidth * bcm->nodes[i]->channels));
+ agg_peak = max(agg_peak,
+ bcm->nodes[i]->max_peak * bcm->aux_data.width /
+ bcm->nodes[i]->buswidth);
+ }
+
+ bcm->vote_x = (u64)(agg_avg * 1000ULL / bcm->aux_data.unit);
+ bcm->vote_y = (u64)(agg_peak * 1000ULL / bcm->aux_data.unit);
+
+ if (bcm->keepalive && bcm->vote_x == 0 && bcm->vote_y == 0) {
+ bcm->vote_x = 1;
+ bcm->vote_y = 1;
+ }
+
+ bcm->dirty = false;
+}
+
+static int qcom_icc_aggregate(struct icc_node *node, u32 avg_bw,
+ u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+ size_t i;
+ struct qcom_icc_node *qn;
+
+ qn = node->data;
+
+ *agg_avg += avg_bw;
+ *agg_peak = max_t(u64, agg_peak, peak_bw);
+
+ qn->sum_avg = *agg_avg;
+ qn->max_peak = *agg_peak;
+
+ for (i = 0; i < qn->num_bcms; i++)
+ qn->bcms[i]->dirty = true;
+
+ return 0;
+}
+
+static int qcom_icc_set(struct icc_node *src, struct icc_node *dst,
+ u32 avg, u32 peak)
+{
+ struct qcom_icc_provider *qp;
+ struct qcom_icc_node *qn;
+ struct icc_node *node;
+ struct icc_provider *provider;
+ struct tcs_cmd amc[SDM845_MAX_BCMS];
+ struct list_head commit_list;
+ int commit_idx[SDM845_MAX_VCD];
+ int ret = 0, i;
+
+ if (!src)
+ node = dst;
+ else
+ node = src;
+
+ qn = node->data;
+ provider = node->provider;
+ qp = to_qcom_provider(node->provider);
+
+ INIT_LIST_HEAD(&commit_list);
+
+ for (i = 0; i < qp->num_bcms; i++) {
+ if (qp->bcms[i]->dirty) {
+ qcom_icc_bcm_aggregate(qn->bcms[i]);
+ list_add_tail(&qp->bcms[i]->list, &commit_list);
+ }
+ }
+
+ /* Construct the command list based on a pre ordered list of BCMs
+ * based on VCD
+ */
+ qcom_tcs_list_gen(&commit_list, amc, commit_idx);
+
+ if (!commit_idx[0])
+ return ret;
+
+ ret = rpmh_invalidate(qp->rpmh_client);
+ if (ret) {
+ pr_err("Error invalidating RPMH client (%d)\n", ret);
+ return ret;
+ }
+
+ ret = rpmh_write_batch(qp->rpmh_client, RPMH_ACTIVE_ONLY_STATE, amc,
+ commit_idx);
+ if (ret) {
+ pr_err("Error sending AMC RPMH requests (%d)\n", ret);
+ return ret;
+ }
+
+ /* TODO: collect and send wake and sleep sets */
+ return ret;
+}
+
+static int cmp_vcd(const void *_l, const void *_r)
+{
+ const struct qcom_icc_bcm **l = (const struct qcom_icc_bcm **)_l;
+ const struct qcom_icc_bcm **r = (const struct qcom_icc_bcm **)_r;
+
+ if (l[0]->aux_data.vcd < r[0]->aux_data.vcd)
+ return -1;
+ else if (l[0]->aux_data.vcd == r[0]->aux_data.vcd)
+ return 0;
+ else
+ return 1;
+}
+
+static int qnoc_probe(struct platform_device *pdev)
+{
+ const struct qcom_icc_desc *desc;
+ struct qcom_icc_node **qnodes;
+ struct qcom_icc_provider *qp;
+ struct icc_provider *provider;
+ size_t num_nodes, i;
+ int ret;
+
+ desc = of_device_get_match_data(&pdev->dev);
+ if (!desc)
+ return -EINVAL;
+
+ qnodes = desc->nodes;
+ num_nodes = desc->num_nodes;
+
+ qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
+ if (!qp)
+ return -ENOMEM;
+
+ provider = &qp->provider;
+ provider->dev = &pdev->dev;
+ provider->set = &qcom_icc_set;
+ provider->aggregate = &qcom_icc_aggregate;
+ INIT_LIST_HEAD(&provider->nodes);
+ provider->data = qp;
+
+ qp->rpmh_client = rpmh_get_client(pdev);
+ qp->bcms = desc->bcms;
+ qp->num_bcms = desc->num_bcms;
+
+ ret = icc_provider_add(provider);
+ if (ret) {
+ dev_err(&pdev->dev, "error adding interconnect provider\n");
+ return ret;
+ }
+
+ for (i = 0; i < num_nodes; i++) {
+ struct icc_node *node;
+ int ret;
+ size_t j;
+
+ node = icc_node_create(qnodes[i]->id);
+ if (IS_ERR(node)) {
+ ret = PTR_ERR(node);
+ goto err;
+ }
+
+ node->name = qnodes[i]->name;
+ node->data = qnodes[i];
+ icc_node_add(node, provider);
+
+ dev_dbg(&pdev->dev, "registered node %p %s %d\n", node,
+ qnodes[i]->name, node->id);
+
+ ret = qcom_icc_init(node);
+ if (ret)
+ dev_err(&pdev->dev, "%s init error (%d)\n", node->name,
+ ret);
+
+ /* populate links */
+ for (j = 0; j < qnodes[i]->num_links; j++)
+ if (qnodes[i]->links[j])
+ icc_link_create(node, qnodes[i]->links[j]);
+ }
+
+ for (i = 0; i < qp->num_bcms; i++)
+ qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
+
+ /* Pre sort the BCMs based on VCD for ease of generating a command list
+ * that groups the BCMs with the same VCD together. VCDs are numbered
+ * with lowest being the most expensive time wise, ensuring that
+ * those commands are being sent the earliest in the queue.
+ */
+ sort(qp->bcms, qp->num_bcms, sizeof(*qp->bcms), cmp_vcd, NULL);
+
+ platform_set_drvdata(pdev, provider);
+ dev_info(&pdev->dev, "Registered SDM845 ICC\n");
+
+ return ret;
+err:
+ icc_provider_del(provider);
+ return ret;
+}
+
+static int qnoc_remove(struct platform_device *pdev)
+{
+ struct icc_provider *provider = platform_get_drvdata(pdev);
+
+ icc_provider_del(provider);
+
+ return 0;
+}
+
+static const struct of_device_id qnoc_of_match[] = {
+ { .compatible = "qcom,sdm845-rsc-hlos", .data = &sdm845_rsc_hlos },
+ { },
+};
+MODULE_DEVICE_TABLE(of, qnoc_of_match);
+
+static struct platform_driver qnoc_driver = {
+ .probe = qnoc_probe,
+ .remove = qnoc_remove,
+ .driver = {
+ .name = "qnoc-sdm845",
+ .of_match_table = qnoc_of_match,
+ },
+};
+module_platform_driver(qnoc_driver);
+
+MODULE_AUTHOR("David Dai <[email protected]>");
+MODULE_DESCRIPTION("Qualcomm sdm845 NoC driver");
+MODULE_LICENSE("GPL v2");
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project