From patchwork Fri Sep 1 11:43:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nitin Rawat X-Patchwork-Id: 719713 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB3C7CA0FED for ; Fri, 1 Sep 2023 11:44:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349251AbjIALot (ORCPT ); Fri, 1 Sep 2023 07:44:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243533AbjIALor (ORCPT ); Fri, 1 Sep 2023 07:44:47 -0400 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12F6610F9; Fri, 1 Sep 2023 04:44:07 -0700 (PDT) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3816v7xf017622; Fri, 1 Sep 2023 11:43:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=qcppdkim1; bh=gv3F6JpgfJzVGsPB9w2oRONYIlWFgoudZluDfWpVamw=; b=bM2wRDGwafRvm++1czRtqEs0DQvCMafRymWAeERaVrPtL1RP5YiCY2vB0yVLzVuqJVVn oBUbWAY9u1v6qCrDRO1YkXhm9OLdovgc71ga0WWVZd45q+wHuWtIwlWeuKBgS0E95qy8 Yf3EKcJuO10Muekw/hrPABDx2a4jGgE3iTrD6EmSg/iB8EvHb/UpBOkLdWbnYxDzokBY 9w5V6iitKA3xS0jVGZvn6zLL74ZGY4qSD4gK82b2gPzti81P5NhkF1wIbsh09335SyXE kzPK5PvjhxAy6lL7gax9CICqzmYVxaTes/AGV4k1Na335rfqdEM3Q/EHltOn/8NLjb7V JA== Received: from apblrppmta01.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3stxru25fx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Sep 2023 11:43:44 +0000 Received: from pps.filterd (APBLRPPMTA01.qualcomm.com [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 381BgmjC013920; Fri, 1 Sep 2023 11:43:41 GMT Received: from pps.reinject (localhost [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTP id 3sqafmj088-1; Fri, 01 Sep 2023 11:43:41 +0000 Received: from APBLRPPMTA01.qualcomm.com (APBLRPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 381BhdDP014633; Fri, 1 Sep 2023 11:43:41 GMT Received: from hu-maiyas-hyd.qualcomm.com (hu-nitirawa-hyd.qualcomm.com [10.213.109.152]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTP id 381BhfnT014681; Fri, 01 Sep 2023 11:43:41 +0000 Received: by hu-maiyas-hyd.qualcomm.com (Postfix, from userid 2342877) id 89B225006A6; Fri, 1 Sep 2023 17:13:40 +0530 (+0530) From: Nitin Rawat To: mani@kernel.org, agross@kernel.org, andersson@kernel.org, konrad.dybcio@linaro.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: quic_cang@quicinc.com, quic_nguyenb@quicinc.com, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Nitin Rawat , Naveen Kumar Goud Arepalli Subject: [PATCH V6 3/6] scsi: ufs: qcom: Add multiple frequency support for unipro clk attributes Date: Fri, 1 Sep 2023 17:13:33 +0530 Message-Id: <20230901114336.31339-4-quic_nitirawa@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230901114336.31339-1-quic_nitirawa@quicinc.com> References: <20230901114336.31339-1-quic_nitirawa@quicinc.com> X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: TSGAZZgY7_vj5hrXsKx_2vtNEeN6RvUf X-Proofpoint-ORIG-GUID: TSGAZZgY7_vj5hrXsKx_2vtNEeN6RvUf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-09-01_09,2023-08-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 spamscore=0 clxscore=1015 malwarescore=0 adultscore=0 priorityscore=1501 impostorscore=0 suspectscore=0 mlxlogscore=999 mlxscore=0 bulkscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2308100000 definitions=main-2309010109 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add Support to configure CORE_CLK_1US_CYCLES, PA_VS_CORE_CLK_40NS_CYCLES for multiple unipro clock frequencies. Currently this is handled only for only 150Mhz and 75MHz. Since different qualcomm targets support different unipro frequency, add support to handle all other frequencies like 403MHz, 300MHz, 202MHz, 150 MHz, 75Mhz, 37.5 MHz. Co-developed-by: Naveen Kumar Goud Arepalli Signed-off-by: Naveen Kumar Goud Arepalli Signed-off-by: Nitin Rawat --- drivers/ufs/host/ufs-qcom.c | 96 ++++++++++++++++++++++++++++--------- drivers/ufs/host/ufs-qcom.h | 10 ++++ 2 files changed, 84 insertions(+), 22 deletions(-) -- 2.17.1 diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 018e391c276e..e3648e936498 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -94,8 +94,7 @@ static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS]; static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host); static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, - u32 clk_cycles, - u32 clk_40ns_cycles); + bool is_max_freq); static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd) { @@ -686,13 +685,14 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, return -EINVAL; } - if (ufs_qcom_cap_qunipro(host)) - /* - * set unipro core clock cycles to 150 & clear clock - * divider - */ - err = ufs_qcom_set_core_clk_ctrl(hba, - 150, 6); + if (ufs_qcom_cap_qunipro(host)) { + err = ufs_qcom_set_core_clk_ctrl(hba, true); + if (err) { + dev_err(hba->dev, + "%s cfg core clk ctrl failed\n", + __func__); + } + } /* * Some UFS devices (and may be host) have issues if LCC is @@ -1297,13 +1297,67 @@ static void ufs_qcom_exit(struct ufs_hba *hba) phy_exit(host->generic_phy); } static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, - u32 cycles_in_1us, - u32 cycles_in_40ns) + bool is_max_freq) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); + struct list_head *head = &hba->clk_list_head; u32 core_clk_ctrl_reg, reg; + struct ufs_clk_info *clki; + u32 cycles_in_1us, cycles_in_40ns; int ret; + list_for_each_entry(clki, head, list) { + if (!IS_ERR_OR_NULL(clki->clk) && + !strcmp(clki->name, "core_clk_unipro")) { + if (is_max_freq) + cycles_in_1us = clki->max_freq; + else + cycles_in_1us = clk_get_rate(clki->clk); + break; + } + } + + if ((cycles_in_1us % (1000 * 1000)) != 0) + cycles_in_1us = cycles_in_1us/(1000 * 1000) + 1; + else + cycles_in_1us = cycles_in_1us/(1000 * 1000); + + /* + * Generic formulae for cycles_in_40ns = (freq_unipro/25) is not + * applicable for all frequencies. For ex: ceil(37.5 MHz/25) will + * be 2 and ceil(403 MHZ/25) will be 17 whereas Hardware + * specification expect to be 16. Hence use exact hardware spec + * mandated value for cycles_in_40ns instead of calculating using + * generic formulae. + */ + switch (cycles_in_1us) { + case UNIPRO_CORE_CLK_FREQ_403_MHZ: + cycles_in_40ns = 16; + break; + case UNIPRO_CORE_CLK_FREQ_300_MHZ: + cycles_in_40ns = 12; + break; + case UNIPRO_CORE_CLK_FREQ_201_5_MHZ: + cycles_in_40ns = 8; + break; + case UNIPRO_CORE_CLK_FREQ_150_MHZ: + cycles_in_40ns = 6; + break; + case UNIPRO_CORE_CLK_FREQ_100_MHZ: + cycles_in_40ns = 4; + break; + case UNIPRO_CORE_CLK_FREQ_75_MHZ: + cycles_in_40ns = 3; + break; + case UNIPRO_CORE_CLK_FREQ_37_5_MHZ: + cycles_in_40ns = 2; + break; + default: + ret = -EINVAL; + dev_err(hba->dev, "UNIPRO clk freq %u MHz not supported\n", + cycles_in_1us); + } + ret = ufshcd_dme_get(hba, UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL), &core_clk_ctrl_reg); @@ -1326,7 +1380,7 @@ static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, /* Clear CORE_CLK_DIV_EN */ core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT; - err = ufshcd_dme_set(hba, + ret = ufshcd_dme_set(hba, UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL), core_clk_ctrl_reg); /* @@ -1334,25 +1388,25 @@ static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, * PA_VS_CORE_CLK_40NS_CYCLES attribute per programmed * frequency of unipro core clk of UFS host controller. */ - if (!err && (host->hw_ver.major >= 4)) { + if (!ret && (host->hw_ver.major >= 4)) { if (cycles_in_40ns > PA_VS_CORE_CLK_40NS_CYCLES_MASK) return -EINVAL; - err = ufshcd_dme_get(hba, + ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_CORE_CLK_40NS_CYCLES), ®); - if (err) - return err; + if (ret) + return ret; reg &= ~PA_VS_CORE_CLK_40NS_CYCLES_MASK; reg |= cycles_in_40ns; - err = ufshcd_dme_set(hba, + ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_VS_CORE_CLK_40NS_CYCLES), reg); } - return err; + return ret; } static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba) @@ -1368,8 +1422,7 @@ static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba) if (!ufs_qcom_cap_qunipro(host)) return 0; - /* set unipro core clock cycles to 150 and clear clock divider */ - return ufs_qcom_set_core_clk_ctrl(hba, 150, 6); + return ufs_qcom_set_core_clk_ctrl(hba, true); } static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba) @@ -1404,8 +1457,7 @@ static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba) if (!ufs_qcom_cap_qunipro(host)) return 0; - /* set unipro core clock cycles to 75 and clear clock divider */ - return ufs_qcom_set_core_clk_ctrl(hba, 75, 3); + return ufs_qcom_set_core_clk_ctrl(hba, false); } static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h index d81bf1a1b77a..bc176ef58e3e 100644 --- a/drivers/ufs/host/ufs-qcom.h +++ b/drivers/ufs/host/ufs-qcom.h @@ -9,6 +9,7 @@ #include #include #include +#include #define MAX_UFS_QCOM_HOSTS 1 #define MAX_U32 (~(u32)0) @@ -79,6 +80,15 @@ enum { UFS_MEM_CQIS_VS = 0x8, }; +/* QCOM UFS host controller core clk frequencies */ +#define UNIPRO_CORE_CLK_FREQ_37_5_MHZ 38 +#define UNIPRO_CORE_CLK_FREQ_75_MHZ 75 +#define UNIPRO_CORE_CLK_FREQ_100_MHZ 100 +#define UNIPRO_CORE_CLK_FREQ_150_MHZ 150 +#define UNIPRO_CORE_CLK_FREQ_300_MHZ 300 +#define UNIPRO_CORE_CLK_FREQ_201_5_MHZ 202 +#define UNIPRO_CORE_CLK_FREQ_403_MHZ 403 + #define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x) (0x000 + x) #define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x) (0x400 + x)