Re: [PATCH v4 1/7] powerpc/pseries/iommu: Create defines for operations in ibm, ddw-applicable
gt;addr_lo); > > return ret; > } > @@ -996,7 +1005,7 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) > int page_shift; > u64 dma_addr, max_addr; > struct device_node *dn; > - u32 ddw_avail[3]; > + u32 ddw_avail[DDW_APPLICABLE_SIZE]; > struct direct_window *window; > struct property *win64; > struct dynamic_dma_window_prop *ddwprop; > @@ -1029,7 +1038,7 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) >* the property is actually in the parent, not the PE >*/ > ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable", > - _avail[0], 3); > + _avail[0], > DDW_APPLICABLE_SIZE); > if (ret) > goto out_failed; > Tested-by: David Dai
Re: [PATCH v4 2/7] powerpc/pseries/iommu: Update call to ibm, query-pe-dma-windows
> query_out, > cfg_addr, BUID_HI(buid), BUID_LO(buid)); > - dev_info(>dev, "ibm,query-pe-dma-windows(%x) %x %x %x" > - " returned %d\n", ddw_avail[DDW_QUERY_PE_DMA_WIN], > cfg_addr, > - BUID_HI(buid), BUID_LO(buid), ret); > + dev_info(>dev, "ibm,query-pe-dma-windows(%x) %x %x %x > returned %d\n", > + ddw_avail[DDW_QUERY_PE_DMA_WIN], cfg_addr, > BUID_HI(buid), > + BUID_LO(buid), ret); > + > + switch (out_sz) { > + case 5: > + query->windows_available = query_out[0]; > + query->largest_available_block = query_out[1]; > + query->page_size = query_out[2]; > + query->migration_capable = query_out[3]; > + break; > + case 6: > + query->windows_available = query_out[0]; > + query->largest_available_block = ((u64)query_out[1] << > 32) | > + query_out[2]; > + query->page_size = query_out[3]; > + query->migration_capable = query_out[4]; > + break; > + } > + > return ret; > } > > @@ -1049,7 +1120,7 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) >* of page sizes: supported and supported for migrate-dma. >*/ > dn = pci_device_to_OF_node(dev); > - ret = query_ddw(dev, ddw_avail, ); > + ret = query_ddw(dev, ddw_avail, , pdn); > if (ret != 0) > goto out_failed; > > @@ -1077,7 +1148,7 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) > /* check largest block * page size > max memory hotplug addr */ > max_addr = ddw_memory_hotplug_max(); > if (query.largest_available_block < (max_addr >> page_shift)) { > - dev_dbg(>dev, "can't map partition max 0x%llx with > %u " > + dev_dbg(>dev, "can't map partition max 0x%llx with > %llu " > "%llu-sized pages\n", > max_addr, query.largest_available_block, > 1ULL << page_shift); > goto out_failed; Tested-by: David Dai
Re: [PATCH v4 4/7] powerpc/pseries/iommu: Remove default DMA window before creating DDW
> + default_win_removed = true; > + > + /* Query again, to check if the window is available */ > + ret = query_ddw(dev, ddw_avail, , pdn); > + if (ret != 0) > + goto out_failed; > + > + if (query.windows_available == 0) { > + /* no windows are available for this device. */ > + dev_dbg(>dev, "no free dynamic windows"); > + goto out_failed; > + } > } > if (query.page_size & 4) { > page_shift = 24; /* 16MB */ > @@ -1231,6 +1288,8 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) > kfree(win64); > > out_failed: > + if (default_win_removed) > + reset_dma_window(dev, pdn); > > fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); > if (!fpdn) Tested-by: David Dai
Re: [PATCH v4 3/7] powerpc/pseries/iommu: Move window-removing part of remove_ddw into remove_dma_window
On Thu, 2020-07-16 at 04:16 -0300, Leonardo Bras wrote: > Move the window-removing part of remove_ddw into a new function > (remove_dma_window), so it can be used to remove other DMA windows. > > It's useful for removing DMA windows that don't create > DIRECT64_PROPNAME > property, like the default DMA window from the device, which uses > "ibm,dma-window". > > Signed-off-by: Leonardo Bras > --- > arch/powerpc/platforms/pseries/iommu.c | 45 +++- > -- > 1 file changed, 27 insertions(+), 18 deletions(-) > > diff --git a/arch/powerpc/platforms/pseries/iommu.c > b/arch/powerpc/platforms/pseries/iommu.c > index 1a933c4e8bba..4e33147825cc 100644 > --- a/arch/powerpc/platforms/pseries/iommu.c > +++ b/arch/powerpc/platforms/pseries/iommu.c > @@ -781,25 +781,14 @@ static int __init disable_ddw_setup(char *str) > > early_param("disable_ddw", disable_ddw_setup); > > -static void remove_ddw(struct device_node *np, bool remove_prop) > +static void remove_dma_window(struct device_node *np, u32 > *ddw_avail, > + struct property *win) > { > struct dynamic_dma_window_prop *dwp; > - struct property *win64; > - u32 ddw_avail[DDW_APPLICABLE_SIZE]; > u64 liobn; > - int ret = 0; > - > - ret = of_property_read_u32_array(np, "ibm,ddw-applicable", > - _avail[0], > DDW_APPLICABLE_SIZE); > - > - win64 = of_find_property(np, DIRECT64_PROPNAME, NULL); > - if (!win64) > - return; > - > - if (ret || win64->length < sizeof(*dwp)) > - goto delprop; > + int ret; > > - dwp = win64->value; > + dwp = win->value; > liobn = (u64)be32_to_cpu(dwp->liobn); > > /* clear the whole window, note the arg is in kernel pages */ > @@ -821,10 +810,30 @@ static void remove_ddw(struct device_node *np, > bool remove_prop) > pr_debug("%pOF: successfully removed direct window: > rtas returned " > "%d to ibm,remove-pe-dma-window(%x) %llx\n", > np, ret, ddw_avail[DDW_REMOVE_PE_DMA_WIN], > liobn); > +} > + > +static void remove_ddw(struct device_node *np, bool remove_prop) > +{ > + struct property *win; > + u32 ddw_avail[DDW_APPLICABLE_SIZE]; > + int ret = 0; > + > + ret = of_property_read_u32_array(np, "ibm,ddw-applicable", > + _avail[0], > DDW_APPLICABLE_SIZE); > + if (ret) > + return; > + > + win = of_find_property(np, DIRECT64_PROPNAME, NULL); > + if (!win) > + return; > + > + if (win->length >= sizeof(struct dynamic_dma_window_prop)) > + remove_dma_window(np, ddw_avail, win); > + > + if (!remove_prop) > + return; > > -delprop: > - if (remove_prop) > - ret = of_remove_property(np, win64); > + ret = of_remove_property(np, win); > if (ret) > pr_warn("%pOF: failed to remove direct window property: > %d\n", > np, ret); Tested-by: David Dai
Re: [PATCH v4 1/7] powerpc/pseries/iommu: Create defines for operations in ibm, ddw-applicable
gt;addr_lo); > > return ret; > } > @@ -996,7 +1005,7 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) > int page_shift; > u64 dma_addr, max_addr; > struct device_node *dn; > - u32 ddw_avail[3]; > + u32 ddw_avail[DDW_APPLICABLE_SIZE]; > struct direct_window *window; > struct property *win64; > struct dynamic_dma_window_prop *ddwprop; > @@ -1029,7 +1038,7 @@ static u64 enable_ddw(struct pci_dev *dev, > struct device_node *pdn) >* the property is actually in the parent, not the PE >*/ > ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable", > - _avail[0], 3); > + _avail[0], > DDW_APPLICABLE_SIZE); > if (ret) > goto out_failed; > Tested-by: David Dai
[RFC PATCH 4/4] interconnect: qcom: sdm845: Split qnodes into their respective NoCs
In order to better represent the hardware and its different Network-On-Chip devices, split the sdm845 provider driver into NoC specific providers. Remove duplicate functionality already provided by the icc rpmh and bcm voter drivers to calculate and commit bandwidth requests to hardware. Signed-off-by: David Dai --- drivers/interconnect/qcom/sdm845.c | 727 +++-- 1 file changed, 206 insertions(+), 521 deletions(-) diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index 502a6c2..a731f4d 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -16,133 +16,8 @@ #include #include -#include -#include -#include - -#define to_qcom_provider(_provider) \ - container_of(_provider, struct qcom_icc_provider, provider) - -struct qcom_icc_provider { - struct icc_provider provider; - struct device *dev; - struct qcom_icc_bcm **bcms; - size_t num_bcms; -}; - -/** - * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager (BCM) - * @unit: divisor used to convert bytes/sec bw value to an RPMh msg - * @width: multiplier used to convert bytes/sec bw value to an RPMh msg - * @vcd: virtual clock domain that this bcm belongs to - * @reserved: reserved field - */ -struct bcm_db { - __le32 unit; - __le16 width; - u8 vcd; - u8 reserved; -}; - -#define SDM845_MAX_LINKS 43 -#define SDM845_MAX_BCMS30 -#define SDM845_MAX_BCM_PER_NODE2 -#define SDM845_MAX_VCD 10 - -/* - * The AMC bucket denotes constraints that are applied to hardware when - * icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied - * when the execution environment transitions between active and low power mode. - */ -#define QCOM_ICC_BUCKET_AMC0 -#define QCOM_ICC_BUCKET_WAKE 1 -#define QCOM_ICC_BUCKET_SLEEP 2 -#define QCOM_ICC_NUM_BUCKETS 3 -#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC) -#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE) -#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP) -#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) -#define QCOM_ICC_TAG_ALWAYS(QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ -QCOM_ICC_TAG_SLEEP) - -/** - * 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_bcms: 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[QCOM_ICC_NUM_BUCKETS]; - u64 max_peak[QCOM_ICC_NUM_BUCKETS]; - 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 the bcm needs to be committed - * @keepalive: flag used to indicate whether a keepalive is required - * @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[QCOM_ICC_NUM_BUCKETS]; - u64 vote_y[QCOM_ICC_NUM_BUCKETS]; - 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; -}; - -struct qcom_icc_desc { - struct qcom_icc_node **nodes; - size_t num_nodes; - struct qcom_icc_bcm **bcms; - size_t num_bcms; -}; - -#define DEFINE_QNODE(_name, _id, _channels, _buswidth, \ - _numlinks, ...) \ - static struct qcom_icc_node
[RFC PATCH 3/4] interconnect: qcom: Refactor icc rpmh support
Add bcm voter driver and add support for RPMh specific interconnect providers so that they may be re-used for icc-next RPMh based provider drivers. Signed-off-by: David Dai --- drivers/interconnect/qcom/Kconfig | 8 + drivers/interconnect/qcom/Makefile| 4 + drivers/interconnect/qcom/bcm-voter.c | 355 ++ drivers/interconnect/qcom/bcm-voter.h | 28 +++ drivers/interconnect/qcom/icc-rpmh.c | 154 +++ drivers/interconnect/qcom/icc-rpmh.h | 150 ++ 6 files changed, 699 insertions(+) create mode 100644 drivers/interconnect/qcom/bcm-voter.c create mode 100644 drivers/interconnect/qcom/bcm-voter.h create mode 100644 drivers/interconnect/qcom/icc-rpmh.c create mode 100644 drivers/interconnect/qcom/icc-rpmh.h diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index 6ab4012..8ff255d 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -18,9 +18,17 @@ config INTERCONNECT_QCOM_SDM845 tristate "Qualcomm SDM845 interconnect driver" depends on INTERCONNECT_QCOM depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST + select INTERCONNECT_QCOM_RPMH + select INTERCONNECT_QCOM_BCM_VOTER help This is a driver for the Qualcomm Network-on-Chip on sdm845-based platforms. +config INTERCONNECT_QCOM_BCM_VOTER + tristate + +config INTERCONNECT_QCOM_RPMH + tristate + config INTERCONNECT_QCOM_SMD_RPM tristate diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index 67dafb7..0f5e88d 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -3,7 +3,11 @@ qnoc-qcs404-objs := qcs404.o qnoc-sdm845-objs := sdm845.o icc-smd-rpm-objs := smd-rpm.o +bcm-voter-objs := bcm-voter.o +icc-rpmh-obj := icc-rpmh.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += icc-smd-rpm.o +obj-$(CONFIG_INTERCONNECT_QCOM_BCM_VOTER) += bcm-voter.o +obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o diff --git a/drivers/interconnect/qcom/bcm-voter.c b/drivers/interconnect/qcom/bcm-voter.c new file mode 100644 index 000..f74ae5f --- /dev/null +++ b/drivers/interconnect/qcom/bcm-voter.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "bcm-voter.h" +#include "icc-rpmh.h" + +static LIST_HEAD(bcm_voters); + +/** + * struct bcm_voter - Bus Clock Manager voter + * @dev: reference to the device that communicates with the BCM + * @np: reference to the device node to match bcm voters + * @lock: mutex to protect commit and wake/sleep lists in the voter + * @commit_list: list containing bcms to be committed to hardware + * @ws_list: list containing bcms that have different wake/sleep votes + * @voter_node: list of bcm voters + */ +struct bcm_voter { + struct device *dev; + struct device_node *np; + struct mutex lock; + struct list_head commit_list; + struct list_head ws_list; + struct list_head voter_node; +}; + +static int cmp_vcd(void *priv, struct list_head *a, struct list_head *b) +{ + const struct qcom_icc_bcm *bcm_a = + list_entry(a, struct qcom_icc_bcm, list); + const struct qcom_icc_bcm *bcm_b = + list_entry(b, struct qcom_icc_bcm, list); + + if (bcm_a->aux_data.vcd < bcm_b->aux_data.vcd) + return -1; + else if (bcm_a->aux_data.vcd == bcm_b->aux_data.vcd) + return 0; + else + return 1; +} + +static void bcm_aggregate(struct qcom_icc_bcm *bcm) +{ + size_t i, bucket; + u64 agg_avg[QCOM_ICC_NUM_BUCKETS] = {0}; + u64 agg_peak[QCOM_ICC_NUM_BUCKETS] = {0}; + u64 temp; + + for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) { + for (i = 0; i < bcm->num_nodes; i++) { + temp = bcm->nodes[i]->sum_avg[bucket] * bcm->aux_data.width; + do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels); + agg_avg[bucket] = max(agg_avg[bucket], temp); + + temp = bcm->nodes[i]->max_peak[bucket] * bcm->aux_data.width; + do_div(temp, bcm->nodes[i]->buswidth); + agg_peak[bucket] = max(agg_peak[bucket], temp); + } + + temp = agg_avg[bucket] * 1000ULL; + do_div(temp, bcm->au
[RFC PATCH 2/4] arm64: dts: sdm845: Redefine interconnect provider DT nodes
Add the DT nodes for each of the Network-On-Chip interconnect buses found on SDM845 based platform and redefine the rsc_hlos child node as a bcm-voter device to better represent the hardware. Signed-off-by: David Dai --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 60 ++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index f406a43..a7ad79d 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1362,6 +1362,54 @@ reg = <0 0x0110 0 0x20>, <0 0x0130 0 0x5>; reg-names = "llcc_base", "llcc_broadcast_base"; interrupts = ; + + mem_noc: interconnect@138 { + compatible = "qcom,sdm845-mem-noc"; + reg = <0 0x0138 0 0x27200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + + dc_noc: interconnect@14e { + compatible = "qcom,sdm845-dc-noc"; + reg = <0 0x014e 0 0x400>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + + config_noc: interconnect@150 { + compatible = "qcom,sdm845-config-noc"; + reg = <0 0x0150 0 0x5080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + + system_noc: interconnect@162 { + compatible = "qcom,sdm845-system-noc"; + reg = <0 0x0162 0 0x18080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + + aggre1_noc: interconnect@16e { + compatible = "qcom,sdm845-aggre1-noc"; + reg = <0 0x016e 0 0xd080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + + aggre2_noc: interconnect@170 { + compatible = "qcom,sdm845-aggre2-noc"; + reg = <0 0x0170 0 0x3b100>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + + mmss_noc: interconnect@174 { + compatible = "qcom,sdm845-mmss-noc"; + reg = <0 0x0174 0 0x1c1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; }; ufs_mem_hc: ufshc@1d84000 { @@ -3090,6 +3138,13 @@ #mbox-cells = <1>; }; + gladiator_noc: interconnect@1790 { + compatible = "qcom,sdm845-gladiator-noc"; + reg = <0 0x1790 0 0xd080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <_bcm_voter>; + }; + apps_rsc: rsc@179c { label = "apps_rsc"; compatible = "qcom,rpmh-rsc"; @@ -3164,9 +3219,8 @@ }; }; - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; + apps_bcm_voter: bcm-voter { + compatible = "qcom,sdm845-bcm-voter"; }; }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[RFC PATCH 1/4] dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings
Redefine the Network-on-Chip devices to more accurately describe the interconnect topology on Qualcomm's SDM845 platform. Each interconnect device can communicate with different instances of the RPMh hardware which are described as RSCs(Resource State Coordinators). As part of updating the DT bindings, convert the existing sdm845 bindings to DT schema format using json-schema. Signed-off-by: David Dai --- .../bindings/interconnect/qcom,bcm-voter.yaml | 45 + .../bindings/interconnect/qcom,sdm845.txt | 24 - .../bindings/interconnect/qcom,sdm845.yaml | 108 + 3 files changed, 153 insertions(+), 24 deletions(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.yaml delete mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm845.yaml diff --git a/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.yaml b/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.yaml new file mode 100644 index 000..74f0715 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,bcm-voter.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm BCM-Voter Interconnect + +maintainers: + - David Dai + +description: | +The Bus Clock Manager (BCM) is a dedicated hardware accelerator +that manages shared system resources by aggregating requests +from multiple Resource State Coordinators (RSC). Interconnect +providers are able to vote for aggregated thresholds values from +consumers by communicating through their respective RSCs. + +properties: + compatible: +enum: + - qcom,sdm845-bcm-voter + +required: + - compatible + +additionalProperties: false + +examples: + - | +apps_rsc: interconnect@179c { +compatible = "qcom,rpmh-rsc"; + +apps_bcm_voter: bcm_voter { +compatible = "qcom,sdm845-bcm-voter"; +}; +}; + +disp_rsc: interconnect@179d { +compatible = "qcom,rpmh-rsc"; + +disp_bcm_voter: bcm_voter { +compatible = "qcom,sdm845-bcm-voter"; +}; +}; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt deleted file mode 100644 index 5c4f1d9..000 --- a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt +++ /dev/null @@ -1,24 +0,0 @@ -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" -- #interconnect-cells : should contain 1 - -Examples: - -apps_rsc: rsc { - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; - }; -}; - diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.yaml new file mode 100644 index 000..1aec321 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.yaml @@ -0,0 +1,108 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sdm845.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SDM845 Network-On-Chip Interconnect + +maintainers: + - David Dai + +description: | + 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 point to at + least one RPMh device child node pertaining to their RSC and each provider + can map to multiple RPMh resources. + +properties: + reg: +maxItems: 1 + + compatible: +enum: + - qcom,sdm845-aggre1-noc + - qcom,sdm845-aggre2-noc + - qcom,sdm845-config-noc + - qcom,sdm845-dc-noc + - qcom,sdm845-gladiator-noc + - qcom,sdm845-mem-noc + - qcom,sdm845-mmss-noc + - qcom,sdm845-system-noc + + '#interconnect-cells': +const: 1 + + qcom,bcm
[RFC PATCH 0/4] Redefine interconnect provider DT nodes for SDM845
While there are no current consumers of the SDM845 interconnect device in devicetree, take this opportunity to redefine the interconnect device nodes as the previous definitions of using a single child node under the apps_rsc device did not accurately capture the description of the hardware. The Network-On-Chip (NoC) interconnect devices should be represented in a manner akin to QCS404 platforms[1] where there is a separation of NoC devices and its RPM/RPMh counterparts. The bcm-voter devices are representing the RPMh devices that the interconnect providers need to communicate with and there can be more than one instance of the Bus Clock Manager (BCM) which can live under different instances of Resource State Coordinators (RSC). There are display use cases where consumers may need to target a different bcm-voter (Some display specific RSC) than the default, and there needs to be a way to represent this connection in devicetree. This patches series extends the original discussion involving the SDM845 interconnect bindings[2] by adding accompanying driver implementations using the split NoC devices. The first patch also updates existing sdm845 binding documentation to DT schema format using json-schema. [1]: https://lkml.org/lkml/2019/6/13/143 [2]: https://lkml.org/lkml/2019/7/19/1063 David Dai (4): dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings arm64: dts: sdm845: Redefine interconnect provider DT nodes interconnect: qcom: Refactor icc rpmh support interconnect: qcom: sdm845: Split qnodes into their respective NoCs .../bindings/interconnect/qcom,bcm-voter.yaml | 45 ++ .../bindings/interconnect/qcom,sdm845.txt | 24 - .../bindings/interconnect/qcom,sdm845.yaml | 108 +++ arch/arm64/boot/dts/qcom/sdm845.dtsi | 60 +- drivers/interconnect/qcom/Kconfig | 8 + drivers/interconnect/qcom/Makefile | 4 + drivers/interconnect/qcom/bcm-voter.c | 355 ++ drivers/interconnect/qcom/bcm-voter.h | 28 + drivers/interconnect/qcom/icc-rpmh.c | 154 + drivers/interconnect/qcom/icc-rpmh.h | 150 + drivers/interconnect/qcom/sdm845.c | 727 ++--- 11 files changed, 1115 insertions(+), 548 deletions(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.yaml delete mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm845.yaml create mode 100644 drivers/interconnect/qcom/bcm-voter.c create mode 100644 drivers/interconnect/qcom/bcm-voter.h create mode 100644 drivers/interconnect/qcom/icc-rpmh.c create mode 100644 drivers/interconnect/qcom/icc-rpmh.h -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[v1] e1000e: EEH on e1000e adapter detects io perm failure can trigger crash
We see the behavior when EEH e1000e adapter detects io permanent failure, it will crash kernel with this stack: EEH: Beginning: 'error_detected(permanent failure)' EEH: PE#90 (PCI 0115:90:00.1): Invoking e1000e->error_detected(permanent failure) EEH: PE#90 (PCI 0115:90:00.1): e1000e driver reports: 'disconnect' EEH: PE#90 (PCI 0115:90:00.0): Invoking e1000e->error_detected(permanent failure) EEH: PE#90 (PCI 0115:90:00.0): e1000e driver reports: 'disconnect' EEH: Finished:'error_detected(permanent failure)' Oops: Exception in kernel mode, sig: 5 [#1] NIP [c07b1be0] free_msi_irqs+0xa0/0x280 LR [c07b1bd0] free_msi_irqs+0x90/0x280 Call Trace: [c004f491ba10] [c07b1bd0] free_msi_irqs+0x90/0x280 (unreliable) [c004f491ba70] [c07b260c] pci_disable_msi+0x13c/0x180 [c004f491bab0] [d46381ac] e1000_remove+0x234/0x2a0 [e1000e] [c004f491baf0] [c0783cec] pci_device_remove+0x6c/0x120 [c004f491bb30] [c088da6c] device_release_driver_internal+0x2bc/0x3f0 [c004f491bb80] [c076f5a8] pci_stop_and_remove_bus_device+0xb8/0x110 [c004f491bbc0] [c006e890] pci_hp_remove_devices+0x90/0x130 [c004f491bc50] [c004ad34] eeh_handle_normal_event+0x1d4/0x660 [c004f491bd10] [c004bf10] eeh_event_handler+0x1c0/0x1e0 [c004f491bdc0] [c017c4ac] kthread+0x1ac/0x1c0 [c004f491be30] [c000b75c] ret_from_kernel_thread+0x5c/0x80 Basically the e1000e irqs haven't been freed at the time eeh is trying to remove the the e1000e device. Need to make sure when e1000e_close is called to bring down the NIC, if adapter error_state is pci_channel_io_perm_failure, it should also bring down the link and free irqs. Reported-by: Morumuri Srivalli Signed-off-by: David Dai --- drivers/net/ethernet/intel/e1000e/netdev.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index d7d56e4..cf618e1 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4715,7 +4715,8 @@ int e1000e_close(struct net_device *netdev) pm_runtime_get_sync(>dev); - if (!test_bit(__E1000_DOWN, >state)) { + if (!test_bit(__E1000_DOWN, >state) || + (adapter->pdev->error_state == pci_channel_io_perm_failure)) { e1000e_down(adapter, true); e1000_free_irq(adapter); -- 1.7.1
Re: [RFC PATCH] interconnect: Replace of_icc_get() with icc_get() and reduce DT binding
On 9/25/2019 6:28 AM, Stephen Boyd wrote: Quoting Bjorn Andersson (2019-09-24 22:59:33) On Tue 24 Sep 22:41 PDT 2019, Stephen Boyd wrote: The DT binding could also be simplified somewhat. Currently a path needs to be specified in DT for each and every use case that is possible for a device to want. Typically the path is to memory, which looks to be reserved for in the binding with the "dma-mem" named path, but sometimes the path is from a device to the CPU or more generically from a device to another device which could be a CPU, cache, DMA master, or another device if some sort of DMA to DMA scenario is happening. Let's remove the pair part of the binding so that we just list out a device's possible endpoints on the bus or busses that it's connected to. If the kernel wants to figure out what the path is to memory or the CPU or a cache or something else it should be able to do that by finding the node for the "destination" endpoint, extracting that node's "interconnects" property, and deriving the path in software. For example, we shouldn't need to write out each use case path by path in DT for each endpoint node that wants to set a bandwidth to memory. We should just be able to indicate what endpoint(s) a device sits on based on the interconnect provider in the system and then walk the various interconnects to find the path from that source endpoint to the destination endpoint. But doesn't this implies that the other end of the path is always some specific node, e.g. DDR? With a single node how would you describe CPU->LLCC or GPU->OCIMEM? By only specifying the endpoint the device uses it describes what the hardware block interfaces with. It doesn't imply that there's only one other end of the path. It implies that the paths should be discoverable by walking the interconnect graph given some source device node and target device node. In most cases the target device node will be a DDR controller node, but sometimes it could be LLCC or OCIMEM. We may need to add some sort of "get the DDR controller device" API or work it into the interconnect API somehow to indicate what target endpoint is desired. By not listing all those paths in DT we gain flexibility to add more paths later on without having to update or tweak DT to describe more paths/routes through the interconnect. I'm unsure that using the target device node or target source device is the correct way to represent the constraints that the consumers apply on the interconnects. While it's true the traffic is intended for the targeted devices, the constraints(QoS or BW) are for the interconnect or specifically the paths that span across the ports of various interconnects(NoC devices in this case). I think having both src and dst properties is still the simplest way to achieve the flexibility that we require to set the constraints for ports(that may not have a target device defined in DT or exists as some intermediate port across multiple interconnects). Obviously this patch doesn't compile but I'm sending it out to start this discussion so we don't get stuck on the binding or the kernel APIs for a long time. It looks like we should be OK in terms of backwards compatibility because we can just ignore the second element in an old binding, but maybe we'll want to describe paths in different directions (e.g. the path from the CPU to the SD controller may be different than the path the SD controller takes to the CPU) and that may require extending interconnect-names to indicate what direction/sort of path it is. I'm basically thinking about master vs. slave ports in AXI land. Cc: Maxime Ripard Cc: Cc: Rob Herring Cc: Cc: Bjorn Andersson Cc: Evan Green Cc: David Dai Signed-off-by: Stephen Boyd --- .../bindings/interconnect/interconnect.txt| 19 --- include/linux/interconnect.h | 13 ++--- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/Documentation/devicetree/bindings/interconnect/interconnect.txt b/Documentation/devicetree/bindings/interconnect/interconnect.txt index 6f5d23a605b7..f8979186b8a7 100644 --- a/Documentation/devicetree/bindings/interconnect/interconnect.txt +++ b/Documentation/devicetree/bindings/interconnect/interconnect.txt @@ -11,7 +11,7 @@ The interconnect provider binding is intended to represent the interconnect controllers in the system. Each provider registers a set of interconnect nodes, which expose the interconnect related capabilities of the interconnect to consumer drivers. These capabilities can be throughput, latency, priority -etc. The consumer drivers set constraints on interconnect path (or endpoints) +etc. The consumer drivers set constraints on interconnect paths (or endpoints) depending on the use case. Interconnect providers can also be interconnect consumers, such as in the case where two network-on-chip fabrics interface directly. @@ -42,23 +42,12 @@ multiple p
[v3] iproute2-next: police: support 64bit rate and peakrate in tc utility
For high speed adapter like Mellanox CX-5 card, it can reach upto 100 Gbits per second bandwidth. Currently htb already supports 64bit rate in tc utility. However police action rate and peakrate are still limited to 32bit value (upto 32 Gbits per second). Taking advantage of the 2 new attributes TCA_POLICE_RATE64 and TCA_POLICE_PEAKRATE64 from kernel, tc can use them to break the 32bit limit, and still keep the backward binary compatibility. Tested-by: David Dai Signed-off-by: David Dai --- Changelog: v1->v2: - Change patch submit component from iproute2 to iproute2-next - Move 2 attributes TCA_POLICE_RATE64 TCA_POLICE_PEAKRATE64 after TCA_POLICE_PAD in pkt_cls.h header to be consistent with kernel's pkt_cls.h header. v2->v3: - Use common functions of duparg and invarg in police filter. --- include/uapi/linux/pkt_cls.h |2 + tc/m_police.c| 149 +++--- tc/tc_core.c | 29 tc/tc_core.h |3 + 4 files changed, 102 insertions(+), 81 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index b057aee..a6aa466 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -160,6 +160,8 @@ enum { TCA_POLICE_RESULT, TCA_POLICE_TM, TCA_POLICE_PAD, + TCA_POLICE_RATE64, + TCA_POLICE_PEAKRATE64, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT }; diff --git a/tc/m_police.c b/tc/m_police.c index 862a39f..a5bc20c 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -49,11 +49,6 @@ static void usage(void) exit(-1); } -static void explain1(char *arg) -{ - fprintf(stderr, "Illegal \"%s\"\n", arg); -} - static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) { @@ -71,6 +66,7 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */ int Rcell_log = -1, Pcell_log = -1; struct rtattr *tail; + __u64 rate64 = 0, prate64 = 0; if (a) /* new way of doing things */ NEXT_ARG(); @@ -82,73 +78,47 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, if (matches(*argv, "index") == 0) { NEXT_ARG(); - if (get_u32(, *argv, 10)) { - fprintf(stderr, "Illegal \"index\"\n"); - return -1; - } + if (get_u32(, *argv, 10)) + invarg("index", *argv); } else if (matches(*argv, "burst") == 0 || strcmp(*argv, "buffer") == 0 || strcmp(*argv, "maxburst") == 0) { NEXT_ARG(); - if (buffer) { - fprintf(stderr, "Double \"buffer/burst\" spec\n"); - return -1; - } - if (get_size_and_cell(, _log, *argv) < 0) { - explain1("buffer"); - return -1; - } + if (buffer) + duparg("buffer/burst", *argv); + if (get_size_and_cell(, _log, *argv) < 0) + invarg("buffer", *argv); } else if (strcmp(*argv, "mtu") == 0 || strcmp(*argv, "minburst") == 0) { NEXT_ARG(); - if (mtu) { - fprintf(stderr, "Double \"mtu/minburst\" spec\n"); - return -1; - } - if (get_size_and_cell(, _log, *argv) < 0) { - explain1("mtu"); - return -1; - } + if (mtu) + duparg("mtu/minburst", *argv); + if (get_size_and_cell(, _log, *argv) < 0) + invarg("mtu", *argv); } else if (strcmp(*argv, "mpu") == 0) { NEXT_ARG(); - if (mpu) { - fprintf(stderr, "Double \"mpu\" spec\n"); - return -1; - } - if (get_size(, *argv)) { - explain1("mpu"); - return -1;
[v3] net_sched: act_police: add 2 new attributes to support police 64bit rate and peakrate
For high speed adapter like Mellanox CX-5 card, it can reach upto 100 Gbits per second bandwidth. Currently htb already supports 64bit rate in tc utility. However police action rate and peakrate are still limited to 32bit value (upto 32 Gbits per second). Add 2 new attributes TCA_POLICE_RATE64 and TCA_POLICE_RATE64 in kernel for 64bit support so that tc utility can use them for 64bit rate and peakrate value to break the 32bit limit, and still keep the backward binary compatibility. Tested-by: David Dai Signed-off-by: David Dai --- Changelog: v1->v2: - Move 2 attributes TCA_POLICE_RATE64 TCA_POLICE_PEAKRATE64 after TCA_POLICE_PAD in pkt_cls.h header. v2->v3: - Use TCA_POLICE_PAD instead of __TCA_POLICE_MAX as padding attr in last parameter in nla_put_u64_64bit() routine. --- include/uapi/linux/pkt_cls.h |2 ++ net/sched/act_police.c | 27 +++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index b057aee..a6aa466 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -160,6 +160,8 @@ enum { TCA_POLICE_RESULT, TCA_POLICE_TM, TCA_POLICE_PAD, + TCA_POLICE_RATE64, + TCA_POLICE_PEAKRATE64, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT }; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 49cec3e..425f2a3 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -40,6 +40,8 @@ static int tcf_police_walker(struct net *net, struct sk_buff *skb, [TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE }, [TCA_POLICE_AVRATE] = { .type = NLA_U32 }, [TCA_POLICE_RESULT] = { .type = NLA_U32 }, + [TCA_POLICE_RATE64] = { .type = NLA_U64 }, + [TCA_POLICE_PEAKRATE64] = { .type = NLA_U64 }, }; static int tcf_police_init(struct net *net, struct nlattr *nla, @@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, struct tcf_police_params *new; bool exists = false; u32 index; + u64 rate64, prate64; if (nla == NULL) return -EINVAL; @@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, } if (R_tab) { new->rate_present = true; - psched_ratecfg_precompute(>rate, _tab->rate, 0); + rate64 = tb[TCA_POLICE_RATE64] ? +nla_get_u64(tb[TCA_POLICE_RATE64]) : 0; + psched_ratecfg_precompute(>rate, _tab->rate, rate64); qdisc_put_rtab(R_tab); } else { new->rate_present = false; } if (P_tab) { new->peak_present = true; - psched_ratecfg_precompute(>peak, _tab->rate, 0); + prate64 = tb[TCA_POLICE_PEAKRATE64] ? + nla_get_u64(tb[TCA_POLICE_PEAKRATE64]) : 0; + psched_ratecfg_precompute(>peak, _tab->rate, prate64); qdisc_put_rtab(P_tab); } else { new->peak_present = false; @@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a, lockdep_is_held(>tcf_lock)); opt.mtu = p->tcfp_mtu; opt.burst = PSCHED_NS2TICKS(p->tcfp_burst); - if (p->rate_present) + if (p->rate_present) { psched_ratecfg_getrate(, >rate); - if (p->peak_present) + if ((police->params->rate.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_RATE64, + police->params->rate.rate_bytes_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + } + if (p->peak_present) { psched_ratecfg_getrate(, >peak); + if ((police->params->peak.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_PEAKRATE64, + police->params->peak.rate_bytes_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + } if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), )) goto nla_put_failure; if (p->tcfp_result && -- 1.7.1
[v2] iproute2-next: police: support 64bit rate and peakrate in tc utility
For high speed adapter like Mellanox CX-5 card, it can reach upto 100 Gbits per second bandwidth. Currently htb already supports 64bit rate in tc utility. However police action rate and peakrate are still limited to 32bit value (upto 32 Gbits per second). Taking advantage of the 2 new attributes TCA_POLICE_RATE64 and TCA_POLICE_PEAKRATE64 from kernel, tc can use them to break the 32bit limit, and still keep the backward binary compatibility. Tested-by: David Dai Signed-off-by: David Dai --- Changelog: v1->v2: - Change patch submit component from iproute2 to iproute2-next - Move 2 attributes TCA_POLICE_RATE64 TCA_POLICE_PEAKRATE64 after TCA_POLICE_PAD in pkt_cls.h header to be consistent with kernel's pkt_cls.h header. --- include/uapi/linux/pkt_cls.h |2 + tc/m_police.c| 64 +++-- tc/tc_core.c | 29 +++ tc/tc_core.h |3 ++ 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index b057aee..a6aa466 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -160,6 +160,8 @@ enum { TCA_POLICE_RESULT, TCA_POLICE_TM, TCA_POLICE_PAD, + TCA_POLICE_RATE64, + TCA_POLICE_PEAKRATE64, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT }; diff --git a/tc/m_police.c b/tc/m_police.c index 862a39f..db913f4 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -71,6 +71,7 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */ int Rcell_log = -1, Pcell_log = -1; struct rtattr *tail; + __u64 rate64 = 0, prate64 = 0; if (a) /* new way of doing things */ NEXT_ARG(); @@ -121,11 +122,11 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, } } else if (strcmp(*argv, "rate") == 0) { NEXT_ARG(); - if (p.rate.rate) { + if (rate64) { fprintf(stderr, "Double \"rate\" spec\n"); return -1; } - if (get_rate(, *argv)) { + if (get_rate64(, *argv)) { explain1("rate"); return -1; } @@ -141,11 +142,11 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, } } else if (matches(*argv, "peakrate") == 0) { NEXT_ARG(); - if (p.peakrate.rate) { + if (prate64) { fprintf(stderr, "Double \"peakrate\" spec\n"); return -1; } - if (get_rate(, *argv)) { + if (get_rate64(, *argv)) { explain1("peakrate"); return -1; } @@ -189,23 +190,23 @@ action_ctrl_ok: if (!ok) return -1; - if (p.rate.rate && avrate) + if (rate64 && avrate) return -1; /* Must at least do late binding, use TB or ewma policing */ - if (!p.rate.rate && !avrate && !p.index) { + if (!rate64 && !avrate && !p.index) { fprintf(stderr, "\"rate\" or \"avrate\" MUST be specified.\n"); return -1; } /* When the TB policer is used, burst is required */ - if (p.rate.rate && !buffer && !avrate) { + if (rate64 && !buffer && !avrate) { fprintf(stderr, "\"burst\" requires \"rate\".\n"); return -1; } - if (p.peakrate.rate) { - if (!p.rate.rate) { + if (prate64) { + if (!rate64) { fprintf(stderr, "\"peakrate\" requires \"rate\".\n"); return -1; } @@ -215,22 +216,24 @@ action_ctrl_ok: } } - if (p.rate.rate) { + if (rate64) { + p.rate.rate = (rate64 >= (1ULL << 32)) ? ~0U : rate64; p.rate.mpu = mpu; p.rate.overhead = overhead; - if (tc_calc_rtable(, rtab, Rcell_log, mtu, - linklayer) < 0) { + if (tc_calc_rtable_64(, rtab, Rcell_log, mtu, + linklayer, rate64) <
[v2] net_sched: act_police: add 2 new attributes to support police 64bit rate and peakrate
For high speed adapter like Mellanox CX-5 card, it can reach upto 100 Gbits per second bandwidth. Currently htb already supports 64bit rate in tc utility. However police action rate and peakrate are still limited to 32bit value (upto 32 Gbits per second). Add 2 new attributes TCA_POLICE_RATE64 and TCA_POLICE_RATE64 in kernel for 64bit support so that tc utility can use them for 64bit rate and peakrate value to break the 32bit limit, and still keep the backward binary compatibility. Tested-by: David Dai Signed-off-by: David Dai --- Changelog: v1->v2: - Move 2 attributes TCA_POLICE_RATE64 TCA_POLICE_PEAKRATE64 after TCA_POLICE_PAD in pkt_cls.h header. --- include/uapi/linux/pkt_cls.h |2 ++ net/sched/act_police.c | 27 +++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index b057aee..a6aa466 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -160,6 +160,8 @@ enum { TCA_POLICE_RESULT, TCA_POLICE_TM, TCA_POLICE_PAD, + TCA_POLICE_RATE64, + TCA_POLICE_PEAKRATE64, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT }; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 49cec3e..425f2a3 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -40,6 +40,8 @@ static int tcf_police_walker(struct net *net, struct sk_buff *skb, [TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE }, [TCA_POLICE_AVRATE] = { .type = NLA_U32 }, [TCA_POLICE_RESULT] = { .type = NLA_U32 }, + [TCA_POLICE_RATE64] = { .type = NLA_U64 }, + [TCA_POLICE_PEAKRATE64] = { .type = NLA_U64 }, }; static int tcf_police_init(struct net *net, struct nlattr *nla, @@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, struct tcf_police_params *new; bool exists = false; u32 index; + u64 rate64, prate64; if (nla == NULL) return -EINVAL; @@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, } if (R_tab) { new->rate_present = true; - psched_ratecfg_precompute(>rate, _tab->rate, 0); + rate64 = tb[TCA_POLICE_RATE64] ? +nla_get_u64(tb[TCA_POLICE_RATE64]) : 0; + psched_ratecfg_precompute(>rate, _tab->rate, rate64); qdisc_put_rtab(R_tab); } else { new->rate_present = false; } if (P_tab) { new->peak_present = true; - psched_ratecfg_precompute(>peak, _tab->rate, 0); + prate64 = tb[TCA_POLICE_PEAKRATE64] ? + nla_get_u64(tb[TCA_POLICE_PEAKRATE64]) : 0; + psched_ratecfg_precompute(>peak, _tab->rate, prate64); qdisc_put_rtab(P_tab); } else { new->peak_present = false; @@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a, lockdep_is_held(>tcf_lock)); opt.mtu = p->tcfp_mtu; opt.burst = PSCHED_NS2TICKS(p->tcfp_burst); - if (p->rate_present) + if (p->rate_present) { psched_ratecfg_getrate(, >rate); - if (p->peak_present) + if ((police->params->rate.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_RATE64, + police->params->rate.rate_bytes_ps, + __TCA_POLICE_MAX)) + goto nla_put_failure; + } + if (p->peak_present) { psched_ratecfg_getrate(, >peak); + if ((police->params->peak.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_PEAKRATE64, + police->params->peak.rate_bytes_ps, + __TCA_POLICE_MAX)) + goto nla_put_failure; + } if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), )) goto nla_put_failure; if (p->tcfp_result && -- 1.7.1
[v1] iproute2: police: support 64bit rate and peakrate in tc utility
For high speed adapter like Mellanox CX-5 card, it can reach upto 100 Gbits per second bandwidth. Currently htb already supports 64bit rate in tc utility. However police action rate and peakrate are still limited to 32bit value (upto 32 Gbits per second). Taking advantage of the 2 new attributes TCA_POLICE_RATE64 and TCA_POLICE_PEAKRATE64 from kernel, tc can use them to break the 32bit limit, and still keep the backward binary compatibility. Tested-by: David Dai Signed-off-by: David Dai --- include/uapi/linux/pkt_cls.h |2 + tc/m_police.c| 64 +++-- tc/tc_core.c | 29 +++ tc/tc_core.h |3 ++ 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index b057aee..eb4ea4d 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -159,6 +159,8 @@ enum { TCA_POLICE_AVRATE, TCA_POLICE_RESULT, TCA_POLICE_TM, + TCA_POLICE_RATE64, + TCA_POLICE_PEAKRATE64, TCA_POLICE_PAD, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT diff --git a/tc/m_police.c b/tc/m_police.c index 862a39f..abdbcce 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -71,6 +71,7 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */ int Rcell_log = -1, Pcell_log = -1; struct rtattr *tail; + __u64 rate64 = 0, prate64 = 0; if (a) /* new way of doing things */ NEXT_ARG(); @@ -121,11 +122,11 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, } } else if (strcmp(*argv, "rate") == 0) { NEXT_ARG(); - if (p.rate.rate) { + if (rate64) { fprintf(stderr, "Double \"rate\" spec\n"); return -1; } - if (get_rate(, *argv)) { + if (get_rate64(, *argv)) { explain1("rate"); return -1; } @@ -141,11 +142,11 @@ static int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, } } else if (matches(*argv, "peakrate") == 0) { NEXT_ARG(); - if (p.peakrate.rate) { + if (prate64) { fprintf(stderr, "Double \"peakrate\" spec\n"); return -1; } - if (get_rate(, *argv)) { + if (get_rate64(, *argv)) { explain1("peakrate"); return -1; } @@ -189,23 +190,23 @@ action_ctrl_ok: if (!ok) return -1; - if (p.rate.rate && avrate) + if (rate64 && avrate) return -1; /* Must at least do late binding, use TB or ewma policing */ - if (!p.rate.rate && !avrate && !p.index) { + if (!rate64 && !avrate && !p.index) { fprintf(stderr, "\"rate\" or \"avrate\" MUST be specified.\n"); return -1; } /* When the TB policer is used, burst is required */ - if (p.rate.rate && !buffer && !avrate) { + if (rate64 && !buffer && !avrate) { fprintf(stderr, "\"burst\" requires \"rate\".\n"); return -1; } - if (p.peakrate.rate) { - if (!p.rate.rate) { + if (prate64) { + if (!rate64) { fprintf(stderr, "\"peakrate\" requires \"rate\".\n"); return -1; } @@ -215,22 +216,24 @@ action_ctrl_ok: } } - if (p.rate.rate) { + if (rate64) { + p.rate.rate = (rate64 >= (1ULL << 32)) ? ~0U : rate64; p.rate.mpu = mpu; p.rate.overhead = overhead; - if (tc_calc_rtable(, rtab, Rcell_log, mtu, - linklayer) < 0) { + if (tc_calc_rtable_64(, rtab, Rcell_log, mtu, + linklayer, rate64) < 0) { fprintf(stderr, "POLICE: failed to calculate rate table.\n"); return -1; } - p.burst = tc_calc_xmittime(p.rate.rate, buffer); + p.bu
[v1] net_sched: act_police: add 2 new attributes to support police 64bit rate and peakrate
For high speed adapter like Mellanox CX-5 card, it can reach upto 100 Gbits per second bandwidth. Currently htb already supports 64bit rate in tc utility. However police action rate and peakrate are still limited to 32bit value (upto 32 Gbits per second). Add 2 new attributes TCA_POLICE_RATE64 and TCA_POLICE_RATE64 in kernel for 64bit support so that tc utility can use them for 64bit rate and peakrate value to break the 32bit limit, and still keep the backward binary compatibility. Tested-by: David Dai Signed-off-by: David Dai --- include/uapi/linux/pkt_cls.h |2 ++ net/sched/act_police.c | 27 +++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index b057aee..eb4ea4d 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -159,6 +159,8 @@ enum { TCA_POLICE_AVRATE, TCA_POLICE_RESULT, TCA_POLICE_TM, + TCA_POLICE_RATE64, + TCA_POLICE_PEAKRATE64, TCA_POLICE_PAD, __TCA_POLICE_MAX #define TCA_POLICE_RESULT TCA_POLICE_RESULT diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 49cec3e..ed5372e 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -40,6 +40,8 @@ static int tcf_police_walker(struct net *net, struct sk_buff *skb, [TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE }, [TCA_POLICE_AVRATE] = { .type = NLA_U32 }, [TCA_POLICE_RESULT] = { .type = NLA_U32 }, + [TCA_POLICE_RATE64] = { .type = NLA_U64 }, + [TCA_POLICE_PEAKRATE64] = { .type = NLA_U64 }, }; static int tcf_police_init(struct net *net, struct nlattr *nla, @@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, struct tcf_police_params *new; bool exists = false; u32 index; + u64 rate64, prate64; if (nla == NULL) return -EINVAL; @@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, } if (R_tab) { new->rate_present = true; - psched_ratecfg_precompute(>rate, _tab->rate, 0); + rate64 = tb[TCA_POLICE_RATE64] ? +nla_get_u64(tb[TCA_POLICE_RATE64]) : 0; + psched_ratecfg_precompute(>rate, _tab->rate, rate64); qdisc_put_rtab(R_tab); } else { new->rate_present = false; } if (P_tab) { new->peak_present = true; - psched_ratecfg_precompute(>peak, _tab->rate, 0); + prate64 = tb[TCA_POLICE_PEAKRATE64] ? + nla_get_u64(tb[TCA_POLICE_PEAKRATE64]) : 0; + psched_ratecfg_precompute(>peak, _tab->rate, prate64); qdisc_put_rtab(P_tab); } else { new->peak_present = false; @@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a, lockdep_is_held(>tcf_lock)); opt.mtu = p->tcfp_mtu; opt.burst = PSCHED_NS2TICKS(p->tcfp_burst); - if (p->rate_present) + if (p->rate_present) { psched_ratecfg_getrate(, >rate); - if (p->peak_present) + if ((police->params->rate.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_RATE64, + police->params->rate.rate_bytes_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + } + if (p->peak_present) { psched_ratecfg_getrate(, >peak); + if ((police->params->peak.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_PEAKRATE64, + police->params->peak.rate_bytes_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + } if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), )) goto nla_put_failure; if (p->tcfp_result && -- 1.7.1
Re: [PATCH v2 2/2] interconnect: qcom: Add tagging and wake/sleep support for sdm845
On 7/30/2019 3:54 PM, Evan Green wrote: On Thu, Jul 18, 2019 at 10:59 AM David Dai wrote: On 7/16/2019 1:15 PM, Evan Green wrote: On Mon, Jul 15, 2019 at 4:34 PM David Dai wrote: Hi Evan, Thanks for the continued help in reviewing these patches! No problem. I want to do more, but haven't found time to do the prerequisite research before jumping into some of the other discussions yet. On 7/11/2019 10:06 AM, Evan Green wrote: Hi Georgi and David, On Tue, Jun 18, 2019 at 2:17 AM Georgi Djakov wrote: From: David Dai Add support for wake and sleep commands by using a tag to indicate whether or not the aggregate and set requests fall into execution state specific bucket. Signed-off-by: David Dai Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sdm845.c | 129 ++--- 1 file changed, 98 insertions(+), 31 deletions(-) diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index fb526004c82e..c100aab39415 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -66,6 +66,17 @@ struct bcm_db { #define SDM845_MAX_BCM_PER_NODE2 #define SDM845_MAX_VCD 10 +#define QCOM_ICC_BUCKET_AMC0 What is AMC again? Is it the "right now" bucket? Maybe a comment on the meaning of this bucket would be helpful. That's correct. Will add a comment for this. +#define QCOM_ICC_BUCKET_WAKE 1 +#define QCOM_ICC_BUCKET_SLEEP 2 +#define QCOM_ICC_NUM_BUCKETS 3 +#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC) +#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE) +#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP) +#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) +#define QCOM_ICC_TAG_ALWAYS(QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ +QCOM_ICC_TAG_SLEEP) + /** * struct qcom_icc_node - Qualcomm specific interconnect nodes * @name: the node name used in debugfs @@ -75,7 +86,9 @@ struct bcm_db { * @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 + * @sum_avg_cached: previous sum aggregate value of all avg bw requests * @max_peak: current max aggregate value of all peak bw requests + * @max_peak_cached: previous max aggregate value of all peak bw requests * @bcms: list of bcms associated with this logical node * @num_bcms: num of @bcms */ @@ -86,8 +99,10 @@ struct qcom_icc_node { u16 num_links; u16 channels; u16 buswidth; - u64 sum_avg; - u64 max_peak; + u64 sum_avg[QCOM_ICC_NUM_BUCKETS]; + u64 sum_avg_cached[QCOM_ICC_NUM_BUCKETS]; + u64 max_peak[QCOM_ICC_NUM_BUCKETS]; + u64 max_peak_cached[QCOM_ICC_NUM_BUCKETS]; struct qcom_icc_bcm *bcms[SDM845_MAX_BCM_PER_NODE]; size_t num_bcms; }; @@ -112,8 +127,8 @@ struct qcom_icc_bcm { const char *name; u32 type; u32 addr; - u64 vote_x; - u64 vote_y; + u64 vote_x[QCOM_ICC_NUM_BUCKETS]; + u64 vote_y[QCOM_ICC_NUM_BUCKETS]; bool dirty; bool keepalive; struct bcm_db aux_data; @@ -555,7 +570,7 @@ inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y, cmd->wait = true; } -static void tcs_list_gen(struct list_head *bcm_list, +static void tcs_list_gen(struct list_head *bcm_list, int bucket, struct tcs_cmd tcs_list[SDM845_MAX_VCD], int n[SDM845_MAX_VCD]) { @@ -573,8 +588,8 @@ static void tcs_list_gen(struct list_head *bcm_list, commit = true; cur_vcd_size = 0; } - tcs_cmd_gen(_list[idx], bcm->vote_x, bcm->vote_y, - bcm->addr, commit); + tcs_cmd_gen(_list[idx], bcm->vote_x[bucket], + bcm->vote_y[bucket], bcm->addr, commit); idx++; n[batch]++; /* @@ -595,32 +610,39 @@ static void tcs_list_gen(struct list_head *bcm_list, static void bcm_aggregate(struct qcom_icc_bcm *bcm) { - size_t i; - u64 agg_avg = 0; - u64 agg_peak = 0; + size_t i, bucket; + u64 agg_avg[QCOM_ICC_NUM_BUCKETS] = {0}; + u64 agg_peak[QCOM_ICC_NUM_BUCKETS] = {0}; u64 temp; - for (i = 0; i < bcm->num_nodes; i++) { - temp = bcm->nodes[i]->sum_avg * bcm->aux_data.width; - do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels); - agg_avg = max(agg_avg, temp); + for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS;
Re: [PATCH 1/2] dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings
On 7/24/2019 11:27 AM, Stephen Boyd wrote: Quoting David Dai (2019-07-24 10:22:57) The way that I view this is that the consumers consume both bandwidth and QoS from these physical NoC devices by getting some path between two endpoints on these different NoCs and applying some constraints. The NoC providers can accomplish that either by writing to MMIO spaces or by talking to some remote processor/hardware to tune its clock speed. The consumer doesn't interact with the RSCs directly, but can select a different bcm voter based on the endpoints that are associated with a particular bcm(apps or disp rsc). Each node(endpoints) will have its own BCM designation and an unique bcm voter. Ok. I get it now. The MMIO nodes will be interconnect providers and they'll know what RSCs they can use by exposing the same RSC "resource" multiple times for each RSC that can be targeted? This is what the postfix is with _DISP on your examples? Presumably there's an _APPS version of the same prefixed endpoint in case the consumer wants to use the APPS RSC instead of the DISP one, or maybe there's just no postfix in this case because APPS is the "default". Right, the suffixes will denote the RSC association and will default to APPS otherwise. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH 1/2] dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings
On 7/24/2019 7:18 AM, Stephen Boyd wrote: Quoting David Dai (2019-07-23 14:48:42) On 7/23/2019 7:42 AM, Stephen Boyd wrote: Quoting David Dai (2019-07-19 13:32:23) +- compatible : shall contain only one of the following: + "qcom,sdm845-bcm-voter", + +Examples: + +apps_rsc: rsc@179c { But there isn't a reg property. I'll change this to the generic example with just apps_rsc: rsc { + label = "apps_rsc"; Is label required? Any answer? Not required. + compatible = "qcom,rpmh-rsc"; + + apps_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; + }; +} + +disp_rsc: rsc@179d { + label = "disp_rsc"; + compatible = "qcom,rpmh-rsc"; + + disp_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; + }; +} diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt index 5c4f1d9..27f9ed9 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt [...] + +mem_noc: interconnect@138 { + compatible = "qcom,sdm845-mem_noc"; + reg = <0 0x138 0 0x27200>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>, <_bcm_voter>; +}; How does a consumer target a particular RSC? For example, how can display decide to use the disp_bcm_voter node from mem_noc here? Maybe you can add that consumer to the example? I was thinking that the association between the bcm voters and the icc nodes would be handled by the interconnect provider, and that there would be a set of display specific icc nodes with their own unique IDs that the consumers could reference. I will mention this as part of the description and provide an example. Ex: interconnects = <_noc MASTER_MDP0_DISP _noc SLAVE_EBI_DISP>; It looks backwards to me. Don't the consumers want to consume a particular RSC, i.e. apps or display RSC, so they can choose where to put the bcm vote and then those RSCs want to find MMIO registers for mmss_noc or mem_noc that they have to write to tune something else like QoS? If the MMIO space is the provider then I'm lost how it can differentiate between the RSCs that may be targetting the particular NoC. The way that I view this is that the consumers consume both bandwidth and QoS from these physical NoC devices by getting some path between two endpoints on these different NoCs and applying some constraints. The NoC providers can accomplish that either by writing to MMIO spaces or by talking to some remote processor/hardware to tune its clock speed. The consumer doesn't interact with the RSCs directly, but can select a different bcm voter based on the endpoints that are associated with a particular bcm(apps or disp rsc). Each node(endpoints) will have its own BCM designation and an unique bcm voter. Maybe I've just completely missed something and this is all decided already. If so, sorry, I'm just trying to understand. No problem, this just means I need to do a better job of explaining. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH 1/2] dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings
Thanks for the feedback Stephen, much appreciated! On 7/23/2019 7:42 AM, Stephen Boyd wrote: Quoting David Dai (2019-07-19 13:32:23) Redefine the Network-on-Chip devices to more accurately describe the interconnect topology on Qualcomm's SDM845 platform. Each interconnect device can communicate with different instances of the RPMh hardware which are described as RSCs(Resource State Coordinators). Signed-off-by: David Dai --- diff --git a/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt b/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt new file mode 100644 index 000..2cf7da2 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt @@ -0,0 +1,32 @@ +Qualcomm BCM-Voter interconnect driver binding +--- + +The Bus Clock Manager (BCM) is a dedicated hardware accelerator +that manages shared system resources by aggregating requests +from multiple Resource State Coordinators (RSC). Interconnect +providers are able to vote for aggregated thresholds values from +consumers by communicating through their respective RSCs. + +Required properties : +- compatible : shall contain only one of the following: + "qcom,sdm845-bcm-voter", + +Examples: + +apps_rsc: rsc@179c { But there isn't a reg property. I'll change this to the generic example with just apps_rsc: rsc { + label = "apps_rsc"; Is label required? + compatible = "qcom,rpmh-rsc"; + + apps_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; + }; +} + +disp_rsc: rsc@179d { + label = "disp_rsc"; + compatible = "qcom,rpmh-rsc"; + + disp_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; + }; +} diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt index 5c4f1d9..27f9ed9 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt @@ -4,21 +4,43 @@ 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. +associated with each execution environment. Provider nodes must point to at +least one RPMh device child node pertaining to their RSC and each provider +can map to multiple RPMh resources. Required properties : - compatible : shall contain only one of the following: - "qcom,sdm845-rsc-hlos" + "qcom,sdm845-aggre1_noc", + "qcom,sdm845-aggre2_noc", + "qcom,sdm845-config_noc", + "qcom,sdm845-dc_noc", + "qcom,sdm845-gladiator_noc", + "qcom,sdm845-mem_noc", + "qcom,sdm845-mmss_noc", + "qcom,sdm845-system_noc", - #interconnect-cells : should contain 1 +- reg : shall contain base register location and length +- qcom,bcm-voter : shall contain phandles to bcm voters Examples: -apps_rsc: rsc { - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; - }; +aggre1_noc: interconnect@16e { + compatible = "qcom,sdm845-aggre1_noc"; + reg = <0x16e 0xd080>; + interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; }; +mmss_noc: interconnect@174 { + compatible = "qcom,sdm845-mmss_noc"; + reg = <0x174 0x1c1000>; + interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>, <_bcm_voter>; +}; + +mem_noc: interconnect@138 { + compatible = "qcom,sdm845-mem_noc"; + reg = <0 0x138 0 0x27200>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>, <_bcm_voter>; +}; How does a consumer target a particular RSC? For example, how can display decide to use the disp_bcm_voter node from mem_noc here? Maybe you can add that consumer to the example? I was thinking that the association between the bcm voters and the icc nodes would be handled by the interconnect provider, and that there would be a set of display specific icc nodes with their own unique IDs that the consumers could reference. I will mention this as part of the description and provide an example. Ex: interconnects = <_noc MASTER_MDP0_DISP _noc SLAVE_EBI_DISP>; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH 2/2] arm64: dts: sdm845: Redefine interconnect provider DT nodes
Thanks for looking over this, Bjorn. On 7/21/2019 12:13 PM, Bjorn Andersson wrote: On Fri 19 Jul 13:32 PDT 2019, David Dai wrote: Add the DT nodes for each of the Network-On-Chip interconnect buses found on SDM845 based platform and redefine the rsc_hlos child node as a bcm-voter device to better represent the hardware. Signed-off-by: David Dai --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 61 ++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index e7d78bc..204222e 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -610,6 +610,62 @@ #power-domain-cells = <1>; }; + aggre1_noc: interconnect@16e { + compatible = "qcom,sdm845-aggre1_noc"; + reg = <0 0x16e 0 0xd080>; Please pad the address to 8 digits and keep nodes sorted by address. Will fix. + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + aggre2_noc: interconnect@170 { + compatible = "qcom,sdm845-aggre2_noc"; + reg = <0 0x170 0 0x3b100>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + config_noc: interconnect@150 { + compatible = "qcom,sdm845-config_noc"; + reg = <0 0x150 0 0x5080>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; [..] qfprom@784000 { compatible = "qcom,qfprom"; reg = <0 0x00784000 0 0x8ff>; @@ -2801,9 +2857,8 @@ }; }; - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; + apps_bcm_voter: bcm_voter { No '_' in node names, so bcm-voter. Ok. Apart from this nits this looks good. Regards, Bjorn + compatible = "qcom,sdm845-bcm-voter"; }; }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 2/2] arm64: dts: sdm845: Redefine interconnect provider DT nodes
Add the DT nodes for each of the Network-On-Chip interconnect buses found on SDM845 based platform and redefine the rsc_hlos child node as a bcm-voter device to better represent the hardware. Signed-off-by: David Dai --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 61 ++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index e7d78bc..204222e 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -610,6 +610,62 @@ #power-domain-cells = <1>; }; + aggre1_noc: interconnect@16e { + compatible = "qcom,sdm845-aggre1_noc"; + reg = <0 0x16e 0 0xd080>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + aggre2_noc: interconnect@170 { + compatible = "qcom,sdm845-aggre2_noc"; + reg = <0 0x170 0 0x3b100>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + config_noc: interconnect@150 { + compatible = "qcom,sdm845-config_noc"; + reg = <0 0x150 0 0x5080>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + dc_noc: interconnect@14e { + compatible = "qcom,sdm845-dc_noc"; + reg = <0 0x14e 0 0x400>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + gladiator_noc: interconnect@1790 { + compatible = "qcom,sdm845-gladiator_noc"; + reg = <0 0x1790 0 0xd080>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + mem_noc: interconnect@138 { + compatible = "qcom,sdm845-mem_noc"; + reg = <0 0x138 0 0x27200>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + mmss_noc: interconnect@174 { + compatible = "qcom,sdm845-mmss_noc"; + reg = <0 0x174 0 0x1c1000>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + + system_noc: interconnect@162 { + compatible = "qcom,sdm845-system_noc"; + reg = <0 0x162 0 0x18080>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; + }; + qfprom@784000 { compatible = "qcom,qfprom"; reg = <0 0x00784000 0 0x8ff>; @@ -2801,9 +2857,8 @@ }; }; - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; + apps_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; }; }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 0/2] Redefine interconnect provider DT nodes for SDM845
Redefine the SDM845 interconnect device nodes as the previous definitions of using a single child node under the apps_rsc device did not accurately capture the description of the hardware. The Network-On-Chip (NoC) interconnect devices should be represented in a manner akin to QCS404 platforms[1] where there is a separation of NoC devices and its RPM/RPMh counterparts. The bcm-voter devices are representing the RPMh devices that the interconnect providers need to communicate with and there can be more than one instance of the Bus Clock Manager (BCM) which can live under different instances of Resource State Coordinators (RSC). There are display use cases where consumers may need to target a different bcm-voter (Some display specific RSC) than the default, and there needs to be a way to represent this connection in devicetree. [1]: https://lkml.org/lkml/2019/6/13/143 David Dai (2): dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings arm64: dts: sdm845: Redefine interconnect provider DT nodes .../bindings/interconnect/qcom,bcm-voter.txt | 32 .../bindings/interconnect/qcom,sdm845.txt | 40 ++ arch/arm64/boot/dts/qcom/sdm845.dtsi | 61 -- 3 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 1/2] dt-bindings: interconnect: Update Qualcomm SDM845 DT bindings
Redefine the Network-on-Chip devices to more accurately describe the interconnect topology on Qualcomm's SDM845 platform. Each interconnect device can communicate with different instances of the RPMh hardware which are described as RSCs(Resource State Coordinators). Signed-off-by: David Dai --- .../bindings/interconnect/qcom,bcm-voter.txt | 32 + .../bindings/interconnect/qcom,sdm845.txt | 40 +- 2 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt diff --git a/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt b/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt new file mode 100644 index 000..2cf7da2 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,bcm-voter.txt @@ -0,0 +1,32 @@ +Qualcomm BCM-Voter interconnect driver binding +--- + +The Bus Clock Manager (BCM) is a dedicated hardware accelerator +that manages shared system resources by aggregating requests +from multiple Resource State Coordinators (RSC). Interconnect +providers are able to vote for aggregated thresholds values from +consumers by communicating through their respective RSCs. + +Required properties : +- compatible : shall contain only one of the following: + "qcom,sdm845-bcm-voter", + +Examples: + +apps_rsc: rsc@179c { + label = "apps_rsc"; + compatible = "qcom,rpmh-rsc"; + + apps_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; + }; +} + +disp_rsc: rsc@179d { + label = "disp_rsc"; + compatible = "qcom,rpmh-rsc"; + + disp_bcm_voter: bcm_voter { + compatible = "qcom,sdm845-bcm-voter"; + }; +} diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt index 5c4f1d9..27f9ed9 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt @@ -4,21 +4,43 @@ 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. +associated with each execution environment. Provider nodes must point to at +least one RPMh device child node pertaining to their RSC and each provider +can map to multiple RPMh resources. Required properties : - compatible : shall contain only one of the following: - "qcom,sdm845-rsc-hlos" + "qcom,sdm845-aggre1_noc", + "qcom,sdm845-aggre2_noc", + "qcom,sdm845-config_noc", + "qcom,sdm845-dc_noc", + "qcom,sdm845-gladiator_noc", + "qcom,sdm845-mem_noc", + "qcom,sdm845-mmss_noc", + "qcom,sdm845-system_noc", - #interconnect-cells : should contain 1 +- reg : shall contain base register location and length +- qcom,bcm-voter : shall contain phandles to bcm voters Examples: -apps_rsc: rsc { - rsc_hlos: interconnect { - compatible = "qcom,sdm845-rsc-hlos"; - #interconnect-cells = <1>; - }; +aggre1_noc: interconnect@16e { + compatible = "qcom,sdm845-aggre1_noc"; + reg = <0x16e 0xd080>; + interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>; }; +mmss_noc: interconnect@174 { + compatible = "qcom,sdm845-mmss_noc"; + reg = <0x174 0x1c1000>; + interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>, <_bcm_voter>; +}; + +mem_noc: interconnect@138 { + compatible = "qcom,sdm845-mem_noc"; + reg = <0 0x138 0 0x27200>; + #interconnect-cells = <1>; + qcom,bcm-voter = <_bcm_voter>, <_bcm_voter>; +}; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v2 2/2] interconnect: qcom: Add tagging and wake/sleep support for sdm845
On 7/16/2019 1:15 PM, Evan Green wrote: On Mon, Jul 15, 2019 at 4:34 PM David Dai wrote: Hi Evan, Thanks for the continued help in reviewing these patches! No problem. I want to do more, but haven't found time to do the prerequisite research before jumping into some of the other discussions yet. On 7/11/2019 10:06 AM, Evan Green wrote: Hi Georgi and David, On Tue, Jun 18, 2019 at 2:17 AM Georgi Djakov wrote: From: David Dai Add support for wake and sleep commands by using a tag to indicate whether or not the aggregate and set requests fall into execution state specific bucket. Signed-off-by: David Dai Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sdm845.c | 129 ++--- 1 file changed, 98 insertions(+), 31 deletions(-) diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index fb526004c82e..c100aab39415 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -66,6 +66,17 @@ struct bcm_db { #define SDM845_MAX_BCM_PER_NODE2 #define SDM845_MAX_VCD 10 +#define QCOM_ICC_BUCKET_AMC0 What is AMC again? Is it the "right now" bucket? Maybe a comment on the meaning of this bucket would be helpful. That's correct. Will add a comment for this. +#define QCOM_ICC_BUCKET_WAKE 1 +#define QCOM_ICC_BUCKET_SLEEP 2 +#define QCOM_ICC_NUM_BUCKETS 3 +#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC) +#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE) +#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP) +#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) +#define QCOM_ICC_TAG_ALWAYS(QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ +QCOM_ICC_TAG_SLEEP) + /** * struct qcom_icc_node - Qualcomm specific interconnect nodes * @name: the node name used in debugfs @@ -75,7 +86,9 @@ struct bcm_db { * @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 + * @sum_avg_cached: previous sum aggregate value of all avg bw requests * @max_peak: current max aggregate value of all peak bw requests + * @max_peak_cached: previous max aggregate value of all peak bw requests * @bcms: list of bcms associated with this logical node * @num_bcms: num of @bcms */ @@ -86,8 +99,10 @@ struct qcom_icc_node { u16 num_links; u16 channels; u16 buswidth; - u64 sum_avg; - u64 max_peak; + u64 sum_avg[QCOM_ICC_NUM_BUCKETS]; + u64 sum_avg_cached[QCOM_ICC_NUM_BUCKETS]; + u64 max_peak[QCOM_ICC_NUM_BUCKETS]; + u64 max_peak_cached[QCOM_ICC_NUM_BUCKETS]; struct qcom_icc_bcm *bcms[SDM845_MAX_BCM_PER_NODE]; size_t num_bcms; }; @@ -112,8 +127,8 @@ struct qcom_icc_bcm { const char *name; u32 type; u32 addr; - u64 vote_x; - u64 vote_y; + u64 vote_x[QCOM_ICC_NUM_BUCKETS]; + u64 vote_y[QCOM_ICC_NUM_BUCKETS]; bool dirty; bool keepalive; struct bcm_db aux_data; @@ -555,7 +570,7 @@ inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y, cmd->wait = true; } -static void tcs_list_gen(struct list_head *bcm_list, +static void tcs_list_gen(struct list_head *bcm_list, int bucket, struct tcs_cmd tcs_list[SDM845_MAX_VCD], int n[SDM845_MAX_VCD]) { @@ -573,8 +588,8 @@ static void tcs_list_gen(struct list_head *bcm_list, commit = true; cur_vcd_size = 0; } - tcs_cmd_gen(_list[idx], bcm->vote_x, bcm->vote_y, - bcm->addr, commit); + tcs_cmd_gen(_list[idx], bcm->vote_x[bucket], + bcm->vote_y[bucket], bcm->addr, commit); idx++; n[batch]++; /* @@ -595,32 +610,39 @@ static void tcs_list_gen(struct list_head *bcm_list, static void bcm_aggregate(struct qcom_icc_bcm *bcm) { - size_t i; - u64 agg_avg = 0; - u64 agg_peak = 0; + size_t i, bucket; + u64 agg_avg[QCOM_ICC_NUM_BUCKETS] = {0}; + u64 agg_peak[QCOM_ICC_NUM_BUCKETS] = {0}; u64 temp; - for (i = 0; i < bcm->num_nodes; i++) { - temp = bcm->nodes[i]->sum_avg * bcm->aux_data.width; - do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels); - agg_avg = max(agg_avg, temp); + for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) { + for (i = 0; i < bcm->num_nodes; i++) { + temp = bcm->nodes[i]->sum_avg_cached[bucket]
Re: [PATCH v2 2/2] interconnect: qcom: Add tagging and wake/sleep support for sdm845
Hi Evan, Thanks for the continued help in reviewing these patches! On 7/11/2019 10:06 AM, Evan Green wrote: Hi Georgi and David, On Tue, Jun 18, 2019 at 2:17 AM Georgi Djakov wrote: From: David Dai Add support for wake and sleep commands by using a tag to indicate whether or not the aggregate and set requests fall into execution state specific bucket. Signed-off-by: David Dai Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sdm845.c | 129 ++--- 1 file changed, 98 insertions(+), 31 deletions(-) diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index fb526004c82e..c100aab39415 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -66,6 +66,17 @@ struct bcm_db { #define SDM845_MAX_BCM_PER_NODE2 #define SDM845_MAX_VCD 10 +#define QCOM_ICC_BUCKET_AMC0 What is AMC again? Is it the "right now" bucket? Maybe a comment on the meaning of this bucket would be helpful. That's correct. Will add a comment for this. +#define QCOM_ICC_BUCKET_WAKE 1 +#define QCOM_ICC_BUCKET_SLEEP 2 +#define QCOM_ICC_NUM_BUCKETS 3 +#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC) +#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE) +#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP) +#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) +#define QCOM_ICC_TAG_ALWAYS(QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ +QCOM_ICC_TAG_SLEEP) + /** * struct qcom_icc_node - Qualcomm specific interconnect nodes * @name: the node name used in debugfs @@ -75,7 +86,9 @@ struct bcm_db { * @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 + * @sum_avg_cached: previous sum aggregate value of all avg bw requests * @max_peak: current max aggregate value of all peak bw requests + * @max_peak_cached: previous max aggregate value of all peak bw requests * @bcms: list of bcms associated with this logical node * @num_bcms: num of @bcms */ @@ -86,8 +99,10 @@ struct qcom_icc_node { u16 num_links; u16 channels; u16 buswidth; - u64 sum_avg; - u64 max_peak; + u64 sum_avg[QCOM_ICC_NUM_BUCKETS]; + u64 sum_avg_cached[QCOM_ICC_NUM_BUCKETS]; + u64 max_peak[QCOM_ICC_NUM_BUCKETS]; + u64 max_peak_cached[QCOM_ICC_NUM_BUCKETS]; struct qcom_icc_bcm *bcms[SDM845_MAX_BCM_PER_NODE]; size_t num_bcms; }; @@ -112,8 +127,8 @@ struct qcom_icc_bcm { const char *name; u32 type; u32 addr; - u64 vote_x; - u64 vote_y; + u64 vote_x[QCOM_ICC_NUM_BUCKETS]; + u64 vote_y[QCOM_ICC_NUM_BUCKETS]; bool dirty; bool keepalive; struct bcm_db aux_data; @@ -555,7 +570,7 @@ inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y, cmd->wait = true; } -static void tcs_list_gen(struct list_head *bcm_list, +static void tcs_list_gen(struct list_head *bcm_list, int bucket, struct tcs_cmd tcs_list[SDM845_MAX_VCD], int n[SDM845_MAX_VCD]) { @@ -573,8 +588,8 @@ static void tcs_list_gen(struct list_head *bcm_list, commit = true; cur_vcd_size = 0; } - tcs_cmd_gen(_list[idx], bcm->vote_x, bcm->vote_y, - bcm->addr, commit); + tcs_cmd_gen(_list[idx], bcm->vote_x[bucket], + bcm->vote_y[bucket], bcm->addr, commit); idx++; n[batch]++; /* @@ -595,32 +610,39 @@ static void tcs_list_gen(struct list_head *bcm_list, static void bcm_aggregate(struct qcom_icc_bcm *bcm) { - size_t i; - u64 agg_avg = 0; - u64 agg_peak = 0; + size_t i, bucket; + u64 agg_avg[QCOM_ICC_NUM_BUCKETS] = {0}; + u64 agg_peak[QCOM_ICC_NUM_BUCKETS] = {0}; u64 temp; - for (i = 0; i < bcm->num_nodes; i++) { - temp = bcm->nodes[i]->sum_avg * bcm->aux_data.width; - do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels); - agg_avg = max(agg_avg, temp); + for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) { + for (i = 0; i < bcm->num_nodes; i++) { + temp = bcm->nodes[i]->sum_avg_cached[bucket] * bcm->aux_data.width; + do_div(temp, bcm->nodes[i]->buswidth * bcm->nodes[i]->channels); + agg_avg[bucket] = max(agg_avg[bucket], temp); - temp = bcm->nodes[i]->max_peak * bcm->aux_da
Re: [PATCH v1 2/2] interconnect: qcom: Add tagging and wake/sleep support for sdm845
On 3/8/2019 10:35 AM, Evan Green wrote: On Fri, Feb 8, 2019 at 9:22 AM Georgi Djakov wrote: From: David Dai Add support for wake and sleep commands by using a tag to indicate whether or not the aggregate and set requests are active only or dual context for a particular path. Signed-off-by: David Dai Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sdm845.c | 101 + 1 file changed, 75 insertions(+), 26 deletions(-) diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index fb526004c82e..13499f681160 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -65,6 +65,12 @@ struct bcm_db { #define SDM845_MAX_BCMS30 #define SDM845_MAX_BCM_PER_NODE2 #define SDM845_MAX_VCD 10 +#define SDM845_MAX_CTX 2 +#define SDM845_EE_STATE2 +#define EE_STATE_WAKE 0 +#define EE_STATE_SLEEP 1 +#define AO_CTX 0 +#define DUAL_CTX 1 I get really lost with these two sets of numbers here. I think this needs some explanation in the comments. From staring at this what I've understood so far is: 1) Clients pass in a tag that buckets their requests into either AO or DUAL within the node. (Although, the requests all seem to get aggregated together no matter what the tag is, more on that later). 2) During icc_set(), we go through the many-to-many mapping of BCMs to nodes. For each BCM, we aggregate all the nodes it has, bucketed again by AO or DUAL. 3) The actual votes sent to RPMh are in terms of WAKE and SLEEP. 4) The mapping from AO/DUAL to WAKE/SLEEP for a particular BCM is: WAKE = AO+DUAL, SLEEP=DUAL. 5) qcom_icc_set() sends EE_STATE_WAKE stuff to RPMH_ACTIVE_ONLY_STATE. 6) If there's any difference between SLEEP and WAKE, then the EE_STATE_WAKE commands are gathered together and sent to RPMH_WAKE_ONLY_STATE, and all the EE_STATE_SLEEP commands are sent to RPMH_SLEEP_STATE. So ultimately the muxing ends up like RPMH_ACTIVE_ONLY_STATE <-- EE_STATE_WAKE <-- AO+DUAL RPMH_SLEEP_STATE <-- EE_STATE_SLEEP <-- DUAL RPMH_WAKE_ONLY_STATE <-- EE_STATE_WAKE <-- AO+DUAL This muxing explanation is correct, there's also an inherent limitation in this muxing where RPMH_ACTIVE cannot differ from RPMH_WAKE. Why do we need this complicated muxing to happen? Is it because we're trying to avoid requiring drivers to specify three different paths in the simple case, when all they care about is "use this bandwidth all the time"? That's a part of it, I don't have strong justification for this legacy way of supporting wake/sleep, so I'm open to new suggestions. What I think would make more sense would be to use the "tag" as a bitfield instead. So you'd have #define QCOM_ICC_TAG_ACTIVE_ONLY 0x0001 #define QCOM_ICC_TAG_SLEEP 0x0002 #define QCOM_ICC_TAG_WAKE 0x0004 #define QCOM_ICC_TAG_ALL_TIMES (QCOM_ICC_TAG_ACTIVE_ONLY | QCOM_ICC_TAG_SLEEP | QCOM_ICC_TAG_WAKE) Drivers that don't care about sleep/wake sets would just not set a tag, or set a tag of QCOM_ICC_TAG_ALL_TIMES. Then in qcom_icc_aggregate(), you aggregate the same values up to three times, one for each bit they have set. Finally in qcom_icc_set, you can pass the votes directly down in their buckets, without doing a weird mapping from AO/DUAL to SLEEP/WAKE/ACTIVE_ONLY. Works for me, I'd still want to optimize out the WAKE/SLEEP commands that are equal to each other though. The sticky part about this is that now rather than one set of sum/peak values, there are now three independent ones, corresponding to each of the tag bits. It seems like the interconnect core wouldn't want to mandate whether providers use the tag as a bitfield or a value. So the provider would need to keep not only the official set of aggregates that are returned back to the core (probably ACTIVE_ONLY, or maybe a max of the three), but also the two shadow copies internally for SLEEP and WAKE. I would ideally like to return the most accurate current state of the system which may be ACTIVE_ONLY or WAKE. We might also run into some confusion when printing out the summaries for each node. In a case where the votes for WAKE != ACTIVE(assuming one or more multiple consumers are intentionally doing this with multiple paths), the state of system will change depending on whether or not we've completed a sleep cycle(If it's prior to sleep, the ACTIVE_ONLY vote will be accurate, and post waking up the WAKE request will be correct) but this is more of a book keeping concern than anything else, as long as consumers understand that this is the expected behavior. On a side note, I don't like the ACTIVE_ONLY name designation for this which was brought over from the rpmh driver, it really means let's set the current state immediately and it has no association with the execution environment state unlike the other WAKE/SLEEP types. If you organized
[PATCH v2] clk: qcom: clk-rpmh: Add IPA clock support
The clk-rpmh driver only supports on and off RPMh clock resources. Let's extend the driver by adding support for clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). The BCM is a configurable shared resource aggregator that scales performance based on a set of frequency points. The Qualcomm IP Accelerator (IPA) clock is an example of a resource that is managed by the BCM and this a requirement from the IPA driver in order to scale its core clock. Signed-off-by: David Dai --- drivers/clk/qcom/clk-rpmh.c | 146 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 147 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..c3fd632 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,31 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK | \ + ((valid) << BCM_TCS_CMD_VALID_SHIFT) | \ + ((vote & BCM_TCS_CMD_VOTE_MASK) \ + << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ +struct bcm_db { + __le32 unit; + __le16 width; + u8 vcd; + u8 reserved; +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -29,6 +54,7 @@ * @aggr_state:rpmh clock aggregated state * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh * @valid_state_mask: mask to determine the state of the rpmh clock + * @unit: divisor to convert rate to rpmh msg in magnitudes of Khz * @dev: device to which it is attached * @peer: pointer to the clock rpmh sibling */ @@ -42,6 +68,7 @@ struct clk_rpmh { u32 aggr_state; u32 last_sent_aggr_state; u32 valid_state_mask; + u32 unit; struct device *dev; struct clk_rpmh *peer; }; @@ -98,6 +125,17 @@ struct clk_rpmh_desc { __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name,\ CLK_RPMH_VRM_EN_OFFSET, 1, _div) +#define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \ + static struct clk_rpmh _platform##_##_name = { \ + .res_name = _res_name, \ + .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),\ + .div = 1, \ + .hw.init = &(struct clk_init_data){ \ + .ops = _rpmh_bcm_ops, \ + .name = #_name, \ + }, \ + } + static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) { return container_of(_hw, struct clk_rpmh, hw); @@ -210,6 +248,96 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + mutex_lock(_clk_lock); + + cmd_state = 0; + if (enable) { + cmd_state = 1; + if (c->aggr_state) + cmd_state = c->aggr_state; + } + + if (c->last_sent_aggr_state == cmd_state) { + mutex_unlock(_clk_lock); + return 0; + } + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + mutex_unlock(_clk_lock); + return ret; + } + + c->last_sent_aggr_state = cmd_state; + + mutex_unlock(_clk_lock); + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + return clk_rpmh_bcm_send_cmd(c, true); +}; + +static void clk_rpmh_bcm_unprepare(struct clk_
Re: [PATCH v1] clk: qcom: clk-rpmh: Add IPA clock support
On 1/14/2019 8:47 AM, Stephen Boyd wrote: Quoting David Dai (2019-01-11 16:56:14) On 1/9/2019 11:28 AM, Stephen Boyd wrote: Quoting David Dai (2018-12-13 18:35:04) + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK | \ + ((valid) << BCM_TCS_CMD_VALID_SHIFT) | \ + ((cpu_to_le32(vote) & \ Why? Sorry, could you clarify this question? If you're referring to the cpu_to_le32, shouldn't we be explicit about converting endianness even if it might be redundant for this particular qcom platform? Is only the vote part of the message in little endian format and the rest is native CPU endianess? It's very odd to see that jammed in the middle of a bit packing statement like that. Typically the whole u32 would be in one or the other endianness. Also, sparse right complains about this macro and it's usage, so something is wrong. Point taken, I'll leave it out of the macro for now. I think one other problem is that rpmh API doesn't really talk about endianness here and that's busted. So if you want to fix endianness issues that needs to be fixed first. Since a similar macro is being used as part of the interconnect provider driver, I was thinking a better place for this macro might be in the tcs.h as part of the rpmh driver? I could submit a different patch for rpmh that mentions endianness along with this change. @@ -29,6 +54,7 @@ * @aggr_state:rpmh clock aggregated state * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh * @valid_state_mask: mask to determine the state of the rpmh clock + * @aux_data: data specific to the bcm rpmh resource But there isn't aux_data. Is this supposed to be unit? And what is unit going to be? 1000? Supposed to be unit, the value is on the order of Khz. Ok, hopefully the kernel-doc comes out easy to understand. @@ -217,6 +340,7 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); +DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0"); It's really IP0?! What was wrong with IPA? Yeah... convention seems to be 2 letters and then a number for most BCM resources. OK. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1] clk: qcom: clk-rpmh: Add IPA clock support
On 1/9/2019 11:28 AM, Stephen Boyd wrote: Quoting David Dai (2018-12-13 18:35:04) The current clk-rpmh driver only supports on and off RPMh clock resources, let's extend the current driver by add support for clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). The BCM is a configurable shared resource aggregator that scales performance based on a preset of frequency points. The Qualcomm IP Accelerator (IPA) clock is an example of a resource that is managed by the BCM and this a requirement from the IPA driver in order to scale its core clock. Please use this commit text instead: The clk-rpmh driver only supports on and off RPMh clock resources. Let's extend the driver by add support for clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). The BCM is a configurable shared resource aggregator that scales performance based on a set of frequency points. The Qualcomm IP Accelerator (IPA) clock is an example of a resource that is managed by the BCM and this a requirement from the IPA driver in order to scale its core clock. Ok. Signed-off-by: David Dai --- drivers/clk/qcom/clk-rpmh.c | 141 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 142 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..ee78c4b 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,31 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK | \ + ((valid) << BCM_TCS_CMD_VALID_SHIFT) | \ + ((cpu_to_le32(vote) & \ Why? Sorry, could you clarify this question? If you're referring to the cpu_to_le32, shouldn't we be explicit about converting endianness even if it might be redundant for this particular qcom platform? + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ +struct bcm_db { + __le32 unit; + __le16 width; + u8 vcd; + u8 reserved; +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -29,6 +54,7 @@ * @aggr_state:rpmh clock aggregated state * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh * @valid_state_mask: mask to determine the state of the rpmh clock + * @aux_data: data specific to the bcm rpmh resource But there isn't aux_data. Is this supposed to be unit? And what is unit going to be? 1000? Supposed to be unit, the value is on the order of Khz. * @dev: device to which it is attached * @peer: pointer to the clock rpmh sibling */ @@ -42,6 +68,7 @@ struct clk_rpmh { u32 aggr_state; u32 last_sent_aggr_state; u32 valid_state_mask; + u32 unit; struct device *dev; struct clk_rpmh *peer; }; @@ -210,6 +248,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + mutex_lock(_clk_lock); + + cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0; Make this into an if statement instead of double ternary? Ok. cmd_state = 0; if (enable) { cmd_state = 1; if (c->aggr_state) cmd_state = c->aggr_state; } + + if (c->last_sent_aggr_state == cmd_state) + return 0; We just returned with a mutex held. Oops! Oops, will fix. + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + return ret; Again! + } + + c->last_sent_aggr_state = cmd_state; + + mutex_unlock(_clk_lock); + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct cl
[PATCH v1] clk: qcom: clk-rpmh: Add IPA clock support
The current clk-rpmh driver only supports on and off RPMh clock resources, let's extend the current driver by add support for clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). The BCM is a configurable shared resource aggregator that scales performance based on a preset of frequency points. The Qualcomm IP Accelerator (IPA) clock is an example of a resource that is managed by the BCM and this a requirement from the IPA driver in order to scale its core clock. Signed-off-by: David Dai --- drivers/clk/qcom/clk-rpmh.c | 141 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 142 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..ee78c4b 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,31 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK | \ + ((valid) << BCM_TCS_CMD_VALID_SHIFT) | \ + ((cpu_to_le32(vote) & \ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ +struct bcm_db { + __le32 unit; + __le16 width; + u8 vcd; + u8 reserved; +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -29,6 +54,7 @@ * @aggr_state:rpmh clock aggregated state * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh * @valid_state_mask: mask to determine the state of the rpmh clock + * @aux_data: data specific to the bcm rpmh resource * @dev: device to which it is attached * @peer: pointer to the clock rpmh sibling */ @@ -42,6 +68,7 @@ struct clk_rpmh { u32 aggr_state; u32 last_sent_aggr_state; u32 valid_state_mask; + u32 unit; struct device *dev; struct clk_rpmh *peer; }; @@ -98,6 +125,17 @@ struct clk_rpmh_desc { __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name,\ CLK_RPMH_VRM_EN_OFFSET, 1, _div) +#define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \ + static struct clk_rpmh _platform##_##_name = { \ + .res_name = _res_name, \ + .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),\ + .div = 1, \ + .hw.init = &(struct clk_init_data){ \ + .ops = _rpmh_bcm_ops, \ + .name = #_name, \ + }, \ + } + static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) { return container_of(_hw, struct clk_rpmh, hw); @@ -210,6 +248,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + mutex_lock(_clk_lock); + + cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0; + + if (c->last_sent_aggr_state == cmd_state) + return 0; + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + return ret; + } + + c->last_sent_aggr_state = cmd_state; + + mutex_unlock(_clk_lock); + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + int ret; + + ret = clk_rpmh_bcm_send_cmd(c, true); + + return ret; +}; + +static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + clk_rpmh_bcm_send_cmd(c, false); +}; + +static int clk_r
Re: [PATCH v10 5/7] interconnect: qcom: Add sdm845 interconnect provider driver
On 12/5/2018 8:00 AM, Georgi Djakov wrote: Hi Evan, On 12/1/18 02:39, Evan Green wrote: On Tue, Nov 27, 2018 at 10:04 AM Georgi Djakov wrote: From: David Dai Introduce Qualcomm SDM845 specific provider driver using the interconnect framework. Signed-off-by: David Dai Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,sdm845.txt | 24 + drivers/interconnect/Kconfig | 5 + drivers/interconnect/Makefile | 1 + drivers/interconnect/qcom/Kconfig | 13 + drivers/interconnect/qcom/Makefile| 5 + drivers/interconnect/qcom/sdm845.c| 836 ++ .../dt-bindings/interconnect/qcom,sdm845.h| 143 +++ 7 files changed, 1027 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt create mode 100644 drivers/interconnect/qcom/Kconfig create mode 100644 drivers/interconnect/qcom/Makefile create mode 100644 drivers/interconnect/qcom/sdm845.c create mode 100644 include/dt-bindings/interconnect/qcom,sdm845.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt new file mode 100644 index ..d45150e99665 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt @@ -0,0 +1,24 @@ +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" I wonder if maybe hlos isn't necessary. Unless you somehow imagine secure mode would have a device tree entry in here as well? Probably not. Ok, will remove it. David, please chime in if you have any concerns with this. No strong preferences in terms of naming, but need to make the distinction between this and potential other rsc types if we're to add additional provider drivers. +- #interconnect-cells : should contain 1 + +Examples: + +apps_rsc: rsc { + qnoc: qnoc-rsc-hlos { + compatible = "qcom,sdm845-rsc-hlos"; + #interconnect-cells = <1>; + }; +}; + ... diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c new file mode 100644 index ..1678de91ca52 --- /dev/null +++ b/drivers/interconnect/qcom/sdm845.c @@ -0,0 +1,836 @@ ... + +static void tcs_list_gen(struct list_head *bcm_list, +struct tcs_cmd *tcs_list, int *n) We could make the prototype of this function be: static void tcs_list_gen(struct list_head *bcm_list, struct tcs_cmd tcs_list[SDM845_MAX_VCD], int n[SDM845_MAX_VCD]) which would catch errors if somebody later passed in an array that wasn't the right size, since we blindly memset below. Yes, sounds good. I will try to optimize it. Thanks, Georgi +{ + 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 ((list_is_last(>list, bcm_list)) || + bcm->aux_data.vcd != list_next_entry(bcm, list)->aux_data.vcd) { + commit = true; + cur_vcd_size = 0; + } + tcs_cmd_gen(_list[idx], bcm->vote_x, bcm->vote_y, + bcm->addr, commit); + idx++; + n[batch]++; + /* +* Batch the BCMs in such a way that we do not split them in +* multiple payloads when they are under the same VCD. This is +* to ensure that every BCM is committed since we only set the +* commit bit on the last BCM request of every VCD. +*/ + if (n[batch] >= MAX_RPMH_PAYLOAD) { + if (!commit) { + n[batch] -= cur_vcd_size; + n[batch + 1] = cur_vcd_size; + } + batch++; + } + } +} + -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v10 5/7] interconnect: qcom: Add sdm845 interconnect provider driver
On 12/5/2018 8:00 AM, Georgi Djakov wrote: Hi Evan, On 12/1/18 02:39, Evan Green wrote: On Tue, Nov 27, 2018 at 10:04 AM Georgi Djakov wrote: From: David Dai Introduce Qualcomm SDM845 specific provider driver using the interconnect framework. Signed-off-by: David Dai Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,sdm845.txt | 24 + drivers/interconnect/Kconfig | 5 + drivers/interconnect/Makefile | 1 + drivers/interconnect/qcom/Kconfig | 13 + drivers/interconnect/qcom/Makefile| 5 + drivers/interconnect/qcom/sdm845.c| 836 ++ .../dt-bindings/interconnect/qcom,sdm845.h| 143 +++ 7 files changed, 1027 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt create mode 100644 drivers/interconnect/qcom/Kconfig create mode 100644 drivers/interconnect/qcom/Makefile create mode 100644 drivers/interconnect/qcom/sdm845.c create mode 100644 include/dt-bindings/interconnect/qcom,sdm845.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt new file mode 100644 index ..d45150e99665 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm845.txt @@ -0,0 +1,24 @@ +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" I wonder if maybe hlos isn't necessary. Unless you somehow imagine secure mode would have a device tree entry in here as well? Probably not. Ok, will remove it. David, please chime in if you have any concerns with this. No strong preferences in terms of naming, but need to make the distinction between this and potential other rsc types if we're to add additional provider drivers. +- #interconnect-cells : should contain 1 + +Examples: + +apps_rsc: rsc { + qnoc: qnoc-rsc-hlos { + compatible = "qcom,sdm845-rsc-hlos"; + #interconnect-cells = <1>; + }; +}; + ... diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c new file mode 100644 index ..1678de91ca52 --- /dev/null +++ b/drivers/interconnect/qcom/sdm845.c @@ -0,0 +1,836 @@ ... + +static void tcs_list_gen(struct list_head *bcm_list, +struct tcs_cmd *tcs_list, int *n) We could make the prototype of this function be: static void tcs_list_gen(struct list_head *bcm_list, struct tcs_cmd tcs_list[SDM845_MAX_VCD], int n[SDM845_MAX_VCD]) which would catch errors if somebody later passed in an array that wasn't the right size, since we blindly memset below. Yes, sounds good. I will try to optimize it. Thanks, Georgi +{ + 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 ((list_is_last(>list, bcm_list)) || + bcm->aux_data.vcd != list_next_entry(bcm, list)->aux_data.vcd) { + commit = true; + cur_vcd_size = 0; + } + tcs_cmd_gen(_list[idx], bcm->vote_x, bcm->vote_y, + bcm->addr, commit); + idx++; + n[batch]++; + /* +* Batch the BCMs in such a way that we do not split them in +* multiple payloads when they are under the same VCD. This is +* to ensure that every BCM is committed since we only set the +* commit bit on the last BCM request of every VCD. +*/ + if (n[batch] >= MAX_RPMH_PAYLOAD) { + if (!commit) { + n[batch] -= cur_vcd_size; + n[batch + 1] = cur_vcd_size; + } + batch++; + } + } +} + -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
On 12/4/2018 11:15 PM, Stephen Boyd wrote: Quoting David Dai (2018-12-04 17:14:10) On 12/4/2018 2:34 PM, Stephen Boyd wrote: Quoting Alex Elder (2018-12-04 13:41:47) On 12/4/18 1:24 PM, Stephen Boyd wrote: Quoting David Dai (2018-12-03 19:50:13) Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Yes, but why? Does the IPA driver need to set clk rates and that somehow doesn't work as a bandwidth request? The IPA core clock is a *clock*, not a bus. Representing it as if it were a bus, abusing the interconnect interface--pretending a bandwidth request is really a clock rate request--is kind of kludgy. I think Bjorn and David (and maybe Georgi? I don't know) decided a long time ago that exposing this as a clock is the right way to do it. I agree with that. But then we translate that clock rate into a bandwidth request to the BCM hardware? Seems really weird because it's doing the opposite of what you say is abusive. What does the IPA driver plan to do with this clk? Calculate a frequency by knowing that it really boils down to some bandwidth that then gets converted back into some clock frequency? Do we have the user somewhere that can be pointed to? The clock rate is translated into a unitless threshold value sent as part of the rpmh msg that BCM takes to select a performance. In this case, the unit conversion is based on the unit value read from the aux data which is in Khz. I understand that this wasn't explicitly mentioned anywhere and I'll improve on that next patch. How is this different from bus bandwidth requests? In those cases the bandwidth is calculated in bits per second or something like that, and written to the hardware so it can convert that bandwidth into kHz and set a bus clk frequency in the clock controller? So in the IPA case we've skipped the bps to kHz conversion step and gone straight to the clk frequency setting part? Is a BCM able to aggregate units of bandwidth or kHz depending on how it's configured and this BCM is configured for kHz? The data written to the hardware is just a 14bit scalar value that it takes to select a performance/frequency from a preset table. It's not really doing any sort of conversion in hardware in this case, instead the value is computed by software based on the aux data given. Think of it as a generic aggregator as opposed to being strictly bandwidth and the aggregator itself does not care what type of value it is(be it Khz or BW/s). Here's a link to the IPA driver implementation: https://lkml.org/lkml/2018/11/7/220 Thanks for the link. It looks like the IPA driver hard codes a rate of 75 MHz. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
On 12/4/2018 11:15 PM, Stephen Boyd wrote: Quoting David Dai (2018-12-04 17:14:10) On 12/4/2018 2:34 PM, Stephen Boyd wrote: Quoting Alex Elder (2018-12-04 13:41:47) On 12/4/18 1:24 PM, Stephen Boyd wrote: Quoting David Dai (2018-12-03 19:50:13) Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Yes, but why? Does the IPA driver need to set clk rates and that somehow doesn't work as a bandwidth request? The IPA core clock is a *clock*, not a bus. Representing it as if it were a bus, abusing the interconnect interface--pretending a bandwidth request is really a clock rate request--is kind of kludgy. I think Bjorn and David (and maybe Georgi? I don't know) decided a long time ago that exposing this as a clock is the right way to do it. I agree with that. But then we translate that clock rate into a bandwidth request to the BCM hardware? Seems really weird because it's doing the opposite of what you say is abusive. What does the IPA driver plan to do with this clk? Calculate a frequency by knowing that it really boils down to some bandwidth that then gets converted back into some clock frequency? Do we have the user somewhere that can be pointed to? The clock rate is translated into a unitless threshold value sent as part of the rpmh msg that BCM takes to select a performance. In this case, the unit conversion is based on the unit value read from the aux data which is in Khz. I understand that this wasn't explicitly mentioned anywhere and I'll improve on that next patch. How is this different from bus bandwidth requests? In those cases the bandwidth is calculated in bits per second or something like that, and written to the hardware so it can convert that bandwidth into kHz and set a bus clk frequency in the clock controller? So in the IPA case we've skipped the bps to kHz conversion step and gone straight to the clk frequency setting part? Is a BCM able to aggregate units of bandwidth or kHz depending on how it's configured and this BCM is configured for kHz? The data written to the hardware is just a 14bit scalar value that it takes to select a performance/frequency from a preset table. It's not really doing any sort of conversion in hardware in this case, instead the value is computed by software based on the aux data given. Think of it as a generic aggregator as opposed to being strictly bandwidth and the aggregator itself does not care what type of value it is(be it Khz or BW/s). Here's a link to the IPA driver implementation: https://lkml.org/lkml/2018/11/7/220 Thanks for the link. It looks like the IPA driver hard codes a rate of 75 MHz. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
Thanks for the quick feedback! On 12/4/2018 11:24 AM, Stephen Boyd wrote: Quoting David Dai (2018-12-03 19:50:13) Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Yes, but why? Does the IPA driver need to set clk rates and that somehow doesn't work as a bandwidth request? Signed-off-by: David Dai --- diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..42e2cd2 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,32 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK |\ Nitpick: Add space before the \ and align them all up on the right side of the page. Ok. + ((valid) << BCM_TCS_CMD_VALID_SHIFT) |\ + ((cpu_to_le32(vote) &\ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ + Nitpick: Please remove the newline between comment and struct. Ok. +struct bcm_db { + u32 unit; + u16 width; + u8 vcd; + u8 reserved; These would need __le32 and __le16 for the byte swap. Ok. +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -210,6 +249,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0; + + if (c->last_sent_aggr_state == cmd_state) + return 0; + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + return ret; + } + + c->last_sent_aggr_state = cmd_state; + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + int ret = 0; Don't initialize variables and then reassign them right after. Ok. + + mutex_lock(_clk_lock); + ret = clk_rpmh_bcm_send_cmd(c, true); + mutex_unlock(_clk_lock); + + return ret; +}; + +static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, false); + mutex_unlock(_clk_lock); +}; + +static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, +unsigned long parent_rate) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + c->aggr_state = rate / (c->aux_data.unit * 1000); + + if (clk_hw_is_prepared(hw)) { Why do we need to check is_prepared? Add a comment indicating we can't send the request when the clk is disabled? Since the BCM only takes in numerical values as part of its msg (as opposed to enable or disable of some sort), this is so that we don't actually enable the clock if it hasn't been prepared yet. Sending a value of zero vs a non-zero would be the equivalent turning the clocks on and off and the behavior I'm trying to emulate here is to only change the rate in the system if the clock is on. + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, true); This function is always inside mutex_lock()/unlock() pair, so push the lock into the function? Makes sense, done. + mutex_unlock(_clk_lock); + } + + return 0; +}; + +static long clk_rpmh_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + return rate; +} + +static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + return c->aggr_state * c->aux_data.unit * 1000; What is 1000 for? The unit is in order of Khz, I can do the conversion for KHz to Hz the time when we fetch the aux data. +} + +sta
Re: [RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
Thanks for the quick feedback! On 12/4/2018 11:24 AM, Stephen Boyd wrote: Quoting David Dai (2018-12-03 19:50:13) Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Yes, but why? Does the IPA driver need to set clk rates and that somehow doesn't work as a bandwidth request? Signed-off-by: David Dai --- diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..42e2cd2 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,32 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK |\ Nitpick: Add space before the \ and align them all up on the right side of the page. Ok. + ((valid) << BCM_TCS_CMD_VALID_SHIFT) |\ + ((cpu_to_le32(vote) &\ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ + Nitpick: Please remove the newline between comment and struct. Ok. +struct bcm_db { + u32 unit; + u16 width; + u8 vcd; + u8 reserved; These would need __le32 and __le16 for the byte swap. Ok. +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -210,6 +249,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0; + + if (c->last_sent_aggr_state == cmd_state) + return 0; + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + return ret; + } + + c->last_sent_aggr_state = cmd_state; + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + int ret = 0; Don't initialize variables and then reassign them right after. Ok. + + mutex_lock(_clk_lock); + ret = clk_rpmh_bcm_send_cmd(c, true); + mutex_unlock(_clk_lock); + + return ret; +}; + +static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, false); + mutex_unlock(_clk_lock); +}; + +static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, +unsigned long parent_rate) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + c->aggr_state = rate / (c->aux_data.unit * 1000); + + if (clk_hw_is_prepared(hw)) { Why do we need to check is_prepared? Add a comment indicating we can't send the request when the clk is disabled? Since the BCM only takes in numerical values as part of its msg (as opposed to enable or disable of some sort), this is so that we don't actually enable the clock if it hasn't been prepared yet. Sending a value of zero vs a non-zero would be the equivalent turning the clocks on and off and the behavior I'm trying to emulate here is to only change the rate in the system if the clock is on. + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, true); This function is always inside mutex_lock()/unlock() pair, so push the lock into the function? Makes sense, done. + mutex_unlock(_clk_lock); + } + + return 0; +}; + +static long clk_rpmh_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + return rate; +} + +static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + return c->aggr_state * c->aux_data.unit * 1000; What is 1000 for? The unit is in order of Khz, I can do the conversion for KHz to Hz the time when we fetch the aux data. +} + +sta
Re: [RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
On 12/4/2018 2:34 PM, Stephen Boyd wrote: Quoting Alex Elder (2018-12-04 13:41:47) On 12/4/18 1:24 PM, Stephen Boyd wrote: Quoting David Dai (2018-12-03 19:50:13) Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Yes, but why? Does the IPA driver need to set clk rates and that somehow doesn't work as a bandwidth request? The IPA core clock is a *clock*, not a bus. Representing it as if it were a bus, abusing the interconnect interface--pretending a bandwidth request is really a clock rate request--is kind of kludgy. I think Bjorn and David (and maybe Georgi? I don't know) decided a long time ago that exposing this as a clock is the right way to do it. I agree with that. But then we translate that clock rate into a bandwidth request to the BCM hardware? Seems really weird because it's doing the opposite of what you say is abusive. What does the IPA driver plan to do with this clk? Calculate a frequency by knowing that it really boils down to some bandwidth that then gets converted back into some clock frequency? Do we have the user somewhere that can be pointed to? The clock rate is translated into a unitless threshold value sent as part of the rpmh msg that BCM takes to select a performance. In this case, the unit conversion is based on the unit value read from the aux data which is in Khz. I understand that this wasn't explicitly mentioned anywhere and I'll improve on that next patch. Here's a link to the IPA driver implementation: https://lkml.org/lkml/2018/11/7/220 Of course, none of these details are in the commit text so it's really hard for me as a bystander to figure this all out. So again, please add these sorts of details to the commit text so we can be "sold" on the idea of the patch instead of stating what the patch does. Understood, I'll be as detailed and as explicit as I can in the future. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
On 12/4/2018 2:34 PM, Stephen Boyd wrote: Quoting Alex Elder (2018-12-04 13:41:47) On 12/4/18 1:24 PM, Stephen Boyd wrote: Quoting David Dai (2018-12-03 19:50:13) Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Yes, but why? Does the IPA driver need to set clk rates and that somehow doesn't work as a bandwidth request? The IPA core clock is a *clock*, not a bus. Representing it as if it were a bus, abusing the interconnect interface--pretending a bandwidth request is really a clock rate request--is kind of kludgy. I think Bjorn and David (and maybe Georgi? I don't know) decided a long time ago that exposing this as a clock is the right way to do it. I agree with that. But then we translate that clock rate into a bandwidth request to the BCM hardware? Seems really weird because it's doing the opposite of what you say is abusive. What does the IPA driver plan to do with this clk? Calculate a frequency by knowing that it really boils down to some bandwidth that then gets converted back into some clock frequency? Do we have the user somewhere that can be pointed to? The clock rate is translated into a unitless threshold value sent as part of the rpmh msg that BCM takes to select a performance. In this case, the unit conversion is based on the unit value read from the aux data which is in Khz. I understand that this wasn't explicitly mentioned anywhere and I'll improve on that next patch. Here's a link to the IPA driver implementation: https://lkml.org/lkml/2018/11/7/220 Of course, none of these details are in the commit text so it's really hard for me as a bystander to figure this all out. So again, please add these sorts of details to the commit text so we can be "sold" on the idea of the patch instead of stating what the patch does. Understood, I'll be as detailed and as explicit as I can in the future. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[RFC PATCH] Add IPA clock support for clk-rpmh
This patch extends the existing clk-rpmh driver to support a different type of RPMh resource known as Bus Clock Manager(BCM) in order to scale performance for the Qualcomm IP Accelerator(IPA) core clock. David Dai (1): clk: qcom: clk-rpmh: Add IPA clock support drivers/clk/qcom/clk-rpmh.c | 142 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 143 insertions(+) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[RFC PATCH] Add IPA clock support for clk-rpmh
This patch extends the existing clk-rpmh driver to support a different type of RPMh resource known as Bus Clock Manager(BCM) in order to scale performance for the Qualcomm IP Accelerator(IPA) core clock. David Dai (1): clk: qcom: clk-rpmh: Add IPA clock support drivers/clk/qcom/clk-rpmh.c | 142 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 143 insertions(+) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Signed-off-by: David Dai --- drivers/clk/qcom/clk-rpmh.c | 142 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 143 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..42e2cd2 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,32 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK |\ + ((valid) << BCM_TCS_CMD_VALID_SHIFT) |\ + ((cpu_to_le32(vote) &\ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ + +struct bcm_db { + u32 unit; + u16 width; + u8 vcd; + u8 reserved; +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -29,6 +55,7 @@ * @aggr_state:rpmh clock aggregated state * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh * @valid_state_mask: mask to determine the state of the rpmh clock + * @aux_data: data specific to the bcm rpmh resource * @dev: device to which it is attached * @peer: pointer to the clock rpmh sibling */ @@ -42,6 +69,7 @@ struct clk_rpmh { u32 aggr_state; u32 last_sent_aggr_state; u32 valid_state_mask; + struct bcm_db aux_data; struct device *dev; struct clk_rpmh *peer; }; @@ -98,6 +126,17 @@ struct clk_rpmh_desc { __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name,\ CLK_RPMH_VRM_EN_OFFSET, 1, _div) +#define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \ + static struct clk_rpmh _platform##_##_name = { \ + .res_name = _res_name, \ + .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),\ + .div = 1, \ + .hw.init = &(struct clk_init_data){ \ + .ops = _rpmh_bcm_ops, \ + .name = #_name, \ + }, \ + } + static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) { return container_of(_hw, struct clk_rpmh, hw); @@ -210,6 +249,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0; + + if (c->last_sent_aggr_state == cmd_state) + return 0; + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + return ret; + } + + c->last_sent_aggr_state = cmd_state; + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + int ret = 0; + + mutex_lock(_clk_lock); + ret = clk_rpmh_bcm_send_cmd(c, true); + mutex_unlock(_clk_lock); + + return ret; +}; + +static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, false); + mutex_unlock(_clk_lock); +}; + +static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, +unsigned long parent_rate) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + c->aggr_state = rate / (c->aux_data.unit * 1000); + + if (clk_hw_is_prepared(hw)) { + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, true); + mutex_unlock(_clk_lock); + } + +
[RFC PATCH] clk: qcom: clk-rpmh: Add IPA clock support
Add IPA clock support by extending the current clk rpmh driver to support clocks that are managed by a different type of RPMh resource known as Bus Clock Manager(BCM). Signed-off-by: David Dai --- drivers/clk/qcom/clk-rpmh.c | 142 ++ include/dt-bindings/clock/qcom,rpmh.h | 1 + 2 files changed, 143 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc77..42e2cd2 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -18,6 +18,32 @@ #define CLK_RPMH_ARC_EN_OFFSET 0 #define CLK_RPMH_VRM_EN_OFFSET 4 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHIFT29 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_SHIFT 0 + +#define BCM_TCS_CMD(valid, vote) \ + (BCM_TCS_CMD_COMMIT_MASK |\ + ((valid) << BCM_TCS_CMD_VALID_SHIFT) |\ + ((cpu_to_le32(vote) &\ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT)) + +/** + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) + * @unit: divisor used to convert Hz value to an RPMh msg + * @width: multiplier used to convert Hz value to an RPMh msg + * @vcd: virtual clock domain that this bcm belongs to + * @reserved: reserved to pad the struct + */ + +struct bcm_db { + u32 unit; + u16 width; + u8 vcd; + u8 reserved; +}; + /** * struct clk_rpmh - individual rpmh clock data structure * @hw:handle between common and hardware-specific interfaces @@ -29,6 +55,7 @@ * @aggr_state:rpmh clock aggregated state * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh * @valid_state_mask: mask to determine the state of the rpmh clock + * @aux_data: data specific to the bcm rpmh resource * @dev: device to which it is attached * @peer: pointer to the clock rpmh sibling */ @@ -42,6 +69,7 @@ struct clk_rpmh { u32 aggr_state; u32 last_sent_aggr_state; u32 valid_state_mask; + struct bcm_db aux_data; struct device *dev; struct clk_rpmh *peer; }; @@ -98,6 +126,17 @@ struct clk_rpmh_desc { __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name,\ CLK_RPMH_VRM_EN_OFFSET, 1, _div) +#define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \ + static struct clk_rpmh _platform##_##_name = { \ + .res_name = _res_name, \ + .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),\ + .div = 1, \ + .hw.init = &(struct clk_init_data){ \ + .ops = _rpmh_bcm_ops, \ + .name = #_name, \ + }, \ + } + static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) { return container_of(_hw, struct clk_rpmh, hw); @@ -210,6 +249,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, .recalc_rate= clk_rpmh_recalc_rate, }; +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) +{ + struct tcs_cmd cmd = { 0 }; + u32 cmd_state; + int ret; + + cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0; + + if (c->last_sent_aggr_state == cmd_state) + return 0; + + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(enable, cmd_state); + + ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, , 1); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + return ret; + } + + c->last_sent_aggr_state = cmd_state; + + return 0; +} + +static int clk_rpmh_bcm_prepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + int ret = 0; + + mutex_lock(_clk_lock); + ret = clk_rpmh_bcm_send_cmd(c, true); + mutex_unlock(_clk_lock); + + return ret; +}; + +static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, false); + mutex_unlock(_clk_lock); +}; + +static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, +unsigned long parent_rate) +{ + struct clk_rpmh *c = to_clk_rpmh(hw); + + c->aggr_state = rate / (c->aux_data.unit * 1000); + + if (clk_hw_is_prepared(hw)) { + mutex_lock(_clk_lock); + clk_rpmh_bcm_send_cmd(c, true); + mutex_unlock(_clk_lock); + } + +
[PATCH v3 0/2] Add 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 across 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]. Changes in v3 [6]: - Updated provider set prototype to be compatible with v8 of ICC framework - Added additional comments and fixed format (Evan G.) - Fixed endianess issues (Evan G.) - Added clean up of nodes in probe failure and qnoc_remove (Evan G.) - Merged sdm845 local node IDs with qcom dt-binding IDs - Removed IPA CORE nodes and BCMs. Changes in v2 [5]: - Updated to use the latest RPMH and CommandDB patches - Fixed bug in bcm aggregation - Updated sdm845 provider dt entry Changes in v1 [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/8/10/387 [2]: https://lkml.org/lkml/2018/6/20/519 [3]: https://lkml.org/lkml/2018/4/10/714 [4]: https://patchwork.kernel.org/patch/10428167/ [5]: https://lkml.org/lkml/2018/6/29/743 [6]: https://lkml.org/lkml/2018/7/18/1109 Summary of the patches: Patch 1 creates the Qualcomm SDM845 Specific provider driver. Patch 2 Adds dt binding for SDM845 provider TODO: * 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/sdm845.c | 844 + include/dt-bindings/interconnect/qcom.h| 110 ++- 6 files changed, 989 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt 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
[PATCH v3 0/2] Add 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 across 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]. Changes in v3 [6]: - Updated provider set prototype to be compatible with v8 of ICC framework - Added additional comments and fixed format (Evan G.) - Fixed endianess issues (Evan G.) - Added clean up of nodes in probe failure and qnoc_remove (Evan G.) - Merged sdm845 local node IDs with qcom dt-binding IDs - Removed IPA CORE nodes and BCMs. Changes in v2 [5]: - Updated to use the latest RPMH and CommandDB patches - Fixed bug in bcm aggregation - Updated sdm845 provider dt entry Changes in v1 [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/8/10/387 [2]: https://lkml.org/lkml/2018/6/20/519 [3]: https://lkml.org/lkml/2018/4/10/714 [4]: https://patchwork.kernel.org/patch/10428167/ [5]: https://lkml.org/lkml/2018/6/29/743 [6]: https://lkml.org/lkml/2018/7/18/1109 Summary of the patches: Patch 1 creates the Qualcomm SDM845 Specific provider driver. Patch 2 Adds dt binding for SDM845 provider TODO: * 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/sdm845.c | 844 + include/dt-bindings/interconnect/qcom.h| 110 ++- 6 files changed, 989 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt 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
[PATCH v3 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 --- .../bindings/interconnect/qcom-sdm845.txt | 22 + drivers/interconnect/qcom/Kconfig | 8 + drivers/interconnect/qcom/Makefile | 1 + drivers/interconnect/qcom/sdm845.c | 844 + include/dt-bindings/interconnect/qcom.h| 110 ++- 5 files changed, 984 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt 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 000..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 add6d7e..170ef3d 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -21,3 +21,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/sdm845.c b/drivers/interconnect/qcom/sdm845.c new file mode 100644 index 000..57aba8a --- /dev/null +++ b/drivers/interconnect/qcom/sdm845.c @@ -0,0 +1,844 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define BCM_TCS_CMD_COMMIT_SHFT30 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20001 +#define BCM_TCS_CMD_VOTE_X_SHFT14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT0 +#define BCM_TCS_CMD_VOTE_Y_MASK0xfffc000 + +#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \ + ((commit << BCM_TCS_CMD_COMMIT_SHFT) |\ + (valid << BCM_TCS_CMD_VALID_SHFT) |\ + ((cpu_to_le32(vote_x) &\ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) |\ + ((cpu_to_le32(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, _keepa
[PATCH v3 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 --- .../bindings/interconnect/qcom-sdm845.txt | 22 + drivers/interconnect/qcom/Kconfig | 8 + drivers/interconnect/qcom/Makefile | 1 + drivers/interconnect/qcom/sdm845.c | 844 + include/dt-bindings/interconnect/qcom.h| 110 ++- 5 files changed, 984 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-sdm845.txt 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 000..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 add6d7e..170ef3d 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -21,3 +21,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/sdm845.c b/drivers/interconnect/qcom/sdm845.c new file mode 100644 index 000..57aba8a --- /dev/null +++ b/drivers/interconnect/qcom/sdm845.c @@ -0,0 +1,844 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define BCM_TCS_CMD_COMMIT_SHFT30 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20001 +#define BCM_TCS_CMD_VOTE_X_SHFT14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT0 +#define BCM_TCS_CMD_VOTE_Y_MASK0xfffc000 + +#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \ + ((commit << BCM_TCS_CMD_COMMIT_SHFT) |\ + (valid << BCM_TCS_CMD_VALID_SHFT) |\ + ((cpu_to_le32(vote_x) &\ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) |\ + ((cpu_to_le32(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, _keepa
[PATCH v3 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 --- 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 1097c7e..4d15784 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1651,6 +1651,11 @@ compatible = "qcom,sdm845-rpmh-clk"; #clock-cells = <1>; }; + + qnoc: qnoc{ + compatible = "qcom,sdm845-rsc-hlos"; + #interconnect-cells = <1>; + }; }; ufsphy: phy@1d87000 { -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v3 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 --- 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 1097c7e..4d15784 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1651,6 +1651,11 @@ compatible = "qcom,sdm845-rpmh-clk"; #clock-cells = <1>; }; + + qnoc: qnoc{ + compatible = "qcom,sdm845-rsc-hlos"; + #interconnect-cells = <1>; + }; }; ufsphy: phy@1d87000 { -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFC PATCH v2 1/2] interconnect: qcom: Add sdm845 interconnect provider driver
Hi Evan, Thanks for taking the time to review and feedback! On 7/27/2018 2:12 PM, Evan Green wrote: Hi David, On Thu, Jul 26, 2018 at 4:30 PM David Dai wrote: Introduce Qualcomm SDM845 specific provider driver using the interconnect framework. Signed-off-by: David Dai --- .../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/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c new file mode 100644 index 000..bf13053 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "qcom-icc-ids.h" + +#define BCM_TCS_CMD_COMMIT_SHFT30 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20001 +#define BCM_TCS_CMD_VOTE_X_SHFT14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT0 +#define BCM_TCS_CMD_VOTE_Y_MASK0xfffc000 + +#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)) These values that are >8 bits (vote_x and vote_y) should be converted from cpu to little endian. Done. + +#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 device *dev; + 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_BCMS30 +#define SDM845_MAX_BCM_PER_NODE2 +#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 *
Re: [RFC PATCH v2 1/2] interconnect: qcom: Add sdm845 interconnect provider driver
Hi Evan, Thanks for taking the time to review and feedback! On 7/27/2018 2:12 PM, Evan Green wrote: Hi David, On Thu, Jul 26, 2018 at 4:30 PM David Dai wrote: Introduce Qualcomm SDM845 specific provider driver using the interconnect framework. Signed-off-by: David Dai --- .../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/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c new file mode 100644 index 000..bf13053 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "qcom-icc-ids.h" + +#define BCM_TCS_CMD_COMMIT_SHFT30 +#define BCM_TCS_CMD_COMMIT_MASK0x4000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20001 +#define BCM_TCS_CMD_VOTE_X_SHFT14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT0 +#define BCM_TCS_CMD_VOTE_Y_MASK0xfffc000 + +#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)) These values that are >8 bits (vote_x and vote_y) should be converted from cpu to little endian. Done. + +#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 device *dev; + 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_BCMS30 +#define SDM845_MAX_BCM_PER_NODE2 +#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 *
[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]. Changes in v2 [5]: - Updated to use the latest RPMH and CommandDB patches - Fixed bug in bcm aggregation - Updated sdm845 provider dt entry Changes in v1 [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/6/20/519 [3]: https://lkml.org/lkml/2018/4/10/714 [4]: https://patchwork.kernel.org/patch/10428167/ [5]: https://lkml.org/lkml/2018/6/29/743 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
[RFC PATCH v2 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. Signed-off-by: David Dai --- 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..caffa67 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{ + compatible = "qcom,sdm845-rsc-hlos"; + #interconnect-cells = <1>; + }; }; intc: interrupt-controller@17a0 { -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[RFC PATCH v2 1/2] interconnect: qcom: Add sdm845 interconnect provider driver
Introduce Qualcomm SDM845 specific provider driver using the interconnect framework. Signed-off-by: David Dai --- .../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 000..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 000..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 + +#defineMASTER_APPSS_PROC 0 +#defineMASTER_TCU_01 +#defineMASTER_IPA_CORE 2 +#defineMASTER_LLCC 3 +#defineMASTER_GNOC_CFG 4 +#defineMASTER_A1NOC_CFG5 +#defineMASTER_A2NOC_CFG6 +#defineMASTER_CNOC_DC_NOC 7 +#defineMASTER_MEM_NOC_CFG 8 +#defineMASTER_CNOC_MNOC_CFG9 +#defineMASTER_QDSS_BAM 10 +#defineMASTER_BLSP_1 11 +#defineMASTER_BLSP_2 12 +#defineMASTER_SNOC_CFG 13 +#defineMASTER_SPDM 14 +#defineMASTER_TIC 15 +#defineMASTER_TSIF 16 +#defineMASTER_A1NOC_SNOC 17 +#defineMASTER_A2NOC_SNOC 18 +#defineMASTER_GNOC_MEM_NOC 19 +#defineMASTER_CNOC_A2NOC 20 +#defineMASTER_GNOC_SNOC21 +#defineMASTER_MEM_NOC_SNOC 22 +#defineMASTER_MNOC_HF_MEM_NOC 23 +#defineMASTER_MNOC_SF_MEM_NOC 24 +#defineMASTER_ANOC_PCIE_SNOC 25 +#defineMASTER_SNOC_CNOC26 +#defineMASTER_SNOC_GC_MEM_NOC 27 +#defineMASTER_SNOC_SF_MEM_NOC 28 +#defineMASTER_CAMNOC_HF0 29 +#defineMASTER_CAMNOC_HF0_UNCOMP30 +#defineMASTER_CAMNOC_HF1 31 +#defineMASTER_CAMNOC_HF1_UNCOMP32 +#defineMASTER_CAMNOC_SF33 +#defineMASTER_CAMNOC_SF_UNCOMP 34 +#defineMASTER_CRYPTO 35 +#defineMASTER_GFX3D36 +#defineMASTER_IPA 37 +#defineMASTER_MDP0 38 +#defineMASTER_MDP1 39 +#defineMASTER_PIMEM40 +#defineMASTER_ROTATOR 41 +#defineMASTER_VIDEO_P0 42 +#defineMASTER
[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]. Changes in v2 [5]: - Updated to use the latest RPMH and CommandDB patches - Fixed bug in bcm aggregation - Updated sdm845 provider dt entry Changes in v1 [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/6/20/519 [3]: https://lkml.org/lkml/2018/4/10/714 [4]: https://patchwork.kernel.org/patch/10428167/ [5]: https://lkml.org/lkml/2018/6/29/743 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
[RFC PATCH v2 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. Signed-off-by: David Dai --- 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..caffa67 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{ + compatible = "qcom,sdm845-rsc-hlos"; + #interconnect-cells = <1>; + }; }; intc: interrupt-controller@17a0 { -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[RFC PATCH v2 1/2] interconnect: qcom: Add sdm845 interconnect provider driver
Introduce Qualcomm SDM845 specific provider driver using the interconnect framework. Signed-off-by: David Dai --- .../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 000..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 000..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 + +#defineMASTER_APPSS_PROC 0 +#defineMASTER_TCU_01 +#defineMASTER_IPA_CORE 2 +#defineMASTER_LLCC 3 +#defineMASTER_GNOC_CFG 4 +#defineMASTER_A1NOC_CFG5 +#defineMASTER_A2NOC_CFG6 +#defineMASTER_CNOC_DC_NOC 7 +#defineMASTER_MEM_NOC_CFG 8 +#defineMASTER_CNOC_MNOC_CFG9 +#defineMASTER_QDSS_BAM 10 +#defineMASTER_BLSP_1 11 +#defineMASTER_BLSP_2 12 +#defineMASTER_SNOC_CFG 13 +#defineMASTER_SPDM 14 +#defineMASTER_TIC 15 +#defineMASTER_TSIF 16 +#defineMASTER_A1NOC_SNOC 17 +#defineMASTER_A2NOC_SNOC 18 +#defineMASTER_GNOC_MEM_NOC 19 +#defineMASTER_CNOC_A2NOC 20 +#defineMASTER_GNOC_SNOC21 +#defineMASTER_MEM_NOC_SNOC 22 +#defineMASTER_MNOC_HF_MEM_NOC 23 +#defineMASTER_MNOC_SF_MEM_NOC 24 +#defineMASTER_ANOC_PCIE_SNOC 25 +#defineMASTER_SNOC_CNOC26 +#defineMASTER_SNOC_GC_MEM_NOC 27 +#defineMASTER_SNOC_SF_MEM_NOC 28 +#defineMASTER_CAMNOC_HF0 29 +#defineMASTER_CAMNOC_HF0_UNCOMP30 +#defineMASTER_CAMNOC_HF1 31 +#defineMASTER_CAMNOC_HF1_UNCOMP32 +#defineMASTER_CAMNOC_SF33 +#defineMASTER_CAMNOC_SF_UNCOMP 34 +#defineMASTER_CRYPTO 35 +#defineMASTER_GFX3D36 +#defineMASTER_IPA 37 +#defineMASTER_MDP0 38 +#defineMASTER_MDP1 39 +#defineMASTER_PIMEM40 +#defineMASTER_ROTATOR 41 +#defineMASTER_VIDEO_P0 42 +#defineMASTER
[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
[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
[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 --- .../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 000..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 000..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 + +#defineMASTER_APPSS_PROC 0 +#defineMASTER_TCU_01 +#defineMASTER_IPA_CORE 2 +#defineMASTER_LLCC 3 +#defineMASTER_GNOC_CFG 4 +#defineMASTER_A1NOC_CFG5 +#defineMASTER_A2NOC_CFG6 +#defineMASTER_CNOC_DC_NOC 7 +#defineMASTER_MEM_NOC_CFG 8 +#defineMASTER_CNOC_MNOC_CFG9 +#defineMASTER_QDSS_BAM 10 +#defineMASTER_BLSP_1 11 +#defineMASTER_BLSP_2 12 +#defineMASTER_SNOC_CFG 13 +#defineMASTER_SPDM 14 +#defineMASTER_TIC 15 +#defineMASTER_TSIF 16 +#defineMASTER_A1NOC_SNOC 17 +#defineMASTER_A2NOC_SNOC 18 +#defineMASTER_GNOC_MEM_NOC 19 +#defineMASTER_CNOC_A2NOC 20 +#defineMASTER_GNOC_SNOC21 +#defineMASTER_MEM_NOC_SNOC 22 +#defineMASTER_MNOC_HF_MEM_NOC 23 +#defineMASTER_MNOC_SF_MEM_NOC 24 +#defineMASTER_ANOC_PCIE_SNOC 25 +#defineMASTER_SNOC_CNOC26 +#defineMASTER_SNOC_GC_MEM_NOC 27 +#defineMASTER_SNOC_SF_MEM_NOC 28 +#defineMASTER_CAMNOC_HF0 29 +#defineMASTER_CAMNOC_HF0_UNCOMP30 +#defineMASTER_CAMNOC_HF1 31 +#defineMASTER_CAMNOC_HF1_UNCOMP32 +#defineMASTER_CAMNOC_SF33 +#defineMASTER_CAMNOC_SF_UNCOMP 34 +#defineMASTER_CRYPTO 35 +#defineMASTER_GFX3D36 +#defineMASTER_IPA 37 +#defineMASTER_MDP0 38 +#defineMASTER_MDP1 39 +#defineMASTER_PIMEM40 +#defineMASTER_ROTATOR
[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 --- .../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 000..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 000..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 + +#defineMASTER_APPSS_PROC 0 +#defineMASTER_TCU_01 +#defineMASTER_IPA_CORE 2 +#defineMASTER_LLCC 3 +#defineMASTER_GNOC_CFG 4 +#defineMASTER_A1NOC_CFG5 +#defineMASTER_A2NOC_CFG6 +#defineMASTER_CNOC_DC_NOC 7 +#defineMASTER_MEM_NOC_CFG 8 +#defineMASTER_CNOC_MNOC_CFG9 +#defineMASTER_QDSS_BAM 10 +#defineMASTER_BLSP_1 11 +#defineMASTER_BLSP_2 12 +#defineMASTER_SNOC_CFG 13 +#defineMASTER_SPDM 14 +#defineMASTER_TIC 15 +#defineMASTER_TSIF 16 +#defineMASTER_A1NOC_SNOC 17 +#defineMASTER_A2NOC_SNOC 18 +#defineMASTER_GNOC_MEM_NOC 19 +#defineMASTER_CNOC_A2NOC 20 +#defineMASTER_GNOC_SNOC21 +#defineMASTER_MEM_NOC_SNOC 22 +#defineMASTER_MNOC_HF_MEM_NOC 23 +#defineMASTER_MNOC_SF_MEM_NOC 24 +#defineMASTER_ANOC_PCIE_SNOC 25 +#defineMASTER_SNOC_CNOC26 +#defineMASTER_SNOC_GC_MEM_NOC 27 +#defineMASTER_SNOC_SF_MEM_NOC 28 +#defineMASTER_CAMNOC_HF0 29 +#defineMASTER_CAMNOC_HF0_UNCOMP30 +#defineMASTER_CAMNOC_HF1 31 +#defineMASTER_CAMNOC_HF1_UNCOMP32 +#defineMASTER_CAMNOC_SF33 +#defineMASTER_CAMNOC_SF_UNCOMP 34 +#defineMASTER_CRYPTO 35 +#defineMASTER_GFX3D36 +#defineMASTER_IPA 37 +#defineMASTER_MDP0 38 +#defineMASTER_MDP1 39 +#defineMASTER_PIMEM40 +#defineMASTER_ROTATOR
[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 --- 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@17a0 { -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[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 --- 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@17a0 { -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project