Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp296008imu; Fri, 25 Jan 2019 02:27:45 -0800 (PST) X-Google-Smtp-Source: ALg8bN47wNxC1S+cyMrfCvSZiMPBvS5dGaSJSP8KBmHjbQMZGtJkcXdtDqRJkWwWCufLC2Thr1Ho X-Received: by 2002:a62:3a04:: with SMTP id h4mr10304989pfa.119.1548412065631; Fri, 25 Jan 2019 02:27:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548412065; cv=none; d=google.com; s=arc-20160816; b=RIZK86Z0Esw+ncpOyMR/wT8wdI9U4Ubzlffm5ziAuRWePrT3F6rVz/bdu6BGVgDugO JaBPbNN89PlaLgMumSuLZVIOh7L/MzwfRVq1q0X8bH9qafoy/9bGz4XEZE8zq+RgHqge fm8KjWFgE51JQQsEYJzqqCKjnJa/Ur7MQ/X0ijK20S4mqdDcWhdmvbfCci2RkaaC9UDM yMW3V72SIH/OTGKRPjfK5k173kppsNuQz4xYMHqf0QOvUFFkx5Lk/UdwQKo1soLsocwr oSRZ4aLQW/W8glPOMcToddtpSCKmXY29FtbEgEj4/y+Z2TskP0EUlDdqYg69OPxAvA0T IWhQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dmarc-filter :dkim-signature:dkim-signature; bh=fqETU3PgCjLWPsNKelYHssEulMG9Thu4Nti94DWP0Kg=; b=asEFkFj6UQ7fc4jGKdlsNRnRAk5nGfgf0wJthtswJPZTB4Pw7vABlSL6f7TiQh/43p fbvPggtl4rEGCSwwnMvC61+h8qDWUfoeL34bdCI5c7IO+12IOyhNSc3T08XI1x3jwxGJ wmAHaf2hDzwRcmUxzryK3NLTYRhhQPIV9L70UxnMgO/ycUiiP9Tnj4X34al2k/1Q/i8C qcDXHeVtiBu596fYDVzloHn1MlIGMdnuy0IpFCQGaU8JioyO8lTfy762IbJbCpVO6lVd CCU9W+MvtJut6WRhZOKe5L+CEccKvN/UUriSx01oxid9devxHg8GJgtRA1mWWszArNYK Grkw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=bWO0NF1t; dkim=pass header.i=@codeaurora.org header.s=default header.b=brgq0wCm; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g83si25906484pfb.278.2019.01.25.02.27.29; Fri, 25 Jan 2019 02:27:45 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=bWO0NF1t; dkim=pass header.i=@codeaurora.org header.s=default header.b=brgq0wCm; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727035AbfAYK1Y (ORCPT + 99 others); Fri, 25 Jan 2019 05:27:24 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:51926 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726111AbfAYK1Y (ORCPT ); Fri, 25 Jan 2019 05:27:24 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id E34A560860; Fri, 25 Jan 2019 10:27:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1548412042; bh=c+GDTmxrBhiB3/4oGThGKKRugwPSP1KM2Tru1zCM4pk=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=bWO0NF1t2yJbJ/STpfHZUj1g9EM4bCdjAh++3FZ3eZK9d0BN97fUXizVPRtNLTjwi jm2e4AQLGSVc3BeUUPyG+Et51SOKXB74LeACwlb7kXyF301WVmohUdBVEBTjDLOxTY /w3hMiSIpOyEakajfR9vaAFmdWi87aE2GlTC6Sa4= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.0 Received: from [10.206.24.30] (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: asutoshd@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id E3BCB60860; Fri, 25 Jan 2019 10:27:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1548412038; bh=c+GDTmxrBhiB3/4oGThGKKRugwPSP1KM2Tru1zCM4pk=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=brgq0wCmlKXXl3z+zG2Xdkf72+1KJjl0MCbfJ5iHYrEmnSacr6q0puTY1t2oA8XYY 1pFX64irHJbIG4tNn6jI+X+O3W34hTJLNi2vHluEG3OIXeq2PSEuV0dCvtLflueZmM 0G64ewIt8JflzBCBW4lUUaQqozDSp382JN+786BA= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E3BCB60860 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=asutoshd@codeaurora.org Subject: Re: [ 1/1] scsi: qcom-ufs: Add support for bus voting using ICB framework To: Georgi Djakov , subhashj@codeaurora.org, cang@codeaurora.org, vivek.gautam@codeaurora.org, rnayak@codeaurora.org, vinholikatti@gmail.com, jejb@linux.vnet.ibm.com, martin.petersen@oracle.com, linux-scsi@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org, Rob Herring , Mark Rutland , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , open list References: From: "Asutosh Das (asd)" Message-ID: <4f58c58a-aeb6-6cad-96ac-43f6843715ce@codeaurora.org> Date: Fri, 25 Jan 2019 15:57:11 +0530 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 1/24/2019 5:16 PM, Georgi Djakov wrote: > Hi Asutosh, > > Thanks for the patch! > > On 1/24/19 09:01, Asutosh Das wrote: >> Adapt to the new ICB framework for bus bandwidth voting. > > It's actually called interconnect API or interconnect framework. Thanks! will change it. > >> This requires the source/destination port ids. >> Also this requires a tuple of values. >> >> The tuple is for two different paths - from UFS master >> to BIMC slave. The other is from CPU master to UFS slave. >> This tuple consists of the average and peak bandwidth. >> >> Signed-off-by: Asutosh Das >> --- > > You can put here (below the --- line) the text from the cover letter. > Usually people do not add separate cover letters for single patches. Ok - will do so. > >> .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 12 ++ >> drivers/scsi/ufs/ufs-qcom.c | 234 ++++++++++++++++----- >> drivers/scsi/ufs/ufs-qcom.h | 20 ++ >> 3 files changed, 218 insertions(+), 48 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt >> index a99ed55..94249ef 100644 >> --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt >> +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt >> @@ -45,6 +45,18 @@ Optional properties: >> Note: If above properties are not defined it can be assumed that the supply >> regulators or clocks are always on. >> >> +* Following bus parameters are required: >> +interconnects >> +interconnect-names > > Is the above really required? Are the interconnect bandwidth requests > required to enable something critical to UFS functionality? > Would UFS still work without any bandwidth scaling, although for example > slower? Could you please clarify. Yes - UFS will still work without any bandwidth scaling - but the performance would be terrible. > >> +- Please refer to Documentation/devicetree/bindings/interconnect/ >> + for more details on the above. >> +qcom,msm-bus,name - string describing the bus path >> +qcom,msm-bus,num-cases - number of configurations in which ufs can operate in >> +qcom,msm-bus,num-paths - number of paths to vote for >> +qcom,msm-bus,vectors-KBps - Takes a tuple , (2 tuples for 2 num-paths) >> + The number of these entries *must* be same as >> + num-cases. > > DT bindings should be submitted as a separate patch. Anyway, people > frown upon putting configuration data in DT. Could we put this data into > the driver as a static table instead of DT? Also maybe use ab/pb for > average/peak bandwidth. The ab/ib value change depending on the target - that's the reasoning for putting it in dts file. However, I'm open to ideas as to how else to handle this. Agree to changing it to pb. > >> + >> Example: >> ufshc@0xfc598000 { >> compatible = "jedec,ufs-1.1"; >> diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c >> index 2b38db2..213e975 100644 >> --- a/drivers/scsi/ufs/ufs-qcom.c >> +++ b/drivers/scsi/ufs/ufs-qcom.c >> @@ -16,6 +16,7 @@ >> #include >> #include >> #include >> +#include >> #include > > Alphabetical order? Agreed. > >> >> #include "ufshcd.h" >> @@ -27,6 +28,10 @@ >> #define UFS_QCOM_DEFAULT_DBG_PRINT_EN \ >> (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN) >> >> +#define UFS_DDR "ufs-ddr" >> +#define CPU_UFS "cpu-ufs" > > Not sure if it's really useful to have them as #defines. Also maybe use > "ufs-mem" instead of "ufs-ddr" to be more consistent with other users. I can declare these as strings too - I don't have a preference. Please let me know if you've a preference. The reason for ufs-ddr was that it describes the path from ufs device to ddr. Am fine with ufs-mem too. > >> + >> + >> enum { >> TSTBUS_UAWM, >> TSTBUS_UARM, >> @@ -714,7 +719,6 @@ static int ufs_qcom_get_pwr_dev_param(struct ufs_qcom_dev_params *qcom_param, >> return 0; >> } >> >> -#ifdef CONFIG_MSM_BUS_SCALING >> static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host, >> const char *speed_mode) >> { >> @@ -768,24 +772,83 @@ static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result) >> } >> } >> >> +static int ufs_qcom_get_ib_ab(struct ufs_qcom_host *host, int index, >> + struct qcom_bus_vectors *ufs_ddr_vec, >> + struct qcom_bus_vectors *cpu_ufs_vec) >> +{ >> + struct qcom_bus_path *usecase; >> + >> + if (!host->qbsd) >> + return -EINVAL; >> + >> + if (index > host->qbsd->num_usecase) >> + return -EINVAL; >> + >> + usecase = host->qbsd->usecase; >> + >> + /* >> + * >> + * usecase:0 usecase:0 >> + * ufs->ddr cpu->ufs >> + * |vec[0&1] | vec[2&3]| >> + * +----+----+----+----+ >> + * | ab | ib | ab | ib | >> + * |----+----+----+----+ >> + * . >> + * . >> + * . >> + * usecase:n usecase:n >> + * ufs->ddr cpu->ufs >> + * |vec[0&1] | vec[2&3]| >> + * +----+----+----+----+ >> + * | ab | ib | ab | ib | >> + * |----+----+----+----+ >> + */ >> + >> + /* index refers to offset in usecase */ >> + ufs_ddr_vec->ab = usecase[index].vec[0].ab; >> + ufs_ddr_vec->ib = usecase[index].vec[0].ib; >> + >> + cpu_ufs_vec->ab = usecase[index].vec[1].ab; >> + cpu_ufs_vec->ib = usecase[index].vec[1].ib; >> + >> + return 0; >> +} >> + >> static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote) >> { >> int err = 0; >> + struct qcom_bus_scale_data *d = host->qbsd; >> + struct qcom_bus_vectors path0, path1; >> + struct device *dev = host->hba->dev; >> >> - if (vote != host->bus_vote.curr_vote) { >> - err = msm_bus_scale_client_update_request( >> - host->bus_vote.client_handle, vote); >> - if (err) { >> - dev_err(host->hba->dev, >> - "%s: msm_bus_scale_client_update_request() failed: bus_client_handle=0x%x, vote=%d, err=%d\n", >> - __func__, host->bus_vote.client_handle, >> - vote, err); >> - goto out; >> - } >> + err = ufs_qcom_get_ib_ab(host, vote, &path0, &path1); >> + if (err) { >> + dev_err(dev, "Error: failed (%d) to get ib/ab\n", >> + err); >> + return err; >> + } >> >> - host->bus_vote.curr_vote = vote; >> + dev_dbg(dev, "Setting vote: %d: ufs-ddr: ab: %llu ib: %llu\n", vote, >> + path0.ab, path0.ib); >> + err = icc_set_bw(d->ufs_ddr, path0.ab, path0.ib); >> + if (err) { >> + dev_err(dev, "Error: (%d) failed setting (%s) bus vote\n", err, >> + UFS_DDR); >> + return err; >> } >> -out: >> + >> + dev_dbg(dev, "Setting: cpu-ufs: ab: %llu ib: %llu\n", path1.ab, >> + path1.ib); >> + err = icc_set(d->cpu_ufs, path1.ab, path1.ib); >> + if (err) { >> + dev_err(dev, "Error: (%d) failed setting (%s) bus vote\n", err, >> + CPU_UFS); >> + return err; >> + } >> + >> + host->bus_vote.curr_vote = vote; >> + >> return err; >> } >> >> @@ -807,6 +870,7 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host) >> dev_err(host->hba->dev, "%s: failed %d\n", __func__, err); >> else >> host->bus_vote.saved_vote = vote; >> + >> return err; >> } >> >> @@ -837,34 +901,114 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host) >> return count; >> } >> >> +static struct qcom_bus_scale_data *ufs_qcom_get_bus_scale_data(struct device >> + *dev) >> + >> +{ >> + struct platform_device *pdev = to_platform_device(dev); >> + struct device_node *of_node = dev->of_node; >> + struct qcom_bus_scale_data *qsd; >> + struct qcom_bus_path *usecase = NULL; >> + int ret = 0, i = 0, j, num_paths, len; >> + const uint32_t *vec_arr = NULL; > > Please use u32 instead of uint32_t. Agreed. > >> + bool mem_err = false; >> + >> + if (!pdev) { >> + dev_err(dev, "Null platform device!\n"); >> + return NULL; >> + } >> + >> + qsd = devm_kzalloc(dev, sizeof(struct qcom_bus_scale_data), GFP_KERNEL); >> + if (!qsd) >> + return NULL; >> + >> + ret = of_property_read_string(of_node, "qcom,msm-bus,name", &qsd->name); >> + if (ret) { >> + dev_err(dev, "Error: (%d) Bus name missing!\n", ret); >> + return NULL; >> + } >> + >> + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases", >> + &qsd->num_usecase); >> + if (ret) { >> + pr_err("Error: num-usecases not found\n"); >> + goto err; >> + } >> + >> + usecase = devm_kzalloc(dev, (sizeof(struct qcom_bus_path) * >> + qsd->num_usecase), GFP_KERNEL); >> + if (!usecase) >> + return NULL; >> + >> + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths", >> + &num_paths); >> + if (ret) { >> + pr_err("Error: num_paths not found\n"); >> + return NULL; >> + } >> + >> + vec_arr = of_get_property(of_node, "qcom,msm-bus,vectors-KBps", &len); >> + if (vec_arr == NULL) { >> + pr_err("Error: Vector array not found\n"); >> + return NULL; >> + } >> + >> + for (i = 0; i < qsd->num_usecase; i++) { >> + usecase[i].num_paths = num_paths; >> + usecase[i].vec = devm_kzalloc(dev, num_paths * >> + sizeof(struct qcom_bus_vectors), >> + GFP_KERNEL); >> + if (!usecase[i].vec) { >> + mem_err = true; >> + dev_err(dev, "Error: Failed to alloc mem for vectors\n"); >> + goto err; >> + } >> + >> + for (j = 0; j < num_paths; j++) { >> + int idx = ((i * num_paths) + j) * 2; >> + >> + usecase[i].vec[j].ab = (uint64_t) >> + be32_to_cpu(vec_arr[idx]); >> + usecase[i].vec[j].ib = (uint64_t) >> + be32_to_cpu(vec_arr[idx + 1]); >> + } >> + } >> + >> + qsd->usecase = usecase; >> + return qsd; >> +err: >> + if (mem_err) { >> + for (; i > 0; i--) >> + kfree(usecase[i].vec); >> + } >> + return NULL; >> +} > > We wouldn't need all the above DT parsing if we add a sdm845 bandwidth > usecase table. Could you give it a try? Replied above - Please let me know if you've any suggestions on how else to handle this, as it can change with targets. > > Thanks, > Georgi > Hi Georgi - thanks for the comments. Replied to your comments inline. -asd -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project