1b5d2f741SDavid Dai // SPDX-License-Identifier: GPL-2.0 2b5d2f741SDavid Dai /* 3b5d2f741SDavid Dai * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4b5d2f741SDavid Dai * 5b5d2f741SDavid Dai */ 6b5d2f741SDavid Dai 7b5d2f741SDavid Dai #include <asm/div64.h> 8b5d2f741SDavid Dai #include <dt-bindings/interconnect/qcom,sdm845.h> 9b5d2f741SDavid Dai #include <linux/device.h> 10b5d2f741SDavid Dai #include <linux/interconnect.h> 11b5d2f741SDavid Dai #include <linux/interconnect-provider.h> 12b5d2f741SDavid Dai #include <linux/io.h> 13b5d2f741SDavid Dai #include <linux/module.h> 14b5d2f741SDavid Dai #include <linux/of_device.h> 15b5d2f741SDavid Dai #include <linux/of_platform.h> 16b5d2f741SDavid Dai #include <linux/platform_device.h> 17b5d2f741SDavid Dai #include <linux/sort.h> 18b5d2f741SDavid Dai 19b5d2f741SDavid Dai #include <soc/qcom/cmd-db.h> 20b5d2f741SDavid Dai #include <soc/qcom/rpmh.h> 21b5d2f741SDavid Dai #include <soc/qcom/tcs.h> 22b5d2f741SDavid Dai 23b5d2f741SDavid Dai #define BCM_TCS_CMD_COMMIT_SHFT 30 24b5d2f741SDavid Dai #define BCM_TCS_CMD_COMMIT_MASK 0x40000000 25b5d2f741SDavid Dai #define BCM_TCS_CMD_VALID_SHFT 29 26b5d2f741SDavid Dai #define BCM_TCS_CMD_VALID_MASK 0x20000000 27b5d2f741SDavid Dai #define BCM_TCS_CMD_VOTE_X_SHFT 14 28b5d2f741SDavid Dai #define BCM_TCS_CMD_VOTE_MASK 0x3fff 29b5d2f741SDavid Dai #define BCM_TCS_CMD_VOTE_Y_SHFT 0 30b5d2f741SDavid Dai #define BCM_TCS_CMD_VOTE_Y_MASK 0xfffc000 31b5d2f741SDavid Dai 32b5d2f741SDavid Dai #define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \ 33b5d2f741SDavid Dai (((commit) << BCM_TCS_CMD_COMMIT_SHFT) | \ 34b5d2f741SDavid Dai ((valid) << BCM_TCS_CMD_VALID_SHFT) | \ 35b5d2f741SDavid Dai ((cpu_to_le32(vote_x) & \ 36b5d2f741SDavid Dai BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) | \ 37b5d2f741SDavid Dai ((cpu_to_le32(vote_y) & \ 38b5d2f741SDavid Dai BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_Y_SHFT)) 39b5d2f741SDavid Dai 40b5d2f741SDavid Dai #define to_qcom_provider(_provider) \ 41b5d2f741SDavid Dai container_of(_provider, struct qcom_icc_provider, provider) 42b5d2f741SDavid Dai 43b5d2f741SDavid Dai struct qcom_icc_provider { 44b5d2f741SDavid Dai struct icc_provider provider; 45b5d2f741SDavid Dai struct device *dev; 46b5d2f741SDavid Dai struct qcom_icc_bcm **bcms; 47b5d2f741SDavid Dai size_t num_bcms; 48b5d2f741SDavid Dai }; 49b5d2f741SDavid Dai 50b5d2f741SDavid Dai /** 51b5d2f741SDavid Dai * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager (BCM) 52b5d2f741SDavid Dai * @unit: divisor used to convert bytes/sec bw value to an RPMh msg 53b5d2f741SDavid Dai * @width: multiplier used to convert bytes/sec bw value to an RPMh msg 54b5d2f741SDavid Dai * @vcd: virtual clock domain that this bcm belongs to 55b5d2f741SDavid Dai * @reserved: reserved field 56b5d2f741SDavid Dai */ 57b5d2f741SDavid Dai struct bcm_db { 58b5d2f741SDavid Dai __le32 unit; 59b5d2f741SDavid Dai __le16 width; 60b5d2f741SDavid Dai u8 vcd; 61b5d2f741SDavid Dai u8 reserved; 62b5d2f741SDavid Dai }; 63b5d2f741SDavid Dai 64b5d2f741SDavid Dai #define SDM845_MAX_LINKS 43 65b5d2f741SDavid Dai #define SDM845_MAX_BCMS 30 66b5d2f741SDavid Dai #define SDM845_MAX_BCM_PER_NODE 2 67b5d2f741SDavid Dai #define SDM845_MAX_VCD 10 68b5d2f741SDavid Dai 699e3ce77cSDavid Dai /* 709e3ce77cSDavid Dai * The AMC bucket denotes constraints that are applied to hardware when 719e3ce77cSDavid Dai * icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied 729e3ce77cSDavid Dai * when the execution environment transitions between active and low power mode. 739e3ce77cSDavid Dai */ 749e3ce77cSDavid Dai #define QCOM_ICC_BUCKET_AMC 0 759e3ce77cSDavid Dai #define QCOM_ICC_BUCKET_WAKE 1 769e3ce77cSDavid Dai #define QCOM_ICC_BUCKET_SLEEP 2 779e3ce77cSDavid Dai #define QCOM_ICC_NUM_BUCKETS 3 789e3ce77cSDavid Dai #define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC) 799e3ce77cSDavid Dai #define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE) 809e3ce77cSDavid Dai #define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP) 819e3ce77cSDavid Dai #define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) 829e3ce77cSDavid Dai #define QCOM_ICC_TAG_ALWAYS (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ 839e3ce77cSDavid Dai QCOM_ICC_TAG_SLEEP) 849e3ce77cSDavid Dai 85b5d2f741SDavid Dai /** 86b5d2f741SDavid Dai * struct qcom_icc_node - Qualcomm specific interconnect nodes 87b5d2f741SDavid Dai * @name: the node name used in debugfs 88b5d2f741SDavid Dai * @links: an array of nodes where we can go next while traversing 89b5d2f741SDavid Dai * @id: a unique node identifier 90b5d2f741SDavid Dai * @num_links: the total number of @links 91b5d2f741SDavid Dai * @channels: num of channels at this node 92b5d2f741SDavid Dai * @buswidth: width of the interconnect between a node and the bus 93b5d2f741SDavid Dai * @sum_avg: current sum aggregate value of all avg bw requests 94b5d2f741SDavid Dai * @max_peak: current max aggregate value of all peak bw requests 95b5d2f741SDavid Dai * @bcms: list of bcms associated with this logical node 96b5d2f741SDavid Dai * @num_bcms: num of @bcms 97b5d2f741SDavid Dai */ 98b5d2f741SDavid Dai struct qcom_icc_node { 99b5d2f741SDavid Dai const char *name; 100b5d2f741SDavid Dai u16 links[SDM845_MAX_LINKS]; 101b5d2f741SDavid Dai u16 id; 102b5d2f741SDavid Dai u16 num_links; 103b5d2f741SDavid Dai u16 channels; 104b5d2f741SDavid Dai u16 buswidth; 1059e3ce77cSDavid Dai u64 sum_avg[QCOM_ICC_NUM_BUCKETS]; 1069e3ce77cSDavid Dai u64 max_peak[QCOM_ICC_NUM_BUCKETS]; 107b5d2f741SDavid Dai struct qcom_icc_bcm *bcms[SDM845_MAX_BCM_PER_NODE]; 108b5d2f741SDavid Dai size_t num_bcms; 109b5d2f741SDavid Dai }; 110b5d2f741SDavid Dai 111b5d2f741SDavid Dai /** 112b5d2f741SDavid Dai * struct qcom_icc_bcm - Qualcomm specific hardware accelerator nodes 113b5d2f741SDavid Dai * known as Bus Clock Manager (BCM) 114b5d2f741SDavid Dai * @name: the bcm node name used to fetch BCM data from command db 115b5d2f741SDavid Dai * @type: latency or bandwidth bcm 116b5d2f741SDavid Dai * @addr: address offsets used when voting to RPMH 117b5d2f741SDavid Dai * @vote_x: aggregated threshold values, represents sum_bw when @type is bw bcm 118b5d2f741SDavid Dai * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm 119b5d2f741SDavid Dai * @dirty: flag used to indicate whether the bcm needs to be committed 120b5d2f741SDavid Dai * @keepalive: flag used to indicate whether a keepalive is required 121b5d2f741SDavid Dai * @aux_data: auxiliary data used when calculating threshold values and 122b5d2f741SDavid Dai * communicating with RPMh 123b5d2f741SDavid Dai * @list: used to link to other bcms when compiling lists for commit 124b5d2f741SDavid Dai * @num_nodes: total number of @num_nodes 125b5d2f741SDavid Dai * @nodes: list of qcom_icc_nodes that this BCM encapsulates 126b5d2f741SDavid Dai */ 127b5d2f741SDavid Dai struct qcom_icc_bcm { 128b5d2f741SDavid Dai const char *name; 129b5d2f741SDavid Dai u32 type; 130b5d2f741SDavid Dai u32 addr; 1319e3ce77cSDavid Dai u64 vote_x[QCOM_ICC_NUM_BUCKETS]; 1329e3ce77cSDavid Dai u64 vote_y[QCOM_ICC_NUM_BUCKETS]; 133b5d2f741SDavid Dai bool dirty; 134b5d2f741SDavid Dai bool keepalive; 135b5d2f741SDavid Dai struct bcm_db aux_data; 136b5d2f741SDavid Dai struct list_head list; 137b5d2f741SDavid Dai size_t num_nodes; 138b5d2f741SDavid Dai struct qcom_icc_node *nodes[]; 139b5d2f741SDavid Dai }; 140b5d2f741SDavid Dai 141b5d2f741SDavid Dai struct qcom_icc_fabric { 142b5d2f741SDavid Dai struct qcom_icc_node **nodes; 143b5d2f741SDavid Dai size_t num_nodes; 144b5d2f741SDavid Dai }; 145b5d2f741SDavid Dai 146b5d2f741SDavid Dai struct qcom_icc_desc { 147b5d2f741SDavid Dai struct qcom_icc_node **nodes; 148b5d2f741SDavid Dai size_t num_nodes; 149b5d2f741SDavid Dai struct qcom_icc_bcm **bcms; 150b5d2f741SDavid Dai size_t num_bcms; 151b5d2f741SDavid Dai }; 152b5d2f741SDavid Dai 153b5d2f741SDavid Dai #define DEFINE_QNODE(_name, _id, _channels, _buswidth, \ 154b5d2f741SDavid Dai _numlinks, ...) \ 155b5d2f741SDavid Dai static struct qcom_icc_node _name = { \ 156b5d2f741SDavid Dai .id = _id, \ 157b5d2f741SDavid Dai .name = #_name, \ 158b5d2f741SDavid Dai .channels = _channels, \ 159b5d2f741SDavid Dai .buswidth = _buswidth, \ 160b5d2f741SDavid Dai .num_links = _numlinks, \ 161b5d2f741SDavid Dai .links = { __VA_ARGS__ }, \ 162b5d2f741SDavid Dai } 163b5d2f741SDavid Dai 164b5d2f741SDavid Dai DEFINE_QNODE(qhm_a1noc_cfg, MASTER_A1NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A1NOC); 165b5d2f741SDavid Dai DEFINE_QNODE(qhm_qup1, MASTER_BLSP_1, 1, 4, 1, SLAVE_A1NOC_SNOC); 166b5d2f741SDavid Dai DEFINE_QNODE(qhm_tsif, MASTER_TSIF, 1, 4, 1, SLAVE_A1NOC_SNOC); 167b5d2f741SDavid Dai DEFINE_QNODE(xm_sdc2, MASTER_SDCC_2, 1, 8, 1, SLAVE_A1NOC_SNOC); 168b5d2f741SDavid Dai DEFINE_QNODE(xm_sdc4, MASTER_SDCC_4, 1, 8, 1, SLAVE_A1NOC_SNOC); 169b5d2f741SDavid Dai DEFINE_QNODE(xm_ufs_card, MASTER_UFS_CARD, 1, 8, 1, SLAVE_A1NOC_SNOC); 170b5d2f741SDavid Dai DEFINE_QNODE(xm_ufs_mem, MASTER_UFS_MEM, 1, 8, 1, SLAVE_A1NOC_SNOC); 171b5d2f741SDavid Dai DEFINE_QNODE(xm_pcie_0, MASTER_PCIE_0, 1, 8, 1, SLAVE_ANOC_PCIE_A1NOC_SNOC); 172b5d2f741SDavid Dai DEFINE_QNODE(qhm_a2noc_cfg, MASTER_A2NOC_CFG, 1, 4, 1, SLAVE_SERVICE_A2NOC); 173b5d2f741SDavid Dai DEFINE_QNODE(qhm_qdss_bam, MASTER_QDSS_BAM, 1, 4, 1, SLAVE_A2NOC_SNOC); 174b5d2f741SDavid Dai DEFINE_QNODE(qhm_qup2, MASTER_BLSP_2, 1, 4, 1, SLAVE_A2NOC_SNOC); 175b5d2f741SDavid Dai DEFINE_QNODE(qnm_cnoc, MASTER_CNOC_A2NOC, 1, 8, 1, SLAVE_A2NOC_SNOC); 176b5d2f741SDavid Dai DEFINE_QNODE(qxm_crypto, MASTER_CRYPTO, 1, 8, 1, SLAVE_A2NOC_SNOC); 177b5d2f741SDavid Dai DEFINE_QNODE(qxm_ipa, MASTER_IPA, 1, 8, 1, SLAVE_A2NOC_SNOC); 178b5d2f741SDavid Dai DEFINE_QNODE(xm_pcie3_1, MASTER_PCIE_1, 1, 8, 1, SLAVE_ANOC_PCIE_SNOC); 179b5d2f741SDavid Dai DEFINE_QNODE(xm_qdss_etr, MASTER_QDSS_ETR, 1, 8, 1, SLAVE_A2NOC_SNOC); 180b5d2f741SDavid Dai DEFINE_QNODE(xm_usb3_0, MASTER_USB3_0, 1, 8, 1, SLAVE_A2NOC_SNOC); 181b5d2f741SDavid Dai DEFINE_QNODE(xm_usb3_1, MASTER_USB3_1, 1, 8, 1, SLAVE_A2NOC_SNOC); 182b5d2f741SDavid Dai DEFINE_QNODE(qxm_camnoc_hf0_uncomp, MASTER_CAMNOC_HF0_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP); 183b5d2f741SDavid Dai DEFINE_QNODE(qxm_camnoc_hf1_uncomp, MASTER_CAMNOC_HF1_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP); 184b5d2f741SDavid Dai DEFINE_QNODE(qxm_camnoc_sf_uncomp, MASTER_CAMNOC_SF_UNCOMP, 1, 32, 1, SLAVE_CAMNOC_UNCOMP); 185b5d2f741SDavid Dai DEFINE_QNODE(qhm_spdm, MASTER_SPDM, 1, 4, 1, SLAVE_CNOC_A2NOC); 186b5d2f741SDavid Dai 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); 187b5d2f741SDavid Dai 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); 188b5d2f741SDavid Dai 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); 189b5d2f741SDavid Dai DEFINE_QNODE(qhm_cnoc, MASTER_CNOC_DC_NOC, 1, 4, 2, SLAVE_LLCC_CFG, SLAVE_MEM_NOC_CFG); 190b5d2f741SDavid Dai DEFINE_QNODE(acm_l3, MASTER_APPSS_PROC, 1, 16, 3, SLAVE_GNOC_SNOC, SLAVE_GNOC_MEM_NOC, SLAVE_SERVICE_GNOC); 191b5d2f741SDavid Dai DEFINE_QNODE(pm_gnoc_cfg, MASTER_GNOC_CFG, 1, 4, 1, SLAVE_SERVICE_GNOC); 192b5d2f741SDavid Dai DEFINE_QNODE(llcc_mc, MASTER_LLCC, 4, 4, 1, SLAVE_EBI1); 193b5d2f741SDavid Dai DEFINE_QNODE(acm_tcu, MASTER_TCU_0, 1, 8, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC); 194b5d2f741SDavid Dai DEFINE_QNODE(qhm_memnoc_cfg, MASTER_MEM_NOC_CFG, 1, 4, 2, SLAVE_MSS_PROC_MS_MPU_CFG, SLAVE_SERVICE_MEM_NOC); 195b5d2f741SDavid Dai DEFINE_QNODE(qnm_apps, MASTER_GNOC_MEM_NOC, 2, 32, 1, SLAVE_LLCC); 196b5d2f741SDavid Dai DEFINE_QNODE(qnm_mnoc_hf, MASTER_MNOC_HF_MEM_NOC, 2, 32, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC); 197b5d2f741SDavid Dai DEFINE_QNODE(qnm_mnoc_sf, MASTER_MNOC_SF_MEM_NOC, 1, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC); 198b5d2f741SDavid Dai DEFINE_QNODE(qnm_snoc_gc, MASTER_SNOC_GC_MEM_NOC, 1, 8, 1, SLAVE_LLCC); 199b5d2f741SDavid Dai DEFINE_QNODE(qnm_snoc_sf, MASTER_SNOC_SF_MEM_NOC, 1, 16, 2, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC); 200b5d2f741SDavid Dai DEFINE_QNODE(qxm_gpu, MASTER_GFX3D, 2, 32, 3, SLAVE_MEM_NOC_GNOC, SLAVE_LLCC, SLAVE_MEM_NOC_SNOC); 201b5d2f741SDavid Dai DEFINE_QNODE(qhm_mnoc_cfg, MASTER_CNOC_MNOC_CFG, 1, 4, 1, SLAVE_SERVICE_MNOC); 202b5d2f741SDavid Dai DEFINE_QNODE(qxm_camnoc_hf0, MASTER_CAMNOC_HF0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); 203b5d2f741SDavid Dai DEFINE_QNODE(qxm_camnoc_hf1, MASTER_CAMNOC_HF1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); 204b5d2f741SDavid Dai DEFINE_QNODE(qxm_camnoc_sf, MASTER_CAMNOC_SF, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); 205b5d2f741SDavid Dai DEFINE_QNODE(qxm_mdp0, MASTER_MDP0, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); 206b5d2f741SDavid Dai DEFINE_QNODE(qxm_mdp1, MASTER_MDP1, 1, 32, 1, SLAVE_MNOC_HF_MEM_NOC); 207b5d2f741SDavid Dai DEFINE_QNODE(qxm_rot, MASTER_ROTATOR, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); 208b5d2f741SDavid Dai DEFINE_QNODE(qxm_venus0, MASTER_VIDEO_P0, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); 209b5d2f741SDavid Dai DEFINE_QNODE(qxm_venus1, MASTER_VIDEO_P1, 1, 32, 1, SLAVE_MNOC_SF_MEM_NOC); 210b5d2f741SDavid Dai DEFINE_QNODE(qxm_venus_arm9, MASTER_VIDEO_PROC, 1, 8, 1, SLAVE_MNOC_SF_MEM_NOC); 211b5d2f741SDavid Dai DEFINE_QNODE(qhm_snoc_cfg, MASTER_SNOC_CFG, 1, 4, 1, SLAVE_SERVICE_SNOC); 212b5d2f741SDavid Dai 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); 213b5d2f741SDavid Dai 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); 214b5d2f741SDavid Dai 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); 215b5d2f741SDavid Dai DEFINE_QNODE(qnm_memnoc, MASTER_MEM_NOC_SNOC, 1, 8, 5, SLAVE_APPSS, SLAVE_SNOC_CNOC, SLAVE_IMEM, SLAVE_PIMEM, SLAVE_QDSS_STM); 216b5d2f741SDavid Dai 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); 217b5d2f741SDavid Dai DEFINE_QNODE(qxm_pimem, MASTER_PIMEM, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM); 218b5d2f741SDavid Dai DEFINE_QNODE(xm_gic, MASTER_GIC, 1, 8, 2, SLAVE_SNOC_MEM_NOC_GC, SLAVE_IMEM); 219b5d2f741SDavid Dai DEFINE_QNODE(qns_a1noc_snoc, SLAVE_A1NOC_SNOC, 1, 16, 1, MASTER_A1NOC_SNOC); 220b5d2f741SDavid Dai DEFINE_QNODE(srvc_aggre1_noc, SLAVE_SERVICE_A1NOC, 1, 4, 0); 221b5d2f741SDavid Dai DEFINE_QNODE(qns_pcie_a1noc_snoc, SLAVE_ANOC_PCIE_A1NOC_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC); 222b5d2f741SDavid Dai DEFINE_QNODE(qns_a2noc_snoc, SLAVE_A2NOC_SNOC, 1, 16, 1, MASTER_A2NOC_SNOC); 223b5d2f741SDavid Dai DEFINE_QNODE(qns_pcie_snoc, SLAVE_ANOC_PCIE_SNOC, 1, 16, 1, MASTER_ANOC_PCIE_SNOC); 224b5d2f741SDavid Dai DEFINE_QNODE(srvc_aggre2_noc, SLAVE_SERVICE_A2NOC, 1, 4, 0); 225b5d2f741SDavid Dai DEFINE_QNODE(qns_camnoc_uncomp, SLAVE_CAMNOC_UNCOMP, 1, 32, 0); 226b5d2f741SDavid Dai DEFINE_QNODE(qhs_a1_noc_cfg, SLAVE_A1NOC_CFG, 1, 4, 1, MASTER_A1NOC_CFG); 227b5d2f741SDavid Dai DEFINE_QNODE(qhs_a2_noc_cfg, SLAVE_A2NOC_CFG, 1, 4, 1, MASTER_A2NOC_CFG); 228b5d2f741SDavid Dai DEFINE_QNODE(qhs_aop, SLAVE_AOP, 1, 4, 0); 229b5d2f741SDavid Dai DEFINE_QNODE(qhs_aoss, SLAVE_AOSS, 1, 4, 0); 230b5d2f741SDavid Dai DEFINE_QNODE(qhs_camera_cfg, SLAVE_CAMERA_CFG, 1, 4, 0); 231b5d2f741SDavid Dai DEFINE_QNODE(qhs_clk_ctl, SLAVE_CLK_CTL, 1, 4, 0); 232b5d2f741SDavid Dai DEFINE_QNODE(qhs_compute_dsp_cfg, SLAVE_CDSP_CFG, 1, 4, 0); 233b5d2f741SDavid Dai DEFINE_QNODE(qhs_cpr_cx, SLAVE_RBCPR_CX_CFG, 1, 4, 0); 234b5d2f741SDavid Dai DEFINE_QNODE(qhs_crypto0_cfg, SLAVE_CRYPTO_0_CFG, 1, 4, 0); 235b5d2f741SDavid Dai DEFINE_QNODE(qhs_dcc_cfg, SLAVE_DCC_CFG, 1, 4, 1, MASTER_CNOC_DC_NOC); 236b5d2f741SDavid Dai DEFINE_QNODE(qhs_ddrss_cfg, SLAVE_CNOC_DDRSS, 1, 4, 0); 237b5d2f741SDavid Dai DEFINE_QNODE(qhs_display_cfg, SLAVE_DISPLAY_CFG, 1, 4, 0); 238b5d2f741SDavid Dai DEFINE_QNODE(qhs_glm, SLAVE_GLM, 1, 4, 0); 239b5d2f741SDavid Dai DEFINE_QNODE(qhs_gpuss_cfg, SLAVE_GFX3D_CFG, 1, 8, 0); 240b5d2f741SDavid Dai DEFINE_QNODE(qhs_imem_cfg, SLAVE_IMEM_CFG, 1, 4, 0); 241b5d2f741SDavid Dai DEFINE_QNODE(qhs_ipa, SLAVE_IPA_CFG, 1, 4, 0); 242b5d2f741SDavid Dai DEFINE_QNODE(qhs_mnoc_cfg, SLAVE_CNOC_MNOC_CFG, 1, 4, 1, MASTER_CNOC_MNOC_CFG); 243b5d2f741SDavid Dai DEFINE_QNODE(qhs_pcie0_cfg, SLAVE_PCIE_0_CFG, 1, 4, 0); 244b5d2f741SDavid Dai DEFINE_QNODE(qhs_pcie_gen3_cfg, SLAVE_PCIE_1_CFG, 1, 4, 0); 245b5d2f741SDavid Dai DEFINE_QNODE(qhs_pdm, SLAVE_PDM, 1, 4, 0); 246b5d2f741SDavid Dai DEFINE_QNODE(qhs_phy_refgen_south, SLAVE_SOUTH_PHY_CFG, 1, 4, 0); 247b5d2f741SDavid Dai DEFINE_QNODE(qhs_pimem_cfg, SLAVE_PIMEM_CFG, 1, 4, 0); 248b5d2f741SDavid Dai DEFINE_QNODE(qhs_prng, SLAVE_PRNG, 1, 4, 0); 249b5d2f741SDavid Dai DEFINE_QNODE(qhs_qdss_cfg, SLAVE_QDSS_CFG, 1, 4, 0); 250b5d2f741SDavid Dai DEFINE_QNODE(qhs_qupv3_north, SLAVE_BLSP_2, 1, 4, 0); 251b5d2f741SDavid Dai DEFINE_QNODE(qhs_qupv3_south, SLAVE_BLSP_1, 1, 4, 0); 252b5d2f741SDavid Dai DEFINE_QNODE(qhs_sdc2, SLAVE_SDCC_2, 1, 4, 0); 253b5d2f741SDavid Dai DEFINE_QNODE(qhs_sdc4, SLAVE_SDCC_4, 1, 4, 0); 254b5d2f741SDavid Dai DEFINE_QNODE(qhs_snoc_cfg, SLAVE_SNOC_CFG, 1, 4, 1, MASTER_SNOC_CFG); 255b5d2f741SDavid Dai DEFINE_QNODE(qhs_spdm, SLAVE_SPDM_WRAPPER, 1, 4, 0); 256b5d2f741SDavid Dai DEFINE_QNODE(qhs_spss_cfg, SLAVE_SPSS_CFG, 1, 4, 0); 257b5d2f741SDavid Dai DEFINE_QNODE(qhs_tcsr, SLAVE_TCSR, 1, 4, 0); 258b5d2f741SDavid Dai DEFINE_QNODE(qhs_tlmm_north, SLAVE_TLMM_NORTH, 1, 4, 0); 259b5d2f741SDavid Dai DEFINE_QNODE(qhs_tlmm_south, SLAVE_TLMM_SOUTH, 1, 4, 0); 260b5d2f741SDavid Dai DEFINE_QNODE(qhs_tsif, SLAVE_TSIF, 1, 4, 0); 261b5d2f741SDavid Dai DEFINE_QNODE(qhs_ufs_card_cfg, SLAVE_UFS_CARD_CFG, 1, 4, 0); 262b5d2f741SDavid Dai DEFINE_QNODE(qhs_ufs_mem_cfg, SLAVE_UFS_MEM_CFG, 1, 4, 0); 263b5d2f741SDavid Dai DEFINE_QNODE(qhs_usb3_0, SLAVE_USB3_0, 1, 4, 0); 264b5d2f741SDavid Dai DEFINE_QNODE(qhs_usb3_1, SLAVE_USB3_1, 1, 4, 0); 265b5d2f741SDavid Dai DEFINE_QNODE(qhs_venus_cfg, SLAVE_VENUS_CFG, 1, 4, 0); 266b5d2f741SDavid Dai DEFINE_QNODE(qhs_vsense_ctrl_cfg, SLAVE_VSENSE_CTRL_CFG, 1, 4, 0); 267b5d2f741SDavid Dai DEFINE_QNODE(qns_cnoc_a2noc, SLAVE_CNOC_A2NOC, 1, 8, 1, MASTER_CNOC_A2NOC); 268b5d2f741SDavid Dai DEFINE_QNODE(srvc_cnoc, SLAVE_SERVICE_CNOC, 1, 4, 0); 269b5d2f741SDavid Dai DEFINE_QNODE(qhs_llcc, SLAVE_LLCC_CFG, 1, 4, 0); 270b5d2f741SDavid Dai DEFINE_QNODE(qhs_memnoc, SLAVE_MEM_NOC_CFG, 1, 4, 1, MASTER_MEM_NOC_CFG); 271b5d2f741SDavid Dai DEFINE_QNODE(qns_gladiator_sodv, SLAVE_GNOC_SNOC, 1, 8, 1, MASTER_GNOC_SNOC); 272b5d2f741SDavid Dai DEFINE_QNODE(qns_gnoc_memnoc, SLAVE_GNOC_MEM_NOC, 2, 32, 1, MASTER_GNOC_MEM_NOC); 273b5d2f741SDavid Dai DEFINE_QNODE(srvc_gnoc, SLAVE_SERVICE_GNOC, 1, 4, 0); 274b5d2f741SDavid Dai DEFINE_QNODE(ebi, SLAVE_EBI1, 4, 4, 0); 275b5d2f741SDavid Dai DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SLAVE_MSS_PROC_MS_MPU_CFG, 1, 4, 0); 276b5d2f741SDavid Dai DEFINE_QNODE(qns_apps_io, SLAVE_MEM_NOC_GNOC, 1, 32, 0); 277b5d2f741SDavid Dai DEFINE_QNODE(qns_llcc, SLAVE_LLCC, 4, 16, 1, MASTER_LLCC); 278b5d2f741SDavid Dai DEFINE_QNODE(qns_memnoc_snoc, SLAVE_MEM_NOC_SNOC, 1, 8, 1, MASTER_MEM_NOC_SNOC); 279b5d2f741SDavid Dai DEFINE_QNODE(srvc_memnoc, SLAVE_SERVICE_MEM_NOC, 1, 4, 0); 280b5d2f741SDavid Dai DEFINE_QNODE(qns2_mem_noc, SLAVE_MNOC_SF_MEM_NOC, 1, 32, 1, MASTER_MNOC_SF_MEM_NOC); 281b5d2f741SDavid Dai DEFINE_QNODE(qns_mem_noc_hf, SLAVE_MNOC_HF_MEM_NOC, 2, 32, 1, MASTER_MNOC_HF_MEM_NOC); 282b5d2f741SDavid Dai DEFINE_QNODE(srvc_mnoc, SLAVE_SERVICE_MNOC, 1, 4, 0); 283b5d2f741SDavid Dai DEFINE_QNODE(qhs_apss, SLAVE_APPSS, 1, 8, 0); 284b5d2f741SDavid Dai DEFINE_QNODE(qns_cnoc, SLAVE_SNOC_CNOC, 1, 8, 1, MASTER_SNOC_CNOC); 285b5d2f741SDavid Dai DEFINE_QNODE(qns_memnoc_gc, SLAVE_SNOC_MEM_NOC_GC, 1, 8, 1, MASTER_SNOC_GC_MEM_NOC); 286b5d2f741SDavid Dai DEFINE_QNODE(qns_memnoc_sf, SLAVE_SNOC_MEM_NOC_SF, 1, 16, 1, MASTER_SNOC_SF_MEM_NOC); 287b5d2f741SDavid Dai DEFINE_QNODE(qxs_imem, SLAVE_IMEM, 1, 8, 0); 288b5d2f741SDavid Dai DEFINE_QNODE(qxs_pcie, SLAVE_PCIE_0, 1, 8, 0); 289b5d2f741SDavid Dai DEFINE_QNODE(qxs_pcie_gen3, SLAVE_PCIE_1, 1, 8, 0); 290b5d2f741SDavid Dai DEFINE_QNODE(qxs_pimem, SLAVE_PIMEM, 1, 8, 0); 291b5d2f741SDavid Dai DEFINE_QNODE(srvc_snoc, SLAVE_SERVICE_SNOC, 1, 4, 0); 292b5d2f741SDavid Dai DEFINE_QNODE(xs_qdss_stm, SLAVE_QDSS_STM, 1, 4, 0); 293b5d2f741SDavid Dai DEFINE_QNODE(xs_sys_tcu_cfg, SLAVE_TCU, 1, 8, 0); 294b5d2f741SDavid Dai 295b5d2f741SDavid Dai #define DEFINE_QBCM(_name, _bcmname, _keepalive, _numnodes, ...) \ 296b5d2f741SDavid Dai static struct qcom_icc_bcm _name = { \ 297b5d2f741SDavid Dai .name = _bcmname, \ 298b5d2f741SDavid Dai .keepalive = _keepalive, \ 299b5d2f741SDavid Dai .num_nodes = _numnodes, \ 300b5d2f741SDavid Dai .nodes = { __VA_ARGS__ }, \ 301b5d2f741SDavid Dai } 302b5d2f741SDavid Dai 303b5d2f741SDavid Dai DEFINE_QBCM(bcm_acv, "ACV", false, 1, &ebi); 304b5d2f741SDavid Dai DEFINE_QBCM(bcm_mc0, "MC0", true, 1, &ebi); 305b5d2f741SDavid Dai DEFINE_QBCM(bcm_sh0, "SH0", true, 1, &qns_llcc); 306b5d2f741SDavid Dai DEFINE_QBCM(bcm_mm0, "MM0", false, 1, &qns_mem_noc_hf); 307b5d2f741SDavid Dai DEFINE_QBCM(bcm_sh1, "SH1", false, 1, &qns_apps_io); 308b5d2f741SDavid Dai 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); 309b5d2f741SDavid Dai DEFINE_QBCM(bcm_sh2, "SH2", false, 1, &qns_memnoc_snoc); 310b5d2f741SDavid Dai DEFINE_QBCM(bcm_mm2, "MM2", false, 1, &qns2_mem_noc); 311b5d2f741SDavid Dai DEFINE_QBCM(bcm_sh3, "SH3", false, 1, &acm_tcu); 312b5d2f741SDavid Dai DEFINE_QBCM(bcm_mm3, "MM3", false, 5, &qxm_camnoc_sf, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9); 313b5d2f741SDavid Dai DEFINE_QBCM(bcm_sh5, "SH5", false, 1, &qnm_apps); 314b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn0, "SN0", true, 1, &qns_memnoc_sf); 315b5d2f741SDavid Dai DEFINE_QBCM(bcm_ce0, "CE0", false, 1, &qxm_crypto); 316b5d2f741SDavid Dai 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); 317b5d2f741SDavid Dai DEFINE_QBCM(bcm_qup0, "QUP0", false, 2, &qhm_qup1, &qhm_qup2); 318b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn1, "SN1", false, 1, &qxs_imem); 319b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn2, "SN2", false, 1, &qns_memnoc_gc); 320b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn3, "SN3", false, 1, &qns_cnoc); 321b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn4, "SN4", false, 1, &qxm_pimem); 322b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn5, "SN5", false, 1, &xs_qdss_stm); 323b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn6, "SN6", false, 3, &qhs_apss, &srvc_snoc, &xs_sys_tcu_cfg); 324b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn7, "SN7", false, 1, &qxs_pcie); 325b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn8, "SN8", false, 1, &qxs_pcie_gen3); 326b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn9, "SN9", false, 2, &srvc_aggre1_noc, &qnm_aggre1_noc); 327b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn11, "SN11", false, 2, &srvc_aggre2_noc, &qnm_aggre2_noc); 328b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn12, "SN12", false, 2, &qnm_gladiator_sodv, &xm_gic); 329b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn14, "SN14", false, 1, &qnm_pcie_anoc); 330b5d2f741SDavid Dai DEFINE_QBCM(bcm_sn15, "SN15", false, 1, &qnm_memnoc); 331b5d2f741SDavid Dai 332b5d2f741SDavid Dai static struct qcom_icc_node *rsc_hlos_nodes[] = { 333b5d2f741SDavid Dai [MASTER_APPSS_PROC] = &acm_l3, 334b5d2f741SDavid Dai [MASTER_TCU_0] = &acm_tcu, 335b5d2f741SDavid Dai [MASTER_LLCC] = &llcc_mc, 336b5d2f741SDavid Dai [MASTER_GNOC_CFG] = &pm_gnoc_cfg, 337b5d2f741SDavid Dai [MASTER_A1NOC_CFG] = &qhm_a1noc_cfg, 338b5d2f741SDavid Dai [MASTER_A2NOC_CFG] = &qhm_a2noc_cfg, 339b5d2f741SDavid Dai [MASTER_CNOC_DC_NOC] = &qhm_cnoc, 340b5d2f741SDavid Dai [MASTER_MEM_NOC_CFG] = &qhm_memnoc_cfg, 341b5d2f741SDavid Dai [MASTER_CNOC_MNOC_CFG] = &qhm_mnoc_cfg, 342b5d2f741SDavid Dai [MASTER_QDSS_BAM] = &qhm_qdss_bam, 343b5d2f741SDavid Dai [MASTER_BLSP_1] = &qhm_qup1, 344b5d2f741SDavid Dai [MASTER_BLSP_2] = &qhm_qup2, 345b5d2f741SDavid Dai [MASTER_SNOC_CFG] = &qhm_snoc_cfg, 346b5d2f741SDavid Dai [MASTER_SPDM] = &qhm_spdm, 347b5d2f741SDavid Dai [MASTER_TIC] = &qhm_tic, 348b5d2f741SDavid Dai [MASTER_TSIF] = &qhm_tsif, 349b5d2f741SDavid Dai [MASTER_A1NOC_SNOC] = &qnm_aggre1_noc, 350b5d2f741SDavid Dai [MASTER_A2NOC_SNOC] = &qnm_aggre2_noc, 351b5d2f741SDavid Dai [MASTER_GNOC_MEM_NOC] = &qnm_apps, 352b5d2f741SDavid Dai [MASTER_CNOC_A2NOC] = &qnm_cnoc, 353b5d2f741SDavid Dai [MASTER_GNOC_SNOC] = &qnm_gladiator_sodv, 354b5d2f741SDavid Dai [MASTER_MEM_NOC_SNOC] = &qnm_memnoc, 355b5d2f741SDavid Dai [MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf, 356b5d2f741SDavid Dai [MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf, 357b5d2f741SDavid Dai [MASTER_ANOC_PCIE_SNOC] = &qnm_pcie_anoc, 358b5d2f741SDavid Dai [MASTER_SNOC_CNOC] = &qnm_snoc, 359b5d2f741SDavid Dai [MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc, 360b5d2f741SDavid Dai [MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf, 361b5d2f741SDavid Dai [MASTER_CAMNOC_HF0] = &qxm_camnoc_hf0, 362b5d2f741SDavid Dai [MASTER_CAMNOC_HF0_UNCOMP] = &qxm_camnoc_hf0_uncomp, 363b5d2f741SDavid Dai [MASTER_CAMNOC_HF1] = &qxm_camnoc_hf1, 364b5d2f741SDavid Dai [MASTER_CAMNOC_HF1_UNCOMP] = &qxm_camnoc_hf1_uncomp, 365b5d2f741SDavid Dai [MASTER_CAMNOC_SF] = &qxm_camnoc_sf, 366b5d2f741SDavid Dai [MASTER_CAMNOC_SF_UNCOMP] = &qxm_camnoc_sf_uncomp, 367b5d2f741SDavid Dai [MASTER_CRYPTO] = &qxm_crypto, 368b5d2f741SDavid Dai [MASTER_GFX3D] = &qxm_gpu, 369b5d2f741SDavid Dai [MASTER_IPA] = &qxm_ipa, 370b5d2f741SDavid Dai [MASTER_MDP0] = &qxm_mdp0, 371b5d2f741SDavid Dai [MASTER_MDP1] = &qxm_mdp1, 372b5d2f741SDavid Dai [MASTER_PIMEM] = &qxm_pimem, 373b5d2f741SDavid Dai [MASTER_ROTATOR] = &qxm_rot, 374b5d2f741SDavid Dai [MASTER_VIDEO_P0] = &qxm_venus0, 375b5d2f741SDavid Dai [MASTER_VIDEO_P1] = &qxm_venus1, 376b5d2f741SDavid Dai [MASTER_VIDEO_PROC] = &qxm_venus_arm9, 377b5d2f741SDavid Dai [MASTER_GIC] = &xm_gic, 378b5d2f741SDavid Dai [MASTER_PCIE_1] = &xm_pcie3_1, 379b5d2f741SDavid Dai [MASTER_PCIE_0] = &xm_pcie_0, 380b5d2f741SDavid Dai [MASTER_QDSS_DAP] = &xm_qdss_dap, 381b5d2f741SDavid Dai [MASTER_QDSS_ETR] = &xm_qdss_etr, 382b5d2f741SDavid Dai [MASTER_SDCC_2] = &xm_sdc2, 383b5d2f741SDavid Dai [MASTER_SDCC_4] = &xm_sdc4, 384b5d2f741SDavid Dai [MASTER_UFS_CARD] = &xm_ufs_card, 385b5d2f741SDavid Dai [MASTER_UFS_MEM] = &xm_ufs_mem, 386b5d2f741SDavid Dai [MASTER_USB3_0] = &xm_usb3_0, 387b5d2f741SDavid Dai [MASTER_USB3_1] = &xm_usb3_1, 388b5d2f741SDavid Dai [SLAVE_EBI1] = &ebi, 389b5d2f741SDavid Dai [SLAVE_A1NOC_CFG] = &qhs_a1_noc_cfg, 390b5d2f741SDavid Dai [SLAVE_A2NOC_CFG] = &qhs_a2_noc_cfg, 391b5d2f741SDavid Dai [SLAVE_AOP] = &qhs_aop, 392b5d2f741SDavid Dai [SLAVE_AOSS] = &qhs_aoss, 393b5d2f741SDavid Dai [SLAVE_APPSS] = &qhs_apss, 394b5d2f741SDavid Dai [SLAVE_CAMERA_CFG] = &qhs_camera_cfg, 395b5d2f741SDavid Dai [SLAVE_CLK_CTL] = &qhs_clk_ctl, 396b5d2f741SDavid Dai [SLAVE_CDSP_CFG] = &qhs_compute_dsp_cfg, 397b5d2f741SDavid Dai [SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx, 398b5d2f741SDavid Dai [SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg, 399b5d2f741SDavid Dai [SLAVE_DCC_CFG] = &qhs_dcc_cfg, 400b5d2f741SDavid Dai [SLAVE_CNOC_DDRSS] = &qhs_ddrss_cfg, 401b5d2f741SDavid Dai [SLAVE_DISPLAY_CFG] = &qhs_display_cfg, 402b5d2f741SDavid Dai [SLAVE_GLM] = &qhs_glm, 403b5d2f741SDavid Dai [SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg, 404b5d2f741SDavid Dai [SLAVE_IMEM_CFG] = &qhs_imem_cfg, 405b5d2f741SDavid Dai [SLAVE_IPA_CFG] = &qhs_ipa, 406b5d2f741SDavid Dai [SLAVE_LLCC_CFG] = &qhs_llcc, 407b5d2f741SDavid Dai [SLAVE_MSS_PROC_MS_MPU_CFG] = &qhs_mdsp_ms_mpu_cfg, 408b5d2f741SDavid Dai [SLAVE_MEM_NOC_CFG] = &qhs_memnoc, 409b5d2f741SDavid Dai [SLAVE_CNOC_MNOC_CFG] = &qhs_mnoc_cfg, 410b5d2f741SDavid Dai [SLAVE_PCIE_0_CFG] = &qhs_pcie0_cfg, 411b5d2f741SDavid Dai [SLAVE_PCIE_1_CFG] = &qhs_pcie_gen3_cfg, 412b5d2f741SDavid Dai [SLAVE_PDM] = &qhs_pdm, 413b5d2f741SDavid Dai [SLAVE_SOUTH_PHY_CFG] = &qhs_phy_refgen_south, 414b5d2f741SDavid Dai [SLAVE_PIMEM_CFG] = &qhs_pimem_cfg, 415b5d2f741SDavid Dai [SLAVE_PRNG] = &qhs_prng, 416b5d2f741SDavid Dai [SLAVE_QDSS_CFG] = &qhs_qdss_cfg, 417b5d2f741SDavid Dai [SLAVE_BLSP_2] = &qhs_qupv3_north, 418b5d2f741SDavid Dai [SLAVE_BLSP_1] = &qhs_qupv3_south, 419b5d2f741SDavid Dai [SLAVE_SDCC_2] = &qhs_sdc2, 420b5d2f741SDavid Dai [SLAVE_SDCC_4] = &qhs_sdc4, 421b5d2f741SDavid Dai [SLAVE_SNOC_CFG] = &qhs_snoc_cfg, 422b5d2f741SDavid Dai [SLAVE_SPDM_WRAPPER] = &qhs_spdm, 423b5d2f741SDavid Dai [SLAVE_SPSS_CFG] = &qhs_spss_cfg, 424b5d2f741SDavid Dai [SLAVE_TCSR] = &qhs_tcsr, 425b5d2f741SDavid Dai [SLAVE_TLMM_NORTH] = &qhs_tlmm_north, 426b5d2f741SDavid Dai [SLAVE_TLMM_SOUTH] = &qhs_tlmm_south, 427b5d2f741SDavid Dai [SLAVE_TSIF] = &qhs_tsif, 428b5d2f741SDavid Dai [SLAVE_UFS_CARD_CFG] = &qhs_ufs_card_cfg, 429b5d2f741SDavid Dai [SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg, 430b5d2f741SDavid Dai [SLAVE_USB3_0] = &qhs_usb3_0, 431b5d2f741SDavid Dai [SLAVE_USB3_1] = &qhs_usb3_1, 432b5d2f741SDavid Dai [SLAVE_VENUS_CFG] = &qhs_venus_cfg, 433b5d2f741SDavid Dai [SLAVE_VSENSE_CTRL_CFG] = &qhs_vsense_ctrl_cfg, 434b5d2f741SDavid Dai [SLAVE_MNOC_SF_MEM_NOC] = &qns2_mem_noc, 435b5d2f741SDavid Dai [SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc, 436b5d2f741SDavid Dai [SLAVE_A2NOC_SNOC] = &qns_a2noc_snoc, 437b5d2f741SDavid Dai [SLAVE_MEM_NOC_GNOC] = &qns_apps_io, 438b5d2f741SDavid Dai [SLAVE_CAMNOC_UNCOMP] = &qns_camnoc_uncomp, 439b5d2f741SDavid Dai [SLAVE_SNOC_CNOC] = &qns_cnoc, 440b5d2f741SDavid Dai [SLAVE_CNOC_A2NOC] = &qns_cnoc_a2noc, 441b5d2f741SDavid Dai [SLAVE_GNOC_SNOC] = &qns_gladiator_sodv, 442b5d2f741SDavid Dai [SLAVE_GNOC_MEM_NOC] = &qns_gnoc_memnoc, 443b5d2f741SDavid Dai [SLAVE_LLCC] = &qns_llcc, 444b5d2f741SDavid Dai [SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf, 445b5d2f741SDavid Dai [SLAVE_SNOC_MEM_NOC_GC] = &qns_memnoc_gc, 446b5d2f741SDavid Dai [SLAVE_SNOC_MEM_NOC_SF] = &qns_memnoc_sf, 447b5d2f741SDavid Dai [SLAVE_MEM_NOC_SNOC] = &qns_memnoc_snoc, 448b5d2f741SDavid Dai [SLAVE_ANOC_PCIE_A1NOC_SNOC] = &qns_pcie_a1noc_snoc, 449b5d2f741SDavid Dai [SLAVE_ANOC_PCIE_SNOC] = &qns_pcie_snoc, 450b5d2f741SDavid Dai [SLAVE_IMEM] = &qxs_imem, 451b5d2f741SDavid Dai [SLAVE_PCIE_0] = &qxs_pcie, 452b5d2f741SDavid Dai [SLAVE_PCIE_1] = &qxs_pcie_gen3, 453b5d2f741SDavid Dai [SLAVE_PIMEM] = &qxs_pimem, 454b5d2f741SDavid Dai [SLAVE_SERVICE_A1NOC] = &srvc_aggre1_noc, 455b5d2f741SDavid Dai [SLAVE_SERVICE_A2NOC] = &srvc_aggre2_noc, 456b5d2f741SDavid Dai [SLAVE_SERVICE_CNOC] = &srvc_cnoc, 457b5d2f741SDavid Dai [SLAVE_SERVICE_GNOC] = &srvc_gnoc, 458b5d2f741SDavid Dai [SLAVE_SERVICE_MEM_NOC] = &srvc_memnoc, 459b5d2f741SDavid Dai [SLAVE_SERVICE_MNOC] = &srvc_mnoc, 460b5d2f741SDavid Dai [SLAVE_SERVICE_SNOC] = &srvc_snoc, 461b5d2f741SDavid Dai [SLAVE_QDSS_STM] = &xs_qdss_stm, 462b5d2f741SDavid Dai [SLAVE_TCU] = &xs_sys_tcu_cfg, 463b5d2f741SDavid Dai }; 464b5d2f741SDavid Dai 465b5d2f741SDavid Dai static struct qcom_icc_bcm *rsc_hlos_bcms[] = { 466b5d2f741SDavid Dai &bcm_acv, 467b5d2f741SDavid Dai &bcm_mc0, 468b5d2f741SDavid Dai &bcm_sh0, 469b5d2f741SDavid Dai &bcm_mm0, 470b5d2f741SDavid Dai &bcm_sh1, 471b5d2f741SDavid Dai &bcm_mm1, 472b5d2f741SDavid Dai &bcm_sh2, 473b5d2f741SDavid Dai &bcm_mm2, 474b5d2f741SDavid Dai &bcm_sh3, 475b5d2f741SDavid Dai &bcm_mm3, 476b5d2f741SDavid Dai &bcm_sh5, 477b5d2f741SDavid Dai &bcm_sn0, 478b5d2f741SDavid Dai &bcm_ce0, 479b5d2f741SDavid Dai &bcm_cn0, 480b5d2f741SDavid Dai &bcm_qup0, 481b5d2f741SDavid Dai &bcm_sn1, 482b5d2f741SDavid Dai &bcm_sn2, 483b5d2f741SDavid Dai &bcm_sn3, 484b5d2f741SDavid Dai &bcm_sn4, 485b5d2f741SDavid Dai &bcm_sn5, 486b5d2f741SDavid Dai &bcm_sn6, 487b5d2f741SDavid Dai &bcm_sn7, 488b5d2f741SDavid Dai &bcm_sn8, 489b5d2f741SDavid Dai &bcm_sn9, 490b5d2f741SDavid Dai &bcm_sn11, 491b5d2f741SDavid Dai &bcm_sn12, 492b5d2f741SDavid Dai &bcm_sn14, 493b5d2f741SDavid Dai &bcm_sn15, 494b5d2f741SDavid Dai }; 495b5d2f741SDavid Dai 496b5d2f741SDavid Dai static struct qcom_icc_desc sdm845_rsc_hlos = { 497b5d2f741SDavid Dai .nodes = rsc_hlos_nodes, 498b5d2f741SDavid Dai .num_nodes = ARRAY_SIZE(rsc_hlos_nodes), 499b5d2f741SDavid Dai .bcms = rsc_hlos_bcms, 500b5d2f741SDavid Dai .num_bcms = ARRAY_SIZE(rsc_hlos_bcms), 501b5d2f741SDavid Dai }; 502b5d2f741SDavid Dai 503b5d2f741SDavid Dai static int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev) 504b5d2f741SDavid Dai { 505b5d2f741SDavid Dai struct qcom_icc_node *qn; 506b5d2f741SDavid Dai const struct bcm_db *data; 507b5d2f741SDavid Dai size_t data_count; 508b5d2f741SDavid Dai int i; 509b5d2f741SDavid Dai 510b5d2f741SDavid Dai bcm->addr = cmd_db_read_addr(bcm->name); 511b5d2f741SDavid Dai if (!bcm->addr) { 512b5d2f741SDavid Dai dev_err(dev, "%s could not find RPMh address\n", 513b5d2f741SDavid Dai bcm->name); 514b5d2f741SDavid Dai return -EINVAL; 515b5d2f741SDavid Dai } 516b5d2f741SDavid Dai 517b5d2f741SDavid Dai data = cmd_db_read_aux_data(bcm->name, &data_count); 518b5d2f741SDavid Dai if (IS_ERR(data)) { 519b5d2f741SDavid Dai dev_err(dev, "%s command db read error (%ld)\n", 520b5d2f741SDavid Dai bcm->name, PTR_ERR(data)); 521b5d2f741SDavid Dai return PTR_ERR(data); 522b5d2f741SDavid Dai } 523b5d2f741SDavid Dai if (!data_count) { 524b5d2f741SDavid Dai dev_err(dev, "%s command db missing or partial aux data\n", 525b5d2f741SDavid Dai bcm->name); 526b5d2f741SDavid Dai return -EINVAL; 527b5d2f741SDavid Dai } 528b5d2f741SDavid Dai 529b5d2f741SDavid Dai bcm->aux_data.unit = le32_to_cpu(data->unit); 530b5d2f741SDavid Dai bcm->aux_data.width = le16_to_cpu(data->width); 531b5d2f741SDavid Dai bcm->aux_data.vcd = data->vcd; 532b5d2f741SDavid Dai bcm->aux_data.reserved = data->reserved; 533b5d2f741SDavid Dai 534b5d2f741SDavid Dai /* 535b5d2f741SDavid Dai * Link Qnodes to their respective BCMs 536b5d2f741SDavid Dai */ 537b5d2f741SDavid Dai for (i = 0; i < bcm->num_nodes; i++) { 538b5d2f741SDavid Dai qn = bcm->nodes[i]; 539b5d2f741SDavid Dai qn->bcms[qn->num_bcms] = bcm; 540b5d2f741SDavid Dai qn->num_bcms++; 541b5d2f741SDavid Dai } 542b5d2f741SDavid Dai 543b5d2f741SDavid Dai return 0; 544b5d2f741SDavid Dai } 545b5d2f741SDavid Dai 546b5d2f741SDavid Dai inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y, 547b5d2f741SDavid Dai u32 addr, bool commit) 548b5d2f741SDavid Dai { 549b5d2f741SDavid Dai bool valid = true; 550b5d2f741SDavid Dai 551b5d2f741SDavid Dai if (!cmd) 552b5d2f741SDavid Dai return; 553b5d2f741SDavid Dai 554b5d2f741SDavid Dai if (vote_x == 0 && vote_y == 0) 555b5d2f741SDavid Dai valid = false; 556b5d2f741SDavid Dai 557b5d2f741SDavid Dai if (vote_x > BCM_TCS_CMD_VOTE_MASK) 558b5d2f741SDavid Dai vote_x = BCM_TCS_CMD_VOTE_MASK; 559b5d2f741SDavid Dai 560b5d2f741SDavid Dai if (vote_y > BCM_TCS_CMD_VOTE_MASK) 561b5d2f741SDavid Dai vote_y = BCM_TCS_CMD_VOTE_MASK; 562b5d2f741SDavid Dai 563b5d2f741SDavid Dai cmd->addr = addr; 564b5d2f741SDavid Dai cmd->data = BCM_TCS_CMD(commit, valid, vote_x, vote_y); 565b5d2f741SDavid Dai 566b5d2f741SDavid Dai /* 567b5d2f741SDavid Dai * Set the wait for completion flag on command that need to be completed 568b5d2f741SDavid Dai * before the next command. 569b5d2f741SDavid Dai */ 570b5d2f741SDavid Dai if (commit) 571b5d2f741SDavid Dai cmd->wait = true; 572b5d2f741SDavid Dai } 573b5d2f741SDavid Dai 5749e3ce77cSDavid Dai static void tcs_list_gen(struct list_head *bcm_list, int bucket, 575b5d2f741SDavid Dai struct tcs_cmd tcs_list[SDM845_MAX_VCD], 576b5d2f741SDavid Dai int n[SDM845_MAX_VCD]) 577b5d2f741SDavid Dai { 578b5d2f741SDavid Dai struct qcom_icc_bcm *bcm; 579b5d2f741SDavid Dai bool commit; 580b5d2f741SDavid Dai size_t idx = 0, batch = 0, cur_vcd_size = 0; 581b5d2f741SDavid Dai 582b5d2f741SDavid Dai memset(n, 0, sizeof(int) * SDM845_MAX_VCD); 583b5d2f741SDavid Dai 584b5d2f741SDavid Dai list_for_each_entry(bcm, bcm_list, list) { 585b5d2f741SDavid Dai commit = false; 586b5d2f741SDavid Dai cur_vcd_size++; 587b5d2f741SDavid Dai if ((list_is_last(&bcm->list, bcm_list)) || 588b5d2f741SDavid Dai bcm->aux_data.vcd != list_next_entry(bcm, list)->aux_data.vcd) { 589b5d2f741SDavid Dai commit = true; 590b5d2f741SDavid Dai cur_vcd_size = 0; 591b5d2f741SDavid Dai } 5929e3ce77cSDavid Dai tcs_cmd_gen(&tcs_list[idx], bcm->vote_x[bucket], 5939e3ce77cSDavid Dai bcm->vote_y[bucket], bcm->addr, commit); 594b5d2f741SDavid Dai idx++; 595b5d2f741SDavid Dai n[batch]++; 596b5d2f741SDavid Dai /* 597b5d2f741SDavid Dai * Batch the BCMs in such a way that we do not split them in 598b5d2f741SDavid Dai * multiple payloads when they are under the same VCD. This is 599b5d2f741SDavid Dai * to ensure that every BCM is committed since we only set the 600b5d2f741SDavid Dai * commit bit on the last BCM request of every VCD. 601b5d2f741SDavid Dai */ 602b5d2f741SDavid Dai if (n[batch] >= MAX_RPMH_PAYLOAD) { 603b5d2f741SDavid Dai if (!commit) { 604b5d2f741SDavid Dai n[batch] -= cur_vcd_size; 605b5d2f741SDavid Dai n[batch + 1] = cur_vcd_size; 606b5d2f741SDavid Dai } 607b5d2f741SDavid Dai batch++; 608b5d2f741SDavid Dai } 609b5d2f741SDavid Dai } 610b5d2f741SDavid Dai } 611b5d2f741SDavid Dai 612b5d2f741SDavid Dai static void bcm_aggregate(struct qcom_icc_bcm *bcm) 613b5d2f741SDavid Dai { 6149e3ce77cSDavid Dai size_t i, bucket; 6159e3ce77cSDavid Dai u64 agg_avg[QCOM_ICC_NUM_BUCKETS] = {0}; 6169e3ce77cSDavid Dai u64 agg_peak[QCOM_ICC_NUM_BUCKETS] = {0}; 617b5d2f741SDavid Dai u64 temp; 618b5d2f741SDavid Dai 6199e3ce77cSDavid Dai for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) { 620b5d2f741SDavid Dai for (i = 0; i < bcm->num_nodes; i++) { 6219e3ce77cSDavid Dai temp = bcm->nodes[i]->sum_avg[bucket] * bcm->aux_data.width; 622b5d2f741SDavid Dai do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels); 6239e3ce77cSDavid Dai agg_avg[bucket] = max(agg_avg[bucket], temp); 624b5d2f741SDavid Dai 6259e3ce77cSDavid Dai temp = bcm->nodes[i]->max_peak[bucket] * bcm->aux_data.width; 626b5d2f741SDavid Dai do_div(temp, bcm->nodes[i]->buswidth); 6279e3ce77cSDavid Dai agg_peak[bucket] = max(agg_peak[bucket], temp); 628b5d2f741SDavid Dai } 629b5d2f741SDavid Dai 6309e3ce77cSDavid Dai temp = agg_avg[bucket] * 1000ULL; 631b5d2f741SDavid Dai do_div(temp, bcm->aux_data.unit); 6329e3ce77cSDavid Dai bcm->vote_x[bucket] = temp; 633b5d2f741SDavid Dai 6349e3ce77cSDavid Dai temp = agg_peak[bucket] * 1000ULL; 635b5d2f741SDavid Dai do_div(temp, bcm->aux_data.unit); 6369e3ce77cSDavid Dai bcm->vote_y[bucket] = temp; 6379e3ce77cSDavid Dai } 638b5d2f741SDavid Dai 6399e3ce77cSDavid Dai if (bcm->keepalive && bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 && 6409e3ce77cSDavid Dai bcm->vote_y[QCOM_ICC_BUCKET_AMC] == 0) { 6419e3ce77cSDavid Dai bcm->vote_x[QCOM_ICC_BUCKET_AMC] = 1; 6429e3ce77cSDavid Dai bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = 1; 6439e3ce77cSDavid Dai bcm->vote_y[QCOM_ICC_BUCKET_AMC] = 1; 6449e3ce77cSDavid Dai bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = 1; 645b5d2f741SDavid Dai } 646b5d2f741SDavid Dai 647b5d2f741SDavid Dai bcm->dirty = false; 648b5d2f741SDavid Dai } 649b5d2f741SDavid Dai 6509e3ce77cSDavid Dai static void qcom_icc_pre_aggregate(struct icc_node *node) 6519e3ce77cSDavid Dai { 6529e3ce77cSDavid Dai size_t i; 6539e3ce77cSDavid Dai struct qcom_icc_node *qn; 6549e3ce77cSDavid Dai 6559e3ce77cSDavid Dai qn = node->data; 6569e3ce77cSDavid Dai 6579e3ce77cSDavid Dai for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) { 6589e3ce77cSDavid Dai qn->sum_avg[i] = 0; 6599e3ce77cSDavid Dai qn->max_peak[i] = 0; 6609e3ce77cSDavid Dai } 6619e3ce77cSDavid Dai } 6629e3ce77cSDavid Dai 663127ab2ccSGeorgi Djakov static int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, 664b5d2f741SDavid Dai u32 peak_bw, u32 *agg_avg, u32 *agg_peak) 665b5d2f741SDavid Dai { 666b5d2f741SDavid Dai size_t i; 667b5d2f741SDavid Dai struct qcom_icc_node *qn; 668b5d2f741SDavid Dai 669b5d2f741SDavid Dai qn = node->data; 670b5d2f741SDavid Dai 6719e3ce77cSDavid Dai if (!tag) 6729e3ce77cSDavid Dai tag = QCOM_ICC_TAG_ALWAYS; 6739e3ce77cSDavid Dai 6749e3ce77cSDavid Dai for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) { 6759e3ce77cSDavid Dai if (tag & BIT(i)) { 6769e3ce77cSDavid Dai qn->sum_avg[i] += avg_bw; 6779e3ce77cSDavid Dai qn->max_peak[i] = max_t(u32, qn->max_peak[i], peak_bw); 6789e3ce77cSDavid Dai } 6799e3ce77cSDavid Dai } 6809e3ce77cSDavid Dai 681b5d2f741SDavid Dai *agg_avg += avg_bw; 682b5d2f741SDavid Dai *agg_peak = max_t(u32, *agg_peak, peak_bw); 683b5d2f741SDavid Dai 684b5d2f741SDavid Dai for (i = 0; i < qn->num_bcms; i++) 685b5d2f741SDavid Dai qn->bcms[i]->dirty = true; 686b5d2f741SDavid Dai 687b5d2f741SDavid Dai return 0; 688b5d2f741SDavid Dai } 689b5d2f741SDavid Dai 690b5d2f741SDavid Dai static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) 691b5d2f741SDavid Dai { 692b5d2f741SDavid Dai struct qcom_icc_provider *qp; 693b5d2f741SDavid Dai struct icc_node *node; 694b5d2f741SDavid Dai struct tcs_cmd cmds[SDM845_MAX_BCMS]; 695b5d2f741SDavid Dai struct list_head commit_list; 696b5d2f741SDavid Dai int commit_idx[SDM845_MAX_VCD]; 697b5d2f741SDavid Dai int ret = 0, i; 698b5d2f741SDavid Dai 699b5d2f741SDavid Dai if (!src) 700b5d2f741SDavid Dai node = dst; 701b5d2f741SDavid Dai else 702b5d2f741SDavid Dai node = src; 703b5d2f741SDavid Dai 704b5d2f741SDavid Dai qp = to_qcom_provider(node->provider); 705b5d2f741SDavid Dai 706b5d2f741SDavid Dai INIT_LIST_HEAD(&commit_list); 707b5d2f741SDavid Dai 708b5d2f741SDavid Dai for (i = 0; i < qp->num_bcms; i++) { 709b5d2f741SDavid Dai if (qp->bcms[i]->dirty) { 710b5d2f741SDavid Dai bcm_aggregate(qp->bcms[i]); 711b5d2f741SDavid Dai list_add_tail(&qp->bcms[i]->list, &commit_list); 712b5d2f741SDavid Dai } 713b5d2f741SDavid Dai } 714b5d2f741SDavid Dai 715b5d2f741SDavid Dai /* 716b5d2f741SDavid Dai * Construct the command list based on a pre ordered list of BCMs 717b5d2f741SDavid Dai * based on VCD. 718b5d2f741SDavid Dai */ 7199e3ce77cSDavid Dai tcs_list_gen(&commit_list, QCOM_ICC_BUCKET_AMC, cmds, commit_idx); 720b5d2f741SDavid Dai 721b5d2f741SDavid Dai if (!commit_idx[0]) 722b5d2f741SDavid Dai return ret; 723b5d2f741SDavid Dai 724b5d2f741SDavid Dai ret = rpmh_invalidate(qp->dev); 725b5d2f741SDavid Dai if (ret) { 726b5d2f741SDavid Dai pr_err("Error invalidating RPMH client (%d)\n", ret); 727b5d2f741SDavid Dai return ret; 728b5d2f741SDavid Dai } 729b5d2f741SDavid Dai 730b5d2f741SDavid Dai ret = rpmh_write_batch(qp->dev, RPMH_ACTIVE_ONLY_STATE, 731b5d2f741SDavid Dai cmds, commit_idx); 732b5d2f741SDavid Dai if (ret) { 733b5d2f741SDavid Dai pr_err("Error sending AMC RPMH requests (%d)\n", ret); 734b5d2f741SDavid Dai return ret; 735b5d2f741SDavid Dai } 736b5d2f741SDavid Dai 7379e3ce77cSDavid Dai INIT_LIST_HEAD(&commit_list); 7389e3ce77cSDavid Dai 7399e3ce77cSDavid Dai for (i = 0; i < qp->num_bcms; i++) { 7409e3ce77cSDavid Dai /* 7419e3ce77cSDavid Dai * Only generate WAKE and SLEEP commands if a resource's 7429e3ce77cSDavid Dai * requirements change as the execution environment transitions 7439e3ce77cSDavid Dai * between different power states. 7449e3ce77cSDavid Dai */ 7459e3ce77cSDavid Dai if (qp->bcms[i]->vote_x[QCOM_ICC_BUCKET_WAKE] != 7469e3ce77cSDavid Dai qp->bcms[i]->vote_x[QCOM_ICC_BUCKET_SLEEP] || 7479e3ce77cSDavid Dai qp->bcms[i]->vote_y[QCOM_ICC_BUCKET_WAKE] != 7489e3ce77cSDavid Dai qp->bcms[i]->vote_y[QCOM_ICC_BUCKET_SLEEP]) { 7499e3ce77cSDavid Dai list_add_tail(&qp->bcms[i]->list, &commit_list); 7509e3ce77cSDavid Dai } 7519e3ce77cSDavid Dai } 7529e3ce77cSDavid Dai 7539e3ce77cSDavid Dai if (list_empty(&commit_list)) 7549e3ce77cSDavid Dai return ret; 7559e3ce77cSDavid Dai 7569e3ce77cSDavid Dai tcs_list_gen(&commit_list, QCOM_ICC_BUCKET_WAKE, cmds, commit_idx); 7579e3ce77cSDavid Dai 7589e3ce77cSDavid Dai ret = rpmh_write_batch(qp->dev, RPMH_WAKE_ONLY_STATE, cmds, commit_idx); 7599e3ce77cSDavid Dai if (ret) { 7609e3ce77cSDavid Dai pr_err("Error sending WAKE RPMH requests (%d)\n", ret); 7619e3ce77cSDavid Dai return ret; 7629e3ce77cSDavid Dai } 7639e3ce77cSDavid Dai 7649e3ce77cSDavid Dai tcs_list_gen(&commit_list, QCOM_ICC_BUCKET_SLEEP, cmds, commit_idx); 7659e3ce77cSDavid Dai 7669e3ce77cSDavid Dai ret = rpmh_write_batch(qp->dev, RPMH_SLEEP_STATE, cmds, commit_idx); 7679e3ce77cSDavid Dai if (ret) { 7689e3ce77cSDavid Dai pr_err("Error sending SLEEP RPMH requests (%d)\n", ret); 7699e3ce77cSDavid Dai return ret; 7709e3ce77cSDavid Dai } 7719e3ce77cSDavid Dai 772b5d2f741SDavid Dai return ret; 773b5d2f741SDavid Dai } 774b5d2f741SDavid Dai 775b5d2f741SDavid Dai static int cmp_vcd(const void *_l, const void *_r) 776b5d2f741SDavid Dai { 777b5d2f741SDavid Dai const struct qcom_icc_bcm **l = (const struct qcom_icc_bcm **)_l; 778b5d2f741SDavid Dai const struct qcom_icc_bcm **r = (const struct qcom_icc_bcm **)_r; 779b5d2f741SDavid Dai 780b5d2f741SDavid Dai if (l[0]->aux_data.vcd < r[0]->aux_data.vcd) 781b5d2f741SDavid Dai return -1; 782b5d2f741SDavid Dai else if (l[0]->aux_data.vcd == r[0]->aux_data.vcd) 783b5d2f741SDavid Dai return 0; 784b5d2f741SDavid Dai else 785b5d2f741SDavid Dai return 1; 786b5d2f741SDavid Dai } 787b5d2f741SDavid Dai 788b5d2f741SDavid Dai static int qnoc_probe(struct platform_device *pdev) 789b5d2f741SDavid Dai { 790b5d2f741SDavid Dai const struct qcom_icc_desc *desc; 791b5d2f741SDavid Dai struct icc_onecell_data *data; 792b5d2f741SDavid Dai struct icc_provider *provider; 793b5d2f741SDavid Dai struct qcom_icc_node **qnodes; 794b5d2f741SDavid Dai struct qcom_icc_provider *qp; 795b5d2f741SDavid Dai struct icc_node *node; 796b5d2f741SDavid Dai size_t num_nodes, i; 797b5d2f741SDavid Dai int ret; 798b5d2f741SDavid Dai 799b5d2f741SDavid Dai desc = of_device_get_match_data(&pdev->dev); 800b5d2f741SDavid Dai if (!desc) 801b5d2f741SDavid Dai return -EINVAL; 802b5d2f741SDavid Dai 803b5d2f741SDavid Dai qnodes = desc->nodes; 804b5d2f741SDavid Dai num_nodes = desc->num_nodes; 805b5d2f741SDavid Dai 806b5d2f741SDavid Dai qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL); 807b5d2f741SDavid Dai if (!qp) 808b5d2f741SDavid Dai return -ENOMEM; 809b5d2f741SDavid Dai 810b5d2f741SDavid Dai data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL); 811b5d2f741SDavid Dai if (!data) 812b5d2f741SDavid Dai return -ENOMEM; 813b5d2f741SDavid Dai 814b5d2f741SDavid Dai provider = &qp->provider; 815b5d2f741SDavid Dai provider->dev = &pdev->dev; 816b5d2f741SDavid Dai provider->set = qcom_icc_set; 8179e3ce77cSDavid Dai provider->pre_aggregate = qcom_icc_pre_aggregate; 818b5d2f741SDavid Dai provider->aggregate = qcom_icc_aggregate; 819b5d2f741SDavid Dai provider->xlate = of_icc_xlate_onecell; 820b5d2f741SDavid Dai INIT_LIST_HEAD(&provider->nodes); 821b5d2f741SDavid Dai provider->data = data; 822b5d2f741SDavid Dai 823b5d2f741SDavid Dai qp->dev = &pdev->dev; 824b5d2f741SDavid Dai qp->bcms = desc->bcms; 825b5d2f741SDavid Dai qp->num_bcms = desc->num_bcms; 826b5d2f741SDavid Dai 827b5d2f741SDavid Dai ret = icc_provider_add(provider); 828b5d2f741SDavid Dai if (ret) { 829b5d2f741SDavid Dai dev_err(&pdev->dev, "error adding interconnect provider\n"); 830b5d2f741SDavid Dai return ret; 831b5d2f741SDavid Dai } 832b5d2f741SDavid Dai 833b5d2f741SDavid Dai for (i = 0; i < num_nodes; i++) { 834b5d2f741SDavid Dai size_t j; 835b5d2f741SDavid Dai 836b5d2f741SDavid Dai node = icc_node_create(qnodes[i]->id); 837b5d2f741SDavid Dai if (IS_ERR(node)) { 838b5d2f741SDavid Dai ret = PTR_ERR(node); 839b5d2f741SDavid Dai goto err; 840b5d2f741SDavid Dai } 841b5d2f741SDavid Dai 842b5d2f741SDavid Dai node->name = qnodes[i]->name; 843b5d2f741SDavid Dai node->data = qnodes[i]; 844b5d2f741SDavid Dai icc_node_add(node, provider); 845b5d2f741SDavid Dai 846b5d2f741SDavid Dai dev_dbg(&pdev->dev, "registered node %p %s %d\n", node, 847b5d2f741SDavid Dai qnodes[i]->name, node->id); 848b5d2f741SDavid Dai 849b5d2f741SDavid Dai /* populate links */ 850b5d2f741SDavid Dai for (j = 0; j < qnodes[i]->num_links; j++) 851b5d2f741SDavid Dai icc_link_create(node, qnodes[i]->links[j]); 852b5d2f741SDavid Dai 853b5d2f741SDavid Dai data->nodes[i] = node; 854b5d2f741SDavid Dai } 855b5d2f741SDavid Dai data->num_nodes = num_nodes; 856b5d2f741SDavid Dai 857b5d2f741SDavid Dai for (i = 0; i < qp->num_bcms; i++) 858b5d2f741SDavid Dai qcom_icc_bcm_init(qp->bcms[i], &pdev->dev); 859b5d2f741SDavid Dai 860b5d2f741SDavid Dai /* 861b5d2f741SDavid Dai * Pre sort the BCMs based on VCD for ease of generating a command list 862b5d2f741SDavid Dai * that groups the BCMs with the same VCD together. VCDs are numbered 863b5d2f741SDavid Dai * with lowest being the most expensive time wise, ensuring that 864b5d2f741SDavid Dai * those commands are being sent the earliest in the queue. 865b5d2f741SDavid Dai */ 866b5d2f741SDavid Dai sort(qp->bcms, qp->num_bcms, sizeof(*qp->bcms), cmp_vcd, NULL); 867b5d2f741SDavid Dai 868b5d2f741SDavid Dai platform_set_drvdata(pdev, qp); 869b5d2f741SDavid Dai 870b5d2f741SDavid Dai dev_dbg(&pdev->dev, "Registered SDM845 ICC\n"); 871b5d2f741SDavid Dai 872b5d2f741SDavid Dai return ret; 873b5d2f741SDavid Dai err: 874b5d2f741SDavid Dai list_for_each_entry(node, &provider->nodes, node_list) { 875b5d2f741SDavid Dai icc_node_del(node); 876b5d2f741SDavid Dai icc_node_destroy(node->id); 877b5d2f741SDavid Dai } 878b5d2f741SDavid Dai 879b5d2f741SDavid Dai icc_provider_del(provider); 880b5d2f741SDavid Dai return ret; 881b5d2f741SDavid Dai } 882b5d2f741SDavid Dai 883b5d2f741SDavid Dai static int qnoc_remove(struct platform_device *pdev) 884b5d2f741SDavid Dai { 885b5d2f741SDavid Dai struct qcom_icc_provider *qp = platform_get_drvdata(pdev); 886b5d2f741SDavid Dai struct icc_provider *provider = &qp->provider; 887b5d2f741SDavid Dai struct icc_node *n; 888b5d2f741SDavid Dai 889b5d2f741SDavid Dai list_for_each_entry(n, &provider->nodes, node_list) { 890b5d2f741SDavid Dai icc_node_del(n); 891b5d2f741SDavid Dai icc_node_destroy(n->id); 892b5d2f741SDavid Dai } 893b5d2f741SDavid Dai 894b5d2f741SDavid Dai return icc_provider_del(provider); 895b5d2f741SDavid Dai } 896b5d2f741SDavid Dai 897b5d2f741SDavid Dai static const struct of_device_id qnoc_of_match[] = { 898b5d2f741SDavid Dai { .compatible = "qcom,sdm845-rsc-hlos", .data = &sdm845_rsc_hlos }, 899b5d2f741SDavid Dai { }, 900b5d2f741SDavid Dai }; 901b5d2f741SDavid Dai MODULE_DEVICE_TABLE(of, qnoc_of_match); 902b5d2f741SDavid Dai 903b5d2f741SDavid Dai static struct platform_driver qnoc_driver = { 904b5d2f741SDavid Dai .probe = qnoc_probe, 905b5d2f741SDavid Dai .remove = qnoc_remove, 906b5d2f741SDavid Dai .driver = { 907b5d2f741SDavid Dai .name = "qnoc-sdm845", 908b5d2f741SDavid Dai .of_match_table = qnoc_of_match, 909b5d2f741SDavid Dai }, 910b5d2f741SDavid Dai }; 911b5d2f741SDavid Dai module_platform_driver(qnoc_driver); 912b5d2f741SDavid Dai 913b5d2f741SDavid Dai MODULE_AUTHOR("David Dai <daidavid1@codeaurora.org>"); 914b5d2f741SDavid Dai MODULE_DESCRIPTION("Qualcomm sdm845 NoC driver"); 915b5d2f741SDavid Dai MODULE_LICENSE("GPL v2"); 916