From patchwork Thu May 14 00:39:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547653 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 344E2138A for ; Thu, 14 May 2020 00:53:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 288F820693 for ; Thu, 14 May 2020 00:53:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="iq9bV2Mv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729439AbgENAxv (ORCPT ); Wed, 13 May 2020 20:53:51 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:45789 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727033AbgENAw6 (ORCPT ); Wed, 13 May 2020 20:52:58 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200514005255epoutp018bdd42adbf9a18dc81fae215e07aba6a~Ovt0RwevN2952029520epoutp01r for ; Thu, 14 May 2020 00:52:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200514005255epoutp018bdd42adbf9a18dc81fae215e07aba6a~Ovt0RwevN2952029520epoutp01r DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417575; bh=HK/1/VP5ov7EOoNpQ0X08DtlhI52O+2EyAZ3cTvlQkI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iq9bV2MvKBaOd4OJVeKR6lAshvSH27Q+7A3iAfWowsketrFby9TCRt2YUM7y7pdX1 Lmd1Spbxo4y04ptgTGF+RPLZd9v6j+1hmvOcudsVMFjAWJ2ljzx0hAv9iWeazxpTft C5Jp5AD9GJtDGgeGrPkn2oWVnuw7NdVhBNMxIc0c= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200514005254epcas5p4e1a104efe68d28acdbb3e0768208a94e~OvtznjCWp1376013760epcas5p4-; Thu, 14 May 2020 00:52:54 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 95.45.10010.6669CBE5; Thu, 14 May 2020 09:52:54 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20200514005254epcas5p27e2ef61a6d7f595ff2eaf4ec65940cf6~OvtzOhf9E1337713377epcas5p2E; Thu, 14 May 2020 00:52:54 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200514005254epsmtrp1fa7c612eaa29d07db168f66d1a091dae~OvtzNnQGq1028710287epsmtrp1j; Thu, 14 May 2020 00:52:54 +0000 (GMT) X-AuditID: b6c32a49-71fff7000000271a-ee-5ebc9666ccf5 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 6C.C3.18461.5669CBE5; Thu, 14 May 2020 09:52:53 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005252epsmtip2f8c61bf224dc7b461d8ca8f6611a8818~OvtxTQi6n3205832058epsmtip2k; Thu, 14 May 2020 00:52:51 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 01/10] scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr Date: Thu, 14 May 2020 06:09:05 +0530 Message-Id: <20200514003914.26052-2-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmphleLIzCtJLcpLzFFi42LZdlhTUzdt2p44g8eHxC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxouja1gKdgtU7P9wnLmB8TVvFyMnh4SAicT/nUsZuxi5OIQEdjNKPLu6jxnC +cQo8anjNRuE841R4uWKw0wwLWcvLYBq2cso8efUWSYIp4VJ4tG+VlaQKjYBbYm707eAdYgI CEsc+dbGCGIzC9xgkniw0gXEFhYIkZi+/AALiM0ioCqxbd5SMJtXwEbi0btHzBDb5CVWbzgA ZnMK2Eps+XKMFWSZhEAnh8SxKe/YIYpcgM6DWCwBtOzV8S1QcSmJl/1tQDYHkJ0t0bPLGCJc I7F03jEWCNte4sCVOSwgJcwCmhLrd+lDnMkn0fv7CRNEJ69ER5sQRLWqRPO7q1Cd0hITu7uh lnpIHJ7SAA25CYwSpzuWsk1glJ2FMHUBI+MqRsnUguLc9NRi0wLDvNRyveLE3OLSvHS95Pzc TYzghKLluYPx7oMPeocYmTgYDzFKcDArifD6rd8dJ8SbklhZlVqUH19UmpNafIhRmoNFSZz3 dNqWOCGB9MSS1OzU1ILUIpgsEwenVANTSJnzMv5rL39Y3Mt0iLvRx/S56k3xjSSHrhmCTzep WJ2tOt9iKMnLwf5Hd9/bgjmJL/fFnYsN/fJddLP5IQ0nrssbfn2R8vxs6v/4YsxzLpWUT+er dX3XXqp508mrVOOz4XZbYI+2p//pZ1947glPZNnwM806SH4CT/BJ1867W42F65NmXvY3dD6p tOPBwhCP2SyJlQ688yy+51fWM86ckSvNXvuHW3TupkzzXsuCKxc4by2Ka8iqP+Ip2X/E5KGY 90yPxOTYsobjCVuOTPnM1NjHdEh56eLfqqoKs+xt0lwSOLR/qMl1mAezzn1975Pa29T1Z380 5uhM2niK2/bm2eaPLVoPRIvjy2eHTVNiKc5INNRiLipOBACNXPbjlwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvG7qtD1xBscfWlo8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujBdH17AU7Bao2P/hOHMD42veLkZODgkBE4mzlxYwdjFycQgJ7GaUeLV6BjNE Qlri+sYJ7BC2sMTKf8/ZIYqamCTOP1/KBJJgE9CWuDt9C5gtAlR05FsbI4jNLPCMSeLUw1IQ W1ggSKKz8wPYIBYBVYlt85aygNi8AjYSj949glomL7F6wwEwm1PAVmLLl2OsILYQUM2yNcsY JzDyLWBkWMUomVpQnJueW2xYYJiXWq5XnJhbXJqXrpecn7uJERzOWpo7GLev+qB3iJGJg/EQ owQHs5IIr9/63XFCvCmJlVWpRfnxRaU5qcWHGKU5WJTEeW8ULowTEkhPLEnNTk0tSC2CyTJx cEo1MEU+O7ZK3TMjRdpH5+OTebG7TsqITjglXarYLNs1qXf95ccX9x7atVxyJRvD1udpddck DFm1lu1PW9zU/m75opfzX4Z5qLzdXc3/WIMtY2/D6vt1N0zdX/XczSsIC/njvWr9Qk4Hhazv UusYZuinv7cW21vvf+7ppyqlrO2yx7yfVNXbHXqUsWP+RaPjf/sVtCu4lbhCtgdNV9mXLhLp /narxgVdC5EraR1FRzlPfMh4bPkn4sMXlwMLn592r5zJbLclNV7V5tZh31kbn0eINi+Y4jBd ek35+iMVi2TyfH+KPvpm+FNhL++i3ktyLgzsISK1oTtCLAX4lm6Kelwf97TOWLZRNuBy1f2d 2zg2hCuxFGckGmoxFxUnAgD+I2701gIAAA== X-CMS-MailID: 20200514005254epcas5p27e2ef61a6d7f595ff2eaf4ec65940cf6 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005254epcas5p27e2ef61a6d7f595ff2eaf4ec65940cf6 References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org In the right behavior, setting the bit to '0' indicates clear and '1' indicates no change. If host controller handles this the other way, UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR can be used. Reviewed-by: Can Guo Reviewed-by: Avri Altman Signed-off-by: Seungwon Jeon Signed-off-by: Alim Akhtar --- drivers/scsi/ufs/ufshcd.c | 11 +++++++++-- drivers/scsi/ufs/ufshcd.h | 5 +++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 698e8d20b4ba..3655b88fc862 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -645,7 +645,11 @@ static inline int ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp) */ static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) { - ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR); + if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR) + ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR); + else + ufshcd_writel(hba, ~(1 << pos), + REG_UTP_TRANSFER_REQ_LIST_CLEAR); } /** @@ -655,7 +659,10 @@ static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) */ static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos) { - ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR); + if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR) + ufshcd_writel(hba, (1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR); + else + ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR); } /** diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 6ffc08ad85f6..071f0edf3f64 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -518,6 +518,11 @@ enum ufshcd_quirks { * ops (get_ufs_hci_version) to get the correct version. */ UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION = 1 << 5, + + /* + * Clear handling for transfer/task request list is just opposite. + */ + UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR = 1 << 6, }; enum ufshcd_caps { From patchwork Thu May 14 00:39:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547609 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2FA3D138A for ; Thu, 14 May 2020 00:53:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 257FD20794 for ; Thu, 14 May 2020 00:53:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="DSfpMS2n" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729439AbgENAw7 (ORCPT ); Wed, 13 May 2020 20:52:59 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:46095 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727792AbgENAw7 (ORCPT ); Wed, 13 May 2020 20:52:59 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20200514005257epoutp0490b71c14987a7489c9596ef3a08cd4d8~Ovt19fvtj0849708497epoutp04N for ; Thu, 14 May 2020 00:52:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20200514005257epoutp0490b71c14987a7489c9596ef3a08cd4d8~Ovt19fvtj0849708497epoutp04N DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417577; bh=aZlGHc5xTiWwAyuHWOUJ6KyldBblFcw6DUpelUfBEa8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DSfpMS2ndcpknIiMrCtxJivV32Az463RSVmQr16ub9DM2QC7f73URoOpWQMM6MHAH jWLDv72FcdGUr1TYcG0H0SxkJLZtW8ojog7ba3yewYNsek7Ah+hFo/KjoGyQEfQUPx sRNExHdYMybC5zSXKJOynJ9ChKu2ymZ8i5kh9I64= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200514005256epcas5p4b505d9649ce18325762618aec51307c7~Ovt1eyqxo0590005900epcas5p4C; Thu, 14 May 2020 00:52:56 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id 6F.6E.23389.8669CBE5; Thu, 14 May 2020 09:52:56 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200514005256epcas5p3ccb5dcc7c96a5cdb9ee78baa8ec1e0d3~Ovt1MOmZ31579215792epcas5p3g; Thu, 14 May 2020 00:52:56 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200514005256epsmtrp2b62267b832bfb80b95da4fe730197dff~Ovt1LCi-a1517815178epsmtrp2P; Thu, 14 May 2020 00:52:56 +0000 (GMT) X-AuditID: b6c32a4b-797ff70000005b5d-de-5ebc9668bdcc Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id CD.C3.18461.8669CBE5; Thu, 14 May 2020 09:52:56 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005254epsmtip23012c0682b1f1e83ceeba407574e8b52~OvtzTUsvL0172201722epsmtip2M; Thu, 14 May 2020 00:52:54 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 02/10] scsi: ufs: add quirk to disallow reset of interrupt aggregation Date: Thu, 14 May 2020 06:09:06 +0530 Message-Id: <20200514003914.26052-3-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdlhTQzdj2p44g11bpSwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxrbd79gKbvFUTDh+i7mB8TJXFyMnh4SAicTHuRPYuhi5OIQEdjNKnG9ayAjh fGKUuPKtB8r5xihx4/pmZpiW9dvuMkEk9jJKHJs1iwUkISTQwiRx56geiM0moC1xd/oWJhBb REBY4si3NkYQm1ngBpPEg5UuILawQLTE13e32UFsFgFViVldrawgNq+AjcT9numsEMvkJVZv OAC2mFPAVmLLl2NQ8VYOifMtEhC2i8Ta2esYIWxhiVfHt7BD2FISn9/tBfqNA8jOlujZZQwR rpFYOu8YC4RtL3HgyhwWkBJmAU2J9bv0Ia7kk+j9/YQJopNXoqNNCKJaVaL53VWoTmmJid3d UMd4SCzddRMaiBMYJf7c+c42gVF2FsLUBYyMqxglUwuKc9NTi00LjPNSy/WKE3OLS/PS9ZLz czcxgpOJlvcOxkcPPugdYmTiYDzEKMHBrCTC67d+d5wQb0piZVVqUX58UWlOavEhRmkOFiVx 3seNW+KEBNITS1KzU1MLUotgskwcnFINTJyx7maZ5i8ecMzqZX/6PmvKS7WLGd26S96JeodM rDebP+mv51chLodDtS0349f/YTX4vdsh2Fd949oQoxuiAjVVnbvfT2ETEGlp6H/wgO/wl/Xz 054b69fdcV0itGqie8J15Q9OosHrtr0K+FPbt+eCS+qHxdfb22W2+Wt658d9en42+rNyiPWt f2Ga9feP/Pkcnqv/vfHTU8+8yJOHGj2Sb+y8uGp5+fGZ03Ircj+JOejlMh+OdSxKtG3PCbab sasn8P/vC/Mrw1Y8vSzpmnl1kU+LkLq7S8nv2c4TE7O9Lv5/nZ2fsTHH4oBc4pq5ohVXp1qV /1frrQp0OsWZ9mD+ZJ0D26TtGFdrqs5UV2Ipzkg01GIuKk4EABwlMJWVAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvG7GtD1xBg8+s1o8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujG2737EV3OKpmHD8FnMD42WuLkZODgkBE4n12+4ydTFycQgJ7GaUuPbrHCNE Qlri+sYJ7BC2sMTKf8/ZIYqamCRedRxkBUmwCWhL3J2+hQnEFgEqOvKtDayZWeAZk8Sph6Ug trBApMSLN4uZQWwWAVWJWV2tYL28AjYS93ums0IskJdYveEAWA2ngK3Eli/HwOJCQDXL1ixj nMDIt4CRYRWjZGpBcW56brFhgWFearlecWJucWleul5yfu4mRnA4a2nuYNy+6oPeIUYmDsZD jBIczEoivH7rd8cJ8aYkVlalFuXHF5XmpBYfYpTmYFES571RuDBOSCA9sSQ1OzW1ILUIJsvE wSnVwCQRrlkh5rroxqbVbhuONgvFCWtwxs7dttDkRMwNyas/uGQ1m212rhV6tXP2HdY/Xxk0 v/Q+dhHPm/H3q7qwthcXp8AkcYb31TlL9f6KXC1jvBMpGK5wzTAqo4v11t+QHu4QZ/6OS5I3 Jq1fO3PW7ecGshv3BeYzNGyWZH1+s7ec+cnDJ3XupWLrricav1k41/V2g/FX0db315dzLLz8 et+5rpY873nfLHf3Hj8Y2Bduf3PTP1eFCrEVn42D4zWvsIYol/dErL4+x1dqNs/NI7Mu2TU+ Omr2zLf40u7g/jmJ/T/iMn9ktPQGGdpVRp9eEizUvyHSrrdc/nsmn0isfb5o7MvesNuVmQ1c ZTpvlFiKMxINtZiLihMBecJRa9YCAAA= X-CMS-MailID: 20200514005256epcas5p3ccb5dcc7c96a5cdb9ee78baa8ec1e0d3 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005256epcas5p3ccb5dcc7c96a5cdb9ee78baa8ec1e0d3 References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Some host controllers support interrupt aggregation but don't allow resetting counter and timer in software. Reviewed-by: Avri Altman Signed-off-by: Seungwon Jeon Signed-off-by: Alim Akhtar --- drivers/scsi/ufs/ufshcd.c | 3 ++- drivers/scsi/ufs/ufshcd.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3655b88fc862..0e9704da58bd 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4884,7 +4884,8 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) * false interrupt if device completes another request after resetting * aggregation and before reading the DB. */ - if (ufshcd_is_intr_aggr_allowed(hba)) + if (ufshcd_is_intr_aggr_allowed(hba) && + !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 071f0edf3f64..53096642f9a8 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -523,6 +523,12 @@ enum ufshcd_quirks { * Clear handling for transfer/task request list is just opposite. */ UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR = 1 << 6, + + /* + * This quirk needs to be enabled if host controller doesn't allow + * that the interrupt aggregation timer and counter are reset by s/w. + */ + UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR = 1 << 7, }; enum ufshcd_caps { From patchwork Thu May 14 00:39:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547613 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ED54259D for ; Thu, 14 May 2020 00:53:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E30AD206DA for ; Thu, 14 May 2020 00:53:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="M6mF41Y/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730851AbgENAxF (ORCPT ); Wed, 13 May 2020 20:53:05 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:19134 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729486AbgENAxD (ORCPT ); Wed, 13 May 2020 20:53:03 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200514005259epoutp03277b014f5fb94f201014522f66e34f0f~Ovt4M3oIC0840308403epoutp03Q for ; Thu, 14 May 2020 00:52:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200514005259epoutp03277b014f5fb94f201014522f66e34f0f~Ovt4M3oIC0840308403epoutp03Q DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417579; bh=kDIy4u6dKypJDeZVrGE9ZKceZgeyPXJh8PvB97xxnQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M6mF41Y/BtfiekB8Pcgc6PuFg9Q79qhHnXtdISoM+7aWmDV90MvtjOeuGumyBF5r4 QjBGAfxh50HRY8I1n5VZ06Pq7Ti0CPE8z/Wq+8rPwK5na0daMVFi91DksXsUmzZkN7 irxJoDW0QgpL+CG4DGdFXt2OLz31tOQhxCcuL2F8= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200514005258epcas5p3724cb2da48af76bb5a8a43dc904bca0a~Ovt3vNDKD1578415784epcas5p3v; Thu, 14 May 2020 00:52:58 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id D2.7E.23389.A669CBE5; Thu, 14 May 2020 09:52:58 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20200514005258epcas5p14733cec8b9ca92e518a8d5a0c27f3f0b~Ovt3PWUKk0561005610epcas5p10; Thu, 14 May 2020 00:52:58 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200514005258epsmtrp2e3521a4d4c066e0c7deda812d688fdfd~Ovt3ObrY81522815228epsmtrp2F; Thu, 14 May 2020 00:52:58 +0000 (GMT) X-AuditID: b6c32a4b-7adff70000005b5d-e5-5ebc966a2298 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 7F.C3.18461.A669CBE5; Thu, 14 May 2020 09:52:58 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005256epsmtip2145bd29b7cd6852b8b9df882a496eb46~Ovt1Tgrin3258132581epsmtip2t; Thu, 14 May 2020 00:52:56 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 03/10] scsi: ufs: add quirk to enable host controller without hce Date: Thu, 14 May 2020 06:09:07 +0530 Message-Id: <20200514003914.26052-4-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA0WSaUwTURSFfTPTYWhSHIvEy6ppQAUVJIoZE1GMNZmESDAx/pCIVp1U2W0F NwQqiNJaAoIbkqIGlOIC1BErIpS6rzWiaI0gChg1pkqLonGplsH477v3nvPOzc2jcKlGFEBt ytjCqTIUaTJSTLRcC58+K+VQW/Lsn65ops/QQjLvvz8lGWfjKRFTc/2hiLHZmrwYO3+DYEz9 3SKmq7WaZI7Y2jFG98xMMqdv/cYYd5vZi6m7aEdxErarVI+xpoYSkr1Qm88W3ekg2KHBFwRb yjcg1mUKYfdadFgitUq8YAOXtimHU0UtXCveWPXOSmY1hWzbrRnGCtBd0CJvCui5cLG+kPCw lL6CQG9O0iLxX3YicFXUIqH4iqDpvhb9c5TXHyWEwVUET3rtuFAUYdB79qOXR0XSM6DnMI95 eCLtC9e/Fo+6cfo5Bn1GuRZRlC+9Egy8ytMm6DAYvvB2VCKhF0Ab7/ASwibDmSYL7mFvOhb4 4ZsiTxbQeyjo7ikkBZEcut32se184cMtfswcAC7HVdKTBXQq7G+dI7Rzoc5wkxB4EVieVBMe CU6HQ2NrlLClD+h/DGCCUwL7iqWCOgwKHU/HnIFQrtOJBGbh4APj2BHLEFgO+ZWh4Kr/jx5H qAH5c1nqdCWnjsmak8FtjVQr0tXZGcrI9ZnpJjT6SyLizehN3+dIK8IoZEVA4bKJkoTGK8lS yQbF9h2cKnONKjuNU1tRIEXIJkn6NXyylFYqtnCpHJfFqf5NMco7oABbfGDgfPjqztxUeYWf PnjSq7jQ2J1xbNKvc76f/OeF3RtXW/iWPvxyJFHWY4zC+vFd28ROB1LeLg0aGiAua6Jqlijr oUA3v+Sb5VtXRczJkaROO559zcZXyU8Vxc5cwVu1d+vyHO2mUsullFh3ztTg/HVJPu7qmEWS GFPc/vC8nt3ez97Mfj6BSD79SNPhrKmsEF96PBhtMKMZPoPjwyIMna5fvS0lmcuXbbfd7z+m +ei/wm8uk98+1dk269Hk41SQsfxHZXPx1ub6O90JS43GsikhrzdPCa4D5syJFKNONhSf0yzP bQ91G9a25HUVDQd2JOrXVH45cHnau/koPkQlI9QbFdERuEqt+AOsnPX1lAMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvG7WtD1xBldu8lk8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujFkvDrEVbJCraGr8wtTAeEqii5GTQ0LARGLiipksXYxcHEICuxkl7nY0MUIk pCWub5zADmELS6z895wdoqiJSeL77/1gRWwC2hJ3p29hArFFgIqOfGsDizMLPGOSOPWwFMQW FgiR2Lb7G9ggFgFViS+bn4HV8ArYSOzZ8g5qgbzE6g0HmEFsTgFbiS1fjrGC2EJANcvWLGOc wMi3gJFhFaNkakFxbnpusWGBYV5quV5xYm5xaV66XnJ+7iZGcDhrae5g3L7qg94hRiYOxkOM EhzMSiK8fut3xwnxpiRWVqUW5ccXleakFh9ilOZgURLnvVG4ME5IID2xJDU7NbUgtQgmy8TB KdXAZBYq9CWkROPE5MSm4FPbJ1rdC1yr8mJihpvi9trKPyvV9VJ65r+8K6xvXLGigNXU43Ky fJH3x9PcfTaXvmodbkm4G6x4NiftWnLJ7J0zFuYlPY4Utn4pxxIjnmd1pTvEML37wWbOvr7H Bml3p8wJDHlWJ7i65UCAxYdNhUzye280H2D3EFfmOjn7tWPsOiOlwLXhVpd/vzTZM6H/9uQl nruPPXh3kvnPVNMFGpM/TYn8/HLTirzFehzzrq379dS5V3htQMBe8Y/HpzHJ2hiLtTXvPHZ0 W5uigrYx2+u7khkbVd41SMT6Lnk7vzzy8KdZE1d88/+zTPxBl0f0qft+OmvZymY9SG1IXjRN 1HYhkxJLcUaioRZzUXEiAIDAqmPWAgAA X-CMS-MailID: 20200514005258epcas5p14733cec8b9ca92e518a8d5a0c27f3f0b X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005258epcas5p14733cec8b9ca92e518a8d5a0c27f3f0b References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Some host controllers don't support host controller enable via HCE. Reviewed-by: Can Guo Reviewed-by: Avri Altman Signed-off-by: Seungwon Jeon Signed-off-by: Alim Akhtar --- drivers/scsi/ufs/ufshcd.c | 76 +++++++++++++++++++++++++++++++++++++-- drivers/scsi/ufs/ufshcd.h | 6 ++++ 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 0e9704da58bd..ee30ed6cc805 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3534,6 +3534,52 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba) "dme-link-startup: error code %d\n", ret); return ret; } +/** + * ufshcd_dme_reset - UIC command for DME_RESET + * @hba: per adapter instance + * + * DME_RESET command is issued in order to reset UniPro stack. + * This function now deal with cold reset. + * + * Returns 0 on success, non-zero value on failure + */ +static int ufshcd_dme_reset(struct ufs_hba *hba) +{ + struct uic_command uic_cmd = {0}; + int ret; + + uic_cmd.command = UIC_CMD_DME_RESET; + + ret = ufshcd_send_uic_cmd(hba, &uic_cmd); + if (ret) + dev_err(hba->dev, + "dme-reset: error code %d\n", ret); + + return ret; +} + +/** + * ufshcd_dme_enable - UIC command for DME_ENABLE + * @hba: per adapter instance + * + * DME_ENABLE command is issued in order to enable UniPro stack. + * + * Returns 0 on success, non-zero value on failure + */ +static int ufshcd_dme_enable(struct ufs_hba *hba) +{ + struct uic_command uic_cmd = {0}; + int ret; + + uic_cmd.command = UIC_CMD_DME_ENABLE; + + ret = ufshcd_send_uic_cmd(hba, &uic_cmd); + if (ret) + dev_err(hba->dev, + "dme-reset: error code %d\n", ret); + + return ret; +} static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba) { @@ -4251,7 +4297,7 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba, bool can_sleep) } /** - * ufshcd_hba_enable - initialize the controller + * ufshcd_hba_execute_hce - initialize the controller * @hba: per adapter instance * * The controller resets itself and controller firmware initialization @@ -4260,7 +4306,7 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba, bool can_sleep) * * Returns 0 on success, non-zero value on failure */ -int ufshcd_hba_enable(struct ufs_hba *hba) +static int ufshcd_hba_execute_hce(struct ufs_hba *hba) { int retry; @@ -4308,6 +4354,32 @@ int ufshcd_hba_enable(struct ufs_hba *hba) return 0; } + +int ufshcd_hba_enable(struct ufs_hba *hba) +{ + int ret; + + if (hba->quirks & UFSHCI_QUIRK_BROKEN_HCE) { + ufshcd_set_link_off(hba); + ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE); + + /* enable UIC related interrupts */ + ufshcd_enable_intr(hba, UFSHCD_UIC_MASK); + ret = ufshcd_dme_reset(hba); + if (!ret) { + ret = ufshcd_dme_enable(hba); + if (!ret) + ufshcd_vops_hce_enable_notify(hba, POST_CHANGE); + if (ret) + dev_err(hba->dev, + "Host controller enable failed with non-hce\n"); + } + } else { + ret = ufshcd_hba_execute_hce(hba); + } + + return ret; +} EXPORT_SYMBOL_GPL(ufshcd_hba_enable); static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 53096642f9a8..f8d08cb9caf7 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -529,6 +529,12 @@ enum ufshcd_quirks { * that the interrupt aggregation timer and counter are reset by s/w. */ UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR = 1 << 7, + + /* + * This quirks needs to be enabled if host controller cannot be + * enabled via HCE register. + */ + UFSHCI_QUIRK_BROKEN_HCE = 1 << 8, }; enum ufshcd_caps { From patchwork Thu May 14 00:39:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547645 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A56EC618 for ; Thu, 14 May 2020 00:53:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9AEE220794 for ; Thu, 14 May 2020 00:53:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="JIDWNnyl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730881AbgENAxF (ORCPT ); Wed, 13 May 2020 20:53:05 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:45844 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729973AbgENAxE (ORCPT ); Wed, 13 May 2020 20:53:04 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200514005302epoutp015af6475ae013b948f4bedc296fb04d7c~Ovt6p32O12942129421epoutp01G for ; Thu, 14 May 2020 00:53:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200514005302epoutp015af6475ae013b948f4bedc296fb04d7c~Ovt6p32O12942129421epoutp01G DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417582; bh=nPCI6KtKTzdjjbh5jTvGpI1fKN6gjrCt7WH8b1I6htY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JIDWNnyl+XfuRRDnU3d+KgrMk0nzdqPUK/FFTRjbvwVmw3f3OCbKM1DkjEG6eQhf0 PGh9m92Kj39McQEFOp7bihys70ZyjenuDEk2ow9Mva6hSXD+4D55oW+CA7rTZmViY+ gdI/c46vhcm3LVMO5QdkuHqNVmS5/bQ3oLqasC5o= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200514005301epcas5p12b499e4a67f841847287592c8d0d802a~Ovt6FMEZK1507415074epcas5p1H; Thu, 14 May 2020 00:53:01 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 2A.45.10010.D669CBE5; Thu, 14 May 2020 09:53:01 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20200514005300epcas5p4ce7ba7fe62567e7ba0066c96473853b2~Ovt5NBVm_0641706417epcas5p4H; Thu, 14 May 2020 00:53:00 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200514005300epsmtrp170edd15e00d54c024bd519712b5f3565~Ovt5L31Oz1129711297epsmtrp1L; Thu, 14 May 2020 00:53:00 +0000 (GMT) X-AuditID: b6c32a49-735ff7000000271a-03-5ebc966d3c8b Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 61.D3.18461.C669CBE5; Thu, 14 May 2020 09:53:00 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005258epsmtip2e0d7cfb9638c1a1d72cfc65a6b2f4d8c~Ovt3TdqWN0066800668epsmtip2I; Thu, 14 May 2020 00:52:58 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 04/10] scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk Date: Thu, 14 May 2020 06:09:08 +0530 Message-Id: <20200514003914.26052-5-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42LZdlhTXTd32p44g+5nghYP5m1js3j58yqb xaf1y1gt5h85x2px/vwGdoubW46yWGx6fI3V4vKuOWwWM87vY7Lovr6DzWL58X9MFv/37GC3 WLr1JqMDr8flvl4mj02rOtk8Ni+p92g5uZ/F4+PTWywefVtWMXp83iTn0X6gmymAI4rLJiU1 J7MstUjfLoEr4+OfbcwF20UrZrRcZW9gvCvYxcjJISFgIrHz3FG2LkYuDiGB3YwS764cY4dw PjFKfD7ezwxSJSTwjVHixicmmI7F576zQhTtZZS49ewLI4TTwiQx/chMVpAqNgFtibvTt4B1 iAgISxz51sYIYjML3GCSeLDSBcQWFgiSaNrWzQJiswioSszdshhsG6+AjcTT+efYIbbJS6ze cAAszilgK7HlyzGwzRICnRwS677fhypykZi84RYLhC0s8er4Fqi4lMTL/jYgmwPIzpbo2WUM Ea6RWDrvGFS5vcSBK3NYQEqYBTQl1u/ShziTT6L39xMmiE5eiY42IYhqVYnmd1ehOqUlJnZ3 s0LYHhKnj65kgQTDBEaJ3R/uM05glJ2FMHUBI+MqRsnUguLc9NRi0wLDvNRyveLE3OLSvHS9 5PzcTYzgdKLluYPx7oMPeocYmTgYDzFKcDArifD6rd8dJ8SbklhZlVqUH19UmpNafIhRmoNF SZz3dNqWOCGB9MSS1OzU1ILUIpgsEwenVANTzK/1ga5H+v/yP4u+Xr06k3Nh/qzo2hctQTpT 6kJ2a/wzL8uUWMrHYlfR7Gpvef/31DmJGXOvVMnKtZ1uD8huXfb1cZ92dcbuCrnPoqLdshoN 04XF/blkH9csVPNwbJ3YILn/lrfUFiaDPKOiWB9lztz7/Y/azht67bH+F8JhtEzm3PeLq8sU b2v/84jNMz+oU3rQhjc+7uwjLYs266nRvncn+DbH+7pyK84ItTy72vVonP+dLI9zphtFPxnb 6G+3W3Nx/qJvAvxVj/9G+n7Oydhy4vI7t4cJK1cf2/UxTiR0y1ShlwlNC299MBE492pj9SMm uaLnCnu48y7flVgjxRJSvGBHlJ3wktMnFiuxFGckGmoxFxUnAgAKIhw5lgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvG7OtD1xBiumSFg8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujI9/tjEXbBetmNFylb2B8a5gFyMnh4SAicTic99Zuxi5OIQEdjNKXLtwghUi IS1xfeMEdghbWGLlv+fsEEVNTBKX3j1hA0mwCWhL3J2+hQnEFgEqOvKtjRHEZhZ4xiRx6mEp iC0sECDxfe8isDiLgKrE3C2LmUFsXgEbiafzz0EtkJdYveEAWJxTwFZiy5djYEcIAdUsW7OM cQIj3wJGhlWMkqkFxbnpucWGBYZ5qeV6xYm5xaV56XrJ+bmbGMHhrKW5g3H7qg96hxiZOBgP MUpwMCuJ8Pqt3x0nxJuSWFmVWpQfX1Sak1p8iFGag0VJnPdG4cI4IYH0xJLU7NTUgtQimCwT B6dUA5Of/J0bJQk5Ez7p7cs5846tb+Hl1todZw+dSf+yl+mjiwJztfWBPYvs2qLjGhRMdv3a vtiv1OH8p40RoWL1U4Qm32o6NNuwyF5urm51R0Gh7USxDUvcv56IEY9WnmUn25KhV9J47cmB f0+6FoV8etqfI3L0GY/0nYaskL8tJk8kt+hz6W7ZfTHX8M+TZYHvLux62nPlab61vceTDxfy dqxa8komd4NTTGhFgU1J+on4OQXbdr27mqhz656E37VNUvb3zr62k/24zn3nBJ595dN6RPry /7yRzpN6fiC2Wi/lx/bXt7jz+DPvdiXcM83fxvniyDyboxZtOcKyLM80Xqi5V6T7Lp8te8LX J32Fu4QSS3FGoqEWc1FxIgAijn9D1gIAAA== X-CMS-MailID: 20200514005300epcas5p4ce7ba7fe62567e7ba0066c96473853b2 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005300epcas5p4ce7ba7fe62567e7ba0066c96473853b2 References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Some UFS host controllers like Exynos uses granularities of PRDT length and offset as bytes, whereas others uses actual segment count. Reviewed-by: Avri Altman Signed-off-by: Kiwoong Kim Signed-off-by: Alim Akhtar --- drivers/scsi/ufs/ufshcd.c | 30 +++++++++++++++++++++++------- drivers/scsi/ufs/ufshcd.h | 6 ++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ee30ed6cc805..ba093d0d0942 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2151,8 +2151,14 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) return sg_segments; if (sg_segments) { - lrbp->utr_descriptor_ptr->prd_table_length = - cpu_to_le16((u16)sg_segments); + + if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) + lrbp->utr_descriptor_ptr->prd_table_length = + cpu_to_le16((sg_segments * + sizeof(struct ufshcd_sg_entry))); + else + lrbp->utr_descriptor_ptr->prd_table_length = + cpu_to_le16((u16) (sg_segments)); prd_table = (struct ufshcd_sg_entry *)lrbp->ucd_prdt_ptr; @@ -3500,11 +3506,21 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) cpu_to_le32(upper_32_bits(cmd_desc_element_addr)); /* Response upiu and prdt offset should be in double words */ - utrdlp[i].response_upiu_offset = - cpu_to_le16(response_offset >> 2); - utrdlp[i].prd_table_offset = cpu_to_le16(prdt_offset >> 2); - utrdlp[i].response_upiu_length = - cpu_to_le16(ALIGNED_UPIU_SIZE >> 2); + if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) { + utrdlp[i].response_upiu_offset = + cpu_to_le16(response_offset); + utrdlp[i].prd_table_offset = + cpu_to_le16(prdt_offset); + utrdlp[i].response_upiu_length = + cpu_to_le16(ALIGNED_UPIU_SIZE); + } else { + utrdlp[i].response_upiu_offset = + cpu_to_le16(response_offset >> 2); + utrdlp[i].prd_table_offset = + cpu_to_le16(prdt_offset >> 2); + utrdlp[i].response_upiu_length = + cpu_to_le16(ALIGNED_UPIU_SIZE >> 2); + } ufshcd_init_lrb(hba, &hba->lrb[i], i); } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index f8d08cb9caf7..a9b9ace9fc72 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -535,6 +535,12 @@ enum ufshcd_quirks { * enabled via HCE register. */ UFSHCI_QUIRK_BROKEN_HCE = 1 << 8, + + /* + * This quirk needs to be enabled if the host controller regards + * resolution of the values of PRDTO and PRDTL in UTRD as byte. + */ + UFSHCD_QUIRK_PRDT_BYTE_GRAN = 1 << 9, }; enum ufshcd_caps { From patchwork Thu May 14 00:39:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547617 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 45FC614C0 for ; Thu, 14 May 2020 00:53:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 40D2C207BB for ; Thu, 14 May 2020 00:53:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="ASA7O6Ds" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727097AbgENAxI (ORCPT ); Wed, 13 May 2020 20:53:08 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:46151 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729166AbgENAxH (ORCPT ); Wed, 13 May 2020 20:53:07 -0400 Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20200514005303epoutp04229c7f6157330b2916cc1396fab0f148~Ovt8WBEe60770907709epoutp04S for ; Thu, 14 May 2020 00:53:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20200514005303epoutp04229c7f6157330b2916cc1396fab0f148~Ovt8WBEe60770907709epoutp04S DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417583; bh=8GKVEUkWRCQ4oEzg+kXJtv/h4uSMVZoIRkh5wQhVTwY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ASA7O6Dsy9m8BwwFJIq/MjQP2TGbOQELDzR8XqfaMKjs1mJrLrLXcnntgBz26A2aS riLJOUNW9zTLoRS0ZkfYPt4dekmftJQw68oo4znjDh1rhPByjXIGK13P6bGdbI36Dj VxDkei8wbZdtwa8e9Usu/RjyKxyh1c/K06qmw//0= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p2.samsung.com (KnoxPortal) with ESMTP id 20200514005303epcas5p20b4908df1bb8a0382aafb393ad782b84~Ovt73PI4f1336113361epcas5p28; Thu, 14 May 2020 00:53:03 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 75.DC.23569.F669CBE5; Thu, 14 May 2020 09:53:03 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20200514005302epcas5p1d2e99ba001cacc4d9e0d8dcf7de3155b~Ovt7ORcye0512105121epcas5p17; Thu, 14 May 2020 00:53:02 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200514005302epsmtrp1db91eb220531ddbb6a7d682f1f64e34d~Ovt7NAEjp1129711297epsmtrp1Z; Thu, 14 May 2020 00:53:02 +0000 (GMT) X-AuditID: b6c32a4a-3c7ff70000005c11-08-5ebc966f38f8 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 34.82.25866.E669CBE5; Thu, 14 May 2020 09:53:02 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005300epsmtip2369ac19e580cac567e91518bfa9bb408~Ovt5T1EGp3258132581epsmtip2v; Thu, 14 May 2020 00:53:00 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 05/10] scsi: ufs: add quirk to fix abnormal ocs fatal error Date: Thu, 14 May 2020 06:09:09 +0530 Message-Id: <20200514003914.26052-6-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42LZdlhTQzd/2p44gymf+C0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxqYjP9gK2vkq1l++yNzAeIa7i5GDQ0LAROLfWZ8uRi4OIYHdjBIv+uayQjif GCXuNr2Ecj4zSpyd8hbI4QTraPw3Eyqxi1GidcNKFginhUni86MFYFVsAtoSd6dvYQKxRQSE JY58a2MEsZkFbjBJPFjpAmILCwRIXG1qYgGxWQRUJS4sn8wGYvMK2EgcujSPHWKbvMTqDQeY QWxOAVuJLV+OgW2WEGjlkNj5fQoLRJGLxNJZfxkhbGGJV8e3QDVLSbzsb2OHeDRbomeXMUS4 RmLpvGNQrfYSB67MYQEpYRbQlFi/Sx/iTD6J3t9PmCA6eSU62oQgqlUlmt9dheqUlpjY3Q0N Ew+J840z2SDBMIFRovFVE9sERtlZCFMXMDKuYpRMLSjOTU8tNi0wykst1ytOzC0uzUvXS87P 3cQITidaXjsYHz74oHeIkYmD8RCjBAezkgiv3/rdcUK8KYmVValF+fFFpTmpxYcYpTlYlMR5 kxq3xAkJpCeWpGanphakFsFkmTg4pRqYkiO2hh3yrV0dW1t1WvPpagbuG7P7LhmtU13QLLau SGjl1/1xJ80P/PysHZXK/+qn6ZyLfAUFq4XLeTbwvpRv8PPwt/tg1/dgUez+r7u0Hz66ZPbv TZ5ZIJvE2XN9OkqZczRPHrF4H8B9izGu6a2d4ezm6NRYfaVkX869Fr8UlvtLVP9V4QQGuHBJ pOtKdta2lb9u3Raa87Qq/Xd033nzzQdfuDPv3vko/AZzzsWHjXPP1554Mp9h8YSVX1cGvXzw lomFMWTF8n/9pdOsvXWeTj8pMa1hh0T7HesYp58ZTQvPtqev8g9Ni2l7IV9eei03J0r4cdCO DYZdZ9fZ8my7dF91Z5ZF1OOwzzE1HPVKLMUZiYZazEXFiQA7sI+0lgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvG7etD1xBp2nFC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxqYjP9gK2vkq1l++yNzAeIa7i5GTQ0LARKLx30zWLkYuDiGBHYwSl0+sZ4NI SEtc3ziBHcIWllj57zk7RFETk8TJ2fOZQRJsAtoSd6dvYQKxRYCKjnxrYwSxmQWeMUmcelgK YgsL+Emc/rQBrIZFQFXiwvLJYAt4BWwkDl2aB7VAXmL1hgNgMzkFbCW2fDnGCmILAdUsW7OM cQIj3wJGhlWMkqkFxbnpucWGBUZ5qeV6xYm5xaV56XrJ+bmbGMHhrKW1g3HPqg96hxiZOBgP MUpwMCuJ8Pqt3x0nxJuSWFmVWpQfX1Sak1p8iFGag0VJnPfrrIVxQgLpiSWp2ampBalFMFkm Dk6pBqZDi16aqnBILjaZs9/RUWvSZHex14Yfu6cFbJHQrY4N2Zj1c2axzObnzy259/qe8F9t F7lBL+bTleiFVVtsovc83XhIMOx9kuEjlznr51vwx75S82e4U9isnHCdpVjjkl3OLrl7G6cx HHUpbK6P7nt+yIWn8bCPy+63UhZ+/Ef87zyuDsjb4jU/sV6sj/PbpMNnfcUzLkT9/Hpy22+5 9U+luv51J6sWt1udO/tAmc/xn0xnZN7x0NfWjdsT1nSUupmsc7C9He7wMPLcTwn7+2/j6iaL mBxZn1qn+DFty6nzddJ3pAQM3nKfCS6bHi31OYX1aJT7lWU7V79mrmLf4XrM/HogLytXgsf2 Ju21fEosxRmJhlrMRcWJABdlsjXWAgAA X-CMS-MailID: 20200514005302epcas5p1d2e99ba001cacc4d9e0d8dcf7de3155b X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005302epcas5p1d2e99ba001cacc4d9e0d8dcf7de3155b References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org From: Kiwoong Kim Some controller like Exynos determines if FATAL ERROR (0x7) in OCS field in UTRD occurs for values other than GOOD (0x0) in STATUS field in response upiu as well as errors that a host controller can't cover. This patch is to prevent from reporting command results in those cases. Signed-off-by: Kiwoong Kim Signed-off-by: Alim Akhtar Reviewed-by: Avri Altman --- drivers/scsi/ufs/ufshcd.c | 6 ++++++ drivers/scsi/ufs/ufshcd.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ba093d0d0942..33ebffa8257d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4794,6 +4794,12 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) /* overall command status of utrd */ ocs = ufshcd_get_tr_ocs(lrbp); + if (hba->quirks & UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR) { + if (be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_1) & + MASK_RSP_UPIU_RESULT) + ocs = OCS_SUCCESS; + } + switch (ocs) { case OCS_SUCCESS: result = ufshcd_get_req_rsp(lrbp->ucd_rsp_ptr); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index a9b9ace9fc72..e1d09c2c4302 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -541,6 +541,12 @@ enum ufshcd_quirks { * resolution of the values of PRDTO and PRDTL in UTRD as byte. */ UFSHCD_QUIRK_PRDT_BYTE_GRAN = 1 << 9, + + /* + * This quirk needs to be enabled if the host controller reports + * OCS FATAL ERROR with device error through sense data + */ + UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR = 1 << 10, }; enum ufshcd_caps { From patchwork Thu May 14 00:39:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547643 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A55C759D for ; Thu, 14 May 2020 00:53:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9B08320693 for ; Thu, 14 May 2020 00:53:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="fQdMBxEc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725952AbgENAxh (ORCPT ); Wed, 13 May 2020 20:53:37 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:46036 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731144AbgENAxK (ORCPT ); Wed, 13 May 2020 20:53:10 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20200514005306epoutp02774366a3cdf2ca9f4167d154dde0f92c~Ovt_faHre1752217522epoutp02- for ; Thu, 14 May 2020 00:53:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20200514005306epoutp02774366a3cdf2ca9f4167d154dde0f92c~Ovt_faHre1752217522epoutp02- DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417586; bh=DDMCtAVCNOenQhQBx8fCmPqcdSKUIHqMO34BELtm7U8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fQdMBxEc3L2+WffDjQ9ZV56VN5301Z5utWItEqJgRyaQciGK1BcJXcZU+7SUBVBRM 8U3VWtRlNrNMKU84V6bbAv+VdrIXrEBCsZspqCow5ER7PXE5u+EBjF7wquXBHtx20x Kd3txFE3WnIChBjbWqtUL34qMUmRXFyq964iUq50= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200514005305epcas5p46fe6ee93d80fa03efeb41a2d276f382a~Ovt9mHVCY0660506605epcas5p4K; Thu, 14 May 2020 00:53:05 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id 47.7E.23389.1769CBE5; Thu, 14 May 2020 09:53:05 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200514005304epcas5p37a311f813416383b6de8af6e809b350d~Ovt9REbwM0461904619epcas5p3S; Thu, 14 May 2020 00:53:04 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200514005304epsmtrp2db26465d2d8f3551167e82cf61e517fc~Ovt9QTndV1522815228epsmtrp2S; Thu, 14 May 2020 00:53:04 +0000 (GMT) X-AuditID: b6c32a4b-7adff70000005b5d-f9-5ebc9671d30c Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 17.82.25866.0769CBE5; Thu, 14 May 2020 09:53:04 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005302epsmtip2dbb136258d86cd9c3268230721ddeb37~Ovt7TwN1T0066900669epsmtip25; Thu, 14 May 2020 00:53:02 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 06/10] dt-bindings: phy: Document Samsung UFS PHY bindings Date: Thu, 14 May 2020 06:09:10 +0530 Message-Id: <20200514003914.26052-7-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrPKsWRmVeSWpSXmKPExsWy7bCmum7htD1xBqtesVs8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujF99+xkLLohWtMw6z97AeE2gi5GDQ0LAROLBj5IuRi4OIYHdjBL/m34xQTif GCXeH+sFcjiBnM+MEpdOeYHYIA2Nq64yQxTtYpTYs6aREaKohUnixpM0EJtNQFvi7vQtYM0i AsISR761gdUwC9xgkniw0gVks7CAv8SRdg8Qk0VAVeLQnXyQCl4BG4kt638wQ6ySl1i94QCY zSlgK7HlyzFWiBpBiZMzn7BATJSXaN46G+wcCYEDHBJTtp5hh2h2kZjZ0QtlC0u8Or4FypaS +PxuLxvE89kSPbuMIcI1EkvnHWOBsO0lDlyZwwJSwiygKbF+lz7EKj6J3t9PmCA6eSU62oQg qlUlmt9dheqUlpjY3c0KYXtI7L0+iR0SUBMYJTpenWCbwCg/C8kHs5B8MAth2wJG5lWMkqkF xbnpqcWmBcZ5qeV6xYm5xaV56XrJ+bmbGMFpSst7B+OjBx/0DjEycTAeYpTgYFYS4fVbvztO iDclsbIqtSg/vqg0J7X4EKM0B4uSOO/jxi1xQgLpiSWp2ampBalFMFkmDk6pBqaqKivHzeev L3lw/S3L5qfO2azVN71LL7IqKr3yucbat5fpXsLrY0tP753clm5boDOrmYv5YerrDRFGz0t+ JD2blDNZvzrA8s3CZYlMu6Im2M8JOyNx9sE+3X2Trb5++Xx/9Y3k7Bonlv5Ftl+l9S4tvf7z Je+zKwHbo5zsuOQeb9s+s1Y2+9ou7rynd8WCjmqwzNyyp+fZpWcXDpg8vs/ZfGLV7C3uczyf qC+//fnJ1fP1h45yPAg7Vz/5p8VKtWSz+Ye2Xe7ep25RoW6/qWbmPNHisB2/bndOKnp3e/YF BhfO1OnuK4x+J86Kr3Sa+9LxXtjamJa7DXwLni7e9UBi8uNWacc9p3dc2evnmLE6/Z8SS3FG oqEWc1FxIgCLmpb/wgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupgkeLIzCtJLcpLzFFi42LZdlhJXrdg2p44gxmHtSwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxq++/YwFF0QrWmadZ29gvCbQxcjJISFgItG46ipzFyMXh5DADkaJOTc/sEIk pCWub5zADmELS6z895wdoqiJSeLGisdsIAk2AW2Ju9O3MIHYIkBFR761MYLYzALPmCROPSwF sYUFfCVu7t7E0sXIwcEioCpx6E4+SJhXwEZiy/ofzBDz5SVWbzgAZnMK2Eps+XIM7AYhoJpl a5YxQtQLSpyc+QRsDLOAusT6eUIQm+QlmrfOZp7AKDgLSdUshKpZSKoWMDKvYpRMLSjOTc8t Niwwykst1ytOzC0uzUvXS87P3cQIjiwtrR2Me1Z90DvEyMTBeIhRgoNZSYTXb/3uOCHelMTK qtSi/Pii0pzU4kOM0hwsSuK8X2ctjBMSSE8sSc1OTS1ILYLJMnFwSjUwnSzbtp0r+FGlzVz+ qOTk0MlXW18tO9iofMzqR3yPzdvnj78/svd/suCzcMqKQ25n2f4emzm96GaX9NUF+gyquzj3 bmhtlYjZnVE1YV3vs5Vrlwhs0v59PnvngvY83skKgpvPrXvifeHDpGmWbRovQ+5O2H5TmTf+ ++ablTW5O1m73mut/ekasdhVxOSQrODp8vj9GjwXJt5itF6edujDnWn/n83wtJy2S5xpWXNy x0SmtLio1Or2fcKOsoYtZjtbfWYKTepQXHMo3b0nceO7CU139/9aHKhzlFHoXv/On9JT08xZ /zK+eVlyrvtZ2KJ9k86em7Hx57fcrv3ty5aJfc+bHVa10meiWdnUk68XH7+qxFKckWioxVxU nAgAMQZ56xsDAAA= X-CMS-MailID: 20200514005304epcas5p37a311f813416383b6de8af6e809b350d X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005304epcas5p37a311f813416383b6de8af6e809b350d References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch documents Samsung UFS PHY device tree bindings Reviewed-by: Rob Herring Signed-off-by: Alim Akhtar Tested-by: Paweł Chmiel --- .../bindings/phy/samsung,ufs-phy.yaml | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml new file mode 100644 index 000000000000..636cc501b54f --- /dev/null +++ b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/samsung,ufs-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung SoC series UFS PHY Device Tree Bindings + +maintainers: + - Alim Akhtar + +properties: + "#phy-cells": + const: 0 + + compatible: + enum: + - samsung,exynos7-ufs-phy + + reg: + maxItems: 1 + + reg-names: + items: + - const: phy-pma + + clocks: + items: + - description: PLL reference clock + - description: symbol clock for input symbol ( rx0-ch0 symbol clock) + - description: symbol clock for input symbol ( rx1-ch1 symbol clock) + - description: symbol clock for output symbol ( tx0 symbol clock) + + clock-names: + items: + - const: ref_clk + - const: rx1_symbol_clk + - const: rx0_symbol_clk + - const: tx0_symbol_clk + + samsung,pmu-syscon: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: phandle for PMU system controller interface, used to + control pmu registers bits for ufs m-phy + +required: + - "#phy-cells" + - compatible + - reg + - reg-names + - clocks + - clock-names + - samsung,pmu-syscon + +additionalProperties: false + +examples: + - | + #include + + ufs_phy: ufs-phy@15571800 { + compatible = "samsung,exynos7-ufs-phy"; + reg = <0x15571800 0x240>; + reg-names = "phy-pma"; + samsung,pmu-syscon = <&pmu_system_controller>; + #phy-cells = <0>; + clocks = <&clock_fsys1 SCLK_COMBO_PHY_EMBEDDED_26M>, + <&clock_fsys1 PHYCLK_UFS20_RX1_SYMBOL_USER>, + <&clock_fsys1 PHYCLK_UFS20_RX0_SYMBOL_USER>, + <&clock_fsys1 PHYCLK_UFS20_TX0_SYMBOL_USER>; + clock-names = "ref_clk", "rx1_symbol_clk", + "rx0_symbol_clk", "tx0_symbol_clk"; + + }; +... From patchwork Thu May 14 00:39:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547633 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7A63459D for ; Thu, 14 May 2020 00:53:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 64FC820693 for ; Thu, 14 May 2020 00:53:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="t10gRpKP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731339AbgENAxQ (ORCPT ); Wed, 13 May 2020 20:53:16 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:45917 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731304AbgENAxP (ORCPT ); Wed, 13 May 2020 20:53:15 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200514005308epoutp01b72ebd432eacb2a208ff6eccf6d79d87~OvuAY1fkE2952029520epoutp012 for ; Thu, 14 May 2020 00:53:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200514005308epoutp01b72ebd432eacb2a208ff6eccf6d79d87~OvuAY1fkE2952029520epoutp012 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417588; bh=sK/hFncn11WBScvtcYDk7R7CcwFLxOCyulZMUjKu6sA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t10gRpKPVa/eizfijPwR1lovg8TgYYNj3kaqBZvhwczwf/VydBezCnsYNGTwUhB9V RLugWBIjbf9AIIXmNC0x/leojFTVQ+xXdrCrQQIV8VqcN6jViP523tkaOljQ/56ZPf M3Mw3VCWXc08vVCXBqBHb4ZwtwyqC5qyYkbtGdT0= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200514005307epcas5p34683dbc6b3566a18b1b306efc6211843~Ovt-6Lbul1578415784epcas5p3B; Thu, 14 May 2020 00:53:07 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id 50.8E.23389.3769CBE5; Thu, 14 May 2020 09:53:07 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20200514005307epcas5p28b00e2fb5e9526c447927b52127480f4~Ovt-gnZAK1337613376epcas5p2A; Thu, 14 May 2020 00:53:07 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200514005307epsmtrp1494bd427208486b5d9b5ea0ad95071eb~Ovt-fuhs91129711297epsmtrp1h; Thu, 14 May 2020 00:53:07 +0000 (GMT) X-AuditID: b6c32a4b-797ff70000005b5d-04-5ebc9673da39 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 38.82.25866.3769CBE5; Thu, 14 May 2020 09:53:07 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005304epsmtip26faba709658528a56c74fda8bb5a294e~Ovt9UJ1eR3265032650epsmtip2f; Thu, 14 May 2020 00:53:04 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar , Kishon Vijay Abraham I Subject: [PATCH v9 07/10] phy: samsung-ufs: add UFS PHY driver for samsung SoC Date: Thu, 14 May 2020 06:09:11 +0530 Message-Id: <20200514003914.26052-8-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrAKsWRmVeSWpSXmKPExsWy7bCmpm7xtD1xBlMvKls8mLeNzeLlz6ts Fp/WL2O1mH/kHKvFhac9bBbnz29gt7i55SiLxabH11gtLu+aw2Yx4/w+Jovu6zvYLJYf/8dk 8X/PDnaLpVtvMjrweVzu62Xy2LSqk81j85J6j5aT+1k8Pj69xeLRt2UVo8fxG9uZPD5vkvNo P9DNFMAZxWWTkpqTWZZapG+XwJXxc9Jk5oI7cxgr5i15xNrA+LmJsYuRk0NCwETi3431zF2M XBxCArsZJZrffYVyPjFKrPk+A8r5zCgxad0FuJbdzbcYIRK7GCWWnvgMVdXCJDFj9UuwKjYB bYm707cwgdgiAsISR761gXUwCzQxS3xZ2sQGkhAWCJDY9/E3M4jNIqAqcWzTf7A4r4CNxO6L v9kg1slLrN5wAKyGU8BWYsuXY6wQNYISJ2c+YQGxmYFqmrfOBrtCQuAMh8SCg9uZIJpdJNr+ PWeFsIUlXh3fwg5hS0m87G8DsjmA7GyJnl3GEOEaiaXzjrFA2PYSB67MYQEpYRbQlFi/Sx9i FZ9E7+8nTBCdvBIdbUIQ1arAoLsK1SktMbG7G2qph8SPR1PArhcSmMAoMf1m7ARG+VlIHpiF 5IFZCMsWMDKvYpRMLSjOTU8tNi0wzkst1ytOzC0uzUvXS87P3cQITmRa3jsYHz34oHeIkYmD 8RCjBAezkgiv3/rdcUK8KYmVValF+fFFpTmpxYcYpTlYlMR5HzduiRMSSE8sSc1OTS1ILYLJ MnFwSjUwXUtrjX7kderIWYF7RtduiDlPWLq5N+uU7zJjkebjerohk/XWsrEoiHaKJfbN9DD5 l/M5+E2+/FLN2xFc36+HzGCw95gXaBYdejnaZrXU6bavk0I0etqsbyf+19hqFmBTHDxBLKLk yKzpYvMfr5I53nDrzmbt9MVyYvf+1N70/fRTXrhVln1reNHzDXo9Jxf/izPw91Dlay7yczhe PbtcUf2m4lI3txiNy71fGurs7jrs+rlZOCRsMatV96S6/1yyMiu+1aVybzznfcSA06DAdKXT sZ/ZlyqX1eQ5hTJP5Voi4qlm96DF1H/yKxdNWXGtMpO5PUvu8YhvzPLPj/kkfqP/zpP0bf2z WhvO2imxFGckGmoxFxUnAgDXFer/0wMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprKIsWRmVeSWpSXmKPExsWy7bCSvG7xtD1xBqumc1g8mLeNzeLlz6ts Fp/WL2O1mH/kHKvFhac9bBbnz29gt7i55SiLxabH11gtLu+aw2Yx4/w+Jovu6zvYLJYf/8dk 8X/PDnaLpVtvMjrweVzu62Xy2LSqk81j85J6j5aT+1k8Pj69xeLRt2UVo8fxG9uZPD5vkvNo P9DNFMAZxWWTkpqTWZZapG+XwJXxc9Jk5oI7cxgr5i15xNrA+LmJsYuRk0NCwERid/MtIJuL Q0hgB6NE3/+DTBAJaYnrGyewQ9jCEiv/PWeHKGpikjjU8ZAVJMEmoC1xd/oWsAYRoKIj39rA JjELTGCWWP7rG5DDwSEs4CfRd6MApIZFQFXi2Kb/bCA2r4CNxO6Lv9kgFshLrN5wgBnE5hSw ldjy5RjYfCGgmmVrljFC1AtKnJz5hAVkJLOAusT6eUIgYWag1uats5knMArOQlI1C6FqFpKq BYzMqxglUwuKc9Nziw0LjPJSy/WKE3OLS/PS9ZLzczcxgmNOS2sH455VH/QOMTJxMB5ilOBg VhLh9Vu/O06INyWxsiq1KD++qDQntfgQozQHi5I479dZC+OEBNITS1KzU1MLUotgskwcnFIN TLN1LXsEDfh8HFJFRVZ/vMW7aRFv34T6vN0z1b/1rXdsaPC6+sghI1vjqb5AYeuJEr3TQWWX rRU/xCx8vavKrK5E5WNHwCN9z1/HEuR3r3nQf0V78Y7301uvaAuJ3N/N6ObA29T3T2L/XQnb LH/J6V+3zZlhNFXq1OKTDW8PrP2R+yjJ6oGfndLf3j/s7vMWs3B4T/ILsnwY16bvLtZUL/zn bLLHjQ+q+WfUmQ0fz9it8mCJgPPVbGdB3i/LtKZuTr2+vDGxZdvxK3vvx7N6OXxYdd7fO1eX jeNCzxr9jox+Fc5Jh9R3L9EtOjjrpVNF28xSl/M5IpdWzJuzX63Z1pIvavWDxzMFXHy/qeu3 KrEUZyQaajEXFScCAHy6x0coAwAA X-CMS-MailID: 20200514005307epcas5p28b00e2fb5e9526c447927b52127480f4 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005307epcas5p28b00e2fb5e9526c447927b52127480f4 References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch introduces Samsung UFS PHY driver. This driver supports to deal with phy calibration and power control according to UFS host driver's behavior. Reviewed-by: Kiwoong Kim Signed-off-by: Seungwon Jeon Signed-off-by: Alim Akhtar Cc: Kishon Vijay Abraham I Tested-by: Paweł Chmiel --- drivers/phy/samsung/Kconfig | 9 + drivers/phy/samsung/Makefile | 1 + drivers/phy/samsung/phy-exynos7-ufs.h | 86 ++++++ drivers/phy/samsung/phy-samsung-ufs.c | 380 ++++++++++++++++++++++++++ drivers/phy/samsung/phy-samsung-ufs.h | 143 ++++++++++ 5 files changed, 619 insertions(+) create mode 100644 drivers/phy/samsung/phy-exynos7-ufs.h create mode 100644 drivers/phy/samsung/phy-samsung-ufs.c create mode 100644 drivers/phy/samsung/phy-samsung-ufs.h diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig index 9e483d1fdaf2..fc1e3c17f842 100644 --- a/drivers/phy/samsung/Kconfig +++ b/drivers/phy/samsung/Kconfig @@ -29,6 +29,15 @@ config PHY_EXYNOS_PCIE Enable PCIe PHY support for Exynos SoC series. This driver provides PHY interface for Exynos PCIe controller. +config PHY_SAMSUNG_UFS + tristate "SAMSUNG SoC series UFS PHY driver" + depends on OF && (ARCH_EXYNOS || COMPILE_TEST) + select GENERIC_PHY + help + Enable this to support the Samsung UFS PHY driver for + Samsung SoCs. This driver provides the interface for UFS + host controller to do PHY related programming. + config PHY_SAMSUNG_USB2 tristate "Samsung USB 2.0 PHY driver" depends on HAS_IOMEM diff --git a/drivers/phy/samsung/Makefile b/drivers/phy/samsung/Makefile index db9b1aa0de6e..3959100fe8a2 100644 --- a/drivers/phy/samsung/Makefile +++ b/drivers/phy/samsung/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o +obj-$(CONFIG_PHY_SAMSUNG_UFS) += phy-samsung-ufs.o obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o phy-exynos-usb2-y += phy-samsung-usb2.o phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o diff --git a/drivers/phy/samsung/phy-exynos7-ufs.h b/drivers/phy/samsung/phy-exynos7-ufs.h new file mode 100644 index 000000000000..c4aab792d30e --- /dev/null +++ b/drivers/phy/samsung/phy-exynos7-ufs.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UFS PHY driver data for Samsung EXYNOS7 SoC + * + * Copyright (C) 2020 Samsung Electronics Co., Ltd. + */ +#ifndef _PHY_EXYNOS7_UFS_H_ +#define _PHY_EXYNOS7_UFS_H_ + +#include "phy-samsung-ufs.h" + +#define EXYNOS7_EMBEDDED_COMBO_PHY_CTRL 0x720 +#define EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_MASK 0x1 +#define EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_EN BIT(0) + +/* Calibration for phy initialization */ +static const struct samsung_ufs_phy_cfg exynos7_pre_init_cfg[] = { + PHY_COMN_REG_CFG(0x00f, 0xfa, PWR_MODE_ANY), + PHY_COMN_REG_CFG(0x010, 0x82, PWR_MODE_ANY), + PHY_COMN_REG_CFG(0x011, 0x1e, PWR_MODE_ANY), + PHY_COMN_REG_CFG(0x017, 0x84, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x035, 0x58, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x036, 0x32, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x037, 0x40, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x03b, 0x83, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x042, 0x88, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x043, 0xa6, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x048, 0x74, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x04c, 0x5b, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x04d, 0x83, PWR_MODE_ANY), + PHY_TRSV_REG_CFG(0x05c, 0x14, PWR_MODE_ANY), + END_UFS_PHY_CFG +}; + +static const struct samsung_ufs_phy_cfg exynos7_post_init_cfg[] = { + END_UFS_PHY_CFG +}; + +/* Calibration for HS mode series A/B */ +static const struct samsung_ufs_phy_cfg exynos7_pre_pwr_hs_cfg[] = { + PHY_COMN_REG_CFG(0x00f, 0xfa, PWR_MODE_HS_ANY), + PHY_COMN_REG_CFG(0x010, 0x82, PWR_MODE_HS_ANY), + PHY_COMN_REG_CFG(0x011, 0x1e, PWR_MODE_HS_ANY), + /* Setting order: 1st(0x16, 2nd(0x15) */ + PHY_COMN_REG_CFG(0x016, 0xff, PWR_MODE_HS_ANY), + PHY_COMN_REG_CFG(0x015, 0x80, PWR_MODE_HS_ANY), + PHY_COMN_REG_CFG(0x017, 0x94, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x036, 0x32, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x037, 0x43, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x038, 0x3f, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x042, 0x88, PWR_MODE_HS_G2_SER_A), + PHY_TRSV_REG_CFG(0x042, 0xbb, PWR_MODE_HS_G2_SER_B), + PHY_TRSV_REG_CFG(0x043, 0xa6, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x048, 0x74, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x034, 0x35, PWR_MODE_HS_G2_SER_A), + PHY_TRSV_REG_CFG(0x034, 0x36, PWR_MODE_HS_G2_SER_B), + PHY_TRSV_REG_CFG(0x035, 0x5b, PWR_MODE_HS_G2_SER_A), + PHY_TRSV_REG_CFG(0x035, 0x5c, PWR_MODE_HS_G2_SER_B), + END_UFS_PHY_CFG +}; + +/* Calibration for HS mode series A/B atfer PMC */ +static const struct samsung_ufs_phy_cfg exynos7_post_pwr_hs_cfg[] = { + PHY_COMN_REG_CFG(0x015, 0x00, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG(0x04d, 0x83, PWR_MODE_HS_ANY), + END_UFS_PHY_CFG +}; + +static const struct samsung_ufs_phy_cfg *exynos7_ufs_phy_cfgs[CFG_TAG_MAX] = { + [CFG_PRE_INIT] = exynos7_pre_init_cfg, + [CFG_POST_INIT] = exynos7_post_init_cfg, + [CFG_PRE_PWR_HS] = exynos7_pre_pwr_hs_cfg, + [CFG_POST_PWR_HS] = exynos7_post_pwr_hs_cfg, +}; + +static struct samsung_ufs_phy_drvdata exynos7_ufs_phy = { + .cfg = exynos7_ufs_phy_cfgs, + .isol = { + .offset = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL, + .mask = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_MASK, + .en = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_EN, + }, + .has_symbol_clk = 1, +}; + +#endif /* _PHY_EXYNOS7_UFS_H_ */ diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c new file mode 100644 index 000000000000..be25617f622b --- /dev/null +++ b/drivers/phy/samsung/phy-samsung-ufs.c @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * UFS PHY driver for Samsung SoC + * + * Copyright (C) 2020 Samsung Electronics Co., Ltd. + * Author: Seungwon Jeon + * Author: Alim Akhtar + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-samsung-ufs.h" + +#define for_each_phy_lane(phy, i) \ + for (i = 0; i < (phy)->lane_cnt; i++) +#define for_each_phy_cfg(cfg) \ + for (; (cfg)->id; (cfg)++) + +#define PHY_DEF_LANE_CNT 1 + +static void samsung_ufs_phy_config(struct samsung_ufs_phy *phy, + const struct samsung_ufs_phy_cfg *cfg, u8 lane) +{ + enum {LANE_0, LANE_1}; /* lane index */ + + switch (lane) { + case LANE_0: + writel(cfg->val, (phy)->reg_pma + cfg->off_0); + break; + case LANE_1: + if (cfg->id == PHY_TRSV_BLK) + writel(cfg->val, (phy)->reg_pma + cfg->off_1); + break; + } +} + +int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy) +{ + struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy); + const unsigned int timeout_us = 100000; + const unsigned int sleep_us = 10; + u32 val; + int err; + + err = readl_poll_timeout( + ufs_phy->reg_pma + PHY_APB_ADDR(PHY_PLL_LOCK_STATUS), + val, (val & PHY_PLL_LOCK_BIT), sleep_us, timeout_us); + if (err) { + dev_err(ufs_phy->dev, + "failed to get phy pll lock acquisition %d\n", err); + goto out; + } + + err = readl_poll_timeout( + ufs_phy->reg_pma + PHY_APB_ADDR(PHY_CDR_LOCK_STATUS), + val, (val & PHY_CDR_LOCK_BIT), sleep_us, timeout_us); + if (err) { + dev_err(ufs_phy->dev, + "failed to get phy cdr lock acquisition %d\n", err); + goto out; + } + +out: + return err; +} + +int samsung_ufs_phy_calibrate(struct phy *phy) +{ + struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy); + struct samsung_ufs_phy_cfg **cfgs = ufs_phy->cfg; + const struct samsung_ufs_phy_cfg *cfg; + int i; + int err = 0; + + if (unlikely(ufs_phy->ufs_phy_state < CFG_PRE_INIT || + ufs_phy->ufs_phy_state >= CFG_TAG_MAX)) { + dev_err(ufs_phy->dev, "invalid phy config index %d\n", + ufs_phy->ufs_phy_state); + return -EINVAL; + } + + if (ufs_phy->is_pre_init) + ufs_phy->is_pre_init = false; + if (ufs_phy->is_post_init) { + ufs_phy->is_post_init = false; + ufs_phy->ufs_phy_state = CFG_POST_INIT; + } + if (ufs_phy->is_pre_pmc) { + ufs_phy->is_pre_pmc = false; + ufs_phy->ufs_phy_state = CFG_PRE_PWR_HS; + } + if (ufs_phy->is_post_pmc) { + ufs_phy->is_post_pmc = false; + ufs_phy->ufs_phy_state = CFG_POST_PWR_HS; + } + + switch (ufs_phy->ufs_phy_state) { + case CFG_PRE_INIT: + ufs_phy->is_post_init = true; + break; + case CFG_POST_INIT: + ufs_phy->is_pre_pmc = true; + break; + case CFG_PRE_PWR_HS: + ufs_phy->is_post_pmc = true; + break; + case CFG_POST_PWR_HS: + break; + default: + dev_err(ufs_phy->dev, "wrong state for phy calibration\n"); + } + + cfg = cfgs[ufs_phy->ufs_phy_state]; + if (!cfg) + goto out; + + for_each_phy_cfg(cfg) { + for_each_phy_lane(ufs_phy, i) { + samsung_ufs_phy_config(ufs_phy, cfg, i); + } + } + + if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS) + err = samsung_ufs_phy_wait_for_lock_acq(phy); +out: + return err; +} + +static int samsung_ufs_phy_symbol_clk_init(struct samsung_ufs_phy *phy) +{ + int ret = 0; + + phy->tx0_symbol_clk = devm_clk_get(phy->dev, "tx0_symbol_clk"); + if (IS_ERR(phy->tx0_symbol_clk)) { + dev_err(phy->dev, "failed to get tx0_symbol_clk clock\n"); + goto out; + } + + phy->rx0_symbol_clk = devm_clk_get(phy->dev, "rx0_symbol_clk"); + if (IS_ERR(phy->rx0_symbol_clk)) { + dev_err(phy->dev, "failed to get rx0_symbol_clk clock\n"); + goto out; + } + + phy->rx1_symbol_clk = devm_clk_get(phy->dev, "rx1_symbol_clk"); + if (IS_ERR(phy->rx0_symbol_clk)) { + dev_err(phy->dev, "failed to get rx1_symbol_clk clock\n"); + goto out; + } + + ret = clk_prepare_enable(phy->tx0_symbol_clk); + if (ret) { + dev_err(phy->dev, "%s: tx0_symbol_clk enable failed %d\n", + __func__, ret); + goto out; + } + ret = clk_prepare_enable(phy->rx0_symbol_clk); + if (ret) { + dev_err(phy->dev, "%s: rx0_symbol_clk enable failed %d\n", + __func__, ret); + goto out; + } + ret = clk_prepare_enable(phy->rx1_symbol_clk); + if (ret) { + dev_err(phy->dev, "%s: rx1_symbol_clk enable failed %d\n", + __func__, ret); + goto out; + } +out: + return ret; +} + +static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy) +{ + int ret; + + phy->ref_clk = devm_clk_get(phy->dev, "ref_clk"); + if (IS_ERR(phy->ref_clk)) + dev_err(phy->dev, "failed to get ref_clk clock\n"); + + ret = clk_prepare_enable(phy->ref_clk); + if (ret) { + dev_err(phy->dev, "%s: ref_clk enable failed %d\n", + __func__, ret); + return ret; + } + + dev_info(phy->dev, "UFS MPHY ref_clk_rate = %ld\n", clk_get_rate(phy->ref_clk)); + + return 0; +} + +static int samsung_ufs_phy_init(struct phy *phy) +{ + struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy); + int ret; + + _phy->lane_cnt = phy->attrs.bus_width; + _phy->ufs_phy_state = CFG_PRE_INIT; + + /** + * In ufs, PHY need to be calibrated at different stages / state + * mainly before Linkstartup, after Linkstartup, before power + * mode change and after power mode change. + * Below state machine initialize the initial state to handle + * PHY calibration at various stages of UFS initialization and power + * mode changes + */ + _phy->is_pre_init = true; + _phy->is_post_init = false; + _phy->is_pre_pmc = false; + _phy->is_post_pmc = false; + + + if (_phy->drvdata->has_symbol_clk) { + ret = samsung_ufs_phy_symbol_clk_init(_phy); + if (ret) + dev_err(_phy->dev, + "failed to set ufs phy symbol clocks\n"); + } + + ret = samsung_ufs_phy_clks_init(_phy); + if (ret) + dev_err(_phy->dev, "failed to set ufs phy clocks\n"); + + samsung_ufs_phy_calibrate(phy); + + return 0; +} + +static int samsung_ufs_phy_power_on(struct phy *phy) +{ + struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy); + + samsung_ufs_phy_ctrl_isol(_phy, false); + return 0; +} + +static int samsung_ufs_phy_power_off(struct phy *phy) +{ + struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy); + + samsung_ufs_phy_ctrl_isol(_phy, true); + return 0; +} + +static int samsung_ufs_phy_set_mode(struct phy *generic_phy, + enum phy_mode mode, int submode) +{ + struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(generic_phy); + + _phy->mode = PHY_MODE_INVALID; + + if (mode > 0) + _phy->mode = mode; + + return 0; +} + +static int samsung_ufs_phy_exit(struct phy *phy) +{ + struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy); + + clk_disable_unprepare(_phy->ref_clk); + + if (_phy->drvdata->has_symbol_clk) { + clk_disable_unprepare(_phy->tx0_symbol_clk); + clk_disable_unprepare(_phy->rx0_symbol_clk); + clk_disable_unprepare(_phy->rx1_symbol_clk); + } + + return 0; +} + +static struct phy_ops samsung_ufs_phy_ops = { + .init = samsung_ufs_phy_init, + .exit = samsung_ufs_phy_exit, + .power_on = samsung_ufs_phy_power_on, + .power_off = samsung_ufs_phy_power_off, + .calibrate = samsung_ufs_phy_calibrate, + .set_mode = samsung_ufs_phy_set_mode, + .owner = THIS_MODULE, +}; + +static const struct of_device_id samsung_ufs_phy_match[]; + +static int samsung_ufs_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct of_device_id *match; + struct samsung_ufs_phy *phy; + struct phy *gen_phy; + struct phy_provider *phy_provider; + const struct samsung_ufs_phy_drvdata *drvdata; + int err = 0; + + match = of_match_node(samsung_ufs_phy_match, dev->of_node); + if (!match) { + err = -EINVAL; + dev_err(dev, "failed to get match_node\n"); + goto out; + } + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) { + err = -ENOMEM; + goto out; + } + + phy->reg_pma = devm_platform_ioremap_resource_byname(pdev, "phy-pma"); + if (IS_ERR(phy->reg_pma)) { + err = PTR_ERR(phy->reg_pma); + goto out; + } + + phy->reg_pmu = syscon_regmap_lookup_by_phandle( + dev->of_node, "samsung,pmu-syscon"); + if (IS_ERR(phy->reg_pmu)) { + err = PTR_ERR(phy->reg_pmu); + dev_err(dev, "failed syscon remap for pmu\n"); + goto out; + } + + gen_phy = devm_phy_create(dev, NULL, &samsung_ufs_phy_ops); + if (IS_ERR(gen_phy)) { + err = PTR_ERR(gen_phy); + dev_err(dev, "failed to create PHY for ufs-phy\n"); + goto out; + } + + drvdata = match->data; + phy->dev = dev; + phy->drvdata = drvdata; + phy->cfg = (struct samsung_ufs_phy_cfg **)drvdata->cfg; + phy->isol = &drvdata->isol; + phy->lane_cnt = PHY_DEF_LANE_CNT; + + phy_set_drvdata(gen_phy, phy); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(phy_provider)) { + err = PTR_ERR(phy_provider); + dev_err(dev, "failed to register phy-provider\n"); + goto out; + } +out: + return err; +} + +static const struct of_device_id samsung_ufs_phy_match[] = { + { + .compatible = "samsung,exynos7-ufs-phy", + .data = &exynos7_ufs_phy, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_ufs_phy_match); + +static struct platform_driver samsung_ufs_phy_driver = { + .probe = samsung_ufs_phy_probe, + .driver = { + .name = "samsung-ufs-phy", + .of_match_table = samsung_ufs_phy_match, + }, +}; +module_platform_driver(samsung_ufs_phy_driver); +MODULE_DESCRIPTION("Samsung SoC UFS PHY Driver"); +MODULE_AUTHOR("Seungwon Jeon "); +MODULE_AUTHOR("Alim Akhtar "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h new file mode 100644 index 000000000000..1cc814d972e8 --- /dev/null +++ b/drivers/phy/samsung/phy-samsung-ufs.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UFS PHY driver for Samsung EXYNOS SoC + * + * Copyright (C) 2020 Samsung Electronics Co., Ltd. + * Author: Seungwon Jeon + * Author: Alim Akhtar + * + */ +#ifndef _PHY_SAMSUNG_UFS_ +#define _PHY_SAMSUNG_UFS_ + +#define PHY_COMN_BLK 1 +#define PHY_TRSV_BLK 2 +#define END_UFS_PHY_CFG { 0 } +#define PHY_TRSV_CH_OFFSET 0x30 +#define PHY_APB_ADDR(off) ((off) << 2) + +#define PHY_COMN_REG_CFG(o, v, d) { \ + .off_0 = PHY_APB_ADDR((o)), \ + .off_1 = 0, \ + .val = (v), \ + .desc = (d), \ + .id = PHY_COMN_BLK, \ +} + +#define PHY_TRSV_REG_CFG(o, v, d) { \ + .off_0 = PHY_APB_ADDR((o)), \ + .off_1 = PHY_APB_ADDR((o) + PHY_TRSV_CH_OFFSET), \ + .val = (v), \ + .desc = (d), \ + .id = PHY_TRSV_BLK, \ +} + +/* UFS PHY registers */ +#define PHY_PLL_LOCK_STATUS 0x1e +#define PHY_CDR_LOCK_STATUS 0x5e + +#define PHY_PLL_LOCK_BIT BIT(5) +#define PHY_CDR_LOCK_BIT BIT(4) + +/* description for PHY calibration */ +enum { + /* applicable to any */ + PWR_DESC_ANY = 0, + /* mode */ + PWR_DESC_PWM = 1, + PWR_DESC_HS = 2, + /* series */ + PWR_DESC_SER_A = 1, + PWR_DESC_SER_B = 2, + /* gear */ + PWR_DESC_G1 = 1, + PWR_DESC_G2 = 2, + PWR_DESC_G3 = 3, + /* field mask */ + MD_MASK = 0x3, + SR_MASK = 0x3, + GR_MASK = 0x7, +}; + +#define PWR_MODE_HS_G1_ANY PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_ANY) +#define PWR_MODE_HS_G1_SER_A PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_A) +#define PWR_MODE_HS_G1_SER_B PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_B) +#define PWR_MODE_HS_G2_ANY PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_ANY) +#define PWR_MODE_HS_G2_SER_A PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_A) +#define PWR_MODE_HS_G2_SER_B PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_B) +#define PWR_MODE_HS_G3_ANY PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_ANY) +#define PWR_MODE_HS_G3_SER_A PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_A) +#define PWR_MODE_HS_G3_SER_B PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_B) +#define PWR_MODE(g, s, m) ((((g) & GR_MASK) << 4) |\ + (((s) & SR_MASK) << 2) | ((m) & MD_MASK)) +#define PWR_MODE_PWM_ANY PWR_MODE(PWR_DESC_ANY,\ + PWR_DESC_ANY, PWR_DESC_PWM) +#define PWR_MODE_HS(g, s) ((((g) & GR_MASK) << 4) |\ + (((s) & SR_MASK) << 2) | PWR_DESC_HS) +#define PWR_MODE_HS_ANY PWR_MODE(PWR_DESC_ANY,\ + PWR_DESC_ANY, PWR_DESC_HS) +#define PWR_MODE_ANY PWR_MODE(PWR_DESC_ANY,\ + PWR_DESC_ANY, PWR_DESC_ANY) +/* PHY calibration point/state */ +enum { + CFG_PRE_INIT, + CFG_POST_INIT, + CFG_PRE_PWR_HS, + CFG_POST_PWR_HS, + CFG_TAG_MAX, +}; + +struct samsung_ufs_phy_cfg { + u32 off_0; + u32 off_1; + u32 val; + u8 desc; + u8 id; +}; + +struct samsung_ufs_phy_drvdata { + const struct samsung_ufs_phy_cfg **cfg; + struct pmu_isol { + u32 offset; + u32 mask; + u32 en; + } isol; + bool has_symbol_clk; +}; + +struct samsung_ufs_phy { + struct device *dev; + void __iomem *reg_pma; + struct regmap *reg_pmu; + struct clk *ref_clk; + struct clk *ref_clk_parent; + struct clk *tx0_symbol_clk; + struct clk *rx0_symbol_clk; + struct clk *rx1_symbol_clk; + const struct samsung_ufs_phy_drvdata *drvdata; + struct samsung_ufs_phy_cfg **cfg; + const struct pmu_isol *isol; + u8 lane_cnt; + int ufs_phy_state; + enum phy_mode mode; + bool is_pre_init; + bool is_post_init; + bool is_pre_pmc; + bool is_post_pmc; +}; + +static inline struct samsung_ufs_phy *get_samsung_ufs_phy(struct phy *phy) +{ + return (struct samsung_ufs_phy *)phy_get_drvdata(phy); +} + +static inline void samsung_ufs_phy_ctrl_isol( + struct samsung_ufs_phy *phy, u32 isol) +{ + regmap_update_bits(phy->reg_pmu, phy->isol->offset, + phy->isol->mask, isol ? 0 : phy->isol->en); +} + +#include "phy-exynos7-ufs.h" + +#endif /* _PHY_SAMSUNG_UFS_ */ From patchwork Thu May 14 00:39:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547621 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F73459D for ; Thu, 14 May 2020 00:53:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 33FF6207BB for ; Thu, 14 May 2020 00:53:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="hEuX2L7s" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725942AbgENAxO (ORCPT ); Wed, 13 May 2020 20:53:14 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:19233 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731593AbgENAxN (ORCPT ); Wed, 13 May 2020 20:53:13 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200514005310epoutp034bf6808b67e98329f365a4c8a9dd5438~OvuCWlbWm0912309123epoutp031 for ; Thu, 14 May 2020 00:53:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200514005310epoutp034bf6808b67e98329f365a4c8a9dd5438~OvuCWlbWm0912309123epoutp031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417590; bh=fsRDJ0h1yMqYOs2pKmhnI3SSBhLPwZ2LmEElFF1iDFE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hEuX2L7sJ5o+imcGGMpdVEiOG4SBEd7lXJQoMcDAtUxyvB4oaU9AuXWjfdkEokqzA ZQ0prrn5oxlZ7C9IndV279cJgJbslh0KRg4B/NuZSShDcI9/3voPrgi7KqzKFJU699 ISPOV7bp+ky5dMcBUZMVBNZH0efKVMHtb1k8AfAQ= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p2.samsung.com (KnoxPortal) with ESMTP id 20200514005309epcas5p27113d13454cd01894936bc8f55161f72~OvuB1adoU0273002730epcas5p2e; Thu, 14 May 2020 00:53:09 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 1F.DC.23569.5769CBE5; Thu, 14 May 2020 09:53:09 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200514005309epcas5p3ccd2b44c1bf20634eea3e232d1c2b62e~OvuBbgG0_1578415784epcas5p3G; Thu, 14 May 2020 00:53:09 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200514005309epsmtrp224ed3faf75c752ee13c0017b331eee76~OvuBashdq1517815178epsmtrp2i; Thu, 14 May 2020 00:53:09 +0000 (GMT) X-AuditID: b6c32a4a-3c7ff70000005c11-1a-5ebc96751802 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id E5.D3.18461.5769CBE5; Thu, 14 May 2020 09:53:09 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005307epsmtip25acec01adf94242af8a3656d6a121a34~Ovt-lAjNf3258132581epsmtip2x; Thu, 14 May 2020 00:53:07 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 08/10] dt-bindings: ufs: Add DT binding documentation for ufs Date: Thu, 14 May 2020 06:09:12 +0530 Message-Id: <20200514003914.26052-9-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrPIsWRmVeSWpSXmKPExsWy7bCmum7ptD1xBnu3qlk8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujOYvyxkL9olVTPn/nKmBsV+wi5GDQ0LAROLJJp4uRi4OIYHdjBJ//39jh3A+ MUrsWb2OGcL5xiixpPMFWxcjJ1jHpZfX2EFsIYG9jBLPD6dC2C1MEo8v6oLYbALaEnenb2EC sUUEhCWOfGtjBLGZBW4wSTxY6QJiCwsESXS1bWIDuYJFQFVi+01xkDCvgI3E/0PfGSFWyUus 3nCAGcTmFLCV2PLlGCtEvJND4lRzOYTtIrFu/TaoemGJV8e3sEPYUhKf3+1lg3gyW6JnlzFE uEZi6bxjLBC2vcSBK3NYQEqYBTQl1u/ShziST6L39xMmiE5eiY42IYhqVYnmd1ehOqUlJnZ3 Qx3jIbFtz0QWSEBNYJT4cf0F6wRG2VkIUxcwMq5ilEwtKM5NTy02LTDKSy3XK07MLS7NS9dL zs/dxAhOI1peOxgfPvigd4iRiYPxEKMEB7OSCK/f+t1xQrwpiZVVqUX58UWlOanFhxilOViU xHmTGrfECQmkJ5akZqemFqQWwWSZODilGpgK17HdF/7V4DHRR+bM5PsXQhe2Z92NdZ5fLM9w vvbG4h6Wo2uMy3bPiOmQajgue+FHnfUsQ8E5gRevPniZLXp7dZR3RoiU1OMDP9n5jW6f3fFg K+eJvy80wg6XLWUIklj2zWT/x4ZrOx9OOanzTHq+odqBl6k6tbusA9NWzes12Kb5vjPr+p+6 axE+Dwu1nkipVkZPvzflW9k7cemo6aeep6y4fLDylXiqt43sK+2VEw5fyhASnZ/EvihCUeLz 36eBWXefeogdebu9vDJ4Zqf4nJboc7NFJS8/e1qgbqNgta5j17/e1StKP2qcOW/DZXvATvv9 Y7GuZ5oVN/kCH5cyLH1T9L9/SvTTOQoz51x/osRSnJFoqMVcVJwIAIml5TmSAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSvG7ptD1xBtPXClg8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujOYvyxkL9olVTPn/nKmBsV+wi5GTQ0LAROLSy2vsXYxcHEICuxklNvzuYINI SEtc3ziBHcIWllj57zlUUROTxIpN05hBEmwC2hJ3p29hArFFgIqOfGtjBLGZBZ4xSZx6WApi CwsESJzo/c3SxcjBwSKgKrH9pjhImFfARuL/oe+MEPPlJVZvOAA2klPAVmLLl2OsILYQUM2y NcsYJzDyLWBkWMUomVpQnJueW2xYYJiXWq5XnJhbXJqXrpecn7uJERzMWpo7GLev+qB3iJGJ g/EQowQHs5IIr9/63XFCvCmJlVWpRfnxRaU5qcWHGKU5WJTEeW8ULowTEkhPLEnNTk0tSC2C yTJxcEo1MKWUiumY3VjLGc8zv+/z95v9b6cIGIuZzlQ+VmjUkD/vheTWR8dKZ00ybZVh9f5a E7Ryo98C7cOcyXsaVmant73edbfMXVmIiXvNSv4j/5gFtd9qXsmoPat1een3rKhA72ru6q1G /kvTUz4Lijoe0zX5dN760eQ/kW5Nb7jvrxHePe9cpjy3Sov6l0XpdfMfLty81ynimHPy2Vnr fjUET57XUO3e+feJs+XL27/YRTKM7fI3t6+N4X+wtPj/oWkXelNmHE5uyPvOpV7A6J4tIvbV x7y6rCHw2oI7U2U68zL+SDz4o9T/+Ooh8exy3wQOGw6G53uuv3j+f8u1bcWbbb5bz/XN76vZ tas15MrP+UosxRmJhlrMRcWJAFpRpVTVAgAA X-CMS-MailID: 20200514005309epcas5p3ccd2b44c1bf20634eea3e232d1c2b62e X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005309epcas5p3ccd2b44c1bf20634eea3e232d1c2b62e References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch adds DT binding for samsung ufs hci Signed-off-by: Alim Akhtar Reviewed-by: Rob Herring --- .../bindings/ufs/samsung,exynos-ufs.yaml | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml diff --git a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml new file mode 100644 index 000000000000..eaa64cc32d52 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/samsung,exynos-ufs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung SoC series UFS host controller Device Tree Bindings + +maintainers: + - Alim Akhtar + +description: | + Each Samsung UFS host controller instance should have its own node. + This binding define Samsung specific binding other then what is used + in the common ufshcd bindings + [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt + +properties: + + compatible: + enum: + - samsung,exynos7-ufs + + reg: + items: + - description: HCI register + - description: vendor specific register + - description: unipro register + - description: UFS protector register + + reg-names: + items: + - const: hci + - const: vs_hci + - const: unipro + - const: ufsp + + clocks: + maxItems: 2 + items: + - description: ufs link core clock + - description: unipro main clock + + clock-names: + maxItems: 2 + items: + - const: core_clk + - const: sclk_unipro_main + + interrupts: + maxItems: 1 + + phys: + maxItems: 1 + + phy-names: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - phys + - phy-names + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + + ufs: ufs@15570000 { + compatible = "samsung,exynos7-ufs"; + reg = <0x15570000 0x100>, + <0x15570100 0x100>, + <0x15571000 0x200>, + <0x15572000 0x300>; + reg-names = "hci", "vs_hci", "unipro", "ufsp"; + interrupts = ; + clocks = <&clock_fsys1 ACLK_UFS20_LINK>, + <&clock_fsys1 SCLK_UFSUNIPRO20_USER>; + clock-names = "core_clk", "sclk_unipro_main"; + pinctrl-names = "default"; + pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>; + phys = <&ufs_phy>; + phy-names = "ufs-phy"; + }; +... From patchwork Thu May 14 00:39:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547629 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92AC5618 for ; Thu, 14 May 2020 00:53:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 688DF207BB for ; Thu, 14 May 2020 00:53:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="jFUvvd6e" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732466AbgENAx1 (ORCPT ); Wed, 13 May 2020 20:53:27 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:45973 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729410AbgENAxZ (ORCPT ); Wed, 13 May 2020 20:53:25 -0400 Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200514005312epoutp0135e32a18c6659830e8226de1ce60794c~OvuE0sxMa3019330193epoutp01Y for ; Thu, 14 May 2020 00:53:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200514005312epoutp0135e32a18c6659830e8226de1ce60794c~OvuE0sxMa3019330193epoutp01Y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417593; bh=PDMiJY/am/0bhgJyyZVMhqytx7f8PSCHMTlceMBvDDU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jFUvvd6eOt4uUwpk/mDfqj/lFB24kwZrevcB2UfOCQw3lY9uYdrajiSl3LpIHCUmZ kjn1/ae+gkZA8+sDbAy29sQbu0/gEV/dugPweZWvZpoqSAbnNZh1pf5Sq0AdiiBdwf 3ih1NnYkdb4qpsF+Ztsgth5BEOyUyK9fuN/9T8RI= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200514005312epcas5p40b86e715994681323a2963e41bd5129d~OvuESVXgQ0590005900epcas5p4d; Thu, 14 May 2020 00:53:12 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 50.EC.23569.8769CBE5; Thu, 14 May 2020 09:53:12 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20200514005311epcas5p21eb58ec4a937e9c13589f81c33d77fe3~OvuDnQKO80273002730epcas5p2l; Thu, 14 May 2020 00:53:11 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200514005311epsmtrp153749e511966b585ee7e65c8cec22c57~OvuDmbuCL1129711297epsmtrp1n; Thu, 14 May 2020 00:53:11 +0000 (GMT) X-AuditID: b6c32a4a-3c7ff70000005c11-20-5ebc9678a05e Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 6A.82.25866.7769CBE5; Thu, 14 May 2020 09:53:11 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005309epsmtip210923ee674087d81f540a0537b1c3436~OvuBk0PnH3265032650epsmtip2h; Thu, 14 May 2020 00:53:09 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 09/10] scsi: ufs-exynos: add UFS host support for Exynos SoCs Date: Thu, 14 May 2020 06:09:13 +0530 Message-Id: <20200514003914.26052-10-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrKKsWRmVeSWpSXmKPExsWy7bCmpm7FtD1xBlPnCFs8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujFcbp7EW9E5kruhpe8PewPjxHFMXIyeHhICJxOcFu9hAbCGB3YwSS59VdDFy AdmfGCUm/37PAuF8ZpTomdAD1/Hz13xWiMQuRom7j2+wQzgtTBJdV7+AVbEJaEvcnb4FzBYR EJY48q2NEcRmFrjBJPFgpQuILSwQJPHx3RJ2EJtFQFXiyeeZzCA2r4CtxMrzX5ghtslLrN5w AMzmBIpv+XKMFaJGUOLkzCcsEDPlJZq3zmYGOUJCYA+HxPxDM9ghml0k5r67DGULS7w6vgXK lpJ42d8GZHMA2dkSPbuMIcI1EkvnHWOBsO0lDlyZwwJSwiygKbF+lz7EKj6J3t9PmCA6eSU6 2oQgqlUlmt9dheqUlpjY3c0KYXtITLzexQYJngmMEjv+LGGfwCg/C8kHs5B8MAth2wJG5lWM kqkFxbnpqcWmBUZ5qeV6xYm5xaV56XrJ+bmbGMEpS8trB+PDBx/0DjEycTAeYpTgYFYS4fVb vztOiDclsbIqtSg/vqg0J7X4EKM0B4uSOG9S45Y4IYH0xJLU7NTUgtQimCwTB6dUAxM/89Uj 3/R3igWJmOZN7/5/zzGwPY/Nfv7iJZtkF0awz2F8/On33xO8J88+OfGmovaC+Xur4zVGprWS lmsfFH47rGR0OvJ8TG327+ClU04sKctf67Rd+95isYwZ24pumttF/9Ox46xKfXN439sHF3e8 nzEh4sLU65nSgvsjytJlbr1PF/55eK1krOozjou6T+Uv9uVsq57aILrwYcpsLpYDB0zYp/5K 3r1n0mTD9oQg84nCLWuMmX+xT7VScMrymXTpr7E5V7XZ0bk15ovOT7t1KdWpXW/dXM2i6uLf hdr5LL2LNFfxLj76xfTqnl+yPKEPpqYZ+9wPfq1UJ1T7aPGbdc8attlFHJxVEWuwpqtEiaU4 I9FQi7moOBEAogLKjMgDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupikeLIzCtJLcpLzFFi42LZdlhJXrd82p44g4fnlSwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxquN01gLeicyV/S0vWFvYPx4jqmLkZNDQsBE4uev+axdjFwcQgI7GCXOLH/K DJGQlri+cQI7hC0ssfLfczBbSKCJSWJyYz2IzSagLXF3+hawQSJANUe+tTGC2MwCz5gkTj0s BbGFBQIkfndcA4uzCKhKPPk8E2w+r4CtxMrzX6B2yUus3nAAzOYEim/5cowVYpeNxLI1yxgh 6gUlTs58wtLFyAE0X11i/TwhiFXyEs1bZzNPYBSchaRqFkLVLCRVCxiZVzFKphYU56bnFhsW GOWllusVJ+YWl+al6yXn525iBEeXltYOxj2rPugdYmTiYDzEKMHBrCTC67d+d5wQb0piZVVq UX58UWlOavEhRmkOFiVx3q+zFsYJCaQnlqRmp6YWpBbBZJk4OKUamPaejL7jsnnl2eePvQ/y 3f2yiiMhaq+hlZDMmwntD2qb3JddzhD5fvro1LZpW1xNo1tfByzOnr/JcZeqqa3BnG1/Tn3a 0Hd+a019fv6Ee15hWlJXeY4d/5l2ctHMCNWLH7b9rVmg2Oz5PSPPPUF9rYpf86x5T99bVciY 9uxZ7JXpG37lwIJJ81yiFtlMfTHtzkav7b7J/D3XTM7uenV/17FtC5t5OS5+mcyyUvbwpp5V 8895TN30ZBW/aWvohLWXgs+y8FYarRDsvvpnf3L5ivnn7iucrf1dkiopmPM1MV5K/ZSu/5Yn Hv6mPjMq+4IiTkfcVYyIrUw5Vrf6/ez0NzX5Z7v5F67rVQovmMJ98f9PJZbijERDLeai4kQA ScT+Vx0DAAA= X-CMS-MailID: 20200514005311epcas5p21eb58ec4a937e9c13589f81c33d77fe3 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005311epcas5p21eb58ec4a937e9c13589f81c33d77fe3 References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch introduces Exynos UFS host controller driver, which mainly handles vendor-specific operations including link startup, power mode change and hibernation/unhibernation. Reported-by: kbuild test robot Reported-by: Julia Lawall [robot: drivers/scsi/ufs/ufs-exynos.c:931:8-10: WARNING: possible condition with no effect (if == else) ] Reviewed-by: Kiwoong Kim Reviewed-by: Avri Altman Signed-off-by: Seungwon Jeon Signed-off-by: Alim Akhtar Tested-by: Paweł Chmiel --- drivers/scsi/ufs/Kconfig | 12 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-exynos.c | 1292 +++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-exynos.h | 287 ++++++++ drivers/scsi/ufs/unipro.h | 33 + 5 files changed, 1625 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-exynos.c create mode 100644 drivers/scsi/ufs/ufs-exynos.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index e2005aeddc2d..7da886d3c323 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -160,3 +160,15 @@ config SCSI_UFS_BSG Select this if you need a bsg device node for your UFS controller. If unsure, say N. + +config SCSI_UFS_EXYNOS + bool "EXYNOS specific hooks to UFS controller platform driver" + depends on SCSI_UFSHCD_PLATFORM && (ARCH_EXYNOS || COMPILE_TEST) + select PHY_SAMSUNG_UFS + help + This selects the EXYNOS specific additions to UFSHCD platform driver. + UFS host on EXYNOS includes HCI and UNIPRO layer, and associates with + UFS-PHY driver. + + Select this if you have UFS host controller on EXYNOS chipset. + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 94c6c5d7334b..f0c5b95ec9cc 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210. obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_CDNS_PLATFORM) += cdns-pltfrm.o obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o +obj-$(CONFIG_SCSI_UFS_EXYNOS) += ufs-exynos.o obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o ufshcd-core-y += ufshcd.o ufs-sysfs.o ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c new file mode 100644 index 000000000000..440f2af83d9c --- /dev/null +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -0,0 +1,1292 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * UFS Host Controller driver for Exynos specific extensions + * + * Copyright (C) 2014-2015 Samsung Electronics Co., Ltd. + * Author: Seungwon Jeon + * Author: Alim Akhtar + * + */ + +#include +#include +#include +#include +#include +#include + +#include "ufshcd.h" +#include "ufshcd-pltfrm.h" +#include "ufshci.h" +#include "unipro.h" + +#include "ufs-exynos.h" + +/* + * Exynos's Vendor specific registers for UFSHCI + */ +#define HCI_TXPRDT_ENTRY_SIZE 0x00 +#define PRDT_PREFECT_EN BIT(31) +#define PRDT_SET_SIZE(x) ((x) & 0x1F) +#define HCI_RXPRDT_ENTRY_SIZE 0x04 +#define HCI_1US_TO_CNT_VAL 0x0C +#define CNT_VAL_1US_MASK 0x3FF +#define HCI_UTRL_NEXUS_TYPE 0x40 +#define HCI_UTMRL_NEXUS_TYPE 0x44 +#define HCI_SW_RST 0x50 +#define UFS_LINK_SW_RST BIT(0) +#define UFS_UNIPRO_SW_RST BIT(1) +#define UFS_SW_RST_MASK (UFS_UNIPRO_SW_RST | UFS_LINK_SW_RST) +#define HCI_DATA_REORDER 0x60 +#define HCI_UNIPRO_APB_CLK_CTRL 0x68 +#define UNIPRO_APB_CLK(v, x) (((v) & ~0xF) | ((x) & 0xF)) +#define HCI_AXIDMA_RWDATA_BURST_LEN 0x6C +#define HCI_GPIO_OUT 0x70 +#define HCI_ERR_EN_PA_LAYER 0x78 +#define HCI_ERR_EN_DL_LAYER 0x7C +#define HCI_ERR_EN_N_LAYER 0x80 +#define HCI_ERR_EN_T_LAYER 0x84 +#define HCI_ERR_EN_DME_LAYER 0x88 +#define HCI_CLKSTOP_CTRL 0xB0 +#define REFCLK_STOP BIT(2) +#define UNIPRO_MCLK_STOP BIT(1) +#define UNIPRO_PCLK_STOP BIT(0) +#define CLK_STOP_MASK (REFCLK_STOP |\ + UNIPRO_MCLK_STOP |\ + UNIPRO_PCLK_STOP) +#define HCI_MISC 0xB4 +#define REFCLK_CTRL_EN BIT(7) +#define UNIPRO_PCLK_CTRL_EN BIT(6) +#define UNIPRO_MCLK_CTRL_EN BIT(5) +#define HCI_CORECLK_CTRL_EN BIT(4) +#define CLK_CTRL_EN_MASK (REFCLK_CTRL_EN |\ + UNIPRO_PCLK_CTRL_EN |\ + UNIPRO_MCLK_CTRL_EN) +/* Device fatal error */ +#define DFES_ERR_EN BIT(31) +#define DFES_DEF_L2_ERRS (UIC_DATA_LINK_LAYER_ERROR_RX_BUF_OF |\ + UIC_DATA_LINK_LAYER_ERROR_PA_INIT) +#define DFES_DEF_L3_ERRS (UIC_NETWORK_UNSUPPORTED_HEADER_TYPE |\ + UIC_NETWORK_BAD_DEVICEID_ENC |\ + UIC_NETWORK_LHDR_TRAP_PACKET_DROPPING) +#define DFES_DEF_L4_ERRS (UIC_TRANSPORT_UNSUPPORTED_HEADER_TYPE |\ + UIC_TRANSPORT_UNKNOWN_CPORTID |\ + UIC_TRANSPORT_NO_CONNECTION_RX |\ + UIC_TRANSPORT_BAD_TC) + +enum { + UNIPRO_L1_5 = 0,/* PHY Adapter */ + UNIPRO_L2, /* Data Link */ + UNIPRO_L3, /* Network */ + UNIPRO_L4, /* Transport */ + UNIPRO_DME, /* DME */ +}; + +/* + * UNIPRO registers + */ +#define UNIPRO_COMP_VERSION 0x000 +#define UNIPRO_DME_PWR_REQ 0x090 +#define UNIPRO_DME_PWR_REQ_POWERMODE 0x094 +#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER0 0x098 +#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER1 0x09C +#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER2 0x0A0 +#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER0 0x0A4 +#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1 0x0A8 +#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2 0x0AC + +/* + * UFS Protector registers + */ +#define UFSPRSECURITY 0x010 +#define NSSMU BIT(14) +#define UFSPSBEGIN0 0x200 +#define UFSPSEND0 0x204 +#define UFSPSLUN0 0x208 +#define UFSPSCTRL0 0x20C + +#define CNTR_DIV_VAL 40 + +static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en); +static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en); + +static inline void exynos_ufs_enable_auto_ctrl_hcc(struct exynos_ufs *ufs) +{ + exynos_ufs_auto_ctrl_hcc(ufs, true); +} + +static inline void exynos_ufs_disable_auto_ctrl_hcc(struct exynos_ufs *ufs) +{ + exynos_ufs_auto_ctrl_hcc(ufs, false); +} + +static inline void exynos_ufs_disable_auto_ctrl_hcc_save( + struct exynos_ufs *ufs, u32 *val) +{ + *val = hci_readl(ufs, HCI_MISC); + exynos_ufs_auto_ctrl_hcc(ufs, false); +} + +static inline void exynos_ufs_auto_ctrl_hcc_restore( + struct exynos_ufs *ufs, u32 *val) +{ + hci_writel(ufs, *val, HCI_MISC); +} + +static inline void exynos_ufs_gate_clks(struct exynos_ufs *ufs) +{ + exynos_ufs_ctrl_clkstop(ufs, true); +} + +static inline void exynos_ufs_ungate_clks(struct exynos_ufs *ufs) +{ + exynos_ufs_ctrl_clkstop(ufs, false); +} + +static int exynos7_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs) +{ + return 0; +} + +static int exynos7_ufs_pre_link(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + u32 val = ufs->drv_data->uic_attr->pa_dbg_option_suite; + int i; + + exynos_ufs_enable_ov_tm(hba); + for_each_ufs_tx_lane(ufs, i) + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x297, i), 0x17); + for_each_ufs_rx_lane(ufs, i) { + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x362, i), 0xff); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x363, i), 0x00); + } + exynos_ufs_disable_ov_tm(hba); + + for_each_ufs_tx_lane(ufs, i) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(TX_HIBERN8_CONTROL, i), 0x0); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_TXPHY_CFGUPDT), 0x1); + udelay(1); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val | (1 << 12)); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_RESET_PHY), 0x1); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_LINE_RESET), 0x1); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_LINE_RESET_REQ), 0x1); + udelay(1600); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val); + + return 0; +} + +static int exynos7_ufs_post_link(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + int i; + + exynos_ufs_enable_ov_tm(hba); + for_each_ufs_tx_lane(ufs, i) { + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x28b, i), 0x83); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x29a, i), 0x07); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x277, i), + TX_LINERESET_N(exynos_ufs_calc_time_cntr(ufs, 200000))); + } + exynos_ufs_disable_ov_tm(hba); + + exynos_ufs_enable_dbg_mode(hba); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0xbb8); + exynos_ufs_disable_dbg_mode(hba); + + return 0; +} + +static int exynos7_ufs_pre_pwr_change(struct exynos_ufs *ufs, + struct ufs_pa_layer_attr *pwr) +{ + unipro_writel(ufs, 0x22, UNIPRO_DBG_FORCE_DME_CTRL_STATE); + + return 0; +} + +static int exynos7_ufs_post_pwr_change(struct exynos_ufs *ufs, + struct ufs_pa_layer_attr *pwr) +{ + struct ufs_hba *hba = ufs->hba; + int lanes = max_t(u32, pwr->lane_rx, pwr->lane_tx); + + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_RXPHY_CFGUPDT), 0x1); + + if (lanes == 1) { + exynos_ufs_enable_dbg_mode(hba); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), 0x1); + exynos_ufs_disable_dbg_mode(hba); + } + + return 0; +} + +/** + * exynos_ufs_auto_ctrl_hcc - HCI core clock control by h/w + * Control should be disabled in the below cases + * - Before host controller S/W reset + * - Access to UFS protector's register + */ +static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en) +{ + u32 misc = hci_readl(ufs, HCI_MISC); + + if (en) + hci_writel(ufs, misc | HCI_CORECLK_CTRL_EN, HCI_MISC); + else + hci_writel(ufs, misc & ~HCI_CORECLK_CTRL_EN, HCI_MISC); +} + +static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en) +{ + u32 ctrl = hci_readl(ufs, HCI_CLKSTOP_CTRL); + u32 misc = hci_readl(ufs, HCI_MISC); + + if (en) { + hci_writel(ufs, misc | CLK_CTRL_EN_MASK, HCI_MISC); + hci_writel(ufs, ctrl | CLK_STOP_MASK, HCI_CLKSTOP_CTRL); + } else { + hci_writel(ufs, ctrl & ~CLK_STOP_MASK, HCI_CLKSTOP_CTRL); + hci_writel(ufs, misc & ~CLK_CTRL_EN_MASK, HCI_MISC); + } +} + +static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + struct list_head *head = &hba->clk_list_head; + struct ufs_clk_info *clki; + u32 pclk_rate; + u32 f_min, f_max; + u8 div = 0; + int ret = 0; + + if (!head || list_empty(head)) + goto out; + + list_for_each_entry(clki, head, list) { + if (!IS_ERR(clki->clk)) { + if (!strcmp(clki->name, "core_clk")) + ufs->clk_hci_core = clki->clk; + else if (!strcmp(clki->name, "sclk_unipro_main")) + ufs->clk_unipro_main = clki->clk; + } + } + + if (!ufs->clk_hci_core || !ufs->clk_unipro_main) { + dev_err(hba->dev, "failed to get clk info\n"); + ret = -EINVAL; + goto out; + } + + ufs->mclk_rate = clk_get_rate(ufs->clk_unipro_main); + pclk_rate = clk_get_rate(ufs->clk_hci_core); + f_min = ufs->pclk_avail_min; + f_max = ufs->pclk_avail_max; + + if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) { + do { + pclk_rate /= (div + 1); + + if (pclk_rate <= f_max) + break; + div++; + } while (pclk_rate >= f_min); + } + + if (unlikely(pclk_rate < f_min || pclk_rate > f_max)) { + dev_err(hba->dev, "not available pclk range %d\n", pclk_rate); + ret = -EINVAL; + goto out; + } + + ufs->pclk_rate = pclk_rate; + ufs->pclk_div = div; + +out: + return ret; +} + +static void exynos_ufs_set_unipro_pclk_div(struct exynos_ufs *ufs) +{ + if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) { + u32 val; + + val = hci_readl(ufs, HCI_UNIPRO_APB_CLK_CTRL); + hci_writel(ufs, UNIPRO_APB_CLK(val, ufs->pclk_div), + HCI_UNIPRO_APB_CLK_CTRL); + } +} + +static void exynos_ufs_set_pwm_clk_div(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + + ufshcd_dme_set(hba, + UIC_ARG_MIB(CMN_PWM_CLK_CTRL), attr->cmn_pwm_clk_ctrl); +} + +static void exynos_ufs_calc_pwm_clk_div(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + const unsigned int div = 30, mult = 20; + const unsigned long pwm_min = 3 * 1000 * 1000; + const unsigned long pwm_max = 9 * 1000 * 1000; + const int divs[] = {32, 16, 8, 4}; + unsigned long clk = 0, _clk, clk_period; + int i = 0, clk_idx = -1; + + clk_period = UNIPRO_PCLK_PERIOD(ufs); + for (i = 0; i < ARRAY_SIZE(divs); i++) { + _clk = NSEC_PER_SEC * mult / (clk_period * divs[i] * div); + if (_clk >= pwm_min && _clk <= pwm_max) { + if (_clk > clk) { + clk_idx = i; + clk = _clk; + } + } + } + + if (clk_idx == -1) { + ufshcd_dme_get(hba, UIC_ARG_MIB(CMN_PWM_CLK_CTRL), &clk_idx); + dev_err(hba->dev, + "failed to decide pwm clock divider, will not change\n"); + } + + attr->cmn_pwm_clk_ctrl = clk_idx & PWM_CLK_CTRL_MASK; +} + +long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period) +{ + const int precise = 10; + long pclk_rate = ufs->pclk_rate; + long clk_period, fraction; + + clk_period = UNIPRO_PCLK_PERIOD(ufs); + fraction = ((NSEC_PER_SEC % pclk_rate) * precise) / pclk_rate; + + return (period * precise) / ((clk_period * precise) + fraction); +} + +static void exynos_ufs_specify_phy_time_attr(struct exynos_ufs *ufs) +{ + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg; + + t_cfg->tx_linereset_p = + exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_p_nsec); + t_cfg->tx_linereset_n = + exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_n_nsec); + t_cfg->tx_high_z_cnt = + exynos_ufs_calc_time_cntr(ufs, attr->tx_high_z_cnt_nsec); + t_cfg->tx_base_n_val = + exynos_ufs_calc_time_cntr(ufs, attr->tx_base_unit_nsec); + t_cfg->tx_gran_n_val = + exynos_ufs_calc_time_cntr(ufs, attr->tx_gran_unit_nsec); + t_cfg->tx_sleep_cnt = + exynos_ufs_calc_time_cntr(ufs, attr->tx_sleep_cnt); + + t_cfg->rx_linereset = + exynos_ufs_calc_time_cntr(ufs, attr->rx_dif_p_nsec); + t_cfg->rx_hibern8_wait = + exynos_ufs_calc_time_cntr(ufs, attr->rx_hibern8_wait_nsec); + t_cfg->rx_base_n_val = + exynos_ufs_calc_time_cntr(ufs, attr->rx_base_unit_nsec); + t_cfg->rx_gran_n_val = + exynos_ufs_calc_time_cntr(ufs, attr->rx_gran_unit_nsec); + t_cfg->rx_sleep_cnt = + exynos_ufs_calc_time_cntr(ufs, attr->rx_sleep_cnt); + t_cfg->rx_stall_cnt = + exynos_ufs_calc_time_cntr(ufs, attr->rx_stall_cnt); +} + +static void exynos_ufs_config_phy_time_attr(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg; + int i; + + exynos_ufs_set_pwm_clk_div(ufs); + + exynos_ufs_enable_ov_tm(hba); + + for_each_ufs_rx_lane(ufs, i) { + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_FILLER_ENABLE, i), + ufs->drv_data->uic_attr->rx_filler_enable); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_LINERESET_VAL, i), + RX_LINERESET(t_cfg->rx_linereset)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_BASE_NVAL_07_00, i), + RX_BASE_NVAL_L(t_cfg->rx_base_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_BASE_NVAL_15_08, i), + RX_BASE_NVAL_H(t_cfg->rx_base_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_GRAN_NVAL_07_00, i), + RX_GRAN_NVAL_L(t_cfg->rx_gran_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_GRAN_NVAL_10_08, i), + RX_GRAN_NVAL_H(t_cfg->rx_gran_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_OV_SLEEP_CNT_TIMER, i), + RX_OV_SLEEP_CNT(t_cfg->rx_sleep_cnt)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_OV_STALL_CNT_TIMER, i), + RX_OV_STALL_CNT(t_cfg->rx_stall_cnt)); + } + + for_each_ufs_tx_lane(ufs, i) { + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_LINERESET_P_VAL, i), + TX_LINERESET_P(t_cfg->tx_linereset_p)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HIGH_Z_CNT_07_00, i), + TX_HIGH_Z_CNT_L(t_cfg->tx_high_z_cnt)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HIGH_Z_CNT_11_08, i), + TX_HIGH_Z_CNT_H(t_cfg->tx_high_z_cnt)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_BASE_NVAL_07_00, i), + TX_BASE_NVAL_L(t_cfg->tx_base_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_BASE_NVAL_15_08, i), + TX_BASE_NVAL_H(t_cfg->tx_base_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_GRAN_NVAL_07_00, i), + TX_GRAN_NVAL_L(t_cfg->tx_gran_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_GRAN_NVAL_10_08, i), + TX_GRAN_NVAL_H(t_cfg->tx_gran_n_val)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_OV_SLEEP_CNT_TIMER, i), + TX_OV_H8_ENTER_EN | + TX_OV_SLEEP_CNT(t_cfg->tx_sleep_cnt)); + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_MIN_ACTIVATETIME, i), + ufs->drv_data->uic_attr->tx_min_activatetime); + } + + exynos_ufs_disable_ov_tm(hba); +} + +static void exynos_ufs_config_phy_cap_attr(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + int i; + + exynos_ufs_enable_ov_tm(hba); + + for_each_ufs_rx_lane(ufs, i) { + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HS_G1_SYNC_LENGTH_CAP, i), + attr->rx_hs_g1_sync_len_cap); + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HS_G2_SYNC_LENGTH_CAP, i), + attr->rx_hs_g2_sync_len_cap); + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HS_G3_SYNC_LENGTH_CAP, i), + attr->rx_hs_g3_sync_len_cap); + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HS_G1_PREP_LENGTH_CAP, i), + attr->rx_hs_g1_prep_sync_len_cap); + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HS_G2_PREP_LENGTH_CAP, i), + attr->rx_hs_g2_prep_sync_len_cap); + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HS_G3_PREP_LENGTH_CAP, i), + attr->rx_hs_g3_prep_sync_len_cap); + } + + if (attr->rx_adv_fine_gran_sup_en == 0) { + for_each_ufs_rx_lane(ufs, i) { + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_ADV_GRANULARITY_CAP, i), 0); + + if (attr->rx_min_actv_time_cap) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_MIN_ACTIVATETIME_CAP, + i), attr->rx_min_actv_time_cap); + + if (attr->rx_hibern8_time_cap) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_HIBERN8TIME_CAP, i), + attr->rx_hibern8_time_cap); + } + } else if (attr->rx_adv_fine_gran_sup_en == 1) { + for_each_ufs_rx_lane(ufs, i) { + if (attr->rx_adv_fine_gran_step) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_ADV_GRANULARITY_CAP, + i), RX_ADV_FINE_GRAN_STEP( + attr->rx_adv_fine_gran_step)); + + if (attr->rx_adv_min_actv_time_cap) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL( + RX_ADV_MIN_ACTIVATETIME_CAP, i), + attr->rx_adv_min_actv_time_cap); + + if (attr->rx_adv_hibern8_time_cap) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_ADV_HIBERN8TIME_CAP, + i), + attr->rx_adv_hibern8_time_cap); + } + } + + exynos_ufs_disable_ov_tm(hba); +} + +static void exynos_ufs_establish_connt(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + enum { + DEV_ID = 0x00, + PEER_DEV_ID = 0x01, + PEER_CPORT_ID = 0x00, + TRAFFIC_CLASS = 0x00, + }; + + /* allow cport attributes to be set */ + ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_IDLE); + + /* local unipro attributes */ + ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID), DEV_ID); + ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), TRUE); + ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), PEER_DEV_ID); + ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID), PEER_CPORT_ID); + ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS), CPORT_DEF_FLAGS); + ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS), TRAFFIC_CLASS); + ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_CONNECTED); +} + +static void exynos_ufs_config_smu(struct exynos_ufs *ufs) +{ + u32 reg, val; + + exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val); + + /* make encryption disabled by default */ + reg = ufsp_readl(ufs, UFSPRSECURITY); + ufsp_writel(ufs, reg | NSSMU, UFSPRSECURITY); + ufsp_writel(ufs, 0x0, UFSPSBEGIN0); + ufsp_writel(ufs, 0xffffffff, UFSPSEND0); + ufsp_writel(ufs, 0xff, UFSPSLUN0); + ufsp_writel(ufs, 0xf1, UFSPSCTRL0); + + exynos_ufs_auto_ctrl_hcc_restore(ufs, &val); +} + +static void exynos_ufs_config_sync_pattern_mask(struct exynos_ufs *ufs, + struct ufs_pa_layer_attr *pwr) +{ + struct ufs_hba *hba = ufs->hba; + u8 g = max_t(u32, pwr->gear_rx, pwr->gear_tx); + u32 mask, sync_len; + enum { + SYNC_LEN_G1 = 80 * 1000, /* 80us */ + SYNC_LEN_G2 = 40 * 1000, /* 44us */ + SYNC_LEN_G3 = 20 * 1000, /* 20us */ + }; + int i; + + if (g == 1) + sync_len = SYNC_LEN_G1; + else if (g == 2) + sync_len = SYNC_LEN_G2; + else if (g == 3) + sync_len = SYNC_LEN_G3; + else + return; + + mask = exynos_ufs_calc_time_cntr(ufs, sync_len); + mask = (mask >> 8) & 0xff; + + exynos_ufs_enable_ov_tm(hba); + + for_each_ufs_rx_lane(ufs, i) + ufshcd_dme_set(hba, + UIC_ARG_MIB_SEL(RX_SYNC_MASK_LENGTH, i), mask); + + exynos_ufs_disable_ov_tm(hba); +} + +static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba, + struct ufs_pa_layer_attr *dev_max_params, + struct ufs_pa_layer_attr *dev_req_params) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + struct phy *generic_phy = ufs->phy; + struct ufs_dev_params ufs_exynos_cap; + int ret; + + if (!dev_req_params) { + pr_err("%s: incoming dev_req_params is NULL\n", __func__); + ret = -EINVAL; + goto out; + } + + + ufs_exynos_cap.tx_lanes = UFS_EXYNOS_LIMIT_NUM_LANES_TX; + ufs_exynos_cap.rx_lanes = UFS_EXYNOS_LIMIT_NUM_LANES_RX; + ufs_exynos_cap.hs_rx_gear = UFS_EXYNOS_LIMIT_HSGEAR_RX; + ufs_exynos_cap.hs_tx_gear = UFS_EXYNOS_LIMIT_HSGEAR_TX; + ufs_exynos_cap.pwm_rx_gear = UFS_EXYNOS_LIMIT_PWMGEAR_RX; + ufs_exynos_cap.pwm_tx_gear = UFS_EXYNOS_LIMIT_PWMGEAR_TX; + ufs_exynos_cap.rx_pwr_pwm = UFS_EXYNOS_LIMIT_RX_PWR_PWM; + ufs_exynos_cap.tx_pwr_pwm = UFS_EXYNOS_LIMIT_TX_PWR_PWM; + ufs_exynos_cap.rx_pwr_hs = UFS_EXYNOS_LIMIT_RX_PWR_HS; + ufs_exynos_cap.tx_pwr_hs = UFS_EXYNOS_LIMIT_TX_PWR_HS; + ufs_exynos_cap.hs_rate = UFS_EXYNOS_LIMIT_HS_RATE; + ufs_exynos_cap.desired_working_mode = + UFS_EXYNOS_LIMIT_DESIRED_MODE; + + ret = ufshcd_get_pwr_dev_param(&ufs_exynos_cap, + dev_max_params, dev_req_params); + if (ret) { + pr_err("%s: failed to determine capabilities\n", __func__); + goto out; + } + + if (ufs->drv_data->pre_pwr_change) + ufs->drv_data->pre_pwr_change(ufs, dev_req_params); + + if (ufshcd_is_hs_mode(dev_req_params)) { + exynos_ufs_config_sync_pattern_mask(ufs, dev_req_params); + + switch (dev_req_params->hs_rate) { + case PA_HS_MODE_A: + case PA_HS_MODE_B: + phy_calibrate(generic_phy); + break; + } + } + + return 0; +out: + return ret; +} + +#define PWR_MODE_STR_LEN 64 +static int exynos_ufs_post_pwr_mode(struct ufs_hba *hba, + struct ufs_pa_layer_attr *pwr_max, + struct ufs_pa_layer_attr *pwr_req) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + struct phy *generic_phy = ufs->phy; + int gear = max_t(u32, pwr_req->gear_rx, pwr_req->gear_tx); + int lanes = max_t(u32, pwr_req->lane_rx, pwr_req->lane_tx); + char pwr_str[PWR_MODE_STR_LEN] = ""; + + /* let default be PWM Gear 1, Lane 1 */ + if (!gear) + gear = 1; + + if (!lanes) + lanes = 1; + + if (ufs->drv_data->post_pwr_change) + ufs->drv_data->post_pwr_change(ufs, pwr_req); + + if ((ufshcd_is_hs_mode(pwr_req))) { + switch (pwr_req->hs_rate) { + case PA_HS_MODE_A: + case PA_HS_MODE_B: + phy_calibrate(generic_phy); + break; + } + + snprintf(pwr_str, PWR_MODE_STR_LEN, "%s series_%s G_%d L_%d", + "FAST", pwr_req->hs_rate == PA_HS_MODE_A ? "A" : "B", + gear, lanes); + } else { + snprintf(pwr_str, PWR_MODE_STR_LEN, "%s G_%d L_%d", + "SLOW", gear, lanes); + } + + dev_info(hba->dev, "Power mode changed to : %s\n", pwr_str); + + return 0; +} + +static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba, + int tag, bool op) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + u32 type; + + type = hci_readl(ufs, HCI_UTRL_NEXUS_TYPE); + + if (op) + hci_writel(ufs, type | (1 << tag), HCI_UTRL_NEXUS_TYPE); + else + hci_writel(ufs, type & ~(1 << tag), HCI_UTRL_NEXUS_TYPE); +} + +static void exynos_ufs_specify_nexus_t_tm_req(struct ufs_hba *hba, + int tag, u8 func) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + u32 type; + + type = hci_readl(ufs, HCI_UTMRL_NEXUS_TYPE); + + switch (func) { + case UFS_ABORT_TASK: + case UFS_QUERY_TASK: + hci_writel(ufs, type | (1 << tag), HCI_UTMRL_NEXUS_TYPE); + break; + case UFS_ABORT_TASK_SET: + case UFS_CLEAR_TASK_SET: + case UFS_LOGICAL_RESET: + case UFS_QUERY_TASK_SET: + hci_writel(ufs, type & ~(1 << tag), HCI_UTMRL_NEXUS_TYPE); + break; + } +} + +static int exynos_ufs_phy_init(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + struct phy *generic_phy = ufs->phy; + int ret = 0; + + if (ufs->avail_ln_rx == 0 || ufs->avail_ln_tx == 0) { + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILRXDATALANES), + &ufs->avail_ln_rx); + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILTXDATALANES), + &ufs->avail_ln_tx); + WARN(ufs->avail_ln_rx != ufs->avail_ln_tx, + "available data lane is not equal(rx:%d, tx:%d)\n", + ufs->avail_ln_rx, ufs->avail_ln_tx); + } + + phy_set_bus_width(generic_phy, ufs->avail_ln_rx); + ret = phy_init(generic_phy); + if (ret) { + dev_err(hba->dev, "%s: phy init failed, ret = %d\n", + __func__, ret); + goto out_exit_phy; + } + + return 0; + +out_exit_phy: + phy_exit(generic_phy); + + return ret; +} + +static void exynos_ufs_config_unipro(struct exynos_ufs *ufs) +{ + struct ufs_hba *hba = ufs->hba; + + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD), + DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTRAILINGCLOCKS), + ufs->drv_data->uic_attr->tx_trailingclks); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), + ufs->drv_data->uic_attr->pa_dbg_option_suite); +} + +static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index) +{ + switch (index) { + case UNIPRO_L1_5: + hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_PA_LAYER); + break; + case UNIPRO_L2: + hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DL_LAYER); + break; + case UNIPRO_L3: + hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_N_LAYER); + break; + case UNIPRO_L4: + hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_T_LAYER); + break; + case UNIPRO_DME: + hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DME_LAYER); + break; + } +} + +static int exynos_ufs_pre_link(struct ufs_hba *hba) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + /* hci */ + exynos_ufs_config_intr(ufs, DFES_DEF_L2_ERRS, UNIPRO_L2); + exynos_ufs_config_intr(ufs, DFES_DEF_L3_ERRS, UNIPRO_L3); + exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4); + exynos_ufs_set_unipro_pclk_div(ufs); + + /* unipro */ + exynos_ufs_config_unipro(ufs); + + /* m-phy */ + exynos_ufs_phy_init(ufs); + exynos_ufs_config_phy_time_attr(ufs); + exynos_ufs_config_phy_cap_attr(ufs); + + if (ufs->drv_data->pre_link) + ufs->drv_data->pre_link(ufs); + + return 0; +} + +static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs) +{ + u32 val; + + val = exynos_ufs_calc_time_cntr(ufs, IATOVAL_NSEC / CNTR_DIV_VAL); + hci_writel(ufs, val & CNT_VAL_1US_MASK, HCI_1US_TO_CNT_VAL); +} + +static int exynos_ufs_post_link(struct ufs_hba *hba) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + struct phy *generic_phy = ufs->phy; + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + + exynos_ufs_establish_connt(ufs); + exynos_ufs_fit_aggr_timeout(ufs); + + hci_writel(ufs, 0xa, HCI_DATA_REORDER); + hci_writel(ufs, PRDT_SET_SIZE(12), HCI_TXPRDT_ENTRY_SIZE); + hci_writel(ufs, PRDT_SET_SIZE(12), HCI_RXPRDT_ENTRY_SIZE); + hci_writel(ufs, (1 << hba->nutrs) - 1, HCI_UTRL_NEXUS_TYPE); + hci_writel(ufs, (1 << hba->nutmrs) - 1, HCI_UTMRL_NEXUS_TYPE); + hci_writel(ufs, 0xf, HCI_AXIDMA_RWDATA_BURST_LEN); + + if (ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB) + ufshcd_dme_set(hba, + UIC_ARG_MIB(T_DBG_SKIP_INIT_HIBERN8_EXIT), TRUE); + + if (attr->pa_granularity) { + exynos_ufs_enable_dbg_mode(hba); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_GRANULARITY), + attr->pa_granularity); + exynos_ufs_disable_dbg_mode(hba); + + if (attr->pa_tactivate) + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), + attr->pa_tactivate); + if (attr->pa_hibern8time && + !(ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER)) + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), + attr->pa_hibern8time); + } + + if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) { + if (!attr->pa_granularity) + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY), + &attr->pa_granularity); + if (!attr->pa_hibern8time) + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME), + &attr->pa_hibern8time); + /* + * not wait for HIBERN8 time to exit hibernation + */ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), 0); + + if (attr->pa_granularity < 1 || attr->pa_granularity > 6) { + /* Valid range for granularity: 1 ~ 6 */ + dev_warn(hba->dev, + "%s: pa_granularty %d is invalid, assuming backwards compatibility\n", + __func__, + attr->pa_granularity); + attr->pa_granularity = 6; + } + } + + phy_calibrate(generic_phy); + + if (ufs->drv_data->post_link) + ufs->drv_data->post_link(ufs); + + return 0; +} + +static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs) +{ + struct device_node *np = dev->of_node; + struct exynos_ufs_drv_data *drv_data = &exynos_ufs_drvs; + struct exynos_ufs_uic_attr *attr; + int ret = 0; + + while (drv_data->compatible) { + if (of_device_is_compatible(np, drv_data->compatible)) { + ufs->drv_data = drv_data; + break; + } + drv_data++; + } + + if (ufs->drv_data && ufs->drv_data->uic_attr) { + attr = ufs->drv_data->uic_attr; + } else { + dev_err(dev, "failed to get uic attributes\n"); + ret = -EINVAL; + goto out; + } + + ufs->pclk_avail_min = PCLK_AVAIL_MIN; + ufs->pclk_avail_max = PCLK_AVAIL_MAX; + + attr->rx_adv_fine_gran_sup_en = RX_ADV_FINE_GRAN_SUP_EN; + attr->rx_adv_fine_gran_step = RX_ADV_FINE_GRAN_STEP_VAL; + attr->rx_adv_min_actv_time_cap = RX_ADV_MIN_ACTV_TIME_CAP; + attr->pa_granularity = PA_GRANULARITY_VAL; + attr->pa_tactivate = PA_TACTIVATE_VAL; + attr->pa_hibern8time = PA_HIBERN8TIME_VAL; + +out: + return ret; +} + +static int exynos_ufs_init(struct ufs_hba *hba) +{ + struct device *dev = hba->dev; + struct platform_device *pdev = to_platform_device(dev); + struct exynos_ufs *ufs; + struct resource *res; + int ret; + + ufs = devm_kzalloc(dev, sizeof(*ufs), GFP_KERNEL); + if (!ufs) + return -ENOMEM; + + /* exynos-specific hci */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vs_hci"); + ufs->reg_hci = devm_ioremap_resource(dev, res); + if (!ufs->reg_hci) { + dev_err(dev, "cannot ioremap for hci vendor register\n"); + return -ENOMEM; + } + + /* unipro */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "unipro"); + ufs->reg_unipro = devm_ioremap_resource(dev, res); + if (!ufs->reg_unipro) { + dev_err(dev, "cannot ioremap for unipro register\n"); + return -ENOMEM; + } + + /* ufs protector */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ufsp"); + ufs->reg_ufsp = devm_ioremap_resource(dev, res); + if (!ufs->reg_ufsp) { + dev_err(dev, "cannot ioremap for ufs protector register\n"); + return -ENOMEM; + } + + ret = exynos_ufs_parse_dt(dev, ufs); + if (ret) { + dev_err(dev, "failed to get dt info.\n"); + goto out; + } + + ufs->phy = devm_phy_get(dev, "ufs-phy"); + if (IS_ERR(ufs->phy)) { + ret = PTR_ERR(ufs->phy); + dev_err(dev, "failed to get ufs-phy\n"); + goto out; + } + + ret = phy_power_on(ufs->phy); + if (ret) + goto phy_off; + + ufs->hba = hba; + ufs->opts = ufs->drv_data->opts; + ufs->rx_sel_idx = PA_MAXDATALANES; + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX) + ufs->rx_sel_idx = 0; + hba->priv = (void *)ufs; + hba->quirks = ufs->drv_data->quirks; + if (ufs->drv_data->drv_init) { + ret = ufs->drv_data->drv_init(dev, ufs); + if (ret) { + dev_err(dev, "failed to init drv-data\n"); + goto out; + } + } + + ret = exynos_ufs_get_clk_info(ufs); + if (ret) + goto out; + exynos_ufs_specify_phy_time_attr(ufs); + exynos_ufs_config_smu(ufs); + return 0; + +phy_off: + phy_power_off(ufs->phy); +out: + hba->priv = NULL; + return ret; +} + +static int exynos_ufs_host_reset(struct ufs_hba *hba) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + unsigned long timeout = jiffies + msecs_to_jiffies(1); + u32 val; + int ret = 0; + + exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val); + + hci_writel(ufs, UFS_SW_RST_MASK, HCI_SW_RST); + + do { + if (!(hci_readl(ufs, HCI_SW_RST) & UFS_SW_RST_MASK)) + goto out; + } while (time_before(jiffies, timeout)); + + dev_err(hba->dev, "timeout host sw-reset\n"); + ret = -ETIMEDOUT; + +out: + exynos_ufs_auto_ctrl_hcc_restore(ufs, &val); + return ret; +} + +static void exynos_ufs_dev_hw_reset(struct ufs_hba *hba) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + hci_writel(ufs, 0 << 0, HCI_GPIO_OUT); + udelay(5); + hci_writel(ufs, 1 << 0, HCI_GPIO_OUT); +} + +static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + + if (!enter) { + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) + exynos_ufs_disable_auto_ctrl_hcc(ufs); + exynos_ufs_ungate_clks(ufs); + + if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) { + const unsigned int granularity_tbl[] = { + 1, 4, 8, 16, 32, 100 + }; + int h8_time = attr->pa_hibern8time * + granularity_tbl[attr->pa_granularity - 1]; + unsigned long us; + s64 delta; + + do { + delta = h8_time - ktime_us_delta(ktime_get(), + ufs->entry_hibern8_t); + if (delta <= 0) + break; + + us = min_t(s64, delta, USEC_PER_MSEC); + if (us >= 10) + usleep_range(us, us + 10); + } while (1); + } + } +} + +static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + if (!enter) { + u32 cur_mode = 0; + u32 pwrmode; + + if (ufshcd_is_hs_mode(&ufs->dev_req_params)) + pwrmode = FAST_MODE; + else + pwrmode = SLOW_MODE; + + ufshcd_dme_get(hba, UIC_ARG_MIB(PA_PWRMODE), &cur_mode); + if (cur_mode != (pwrmode << 4 | pwrmode)) { + dev_warn(hba->dev, "%s: power mode change\n", __func__); + hba->pwr_info.pwr_rx = (cur_mode >> 4) & 0xf; + hba->pwr_info.pwr_tx = cur_mode & 0xf; + ufshcd_config_pwr_mode(hba, &hba->max_pwr_info.info); + } + + if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB)) + exynos_ufs_establish_connt(ufs); + } else { + ufs->entry_hibern8_t = ktime_get(); + exynos_ufs_gate_clks(ufs); + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) + exynos_ufs_enable_auto_ctrl_hcc(ufs); + } +} + +static int exynos_ufs_hce_enable_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + int ret = 0; + + switch (status) { + case PRE_CHANGE: + ret = exynos_ufs_host_reset(hba); + if (ret) + return ret; + exynos_ufs_dev_hw_reset(hba); + break; + case POST_CHANGE: + exynos_ufs_calc_pwm_clk_div(ufs); + if (!(ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)) + exynos_ufs_enable_auto_ctrl_hcc(ufs); + break; + } + + return ret; +} + +static int exynos_ufs_link_startup_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status) +{ + int ret = 0; + + switch (status) { + case PRE_CHANGE: + ret = exynos_ufs_pre_link(hba); + break; + case POST_CHANGE: + ret = exynos_ufs_post_link(hba); + break; + } + + return ret; +} + +static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status, + struct ufs_pa_layer_attr *dev_max_params, + struct ufs_pa_layer_attr *dev_req_params) +{ + int ret = 0; + + switch (status) { + case PRE_CHANGE: + ret = exynos_ufs_pre_pwr_mode(hba, dev_max_params, + dev_req_params); + break; + case POST_CHANGE: + ret = exynos_ufs_post_pwr_mode(hba, NULL, dev_req_params); + break; + } + + return ret; +} + +static void exynos_ufs_hibern8_notify(struct ufs_hba *hba, + enum uic_cmd_dme enter, + enum ufs_notify_change_status notify) +{ + switch ((u8)notify) { + case PRE_CHANGE: + exynos_ufs_pre_hibern8(hba, enter); + break; + case POST_CHANGE: + exynos_ufs_post_hibern8(hba, enter); + break; + } +} + +static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + if (!ufshcd_is_link_active(hba)) + phy_power_off(ufs->phy); + + return 0; +} + +static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + if (!ufshcd_is_link_active(hba)) + phy_power_on(ufs->phy); + + exynos_ufs_config_smu(ufs); + + return 0; +} + +static struct ufs_hba_variant_ops ufs_hba_exynos_ops = { + .name = "exynos_ufs", + .init = exynos_ufs_init, + .hce_enable_notify = exynos_ufs_hce_enable_notify, + .link_startup_notify = exynos_ufs_link_startup_notify, + .pwr_change_notify = exynos_ufs_pwr_change_notify, + .setup_xfer_req = exynos_ufs_specify_nexus_t_xfer_req, + .setup_task_mgmt = exynos_ufs_specify_nexus_t_tm_req, + .hibern8_notify = exynos_ufs_hibern8_notify, + .suspend = exynos_ufs_suspend, + .resume = exynos_ufs_resume, +}; + +static int exynos_ufs_probe(struct platform_device *pdev) +{ + int err; + struct device *dev = &pdev->dev; + + err = ufshcd_pltfrm_init(pdev, &ufs_hba_exynos_ops); + if (err) + dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err); + + return err; +} + +static int exynos_ufs_remove(struct platform_device *pdev) +{ + struct ufs_hba *hba = platform_get_drvdata(pdev); + + pm_runtime_get_sync(&(pdev)->dev); + ufshcd_remove(hba); + return 0; +} + +struct exynos_ufs_drv_data exynos_ufs_drvs = { + + .compatible = "samsung,exynos7-ufs", + .uic_attr = &exynos7_uic_attr, + .quirks = UFSHCD_QUIRK_PRDT_BYTE_GRAN | + UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR | + UFSHCI_QUIRK_BROKEN_HCE | + UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR | + UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR, + .opts = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL | + EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL | + EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX | + EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB | + EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER, + .drv_init = exynos7_ufs_drv_init, + .pre_link = exynos7_ufs_pre_link, + .post_link = exynos7_ufs_post_link, + .pre_pwr_change = exynos7_ufs_pre_pwr_change, + .post_pwr_change = exynos7_ufs_post_pwr_change, +}; + +static const struct of_device_id exynos_ufs_of_match[] = { + { .compatible = "samsung,exynos7-ufs", + .data = &exynos_ufs_drvs }, + {}, +}; + +static const struct dev_pm_ops exynos_ufs_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 exynos_ufs_pltform = { + .probe = exynos_ufs_probe, + .remove = exynos_ufs_remove, + .shutdown = ufshcd_pltfrm_shutdown, + .driver = { + .name = "exynos-ufshc", + .pm = &exynos_ufs_pm_ops, + .of_match_table = of_match_ptr(exynos_ufs_of_match), + }, +}; +module_platform_driver(exynos_ufs_pltform); diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/scsi/ufs/ufs-exynos.h new file mode 100644 index 000000000000..76d6e39efb2f --- /dev/null +++ b/drivers/scsi/ufs/ufs-exynos.h @@ -0,0 +1,287 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UFS Host Controller driver for Exynos specific extensions + * + * Copyright (C) 2014-2015 Samsung Electronics Co., Ltd. + * + */ + +#ifndef _UFS_EXYNOS_H_ +#define _UFS_EXYNOS_H_ + +/* + * UNIPRO registers + */ +#define UNIPRO_DBG_FORCE_DME_CTRL_STATE 0x150 + +/* + * MIBs for PA debug registers + */ +#define PA_DBG_CLK_PERIOD 0x9514 +#define PA_DBG_TXPHY_CFGUPDT 0x9518 +#define PA_DBG_RXPHY_CFGUPDT 0x9519 +#define PA_DBG_MODE 0x9529 +#define PA_DBG_SKIP_RESET_PHY 0x9539 +#define PA_DBG_OV_TM 0x9540 +#define PA_DBG_SKIP_LINE_RESET 0x9541 +#define PA_DBG_LINE_RESET_REQ 0x9543 +#define PA_DBG_OPTION_SUITE 0x9564 +#define PA_DBG_OPTION_SUITE_DYN 0x9565 + +/* + * MIBs for Transport Layer debug registers + */ +#define T_DBG_SKIP_INIT_HIBERN8_EXIT 0xc001 + +/* + * Exynos MPHY attributes + */ +#define TX_LINERESET_N_VAL 0x0277 +#define TX_LINERESET_N(v) (((v) >> 10) & 0xFF) +#define TX_LINERESET_P_VAL 0x027D +#define TX_LINERESET_P(v) (((v) >> 12) & 0xFF) +#define TX_OV_SLEEP_CNT_TIMER 0x028E +#define TX_OV_H8_ENTER_EN (1 << 7) +#define TX_OV_SLEEP_CNT(v) (((v) >> 5) & 0x7F) +#define TX_HIGH_Z_CNT_11_08 0x028C +#define TX_HIGH_Z_CNT_H(v) (((v) >> 8) & 0xF) +#define TX_HIGH_Z_CNT_07_00 0x028D +#define TX_HIGH_Z_CNT_L(v) ((v) & 0xFF) +#define TX_BASE_NVAL_07_00 0x0293 +#define TX_BASE_NVAL_L(v) ((v) & 0xFF) +#define TX_BASE_NVAL_15_08 0x0294 +#define TX_BASE_NVAL_H(v) (((v) >> 8) & 0xFF) +#define TX_GRAN_NVAL_07_00 0x0295 +#define TX_GRAN_NVAL_L(v) ((v) & 0xFF) +#define TX_GRAN_NVAL_10_08 0x0296 +#define TX_GRAN_NVAL_H(v) (((v) >> 8) & 0x3) + +#define RX_FILLER_ENABLE 0x0316 +#define RX_FILLER_EN (1 << 1) +#define RX_LINERESET_VAL 0x0317 +#define RX_LINERESET(v) (((v) >> 12) & 0xFF) +#define RX_LCC_IGNORE 0x0318 +#define RX_SYNC_MASK_LENGTH 0x0321 +#define RX_HIBERN8_WAIT_VAL_BIT_20_16 0x0331 +#define RX_HIBERN8_WAIT_VAL_BIT_15_08 0x0332 +#define RX_HIBERN8_WAIT_VAL_BIT_07_00 0x0333 +#define RX_OV_SLEEP_CNT_TIMER 0x0340 +#define RX_OV_SLEEP_CNT(v) (((v) >> 6) & 0x1F) +#define RX_OV_STALL_CNT_TIMER 0x0341 +#define RX_OV_STALL_CNT(v) (((v) >> 4) & 0xFF) +#define RX_BASE_NVAL_07_00 0x0355 +#define RX_BASE_NVAL_L(v) ((v) & 0xFF) +#define RX_BASE_NVAL_15_08 0x0354 +#define RX_BASE_NVAL_H(v) (((v) >> 8) & 0xFF) +#define RX_GRAN_NVAL_07_00 0x0353 +#define RX_GRAN_NVAL_L(v) ((v) & 0xFF) +#define RX_GRAN_NVAL_10_08 0x0352 +#define RX_GRAN_NVAL_H(v) (((v) >> 8) & 0x3) + +#define CMN_PWM_CLK_CTRL 0x0402 +#define PWM_CLK_CTRL_MASK 0x3 + +#define IATOVAL_NSEC 20000 /* unit: ns */ +#define UNIPRO_PCLK_PERIOD(ufs) (NSEC_PER_SEC / ufs->pclk_rate) + +struct exynos_ufs; + +/* vendor specific pre-defined parameters */ +#define SLOW 1 +#define FAST 2 + +#define UFS_EXYNOS_LIMIT_NUM_LANES_RX 2 +#define UFS_EXYNOS_LIMIT_NUM_LANES_TX 2 +#define UFS_EXYNOS_LIMIT_HSGEAR_RX UFS_HS_G3 +#define UFS_EXYNOS_LIMIT_HSGEAR_TX UFS_HS_G3 +#define UFS_EXYNOS_LIMIT_PWMGEAR_RX UFS_PWM_G4 +#define UFS_EXYNOS_LIMIT_PWMGEAR_TX UFS_PWM_G4 +#define UFS_EXYNOS_LIMIT_RX_PWR_PWM SLOW_MODE +#define UFS_EXYNOS_LIMIT_TX_PWR_PWM SLOW_MODE +#define UFS_EXYNOS_LIMIT_RX_PWR_HS FAST_MODE +#define UFS_EXYNOS_LIMIT_TX_PWR_HS FAST_MODE +#define UFS_EXYNOS_LIMIT_HS_RATE PA_HS_MODE_B +#define UFS_EXYNOS_LIMIT_DESIRED_MODE FAST + +#define RX_ADV_FINE_GRAN_SUP_EN 0x1 +#define RX_ADV_FINE_GRAN_STEP_VAL 0x3 +#define RX_ADV_MIN_ACTV_TIME_CAP 0x9 + +#define PA_GRANULARITY_VAL 0x6 +#define PA_TACTIVATE_VAL 0x3 +#define PA_HIBERN8TIME_VAL 0x20 + +#define PCLK_AVAIL_MIN 70000000 +#define PCLK_AVAIL_MAX 133000000 + +struct exynos_ufs_uic_attr { + /* TX Attributes */ + unsigned int tx_trailingclks; + unsigned int tx_dif_p_nsec; + unsigned int tx_dif_n_nsec; + unsigned int tx_high_z_cnt_nsec; + unsigned int tx_base_unit_nsec; + unsigned int tx_gran_unit_nsec; + unsigned int tx_sleep_cnt; + unsigned int tx_min_activatetime; + /* RX Attributes */ + unsigned int rx_filler_enable; + unsigned int rx_dif_p_nsec; + unsigned int rx_hibern8_wait_nsec; + unsigned int rx_base_unit_nsec; + unsigned int rx_gran_unit_nsec; + unsigned int rx_sleep_cnt; + unsigned int rx_stall_cnt; + unsigned int rx_hs_g1_sync_len_cap; + unsigned int rx_hs_g2_sync_len_cap; + unsigned int rx_hs_g3_sync_len_cap; + unsigned int rx_hs_g1_prep_sync_len_cap; + unsigned int rx_hs_g2_prep_sync_len_cap; + unsigned int rx_hs_g3_prep_sync_len_cap; + /* Common Attributes */ + unsigned int cmn_pwm_clk_ctrl; + /* Internal Attributes */ + unsigned int pa_dbg_option_suite; + /* Changeable Attributes */ + unsigned int rx_adv_fine_gran_sup_en; + unsigned int rx_adv_fine_gran_step; + unsigned int rx_min_actv_time_cap; + unsigned int rx_hibern8_time_cap; + unsigned int rx_adv_min_actv_time_cap; + unsigned int rx_adv_hibern8_time_cap; + unsigned int pa_granularity; + unsigned int pa_tactivate; + unsigned int pa_hibern8time; +}; + +struct exynos_ufs_drv_data { + char *compatible; + struct exynos_ufs_uic_attr *uic_attr; + unsigned int quirks; + unsigned int opts; + /* SoC's specific operations */ + int (*drv_init)(struct device *dev, struct exynos_ufs *ufs); + int (*pre_link)(struct exynos_ufs *ufs); + int (*post_link)(struct exynos_ufs *ufs); + int (*pre_pwr_change)(struct exynos_ufs *ufs, + struct ufs_pa_layer_attr *pwr); + int (*post_pwr_change)(struct exynos_ufs *ufs, + struct ufs_pa_layer_attr *pwr); +}; + +struct ufs_phy_time_cfg { + u32 tx_linereset_p; + u32 tx_linereset_n; + u32 tx_high_z_cnt; + u32 tx_base_n_val; + u32 tx_gran_n_val; + u32 tx_sleep_cnt; + u32 rx_linereset; + u32 rx_hibern8_wait; + u32 rx_base_n_val; + u32 rx_gran_n_val; + u32 rx_sleep_cnt; + u32 rx_stall_cnt; +}; + +struct exynos_ufs { + struct ufs_hba *hba; + struct phy *phy; + void __iomem *reg_hci; + void __iomem *reg_unipro; + void __iomem *reg_ufsp; + struct clk *clk_hci_core; + struct clk *clk_unipro_main; + struct clk *clk_apb; + u32 pclk_rate; + u32 pclk_div; + u32 pclk_avail_min; + u32 pclk_avail_max; + u32 mclk_rate; + int avail_ln_rx; + int avail_ln_tx; + int rx_sel_idx; + struct ufs_pa_layer_attr dev_req_params; + struct ufs_phy_time_cfg t_cfg; + ktime_t entry_hibern8_t; + struct exynos_ufs_drv_data *drv_data; + + u32 opts; +#define EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL BIT(0) +#define EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB BIT(1) +#define EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL BIT(2) +#define EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX BIT(3) +#define EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER BIT(4) +}; + +#define for_each_ufs_rx_lane(ufs, i) \ + for (i = (ufs)->rx_sel_idx; \ + i < (ufs)->rx_sel_idx + (ufs)->avail_ln_rx; i++) +#define for_each_ufs_tx_lane(ufs, i) \ + for (i = 0; i < (ufs)->avail_ln_tx; i++) + +#define EXYNOS_UFS_MMIO_FUNC(name) \ +static inline void name##_writel(struct exynos_ufs *ufs, u32 val, u32 reg)\ +{ \ + writel(val, ufs->reg_##name + reg); \ +} \ + \ +static inline u32 name##_readl(struct exynos_ufs *ufs, u32 reg) \ +{ \ + return readl(ufs->reg_##name + reg); \ +} + +EXYNOS_UFS_MMIO_FUNC(hci); +EXYNOS_UFS_MMIO_FUNC(unipro); +EXYNOS_UFS_MMIO_FUNC(ufsp); +#undef EXYNOS_UFS_MMIO_FUNC + +long exynos_ufs_calc_time_cntr(struct exynos_ufs *, long); + +static inline void exynos_ufs_enable_ov_tm(struct ufs_hba *hba) +{ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OV_TM), TRUE); +} + +static inline void exynos_ufs_disable_ov_tm(struct ufs_hba *hba) +{ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OV_TM), FALSE); +} + +static inline void exynos_ufs_enable_dbg_mode(struct ufs_hba *hba) +{ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), TRUE); +} + +static inline void exynos_ufs_disable_dbg_mode(struct ufs_hba *hba) +{ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), FALSE); +} + +struct exynos_ufs_drv_data exynos_ufs_drvs; + +struct exynos_ufs_uic_attr exynos7_uic_attr = { + .tx_trailingclks = 0x10, + .tx_dif_p_nsec = 3000000, /* unit: ns */ + .tx_dif_n_nsec = 1000000, /* unit: ns */ + .tx_high_z_cnt_nsec = 20000, /* unit: ns */ + .tx_base_unit_nsec = 100000, /* unit: ns */ + .tx_gran_unit_nsec = 4000, /* unit: ns */ + .tx_sleep_cnt = 1000, /* unit: ns */ + .tx_min_activatetime = 0xa, + .rx_filler_enable = 0x2, + .rx_dif_p_nsec = 1000000, /* unit: ns */ + .rx_hibern8_wait_nsec = 4000000, /* unit: ns */ + .rx_base_unit_nsec = 100000, /* unit: ns */ + .rx_gran_unit_nsec = 4000, /* unit: ns */ + .rx_sleep_cnt = 1280, /* unit: ns */ + .rx_stall_cnt = 320, /* unit: ns */ + .rx_hs_g1_sync_len_cap = SYNC_LEN_COARSE(0xf), + .rx_hs_g2_sync_len_cap = SYNC_LEN_COARSE(0xf), + .rx_hs_g3_sync_len_cap = SYNC_LEN_COARSE(0xf), + .rx_hs_g1_prep_sync_len_cap = PREP_LEN(0xf), + .rx_hs_g2_prep_sync_len_cap = PREP_LEN(0xf), + .rx_hs_g3_prep_sync_len_cap = PREP_LEN(0xf), + .pa_dbg_option_suite = 0x30103, +}; +#endif /* _UFS_EXYNOS_H_ */ diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h index 766d551df3fc..4ee64782fd48 100644 --- a/drivers/scsi/ufs/unipro.h +++ b/drivers/scsi/ufs/unipro.h @@ -64,8 +64,25 @@ #define CFGRXOVR4 0x00E9 #define RXSQCTRL 0x00B5 #define CFGRXOVR6 0x00BF +#define RX_HS_G1_SYNC_LENGTH_CAP 0x008B +#define RX_HS_G1_PREP_LENGTH_CAP 0x008C +#define RX_HS_G2_SYNC_LENGTH_CAP 0x0094 +#define RX_HS_G3_SYNC_LENGTH_CAP 0x0095 +#define RX_HS_G2_PREP_LENGTH_CAP 0x0096 +#define RX_HS_G3_PREP_LENGTH_CAP 0x0097 +#define RX_ADV_GRANULARITY_CAP 0x0098 +#define RX_MIN_ACTIVATETIME_CAP 0x008F +#define RX_HIBERN8TIME_CAP 0x0092 +#define RX_ADV_HIBERN8TIME_CAP 0x0099 +#define RX_ADV_MIN_ACTIVATETIME_CAP 0x009A + #define is_mphy_tx_attr(attr) (attr < RX_MODE) +#define RX_ADV_FINE_GRAN_STEP(x) ((((x) & 0x3) << 1) | 0x1) +#define SYNC_LEN_FINE(x) ((x) & 0x3F) +#define SYNC_LEN_COARSE(x) ((1 << 6) | ((x) & 0x3F)) +#define PREP_LEN(x) ((x) & 0xF) + #define RX_MIN_ACTIVATETIME_UNIT_US 100 #define HIBERN8TIME_UNIT_US 100 @@ -124,6 +141,7 @@ #define PA_PACPREQEOBTIMEOUT 0x1591 #define PA_HIBERN8TIME 0x15A7 #define PA_LOCALVERINFO 0x15A9 +#define PA_GRANULARITY 0x15AA #define PA_TACTIVATE 0x15A8 #define PA_PACPFRAMECOUNT 0x15C0 #define PA_PACPERRORCOUNT 0x15C1 @@ -291,4 +309,19 @@ enum { TRUE, }; +/* CPort setting */ +#define E2EFC_ON (1 << 0) +#define E2EFC_OFF (0 << 0) +#define CSD_N_ON (0 << 1) +#define CSD_N_OFF (1 << 1) +#define CSV_N_ON (0 << 2) +#define CSV_N_OFF (1 << 2) +#define CPORT_DEF_FLAGS (CSV_N_OFF | CSD_N_OFF | E2EFC_OFF) + +/* CPort connection state */ +enum { + CPORT_IDLE = 0, + CPORT_CONNECTED, +}; + #endif /* _UNIPRO_H_ */ From patchwork Thu May 14 00:39:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11547625 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 26494618 for ; Thu, 14 May 2020 00:53:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1A62920693 for ; Thu, 14 May 2020 00:53:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="FKYAX0m9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732328AbgENAxT (ORCPT ); Wed, 13 May 2020 20:53:19 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:19289 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730757AbgENAxR (ORCPT ); Wed, 13 May 2020 20:53:17 -0400 Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200514005314epoutp0352f7f78be364a9c8f0269206d8804aad~OvuGnizV00912309123epoutp03B for ; Thu, 14 May 2020 00:53:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200514005314epoutp0352f7f78be364a9c8f0269206d8804aad~OvuGnizV00912309123epoutp03B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589417594; bh=YqesGE9QRWzbUFapaH4d6ciy/qj5O7BFUrBR3w8MJ14=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FKYAX0m9Tvqp4s7BdcJTpmIgfiecnNvYY08Pp/AR67U3VMy8TcPmFKHA3b55Tkrtn ba2oLhohiGNQIvFu2YgZ+L3U7XjNooBAFHSWKAdVyqDLN3ZipkSKUvx1FzF9S7x7fx UuCzeggHlHHR8sNwQP7mMDWgpxtpIJMGbjSV5rag= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p2.samsung.com (KnoxPortal) with ESMTP id 20200514005314epcas5p28eb25c6accaf5dd39326cde31db4bb50~OvuGCaOLN0273002730epcas5p2r; Thu, 14 May 2020 00:53:14 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 69.55.10010.A769CBE5; Thu, 14 May 2020 09:53:14 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200514005313epcas5p3eac58d00d9f617b860a3ac607c8413ec~OvuFpLUWX0947309473epcas5p3B; Thu, 14 May 2020 00:53:13 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200514005313epsmtrp177e6753c225f240c01eaf36bd25e8ff7~OvuFnUU461129711297epsmtrp1o; Thu, 14 May 2020 00:53:13 +0000 (GMT) X-AuditID: b6c32a49-71fff7000000271a-2e-5ebc967ac2b5 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id C7.D3.18461.9769CBE5; Thu, 14 May 2020 09:53:13 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200514005311epsmtip2f8904f0fb29298daef612621d92c40f1~OvuDtJcps3258132581epsmtip2y; Thu, 14 May 2020 00:53:11 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v9 10/10] arm64: dts: Add node for ufs exynos7 Date: Thu, 14 May 2020 06:09:14 +0530 Message-Id: <20200514003914.26052-11-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514003914.26052-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrMKsWRmVeSWpSXmKPExsWy7bCmum7VtD1xBmd6uCwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxpLnbAVdEhXfj29ib2DcKNzFyMkhIWAiMWX/CZYuRi4OIYHdjBKTH/6Hcj4x SkxvP8YO4XxjlJi55g4jTMuEnXOgqvYySszvu8sE4bQwSZy43MMEUsUmoC1xd/oWMFtEQFji yLc2sG5mgRtMEg9WuoDYwgJ2EmdWbQCrYRFQlZi1Zz8riM0rYCvxvvUJE8Q2eYnVGw4wg9ic QPEtX45B1QhKnJz5hAViprxE89bZzCBHSAhs4ZBo/f+SFaLZRWLhvRVsELawxKvjW9ghbCmJ l/1tQDYHkJ0t0bPLGCJcI7F03jEWCNte4sAVkC85gOZrSqzfpQ+xik+i9zfIaSCdvBIdbUIQ 1aoSze+uQnVKS0zs7oY6wENidsN7RkjwTGCU6HiymHECo/wsJB/MQvLBLIRtCxiZVzFKphYU 56anFpsWGOallusVJ+YWl+al6yXn525iBKcrLc8djHcffNA7xMjEwXiIUYKDWUmE12/97jgh 3pTEyqrUovz4otKc1OJDjNIcLErivKfTtsQJCaQnlqRmp6YWpBbBZJk4OKUamNoDL6jl/Ik/ Jr6LdUlD0aTPtsl3dsWm/mQ48LAp4nT3douTVQ/Wy83W0s+LuLXo3YHwhYqydm9ndqntst32 5CvXm9NlCpNTni0/M8+75JDYDTZun3rTK9UHl7zab/997RXWA7LPXe/o/p/wm3XuFP6kqf/f th7Ve+HmY2PUcSaiTang0UW+yLDpqTMenNEN4FNbxTvDOKLwR+rcLMOo7aHJRek+nd9TD4kr S7jOTTjyi+O3acsigR/HTafpLg29vjBUyK3kxjyX+3HfZJptrj1028E5T9af6V3bqs4S76g8 LhHOd3JfFM47LP309ceGNM1LMybMv7H67z47tarpEsFRUW3l3OXsRq/Xah04J6zEUpyRaKjF XFScCACbxsGbxgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpnkeLIzCtJLcpLzFFi42LZdlhJXrdy2p44g6XvtS0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxpLnbAVdEhXfj29ib2DcKNzFyMkhIWAiMWHnHBYQW0hgN6PE7jsxEHFpiesb J7BD2MISK/89B7K5gGqamCTeLZnKCJJgE9CWuDt9CxOILQJUdORbG1icWeAZk8Sph6UgtrCA ncSZVRvAalgEVCVm7dnPCmLzCthKvG99wgSxQF5i9YYDzCA2J1B8y5djrBAH2UgsW7OMEaJe UOLkzCdAh3IAzVeXWD9PCGKVvETz1tnMExgFZyGpmoVQNQtJ1QJG5lWMkqkFxbnpucWGBYZ5 qeV6xYm5xaV56XrJ+bmbGMFxpaW5g3H7qg96hxiZOBgPMUpwMCuJ8Pqt3x0nxJuSWFmVWpQf X1Sak1p8iFGag0VJnPdG4cI4IYH0xJLU7NTUgtQimCwTB6dUA9ORxWrOy2IEFyXFTbQJK2QQ bd6rGCj1sVj7zEzZ5vdiVqd3PJEtMRArnu/gmPv4PGPEL+lXbtcf73IzqT9+rI9r06SACRm3 +1eKN077I7iY89A/tY/LHzV0tHFoGAkm/PSOPmvWL5vKGjt54T9lYRnb7WZZAbNnblxhYZAv 39Hzc5eTy5Oz05RdHrkqyh5y+LLP8X5l2goH5o7fE/p6znilMkWUzc0uShXYnvBCY5WW7cmb XBNWn/14uuz94fJVjal6T9bMaFnKe3DBsa119wU/eCx3FG8pK1e9ZuD1UuL32eCNzP0Svx15 nZjL43p16/z6vv+5lfLkh8+eXfIKj1ZyCj/4uvuW4SK3PSfSFJRYijMSDbWYi4oTARjBggga AwAA X-CMS-MailID: 20200514005313epcas5p3eac58d00d9f617b860a3ac607c8413ec X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200514005313epcas5p3eac58d00d9f617b860a3ac607c8413ec References: <20200514003914.26052-1-alim.akhtar@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Adding dt node foe UFS and UFS-PHY for exynos7 SoC. Signed-off-by: Alim Akhtar Tested-by: Paweł Chmiel --- .../boot/dts/exynos/exynos7-espresso.dts | 4 ++ arch/arm64/boot/dts/exynos/exynos7.dtsi | 43 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts index 7af288fa9475..790f12ca8981 100644 --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts @@ -406,6 +406,10 @@ }; }; +&ufs { + status = "okay"; +}; + &usbdrd_phy { vbus-supply = <&usb30_vbus_reg>; vbus-boost-supply = <&usb3drd_boost_5v>; diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi index 5558045637ac..300ad7326ea8 100644 --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi @@ -220,9 +220,14 @@ #clock-cells = <1>; clocks = <&fin_pll>, <&clock_top1 DOUT_ACLK_FSYS1_200>, <&clock_top1 DOUT_SCLK_MMC0>, - <&clock_top1 DOUT_SCLK_MMC1>; + <&clock_top1 DOUT_SCLK_MMC1>, + <&clock_top1 DOUT_SCLK_UFSUNIPRO20>, + <&clock_top1 DOUT_SCLK_PHY_FSYS1>, + <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>; clock-names = "fin_pll", "dout_aclk_fsys1_200", - "dout_sclk_mmc0", "dout_sclk_mmc1"; + "dout_sclk_mmc0", "dout_sclk_mmc1", + "dout_sclk_ufsunipro20", "dout_sclk_phy_fsys1", + "dout_sclk_phy_fsys1_26m"; }; serial_0: serial@13630000 { @@ -601,6 +606,40 @@ }; }; + ufs: ufs@15570000 { + compatible = "samsung,exynos7-ufs"; + reg = <0x15570000 0x100>, /* 0: HCI standard */ + <0x15570100 0x100>, /* 1: Vendor specificed */ + <0x15571000 0x200>, /* 2: UNIPRO */ + <0x15572000 0x300>; /* 3: UFS protector */ + reg-names = "hci", "vs_hci", "unipro", "ufsp"; + interrupts = ; + clocks = <&clock_fsys1 ACLK_UFS20_LINK>, + <&clock_fsys1 SCLK_UFSUNIPRO20_USER>; + clock-names = "core_clk", "sclk_unipro_main"; + freq-table-hz = <0 0>, <0 0>; + pinctrl-names = "default"; + pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>; + phys = <&ufs_phy>; + phy-names = "ufs-phy"; + status = "disabled"; + }; + + ufs_phy: ufs-phy@15571800 { + compatible = "samsung,exynos7-ufs-phy"; + reg = <0x15571800 0x240>; + reg-names = "phy-pma"; + samsung,pmu-syscon = <&pmu_system_controller>; + #phy-cells = <0>; + clocks = <&clock_fsys1 SCLK_COMBO_PHY_EMBEDDED_26M>, + <&clock_fsys1 PHYCLK_UFS20_RX1_SYMBOL_USER>, + <&clock_fsys1 PHYCLK_UFS20_RX0_SYMBOL_USER>, + <&clock_fsys1 PHYCLK_UFS20_TX0_SYMBOL_USER>; + clock-names = "ref_clk", "rx1_symbol_clk", + "rx0_symbol_clk", + "tx0_symbol_clk"; + }; + usbdrd_phy: phy@15500000 { compatible = "samsung,exynos7-usbdrd-phy"; reg = <0x15500000 0x100>;