From patchwork Mon Feb 25 09:24:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 10828379 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B7D4A1390 for ; Mon, 25 Feb 2019 09:25:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A26CA2AC27 for ; Mon, 25 Feb 2019 09:25:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 95E712AC2D; Mon, 25 Feb 2019 09:25:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2B2032AC2A for ; Mon, 25 Feb 2019 09:25:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WsyxsMqKN0jbUCfPaE8BMrOGCAE9QIVJsRjTat8u0QQ=; b=nJolm5F7hW35fN kXLAoqAOCU3lKSfxE8Hv2U85ts00D0CyfTRJZ5RpmM2j02IYI9tBnB4mxc9Q39DVYeu9kuCMSf8m2 b74m17IeCrISAr0Ct1yQDb2bQiiLVmNoEIZdS6bhSpFdt7agSE8GkkgxMcPlDolEEB773nITz2lFQ GOafp52XEGaXFVTI+REmXV6Syx+eiXSWUgMrwvTVSpje0V10d37yPy6FseDMB/pJIjBQTPu2VUzzB QtHl+xijVSuc7DGfxZWc9Rd8011iAxz+2dQ+YR4Qzfpt4LJuSXKA4/XO9nNIfCmtLKbKcBICged8y xYy87AyD2HPrUTlXJ0Rg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVQ-00054c-Jv; Mon, 25 Feb 2019 09:25:00 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVM-00052Z-94 for linux-mediatek@lists.infradead.org; Mon, 25 Feb 2019 09:24:58 +0000 X-UUID: 84bd23d84a7d4151a2c64cefe0395c57-20190225 X-UUID: 84bd23d84a7d4151a2c64cefe0395c57-20190225 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 854382477; Mon, 25 Feb 2019 01:24:52 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 01:24:50 -0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 17:24:36 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 25 Feb 2019 17:24:36 +0800 From: To: , , , , , , , , , , Subject: [PATCH v2 1/6] scsi: ufs: Introduce ufshcd_get_pwr_dev_param Date: Mon, 25 Feb 2019 17:24:10 +0800 Message-ID: <1551086655-5029-3-git-send-email-stanley.chu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> References: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: F5D2D8FD66A3567D6C9B230E82D279BDD4CC999A893EBC3D614636E8587055612000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190225_012456_338849_189D1849 X-CRM114-Status: GOOD ( 15.52 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org, liwei213@huawei.com, vivek.gautam@codeaurora.org, subhashj@codeaurora.org, Stanley Chu , peter.wang@mediatek.com Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanley Chu ufshcd_get_pwr_dev_param is for vendors to decide finally agreed attributes for power mode change if vendors define their host capability in struct ufs_dev_params. This api is using by both ufs-qcom and ufs-hisi now. Simply re-factor it and then every vendors can reuse it. Signed-off-by: Stanley Chu Reviewed-by: Avri Altman --- drivers/scsi/ufs/ufshcd-pltfrm.c | 98 ++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd-pltfrm.h | 21 +++++++ 2 files changed, 119 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 895a9b5ac989..508c561c9a62 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -39,6 +39,7 @@ #include "ufshcd.h" #include "ufshcd-pltfrm.h" +#include "unipro.h" #define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2 @@ -289,6 +290,103 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba) } } +/** + * ufshcd_get_pwr_dev_param - get finally agreed attributes for + * power mode change + * @pltfrm_param: pointer to platform parameters + * @dev_max: pointer to device attributes + * @agreed_pwr: returned agreed attributes + * + * Returns 0 on success, non-zero value on failure + */ +int ufshcd_get_pwr_dev_param(struct ufs_dev_params *pltfrm_param, + struct ufs_pa_layer_attr *dev_max, + struct ufs_pa_layer_attr *agreed_pwr) +{ + int min_pltfrm_gear; + int min_dev_gear; + bool is_dev_sup_hs = false; + bool is_pltfrm_max_hs = false; + + if (dev_max->pwr_rx == FAST_MODE) + is_dev_sup_hs = true; + + if (pltfrm_param->desired_working_mode == UFS_HS_MODE) { + is_pltfrm_max_hs = true; + min_pltfrm_gear = min_t(u32, pltfrm_param->hs_rx_gear, + pltfrm_param->hs_tx_gear); + } else { + min_pltfrm_gear = min_t(u32, pltfrm_param->pwm_rx_gear, + pltfrm_param->pwm_tx_gear); + } + + /* + * device doesn't support HS but + * pltfrm_param->desired_working_mode is HS, + * thus device and pltfrm_param don't agree + */ + if (!is_dev_sup_hs && is_pltfrm_max_hs) { + pr_info("%s: device doesn't support HS\n", + __func__); + return -ENOTSUPP; + } else if (is_dev_sup_hs && is_pltfrm_max_hs) { + /* + * since device supports HS, it supports FAST_MODE. + * since pltfrm_param->desired_working_mode is also HS + * then final decision (FAST/FASTAUTO) is done according + * to pltfrm_params as it is the restricting factor + */ + agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_hs; + agreed_pwr->pwr_tx = agreed_pwr->pwr_rx; + } else { + /* + * here pltfrm_param->desired_working_mode is PWM. + * it doesn't matter whether device supports HS or PWM, + * in both cases pltfrm_param->desired_working_mode will + * determine the mode + */ + agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_pwm; + agreed_pwr->pwr_tx = agreed_pwr->pwr_rx; + } + + /* + * we would like tx to work in the minimum number of lanes + * between device capability and vendor preferences. + * the same decision will be made for rx + */ + agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx, + pltfrm_param->tx_lanes); + agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx, + pltfrm_param->rx_lanes); + + /* device maximum gear is the minimum between device rx and tx gears */ + min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); + + /* + * if both device capabilities and vendor pre-defined preferences are + * both HS or both PWM then set the minimum gear to be the chosen + * working gear. + * if one is PWM and one is HS then the one that is PWM get to decide + * what is the gear, as it is the one that also decided previously what + * pwr the device will be configured to. + */ + if ((is_dev_sup_hs && is_pltfrm_max_hs) || + (!is_dev_sup_hs && !is_pltfrm_max_hs)) { + agreed_pwr->gear_rx = + min_t(u32, min_dev_gear, min_pltfrm_gear); + } else if (!is_dev_sup_hs) { + agreed_pwr->gear_rx = min_dev_gear; + } else { + agreed_pwr->gear_rx = min_pltfrm_gear; + } + agreed_pwr->gear_tx = agreed_pwr->gear_rx; + + agreed_pwr->hs_rate = pltfrm_param->hs_rate; + + return 0; +} +EXPORT_SYMBOL_GPL(ufshcd_get_pwr_dev_param); + /** * ufshcd_pltfrm_init - probe routine of the driver * @pdev: pointer to Platform device handle diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h index df64c4180340..d3ba62269be6 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.h +++ b/drivers/scsi/ufs/ufshcd-pltfrm.h @@ -16,6 +16,27 @@ #include "ufshcd.h" +#define UFS_PWM_MODE 1 +#define UFS_HS_MODE 2 + +struct ufs_dev_params { + u32 pwm_rx_gear; /* pwm rx gear to work in */ + u32 pwm_tx_gear; /* pwm tx gear to work in */ + u32 hs_rx_gear; /* hs rx gear to work in */ + u32 hs_tx_gear; /* hs tx gear to work in */ + u32 rx_lanes; /* number of rx lanes */ + u32 tx_lanes; /* number of tx lanes */ + u32 rx_pwr_pwm; /* rx pwm working pwr */ + u32 tx_pwr_pwm; /* tx pwm working pwr */ + u32 rx_pwr_hs; /* rx hs working pwr */ + u32 tx_pwr_hs; /* tx hs working pwr */ + u32 hs_rate; /* rate A/B to work in HS */ + u32 desired_working_mode; +}; + +int ufshcd_get_pwr_dev_param(struct ufs_dev_params *dev_param, + struct ufs_pa_layer_attr *dev_max, + struct ufs_pa_layer_attr *agreed_pwr); int ufshcd_pltfrm_init(struct platform_device *pdev, struct ufs_hba_variant_ops *vops); void ufshcd_pltfrm_shutdown(struct platform_device *pdev); From patchwork Mon Feb 25 09:24:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 10828385 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E016413B5 for ; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D08192AC2A for ; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C4BD12AC50; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 62A9B2AC2A for ; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=LjoXRxtAT1xzRtXtN8a/zUly5RxzXSJpdIWsCFMbKIg=; b=c+odC4AzZxJmb8 erBfgv1dqKi74E/9flT7iueQiuPf2MBwuRvWVd1/MdLiEVgAn1iluyKABNX1Fo9nIh+Yt9kX/93o9 3d4LS3q2t+HS46tLKNMqsvKs5rQOsQL7wf9JO9QdRKnVcrVwcZf8T43EVzBEqa50/CdMGkWYqtrmC CxffJnz4N5EhK/bZgPRPAQSZodUSrdLo/21j+oOgfHJBzMdQY6jsdRKhKhtneDxDjET7JWgnyOByJ QKsL2Zbq/fBGQgg9Un6QPouP2S791SMMmSA/OXjJQiGoQw9Ewdh9BN8WJd4iWEaNI3bld+9ulj+Ft mKZOQssaKWGfILG1OJhA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVa-0005jD-Bq; Mon, 25 Feb 2019 09:25:10 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVQ-000524-RA for linux-mediatek@lists.infradead.org; Mon, 25 Feb 2019 09:25:05 +0000 X-UUID: ae2213beb49f4d918aa37c9099177324-20190225 X-UUID: ae2213beb49f4d918aa37c9099177324-20190225 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1459504347; Mon, 25 Feb 2019 01:24:45 -0800 Received: from MTKMBS02N1.mediatek.inc (172.21.101.77) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 01:24:43 -0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs02n1.mediatek.inc (172.21.101.77) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 17:24:36 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 25 Feb 2019 17:24:37 +0800 From: To: , , , , , , , , , , Subject: [PATCH v2 2/6] scsi: ufs-qcom: Re-factor ufshcd_get_pwr_dev_param Date: Mon, 25 Feb 2019 17:24:11 +0800 Message-ID: <1551086655-5029-4-git-send-email-stanley.chu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> References: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190225_012501_191429_AAF2ED17 X-CRM114-Status: GOOD ( 16.27 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org, liwei213@huawei.com, vivek.gautam@codeaurora.org, subhashj@codeaurora.org, Stanley Chu , peter.wang@mediatek.com Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanley Chu ufshcd_get_pwr_dev_param function and ufs_dev_params struct are re-factored to ufs common driver thus change the way this driver used. Signed-off-by: Stanley Chu Reviewed-by: Avri Altman --- drivers/scsi/ufs/ufs-qcom.c | 106 ++---------------------------------- 1 file changed, 4 insertions(+), 102 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 3aeadb14aae1..a6b6f6eb9061 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -595,104 +595,6 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) return err; } -struct ufs_qcom_dev_params { - u32 pwm_rx_gear; /* pwm rx gear to work in */ - u32 pwm_tx_gear; /* pwm tx gear to work in */ - u32 hs_rx_gear; /* hs rx gear to work in */ - u32 hs_tx_gear; /* hs tx gear to work in */ - u32 rx_lanes; /* number of rx lanes */ - u32 tx_lanes; /* number of tx lanes */ - u32 rx_pwr_pwm; /* rx pwm working pwr */ - u32 tx_pwr_pwm; /* tx pwm working pwr */ - u32 rx_pwr_hs; /* rx hs working pwr */ - u32 tx_pwr_hs; /* tx hs working pwr */ - u32 hs_rate; /* rate A/B to work in HS */ - u32 desired_working_mode; -}; - -static int ufs_qcom_get_pwr_dev_param(struct ufs_qcom_dev_params *qcom_param, - struct ufs_pa_layer_attr *dev_max, - struct ufs_pa_layer_attr *agreed_pwr) -{ - int min_qcom_gear; - int min_dev_gear; - bool is_dev_sup_hs = false; - bool is_qcom_max_hs = false; - - if (dev_max->pwr_rx == FAST_MODE) - is_dev_sup_hs = true; - - if (qcom_param->desired_working_mode == FAST) { - is_qcom_max_hs = true; - min_qcom_gear = min_t(u32, qcom_param->hs_rx_gear, - qcom_param->hs_tx_gear); - } else { - min_qcom_gear = min_t(u32, qcom_param->pwm_rx_gear, - qcom_param->pwm_tx_gear); - } - - /* - * device doesn't support HS but qcom_param->desired_working_mode is - * HS, thus device and qcom_param don't agree - */ - if (!is_dev_sup_hs && is_qcom_max_hs) { - pr_err("%s: failed to agree on power mode (device doesn't support HS but requested power is HS)\n", - __func__); - return -ENOTSUPP; - } else if (is_dev_sup_hs && is_qcom_max_hs) { - /* - * since device supports HS, it supports FAST_MODE. - * since qcom_param->desired_working_mode is also HS - * then final decision (FAST/FASTAUTO) is done according - * to qcom_params as it is the restricting factor - */ - agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = - qcom_param->rx_pwr_hs; - } else { - /* - * here qcom_param->desired_working_mode is PWM. - * it doesn't matter whether device supports HS or PWM, - * in both cases qcom_param->desired_working_mode will - * determine the mode - */ - agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = - qcom_param->rx_pwr_pwm; - } - - /* - * we would like tx to work in the minimum number of lanes - * between device capability and vendor preferences. - * the same decision will be made for rx - */ - agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx, - qcom_param->tx_lanes); - agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx, - qcom_param->rx_lanes); - - /* device maximum gear is the minimum between device rx and tx gears */ - min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); - - /* - * if both device capabilities and vendor pre-defined preferences are - * both HS or both PWM then set the minimum gear to be the chosen - * working gear. - * if one is PWM and one is HS then the one that is PWM get to decide - * what is the gear, as it is the one that also decided previously what - * pwr the device will be configured to. - */ - if ((is_dev_sup_hs && is_qcom_max_hs) || - (!is_dev_sup_hs && !is_qcom_max_hs)) - agreed_pwr->gear_rx = agreed_pwr->gear_tx = - min_t(u32, min_dev_gear, min_qcom_gear); - else if (!is_dev_sup_hs) - agreed_pwr->gear_rx = agreed_pwr->gear_tx = min_dev_gear; - else - agreed_pwr->gear_rx = agreed_pwr->gear_tx = min_qcom_gear; - - agreed_pwr->hs_rate = qcom_param->hs_rate; - return 0; -} - #ifdef CONFIG_MSM_BUS_SCALING static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host, const char *speed_mode) @@ -920,7 +822,7 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, { u32 val; struct ufs_qcom_host *host = ufshcd_get_variant(hba); - struct ufs_qcom_dev_params ufs_qcom_cap; + struct ufs_dev_params ufs_qcom_cap; int ret = 0; if (!dev_req_params) { @@ -959,9 +861,9 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, ufs_qcom_cap.hs_rx_gear = UFS_HS_G2; } - ret = ufs_qcom_get_pwr_dev_param(&ufs_qcom_cap, - dev_max_params, - dev_req_params); + ret = ufshcd_get_pwr_dev_param(&ufs_qcom_cap, + dev_max_params, + dev_req_params); if (ret) { pr_err("%s: failed to determine capabilities\n", __func__); From patchwork Mon Feb 25 09:24:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 10828383 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D2ACF922 for ; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C13BA2AC27 for ; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B566D2AC31; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4E7382AC27 for ; Mon, 25 Feb 2019 09:25:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=MwnAg1CdPAsAlUdSARCdqvOkS+LJeINiipeLI2H/vf4=; b=Fjn6uWH7Y1WnM+ 0kAJXfJg7JsesH6KWuhZmw/r3CquApaDLr2PiY21QVtVj/uZ8wzFrRkcd208C1xTwqT7p8zdyyC4g GHeNIuCp6WGMgIGZnnWVq5VNnq/A853bpmGTkJmt5x7MTpWMiG7RgjY5gtaJffIQ5hk33KEVYd0Fa BVTYxaMNNvbTEfOnkCCFWF9tJF33FAwcdZMnv2hB/aQ+hSTh3CU80rpNrVrlrOIv99FGz2CYgp6Ft sySEHWNtrVqSCLwdnTnvu1rvKs91H5XZJA2pIlDjk6otOyRcTb68QDPQzhoBDMbQo1PNqHH9UiDlm lAUXGKc6/44sQMyD07ng==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVR-00055Q-EI; Mon, 25 Feb 2019 09:25:01 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVN-000524-Ay for linux-mediatek@lists.infradead.org; Mon, 25 Feb 2019 09:24:58 +0000 X-UUID: 2f09e54dee7e44ba906addbae404a5d0-20190225 X-UUID: 2f09e54dee7e44ba906addbae404a5d0-20190225 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1968471589; Mon, 25 Feb 2019 01:24:39 -0800 Received: from MTKMBS01N1.mediatek.inc (172.21.101.68) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 01:24:38 -0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 17:24:37 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 25 Feb 2019 17:24:37 +0800 From: To: , , , , , , , , , , Subject: [PATCH v2 3/6] scsi: ufs-hisi: Re-factor ufshcd_get_pwr_dev_param Date: Mon, 25 Feb 2019 17:24:12 +0800 Message-ID: <1551086655-5029-5-git-send-email-stanley.chu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> References: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190225_012457_378606_8CB6AD1A X-CRM114-Status: GOOD ( 15.90 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org, liwei213@huawei.com, vivek.gautam@codeaurora.org, subhashj@codeaurora.org, Stanley Chu , peter.wang@mediatek.com Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanley Chu ufshcd_get_pwr_dev_param function and ufs_dev_params struct are re-factored to ufs common driver thus change the way this driver used. Signed-off-by: Stanley Chu Reviewed-by: Avri Altman --- drivers/scsi/ufs/ufs-hisi.c | 109 ++---------------------------------- 1 file changed, 4 insertions(+), 105 deletions(-) diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index 452e19f8fb47..01faad26ec26 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -272,108 +272,7 @@ static int ufs_hi3660_link_startup_notify(struct ufs_hba *hba, return err; } -struct ufs_hisi_dev_params { - u32 pwm_rx_gear; /* pwm rx gear to work in */ - u32 pwm_tx_gear; /* pwm tx gear to work in */ - u32 hs_rx_gear; /* hs rx gear to work in */ - u32 hs_tx_gear; /* hs tx gear to work in */ - u32 rx_lanes; /* number of rx lanes */ - u32 tx_lanes; /* number of tx lanes */ - u32 rx_pwr_pwm; /* rx pwm working pwr */ - u32 tx_pwr_pwm; /* tx pwm working pwr */ - u32 rx_pwr_hs; /* rx hs working pwr */ - u32 tx_pwr_hs; /* tx hs working pwr */ - u32 hs_rate; /* rate A/B to work in HS */ - u32 desired_working_mode; -}; - -static int ufs_hisi_get_pwr_dev_param( - struct ufs_hisi_dev_params *hisi_param, - struct ufs_pa_layer_attr *dev_max, - struct ufs_pa_layer_attr *agreed_pwr) -{ - int min_hisi_gear; - int min_dev_gear; - bool is_dev_sup_hs = false; - bool is_hisi_max_hs = false; - - if (dev_max->pwr_rx == FASTAUTO_MODE || dev_max->pwr_rx == FAST_MODE) - is_dev_sup_hs = true; - - if (hisi_param->desired_working_mode == FAST) { - is_hisi_max_hs = true; - min_hisi_gear = min_t(u32, hisi_param->hs_rx_gear, - hisi_param->hs_tx_gear); - } else { - min_hisi_gear = min_t(u32, hisi_param->pwm_rx_gear, - hisi_param->pwm_tx_gear); - } - - /* - * device doesn't support HS but - * hisi_param->desired_working_mode is HS, - * thus device and hisi_param don't agree - */ - if (!is_dev_sup_hs && is_hisi_max_hs) { - pr_err("%s: device not support HS\n", __func__); - return -ENOTSUPP; - } else if (is_dev_sup_hs && is_hisi_max_hs) { - /* - * since device supports HS, it supports FAST_MODE. - * since hisi_param->desired_working_mode is also HS - * then final decision (FAST/FASTAUTO) is done according - * to hisi_params as it is the restricting factor - */ - agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = - hisi_param->rx_pwr_hs; - } else { - /* - * here hisi_param->desired_working_mode is PWM. - * it doesn't matter whether device supports HS or PWM, - * in both cases hisi_param->desired_working_mode will - * determine the mode - */ - agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = - hisi_param->rx_pwr_pwm; - } - - /* - * we would like tx to work in the minimum number of lanes - * between device capability and vendor preferences. - * the same decision will be made for rx - */ - agreed_pwr->lane_tx = - min_t(u32, dev_max->lane_tx, hisi_param->tx_lanes); - agreed_pwr->lane_rx = - min_t(u32, dev_max->lane_rx, hisi_param->rx_lanes); - - /* device maximum gear is the minimum between device rx and tx gears */ - min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); - - /* - * if both device capabilities and vendor pre-defined preferences are - * both HS or both PWM then set the minimum gear to be the chosen - * working gear. - * if one is PWM and one is HS then the one that is PWM get to decide - * what is the gear, as it is the one that also decided previously what - * pwr the device will be configured to. - */ - if ((is_dev_sup_hs && is_hisi_max_hs) || - (!is_dev_sup_hs && !is_hisi_max_hs)) - agreed_pwr->gear_rx = agreed_pwr->gear_tx = - min_t(u32, min_dev_gear, min_hisi_gear); - else - agreed_pwr->gear_rx = agreed_pwr->gear_tx = min_hisi_gear; - - agreed_pwr->hs_rate = hisi_param->hs_rate; - - pr_info("ufs final power mode: gear = %d, lane = %d, pwr = %d, rate = %d\n", - agreed_pwr->gear_rx, agreed_pwr->lane_rx, agreed_pwr->pwr_rx, - agreed_pwr->hs_rate); - return 0; -} - -static void ufs_hisi_set_dev_cap(struct ufs_hisi_dev_params *hisi_param) +static void ufs_hisi_set_dev_cap(struct ufs_dev_params *hisi_param) { hisi_param->rx_lanes = UFS_HISI_LIMIT_NUM_LANES_RX; hisi_param->tx_lanes = UFS_HISI_LIMIT_NUM_LANES_TX; @@ -434,7 +333,7 @@ static int ufs_hi3660_pwr_change_notify(struct ufs_hba *hba, struct ufs_pa_layer_attr *dev_max_params, struct ufs_pa_layer_attr *dev_req_params) { - struct ufs_hisi_dev_params ufs_hisi_cap; + struct ufs_dev_params ufs_hisi_cap; int ret = 0; if (!dev_req_params) { @@ -447,8 +346,8 @@ static int ufs_hi3660_pwr_change_notify(struct ufs_hba *hba, switch (status) { case PRE_CHANGE: ufs_hisi_set_dev_cap(&ufs_hisi_cap); - ret = ufs_hisi_get_pwr_dev_param( - &ufs_hisi_cap, dev_max_params, dev_req_params); + ret = ufshcd_get_pwr_dev_param(&ufs_hisi_cap, + dev_max_params, dev_req_params); if (ret) { dev_err(hba->dev, "%s: failed to determine capabilities\n", __func__); From patchwork Mon Feb 25 09:24:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 10828381 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1D7CA922 for ; Mon, 25 Feb 2019 09:25:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06EAC2AC2D for ; Mon, 25 Feb 2019 09:25:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EEBBB2AC37; Mon, 25 Feb 2019 09:25:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 937212AC2D for ; Mon, 25 Feb 2019 09:25:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QJJSGw8ibAdfXHoTQQgJCq2w8PtJ8iMImQvzQw8ayIg=; b=M0ZHj0ALn+K9Wc y3eciUcQrAt8hqjN45nRALMAS3p/H6Zh13v7CJ80/HseYXGyCUatsPY4oe+7HIr9cLVk3+B5bxFsu tGv6NSw1MPIqM3Qcg21n+QvMxcr5kTfWfv9REdf90dG/IWTeIBheyq1S/z4jz6lmQwcy8EmRMPtub 4AaitKYPu1DBckhJslVfyhX2xwHDKr+WLmkhrFIldtco+HHMqiFW64dXnKZWu8KW0GU3iyrhy9SsX TxCaqugv7ncd6FwBBJtG/wF9jBDAQVn7zlWUxa1I61lpSXW4e2q0+TVzqWVEOrbFR7F/5HNbuYxeb iE3O+fnaoMYaMp8GhGGw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVZ-0005be-2l; Mon, 25 Feb 2019 09:25:09 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVO-00052Z-UE for linux-mediatek@lists.infradead.org; Mon, 25 Feb 2019 09:25:01 +0000 X-UUID: 8f6790a938e740f791e9602faee73d40-20190225 X-UUID: 8f6790a938e740f791e9602faee73d40-20190225 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1808243773; Mon, 25 Feb 2019 01:24:52 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 01:24:51 -0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 17:24:37 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 25 Feb 2019 17:24:37 +0800 From: To: , , , , , , , , , , Subject: [PATCH v2 4/6] dt-bindings: scsi: ufs: Add document for ufs-mediatek Date: Mon, 25 Feb 2019 17:24:13 +0800 Message-ID: <1551086655-5029-6-git-send-email-stanley.chu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> References: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 8AAE95325725A3A413C9E91E1F6B23F0AF75B897BAF10258411EC160D7C29FD92000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190225_012458_975658_468757B5 X-CRM114-Status: GOOD ( 11.28 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org, liwei213@huawei.com, vivek.gautam@codeaurora.org, subhashj@codeaurora.org, Stanley Chu , peter.wang@mediatek.com Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanley Chu Add UFS and UFS PHY node document for Mediatek SoC chips. Signed-off-by: Stanley Chu --- .../devicetree/bindings/ufs/ufs-mediatek.txt | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufs-mediatek.txt diff --git a/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt new file mode 100644 index 000000000000..d73804687095 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt @@ -0,0 +1,75 @@ +* Mediatek Universal Flash Storage (UFS) Host Controller + +UFS nodes are defined to describe on-chip UFS hardware macro. +Each UFS Host Controller should have its own node. + +UFS PHY nodes are defined to describe on-chip UFS PHY hardware macro. +Each UFS PHY node should have its own node. + +Required properties for UFS PHY nodes: +- compatible : Compatible list, contains the following controller: + "mediatek,ufs-mphy-12nm" +- reg : Address and length of the UFS PHY register set. +- reg-names : indicates various resources passed to driver (via reg proptery) by name. + Required "reg-names" is "ufs_mphy". +- #phy-cells : This property shall be set to 0 +- clocks : List of phandle and clock specifier pairs. +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "ufs0-unipro-clk" and + "ufs0-mp-clk" are mandatory. + +Required properties for UFS nodes: +- compatible : Compatible list, contains the following controller: + "mediatek,ufshci" +- reg : Address and length of the UFS register set. +- interrupt-parent : interrupt device. +- phys : PHandle to phy. +- phy-names : Name of phy. + Required "phy-name" is "ufsphy". +- clocks : List of phandle and clock specifier pairs. +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. "ufs0-clock" is mandatory. +- freq-table-hz : Array of operating frequencies stored in the same + order as the clocks property. If this property is not + defined or a value in the array is "0" then it is assumed + that the frequency is set by the parent clock or a + fixed rate clock source. +- vcc-supply : Power to the UFS device. +- vcc-fixed-regulator: Specify that vcc-supply is a fixed regulator. +- lanes-per-direction: Number of lanes available per direction. Shall be 1. + +Example: + + ufs_mphy: ufs_mphy@11fa0000 { + compatible = "mediatek,ufs-mphy-12nm"; + reg = <0 0x11fa0000 0 0xc000>; + reg-names = "ufs_mphy"; + #phy-cells = <0>; + + clocks = + <&infracfg_ao INFRACFG_AO_UNIPRO_SCK_CG>, + <&infracfg_ao INFRACFG_AO_UFS_MP_SAP_BCLK_CG>; + clock-names = + "ufs0-unipro-clk", + "ufs0-mp-clk"; + }; + + ufshci:ufshci@11270000 { + compatible = "mediatek,ufshci"; + reg = <0 0x11270000 0 0x2300>; + interrupts = ; + phys = <&ufs_mphy>; + phy-names = "ufsphy"; + + clocks = + <&infracfg_ao INFRACFG_AO_UFS_CG>; + clock-names = + "ufs0-clock"; + freq-table-hz = + <0 0>; + + vcc-supply = <&mt_pmic_vemc_ldo_reg>; + vcc-fixed-regulator; + + lanes-per-direction = <1>; + }; From patchwork Mon Feb 25 09:24:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 10828387 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7174A922 for ; Mon, 25 Feb 2019 09:25:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A3982AACA for ; Mon, 25 Feb 2019 09:25:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E4A92AC2D; Mon, 25 Feb 2019 09:25:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 569E92AACA for ; Mon, 25 Feb 2019 09:25:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zXq+hcWmew7DbQ7txF7W35Ly697gWUa7AAUQRLBHPuE=; b=pg+nNYXLM0OR+8 rVJHFqKBT9jM5t/Ze5SkyDqvchLn9RNNpGI2JQmO1qZSQpQJ97Bt1GziWe4/FPEobgZN3EFcaai+F tbWzGSRvtPBJOPpqV7OEVWLMPemE06Dork5DtsPkeAdmOr3zGOZvbxX6AO7GwuoUjW9V3tOgjsxb4 VmKPzg9o6jZm/N/kvv62isYZyG8N3rBHhzAdA1I4Uwmj004+VaI7ISFaVKkGoZr7mMZ8WZETp64Xc R+JWljLA4DYFYhIaWvC/HFwXEvqvZtfYKZQ4ABBTfqzDrvtg7M9+c6e3RWKHj4gL9VSxIpd3XNcIo LxD+kZhIwkaj1HXyK8vA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVf-0006Uq-Kt; Mon, 25 Feb 2019 09:25:15 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVR-00052Z-1C for linux-mediatek@lists.infradead.org; Mon, 25 Feb 2019 09:25:08 +0000 X-UUID: 12e9d0226d8844e5bf455bdb8844c9d2-20190225 X-UUID: 12e9d0226d8844e5bf455bdb8844c9d2-20190225 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1195625821; Mon, 25 Feb 2019 01:24:39 -0800 Received: from mtkmbs03n1.mediatek.inc (172.21.101.181) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 01:24:38 -0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs03n1.mediatek.inc (172.21.101.181) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 17:24:37 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 25 Feb 2019 17:24:37 +0800 From: To: , , , , , , , , , , Subject: [PATCH v2 5/6] phy: mediatek: Add UFS M-PHY driver Date: Mon, 25 Feb 2019 17:24:14 +0800 Message-ID: <1551086655-5029-7-git-send-email-stanley.chu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> References: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190225_012501_523295_082EA2D3 X-CRM114-Status: GOOD ( 20.62 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org, liwei213@huawei.com, vivek.gautam@codeaurora.org, subhashj@codeaurora.org, Stanley Chu , peter.wang@mediatek.com Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanley Chu Add UFS M-PHY driver on Mediatek chipsets. Signed-off-by: Stanley Chu --- drivers/phy/mediatek/Kconfig | 29 ++-- drivers/phy/mediatek/Makefile | 2 + drivers/phy/mediatek/phy-mtk-ufs-12nm.c | 151 +++++++++++++++++++ drivers/phy/mediatek/phy-mtk-ufs-12nm.h | 52 +++++++ drivers/phy/mediatek/phy-mtk-ufs.c | 189 ++++++++++++++++++++++++ drivers/phy/mediatek/phy-mtk-ufs.h | 76 ++++++++++ 6 files changed, 489 insertions(+), 10 deletions(-) create mode 100644 drivers/phy/mediatek/phy-mtk-ufs-12nm.c create mode 100644 drivers/phy/mediatek/phy-mtk-ufs-12nm.h create mode 100644 drivers/phy/mediatek/phy-mtk-ufs.c create mode 100644 drivers/phy/mediatek/phy-mtk-ufs.h diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index 8857d00b3c65..38c41836ef46 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -2,22 +2,31 @@ # Phy drivers for Mediatek devices # config PHY_MTK_TPHY - tristate "MediaTek T-PHY Driver" - depends on ARCH_MEDIATEK && OF - select GENERIC_PHY - help - Say 'Y' here to add support for MediaTek T-PHY driver, - it supports multiple usb2.0, usb3.0 ports, PCIe and + tristate "MediaTek T-PHY Driver" + depends on ARCH_MEDIATEK && OF + select GENERIC_PHY + help + Say 'Y' here to add support for MediaTek T-PHY driver, + it supports multiple usb2.0, usb3.0 ports, PCIe and SATA, and meanwhile supports two version T-PHY which have different banks layout, the T-PHY with shared banks between multi-ports is first version, otherwise is second veriosn, so you can easily distinguish them by banks layout. config PHY_MTK_XSPHY - tristate "MediaTek XS-PHY Driver" - depends on ARCH_MEDIATEK && OF - select GENERIC_PHY - help + tristate "MediaTek XS-PHY Driver" + depends on ARCH_MEDIATEK && OF + select GENERIC_PHY + help Enable this to support the SuperSpeedPlus XS-PHY transceiver for USB3.1 GEN2 controllers on MediaTek chips. The driver supports multiple USB2.0, USB3.1 GEN2 ports. + +config PHY_MTK_UFS + tristate "Mediatek UFS M-PHY driver" + depends on ARCH_MEDIATEK && OF + select GENERIC_PHY + help + Support for UFS M-PHY on MediaTek chipsets. Enable this to provide + vendor-specific initialization, power on and off flow of specified + M-PHYs. diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index ee49edc97ee9..e29b56b29d21 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -5,3 +5,5 @@ obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o +obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o +obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs-12nm.o diff --git a/drivers/phy/mediatek/phy-mtk-ufs-12nm.c b/drivers/phy/mediatek/phy-mtk-ufs-12nm.c new file mode 100644 index 000000000000..7ddcaaceafbd --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-ufs-12nm.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "phy-mtk-ufs.h" +#include "phy-mtk-ufs-12nm.h" + +#define MPHY_NAME "ufs_phy_mtk_12nm" + +static void ufs_mtk_phy_12nm_power_on(struct ufs_mtk_phy *phy) +{ + /* release DA_MP_PLL_PWR_ON */ + mphy_set_bit(phy, MP_GLB_DIG_8C, PLL_PWR_ON); + mphy_clr_bit(phy, MP_GLB_DIG_8C, FRC_FRC_PWR_ON); + + /* release DA_MP_PLL_ISO_EN */ + mphy_clr_bit(phy, MP_GLB_DIG_8C, PLL_ISO_EN); + mphy_clr_bit(phy, MP_GLB_DIG_8C, FRC_PLL_ISO_EN); + + /* release DA_MP_CDR_PWR_ON */ + mphy_set_bit(phy, MP_LN_RX_44, CDR_PWR_ON); + mphy_clr_bit(phy, MP_LN_RX_44, FRC_CDR_PWR_ON); + + /* release DA_MP_CDR_ISO_EN */ + mphy_clr_bit(phy, MP_LN_RX_44, CDR_ISO_EN); + mphy_clr_bit(phy, MP_LN_RX_44, FRC_CDR_ISO_EN); + + /* release DA_MP_RX0_SQ_EN */ + mphy_set_bit(phy, MP_LN_DIG_RX_AC, RX_SQ_EN); + mphy_clr_bit(phy, MP_LN_DIG_RX_AC, FRC_RX_SQ_EN); + + /* delay 1us to wait DIFZ stable */ + udelay(1); + + /* release DIFZ */ + mphy_clr_bit(phy, MP_LN_DIG_RX_9C, FSM_DIFZ_FRC); +} + +static void ufs_mtk_phy_12nm_power_off(struct ufs_mtk_phy *phy) +{ + /* force DIFZ */ + mphy_set_bit(phy, MP_LN_DIG_RX_9C, FSM_DIFZ_FRC); + + /* force DA_MP_RX0_SQ_EN */ + mphy_set_bit(phy, MP_LN_DIG_RX_AC, FRC_RX_SQ_EN); + mphy_clr_bit(phy, MP_LN_DIG_RX_AC, RX_SQ_EN); + + /* force DA_MP_CDR_ISO_EN */ + mphy_set_bit(phy, MP_LN_RX_44, FRC_CDR_ISO_EN); + mphy_set_bit(phy, MP_LN_RX_44, CDR_ISO_EN); + + /* force DA_MP_CDR_PWR_ON */ + mphy_set_bit(phy, MP_LN_RX_44, FRC_CDR_PWR_ON); + mphy_clr_bit(phy, MP_LN_RX_44, CDR_PWR_ON); + + /* force DA_MP_PLL_ISO_EN */ + mphy_set_bit(phy, MP_GLB_DIG_8C, FRC_PLL_ISO_EN); + mphy_set_bit(phy, MP_GLB_DIG_8C, PLL_ISO_EN); + + /* force DA_MP_PLL_PWR_ON */ + mphy_set_bit(phy, MP_GLB_DIG_8C, FRC_FRC_PWR_ON); + mphy_clr_bit(phy, MP_GLB_DIG_8C, PLL_PWR_ON); +} + +static void ufs_mtk_phy_12nm_power_control(struct ufs_mtk_phy *phy, bool on) +{ + if (on) + ufs_mtk_phy_12nm_power_on(phy); + else + ufs_mtk_phy_12nm_power_off(phy); +} + +static const struct phy_ops ufs_mtk_phy_12nm_phy_ops = { + .power_on = ufs_mtk_phy_power_on, + .power_off = ufs_mtk_phy_power_off, + .owner = THIS_MODULE, +}; + +static struct ufs_mtk_phy_specific_ops phy_12nm_ops = { + .power_control = ufs_mtk_phy_12nm_power_control, +}; + +static int ufs_mtk_phy_12nm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct phy *generic_phy; + struct ufs_mtk_phy_12nm *phy; + int err = 0; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) { + err = -ENOMEM; + goto out; + } + + generic_phy = ufs_mtk_phy_generic_probe(pdev, &phy->common_cfg, + &ufs_mtk_phy_12nm_phy_ops, + &phy_12nm_ops); + + if (!generic_phy) { + dev_info(dev, "%s: ufs_mtk_phy_generic_probe() failed\n", + __func__); + err = -EIO; + goto out; + } + + phy_set_drvdata(generic_phy, phy); + + strlcpy(phy->common_cfg.name, MPHY_NAME, + sizeof(phy->common_cfg.name)); + + err = ufs_mtk_phy_init_clks(generic_phy, &phy->common_cfg); + if (err) { + dev_info(dev, + "%s: ufs_mtk_phy_init_clks() failed %d\n", + __func__, err); + } +out: + return err; +} + +static const struct of_device_id ufs_mtk_phy_12nm_of_match[] = { + {.compatible = "mediatek,ufs-mphy-12nm"}, + {}, +}; +MODULE_DEVICE_TABLE(of, ufs_mtk_phy_12nm_of_match); + +static struct platform_driver ufs_mtk_phy_12nm_driver = { + .probe = ufs_mtk_phy_12nm_probe, + .driver = { + .of_match_table = ufs_mtk_phy_12nm_of_match, + .name = "ufs_mtk_phy_12nm", + }, +}; +module_platform_driver(ufs_mtk_phy_12nm_driver); + +MODULE_DESCRIPTION("Universal Flash Storage (UFS) Mediatek MPHY 12nm"); diff --git a/drivers/phy/mediatek/phy-mtk-ufs-12nm.h b/drivers/phy/mediatek/phy-mtk-ufs-12nm.h new file mode 100644 index 000000000000..5ebcdbd8ec4d --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-ufs-12nm.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef UFS_MTK_PHY_12NM_H_ +#define UFS_MTK_PHY_12NM_H_ + +#include "phy-mtk-ufs.h" + +/* + * MPHY register and offsets + */ +#define MP_GLB_DIG_8C 0x008C +#define FRC_PLL_ISO_EN 0x00000100 +#define PLL_ISO_EN 0x00000200 +#define FRC_FRC_PWR_ON 0x00000400 +#define PLL_PWR_ON 0x00000800 + +#define MP_LN_DIG_RX_9C 0xA09C +#define FSM_DIFZ_FRC 0x00040000 + +#define MP_LN_DIG_RX_AC 0xA0AC +#define FRC_RX_SQ_EN 0x00000001 +#define RX_SQ_EN 0x00000002 + +#define MP_LN_RX_44 0xB044 +#define FRC_CDR_PWR_ON 0x00020000 +#define CDR_PWR_ON 0x00040000 +#define FRC_CDR_ISO_EN 0x00080000 +#define CDR_ISO_EN 0x00100000 + +/* + * This structure represents the 12nm specific phy. + * common_cfg MUST remain the first field in this structure + * in case extra fields are added. This way, when calling + * get_ufs_mtk_phy() of generic phy, we can extract the + * common phy structure (struct ufs_mtk_phy) out of it + * regardless of the relevant specific phy. + */ +struct ufs_mtk_phy_12nm { + struct ufs_mtk_phy common_cfg; +}; + +#endif diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c new file mode 100644 index 000000000000..68ed27eaf195 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-ufs.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include +#include +#include +#include +#include "phy-mtk-ufs.h" + +static int ufs_mtk_phy_base_init(struct platform_device *pdev, + struct ufs_mtk_phy *phy); + +struct phy +*ufs_mtk_phy_generic_probe(struct platform_device *pdev, + struct ufs_mtk_phy *common_cfg, + const struct phy_ops *ufs_mtk_phy_gen_ops, + struct ufs_mtk_phy_specific_ops *phy_spec_ops) +{ + int err; + struct device *dev = &pdev->dev; + struct phy *generic_phy = NULL; + struct phy_provider *phy_provider; + + err = ufs_mtk_phy_base_init(pdev, common_cfg); + if (err) { + dev_info(dev, "%s: phy base init failed %d\n", __func__, err); + goto out; + } + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(phy_provider)) { + err = PTR_ERR(phy_provider); + dev_info(dev, "%s: failed to register phy %d\n", __func__, err); + goto out; + } + + generic_phy = devm_phy_create(dev, NULL, ufs_mtk_phy_gen_ops); + if (IS_ERR(generic_phy)) { + err = PTR_ERR(generic_phy); + dev_info(dev, "%s: failed to create phy %d\n", __func__, err); + generic_phy = NULL; + goto out; + } + + common_cfg->phy_spec_ops = phy_spec_ops; + common_cfg->dev = dev; + +out: + return generic_phy; +} +EXPORT_SYMBOL_GPL(ufs_mtk_phy_generic_probe); + +/* + * This assumes the embedded phy structure inside generic_phy is of type + * struct ufs_mtk_phy. In order to function properly it's crucial + * to keep the embedded struct "struct ufs_mtk_phy common_cfg" + * as the first inside generic_phy. + */ +struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy) +{ + return (struct ufs_mtk_phy *)phy_get_drvdata(generic_phy); +} +EXPORT_SYMBOL_GPL(get_ufs_mtk_phy); + +static int ufs_mtk_phy_ctl_clk(struct ufs_mtk_phy *phy, + struct clk *clk, + bool on) +{ + int ret = 0; + + if (on) { + ret = clk_prepare_enable(clk); + if (ret) { + dev_info(phy->dev, + "%s: mp_clk enable failed %d\n", + __func__, ret); + goto out; + } + } else { + clk_disable_unprepare(clk); + } +out: + return ret; +} + +static int ufs_mtk_phy_ctl_clks(struct phy *generic_phy, bool on) +{ + struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy); + int ret; + + ret = ufs_mtk_phy_ctl_clk(phy, phy->unipro_clk, on); + if (ret) + goto out; + + ret = ufs_mtk_phy_ctl_clk(phy, phy->mp_clk, on); +out: + return ret; +} +EXPORT_SYMBOL_GPL(ufs_mtk_phy_ctl_clks); + +static int ufs_mtk_phy_base_init(struct platform_device *pdev, + struct ufs_mtk_phy *phy) +{ + struct device *dev = &pdev->dev; + struct resource *res; + int err = 0; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ufs_mphy"); + phy->mmio = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)phy->mmio)) { + err = PTR_ERR((void const *)phy->mmio); + phy->mmio = NULL; + dev_info(dev, "%s: ioremap for ufs_mphy resource failed %d\n", + __func__, err); + return err; + } + + return 0; +} + +static +int ufs_mtk_phy_clk_get(struct phy *phy, + const char *name, struct clk **clk_out) +{ + struct clk *clk; + int err = 0; + struct ufs_mtk_phy *ufs_mtk_phy = get_ufs_mtk_phy(phy); + struct device *dev = ufs_mtk_phy->dev; + + clk = devm_clk_get(dev, name); + if (IS_ERR(clk)) { + err = PTR_ERR(clk); + dev_info(dev, "failed to get %s err %d", name, err); + } else { + *clk_out = clk; + } + + return err; +} + +int ufs_mtk_phy_init_clks(struct phy *generic_phy, + struct ufs_mtk_phy *phy) +{ + int err; + + err = ufs_mtk_phy_clk_get(generic_phy, "ufs0-unipro-clk", + &phy->unipro_clk); + if (err) + goto out; + + err = ufs_mtk_phy_clk_get(generic_phy, "ufs0-mp-clk", + &phy->mp_clk); +out: + return err; +} +EXPORT_SYMBOL_GPL(ufs_mtk_phy_init_clks); + +int ufs_mtk_phy_power_on(struct phy *generic_phy) +{ + struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy); + + ufs_mtk_phy_ctl_clks(generic_phy, true); + phy->phy_spec_ops->power_control(phy, true); + + return 0; +} +EXPORT_SYMBOL_GPL(ufs_mtk_phy_power_on); + +int ufs_mtk_phy_power_off(struct phy *generic_phy) +{ + struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy); + + phy->phy_spec_ops->power_control(phy, false); + ufs_mtk_phy_ctl_clks(generic_phy, false); + + return 0; +} +EXPORT_SYMBOL_GPL(ufs_mtk_phy_power_off); + diff --git a/drivers/phy/mediatek/phy-mtk-ufs.h b/drivers/phy/mediatek/phy-mtk-ufs.h new file mode 100644 index 000000000000..7163aae2b56b --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-ufs.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef UFS_MTK_PHY_H_ +#define UFS_MTK_PHY_H_ + +#include +#include +#include +#include +#include + +#define UFS_MTK_PHY_NAME_LEN 30 + +#define mphy_readl(phy, ofs) readl((phy)->mmio + (ofs)) +#define mphy_writel(phy, val, ofs) writel((val), (phy)->mmio + (ofs)) + +#define mphy_set_bit(phy, reg, ofs) \ +do { \ + u32 val; \ + u32 _reg = (reg); \ + struct ufs_mtk_phy *_phy = (phy); \ + val = mphy_readl(_phy, _reg); \ + val = val | (ofs); \ + mphy_writel(_phy, val, _reg); \ +} while (0) + +#define mphy_clr_bit(phy, reg, ofs) \ +do { \ + u32 val; \ + u32 _reg = (reg); \ + struct ufs_mtk_phy *_phy = (phy); \ + val = mphy_readl(_phy, _reg); \ + val = val & ~(ofs); \ + mphy_writel(_phy, val, _reg); \ +} while (0) + +struct ufs_mtk_phy { + struct device *dev; + void __iomem *mmio; + struct clk *mp_clk; + struct clk *unipro_clk; + char name[UFS_MTK_PHY_NAME_LEN]; + struct ufs_mtk_phy_specific_ops *phy_spec_ops; +}; + +/** + * struct ufs_mtk_phy_specific_ops - set of pointers to functions which have a + * specific implementation per phy. Each UFS phy, should implement + * those functions according to its spec and requirements + * @power_control: Control power on/off flow of phy. + */ +struct ufs_mtk_phy_specific_ops { + void (*power_control)(struct ufs_mtk_phy *phy, bool on); +}; + +struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy); +int ufs_mtk_phy_power_on(struct phy *generic_phy); +int ufs_mtk_phy_power_off(struct phy *generic_phy); +int ufs_mtk_phy_init_clks(struct phy *generic_phy, + struct ufs_mtk_phy *phy_common); +struct phy +*ufs_mtk_phy_generic_probe(struct platform_device *pdev, + struct ufs_mtk_phy *common_cfg, + const struct phy_ops *ufs_mtk_phy_gen_ops, + struct ufs_mtk_phy_specific_ops *phy_spec_ops); +#endif From patchwork Mon Feb 25 09:24:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 10828389 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0605913B5 for ; Mon, 25 Feb 2019 09:25:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E29202AACA for ; Mon, 25 Feb 2019 09:25:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D68952AC2A; Mon, 25 Feb 2019 09:25:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 17B6E2AC27 for ; Mon, 25 Feb 2019 09:25:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=vIzQZ9aCbldWVVhFsVRvm3wUCmhkr7of+B50fI3LtJ4=; b=SuMLKeMbKB49+L Vg0IcfTLP+CTRYNGwWBjvg+HqtjxnKD37zef49AbpVKaLMDj+c04x9jwERgD97oE/Ib+1R0qqOAVS s6AY4J8Vyu/e7JwNLnaMGyi+4ggNzrv6gG/w4RdlccNLuuwpi+STvlguur2lb5VCaIgNhM1kACflm rKDcMa5kWH+ssDYSjo4xMsw+5NSisZ1fNWS2/BJ12w5ui1oMyEYurru8Is2k1rSogKv3aKN6BA7XY AmozWV2UtVkvPlRHVjW7Rrw4D8mL4ue15vhmT0FjEGPeE56gxgghKYgGe7MA2u6Z/oFsGTcQ8n8Um iKET+gkrDwhwqyyAvpIg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVg-0006WU-ER; Mon, 25 Feb 2019 09:25:16 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gyCVQ-000539-T5 for linux-mediatek@lists.infradead.org; Mon, 25 Feb 2019 09:25:10 +0000 X-UUID: 339898e2e6294ba1ae04f16b9fb7a259-20190225 X-UUID: 339898e2e6294ba1ae04f16b9fb7a259-20190225 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 95264264; Mon, 25 Feb 2019 01:24:40 -0800 Received: from mtkmbs08n1.mediatek.inc (172.21.101.55) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 01:24:39 -0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs08n1.mediatek.inc (172.21.101.55) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 25 Feb 2019 17:24:37 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 25 Feb 2019 17:24:37 +0800 From: To: , , , , , , , , , , Subject: [PATCH v2 6/6] scsi: ufs-mediatek: Add UFS support for Mediatek SoC chips Date: Mon, 25 Feb 2019 17:24:15 +0800 Message-ID: <1551086655-5029-8-git-send-email-stanley.chu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> References: <1551086655-5029-1-git-send-email-stanley.chu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190225_012501_359660_DBD48C23 X-CRM114-Status: GOOD ( 21.42 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org, liwei213@huawei.com, vivek.gautam@codeaurora.org, subhashj@codeaurora.org, Stanley Chu , peter.wang@mediatek.com Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanley Chu This patch adds UFS support for Mediatek SoC chips. Signed-off-by: Stanley Chu Reviewed-by: Avri Altman --- drivers/scsi/ufs/Kconfig | 14 ++ drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-mediatek.c | 377 ++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-mediatek.h | 61 ++++++ 4 files changed, 453 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-mediatek.c create mode 100644 drivers/scsi/ufs/ufs-mediatek.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 2ddbb26d9c26..58e5a9c8eb5d 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -109,6 +109,20 @@ config SCSI_UFS_QCOM Select this if you have UFS controller on QCOM chipset. If unsure, say N. +config SCSI_UFS_MEDIATEK + tristate "Mediatek specific hooks to UFS controller platform driver" + depends on SCSI_UFSHCD_PLATFORM && ARCH_MEDIATEK + select PHY_MTK_UFS + help + This selects the Mediatek specific additions to UFSHCD platform driver. + UFS host on Mediatek needs some vendor specific configuration before + accessing the hardware which includes PHY configuration and vendor + specific registers. + + Select this if you have UFS controller on Mediatek chipset. + + If unsure, say N. + config SCSI_UFS_HISI tristate "Hisilicon specific hooks to UFS controller platform driver" depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index a3bd70c3652c..2a9097939bcb 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -10,3 +10,4 @@ ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o +obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c new file mode 100644 index 000000000000..ce633dff5888 --- /dev/null +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Authors: + * Stanley Chu + * Peter Wang + * + * Copyright (C) 2019 MediaTek Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "unipro.h" +#include "ufs-mediatek.h" + +void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable) +{ + u32 tmp; + + if (enable) { + ufshcd_dme_get(hba, + UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp); + tmp = tmp | + (1 << RX_SYMBOL_CLK_GATE_EN) | + (1 << SYS_CLK_GATE_EN) | + (1 << TX_CLK_GATE_EN); + ufshcd_dme_set(hba, + UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp); + + ufshcd_dme_get(hba, + UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), &tmp); + tmp = tmp & ~(1 << TX_SYMBOL_CLK_REQ_FORCE); + ufshcd_dme_set(hba, + UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), tmp); + } else { + ufshcd_dme_get(hba, + UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp); + tmp = tmp & ~((1 << RX_SYMBOL_CLK_GATE_EN) | + (1 << SYS_CLK_GATE_EN) | + (1 << TX_CLK_GATE_EN)); + ufshcd_dme_set(hba, + UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp); + + ufshcd_dme_get(hba, + UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), &tmp); + tmp = tmp | (1 << TX_SYMBOL_CLK_REQ_FORCE); + ufshcd_dme_set(hba, + UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), tmp); + } +} + +int ufs_mtk_bind_mphy(struct ufs_hba *hba) +{ + struct ufs_mtk_host *host = ufshcd_get_variant(hba); + struct device *dev = hba->dev; + int err = 0; + + host->mphy = devm_phy_get(dev, "ufsphy"); + + if (host->mphy == ERR_PTR(-EPROBE_DEFER)) { + /* + * UFS driver might be probed before the phy driver does. + * In that case we would like to return EPROBE_DEFER code. + */ + err = -EPROBE_DEFER; + dev_info(dev, + "%s: required phy hasn't probed yet. err = %d\n", + __func__, err); + } else if (IS_ERR(host->mphy)) { + err = PTR_ERR(host->mphy); + dev_info(dev, "%s: PHY get failed %d\n", __func__, err); + } + + if (err) + host->mphy = NULL; + + return err; +} + +/** + * ufs_mtk_setup_clocks - enables/disable clocks + * @hba: host controller instance + * @on: If true, enable clocks else disable them. + * @status: PRE_CHANGE or POST_CHANGE notify + * + * Returns 0 on success, non-zero on failure. + */ +static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on, + enum ufs_notify_change_status status) +{ + struct ufs_mtk_host *host = ufshcd_get_variant(hba); + int ret; + + /* + * In case ufs_mtk_init() is not yet done, simply ignore. + * This ufs_mtk_setup_clocks() shall be called from + * ufs_mtk_init() after init is done. + */ + if (!host) + return 0; + + switch (status) { + case PRE_CHANGE: + if (!on) + ret = phy_power_off(host->mphy); + break; + case POST_CHANGE: + if (on) { + pr_info("%s: phy_power_on\n", __func__); + ret = phy_power_on(host->mphy); + } + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/** + * ufs_mtk_init - find other essential mmio bases + * @hba: host controller instance + * + * Binds PHY with controller and powers up PHY enabling clocks + * and regulators. + * + * Returns -EPROBE_DEFER if binding fails, returns negative error + * on phy power up failure and returns zero on success. + */ +static int ufs_mtk_init(struct ufs_hba *hba) +{ + struct ufs_mtk_host *host; + struct device *dev = hba->dev; + int err = 0; + + host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); + if (!host) { + err = -ENOMEM; + dev_info(dev, "%s: no memory for mtk ufs host\n", __func__); + goto out; + } + + host->hba = hba; + ufshcd_set_variant(hba, host); + + err = ufs_mtk_bind_mphy(hba); + if (err) + goto out_variant_clear; + + /* + * ufshcd_vops_init() is invoked after + * ufshcd_setup_clock(true) in ufshcd_hba_init() thus + * phy clock setup is skipped. + * + * Enable phy clocks specifically here. + */ + ufs_mtk_setup_clocks(hba, true, POST_CHANGE); + + goto out; + +out_variant_clear: + ufshcd_set_variant(hba, NULL); +out: + return err; +} + +static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba, + struct ufs_pa_layer_attr *dev_max_params, + struct ufs_pa_layer_attr *dev_req_params) +{ + struct ufs_dev_params host_cap; + int ret; + + host_cap.tx_lanes = UFS_MTK_LIMIT_NUM_LANES_TX; + host_cap.rx_lanes = UFS_MTK_LIMIT_NUM_LANES_RX; + host_cap.hs_rx_gear = UFS_MTK_LIMIT_HSGEAR_RX; + host_cap.hs_tx_gear = UFS_MTK_LIMIT_HSGEAR_TX; + host_cap.pwm_rx_gear = UFS_MTK_LIMIT_PWMGEAR_RX; + host_cap.pwm_tx_gear = UFS_MTK_LIMIT_PWMGEAR_TX; + host_cap.rx_pwr_pwm = UFS_MTK_LIMIT_RX_PWR_PWM; + host_cap.tx_pwr_pwm = UFS_MTK_LIMIT_TX_PWR_PWM; + host_cap.rx_pwr_hs = UFS_MTK_LIMIT_RX_PWR_HS; + host_cap.tx_pwr_hs = UFS_MTK_LIMIT_TX_PWR_HS; + host_cap.hs_rate = UFS_MTK_LIMIT_HS_RATE; + host_cap.desired_working_mode = + UFS_MTK_LIMIT_DESIRED_MODE; + + ret = ufshcd_get_pwr_dev_param(&host_cap, + dev_max_params, + dev_req_params); + if (ret) { + pr_info("%s: failed to determine capabilities\n", + __func__); + } + + return ret; +} + +static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba, + enum ufs_notify_change_status stage, + struct ufs_pa_layer_attr *dev_max_params, + struct ufs_pa_layer_attr *dev_req_params) +{ + int ret = 0; + + switch (stage) { + case PRE_CHANGE: + ret = ufs_mtk_pre_pwr_change(hba, dev_max_params, + dev_req_params); + break; + case POST_CHANGE: + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int ufs_mtk_pre_link(struct ufs_hba *hba) +{ + int ret; + u32 tmp; + + /* disable deep stall */ + ret = ufshcd_dme_get(hba, UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp); + if (ret) + return ret; + + tmp &= ~(1 << 6); + + ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp); + + return ret; +} + +static int ufs_mtk_post_link(struct ufs_hba *hba) +{ + /* disable device LCC */ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); + + /* enable unipro clock gating feature */ + ufs_mtk_cfg_unipro_cg(hba, true); + + return 0; +} + +static int ufs_mtk_link_startup_notify(struct ufs_hba *hba, + enum ufs_notify_change_status stage) +{ + int ret = 0; + + switch (stage) { + case PRE_CHANGE: + ret = ufs_mtk_pre_link(hba); + break; + case POST_CHANGE: + ret = ufs_mtk_post_link(hba); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) +{ + struct ufs_mtk_host *host = ufshcd_get_variant(hba); + + if (ufshcd_is_link_hibern8(hba)) + phy_power_off(host->mphy); + + return 0; +} + +static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) +{ + struct ufs_mtk_host *host = ufshcd_get_variant(hba); + + if (ufshcd_is_link_hibern8(hba)) + phy_power_on(host->mphy); + + return 0; +} + +/** + * struct ufs_hba_mtk_vops - UFS MTK specific variant operations + * + * The variant operations configure the necessary controller and PHY + * handshake during initialization. + */ +static struct ufs_hba_variant_ops ufs_hba_mtk_vops = { + .name = "mediatek.ufshci", + .init = ufs_mtk_init, + .setup_clocks = ufs_mtk_setup_clocks, + .link_startup_notify = ufs_mtk_link_startup_notify, + .pwr_change_notify = ufs_mtk_pwr_change_notify, + .suspend = ufs_mtk_suspend, + .resume = ufs_mtk_resume, +}; + +/** + * ufs_mtk_probe - probe routine of the driver + * @pdev: pointer to Platform device handle + * + * Return zero for success and non-zero for failure + */ +static int ufs_mtk_probe(struct platform_device *pdev) +{ + int err; + struct device *dev = &pdev->dev; + + /* perform generic probe */ + err = ufshcd_pltfrm_init(pdev, &ufs_hba_mtk_vops); + if (err) + dev_info(dev, "probe failed %d\n", err); + + return err; +} + +/** + * ufs_mtk_remove - set driver_data of the device to NULL + * @pdev: pointer to platform device handle + * + * Always return 0 + */ +static int ufs_mtk_remove(struct platform_device *pdev) +{ + struct ufs_hba *hba = platform_get_drvdata(pdev); + + pm_runtime_get_sync(&(pdev)->dev); + ufshcd_remove(hba); + return 0; +} + +const struct of_device_id ufs_mtk_of_match[] = { + { .compatible = "mediatek,ufshci"}, + {}, +}; + +static const struct dev_pm_ops ufs_mtk_pm_ops = { + .suspend = ufshcd_pltfrm_suspend, + .resume = ufshcd_pltfrm_resume, + .runtime_suspend = ufshcd_pltfrm_runtime_suspend, + .runtime_resume = ufshcd_pltfrm_runtime_resume, + .runtime_idle = ufshcd_pltfrm_runtime_idle, +}; + +static struct platform_driver ufs_mtk_pltform = { + .probe = ufs_mtk_probe, + .remove = ufs_mtk_remove, + .shutdown = ufshcd_pltfrm_shutdown, + .driver = { + .name = "ufshcd-mtk", + .owner = THIS_MODULE, + .pm = &ufs_mtk_pm_ops, + .of_match_table = ufs_mtk_of_match, + }, +}; + +module_platform_driver(ufs_mtk_pltform); + diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h new file mode 100644 index 000000000000..3c964e5d9077 --- /dev/null +++ b/drivers/scsi/ufs/ufs-mediatek.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _UFS_MEDIATEK_H +#define _UFS_MEDIATEK_H + +/* + * Vendor specific pre-defined parameters + */ +#define UFS_MTK_LIMIT_NUM_LANES_RX 1 +#define UFS_MTK_LIMIT_NUM_LANES_TX 1 +#define UFS_MTK_LIMIT_HSGEAR_RX UFS_HS_G3 +#define UFS_MTK_LIMIT_HSGEAR_TX UFS_HS_G3 +#define UFS_MTK_LIMIT_PWMGEAR_RX UFS_PWM_G4 +#define UFS_MTK_LIMIT_PWMGEAR_TX UFS_PWM_G4 +#define UFS_MTK_LIMIT_RX_PWR_PWM SLOW_MODE +#define UFS_MTK_LIMIT_TX_PWR_PWM SLOW_MODE +#define UFS_MTK_LIMIT_RX_PWR_HS FAST_MODE +#define UFS_MTK_LIMIT_TX_PWR_HS FAST_MODE +#define UFS_MTK_LIMIT_HS_RATE PA_HS_MODE_B +#define UFS_MTK_LIMIT_DESIRED_MODE UFS_HS_MODE + +/* + * Other attributes + */ +#define VS_DEBUGCLOCKENABLE 0xD0A1 +#define VS_SAVEPOWERCONTROL 0xD0A6 +#define VS_UNIPROPOWERDOWNCONTROL 0xD0A8 + +/* + * VS_DEBUGCLOCKENABLE + */ +enum { + TX_SYMBOL_CLK_REQ_FORCE = 5, +}; + +/* + * VS_SAVEPOWERCONTROL + */ +enum { + RX_SYMBOL_CLK_GATE_EN = 0, + SYS_CLK_GATE_EN = 2, + TX_CLK_GATE_EN = 3, +}; + +struct ufs_mtk_host { + struct ufs_hba *hba; + struct phy *mphy; +}; + +#endif /* !_UFS_MEDIATEK_H */ +