From patchwork Thu May 28 01:16:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574105 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 683F7166C for ; Thu, 28 May 2020 01:32:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 47790208B8 for ; Thu, 28 May 2020 01:32:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="CvoRxINZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726009AbgE1Bca (ORCPT ); Wed, 27 May 2020 21:32:30 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:34970 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725901AbgE1Bc3 (ORCPT ); Wed, 27 May 2020 21:32:29 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20200528013226epoutp02c852e6d749d7846f4a8ece2af817dc77~TDSU94udj3019730197epoutp02i for ; Thu, 28 May 2020 01:32:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20200528013226epoutp02c852e6d749d7846f4a8ece2af817dc77~TDSU94udj3019730197epoutp02i DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629547; bh=HK/1/VP5ov7EOoNpQ0X08DtlhI52O+2EyAZ3cTvlQkI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CvoRxINZ+mTA0agfax3yn8vaVWRUB4f66icmLId8+zfOpcwEMhCYxa0k+OYZEi70Z Mucv/EMsS5s7qmzsXpGQwvHBgWolcatxZoJxXRgWUiRlD8T4AnUlsOTxOPQ1/4fwu3 3dPCOoABm1KZ89Whsp0WX/xXVNzZy36RYPAGx5mg= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200528013226epcas5p17c56ec6d989480e834855950b36e2334~TDSUe02Wh1882918829epcas5p1c; Thu, 28 May 2020 01:32:26 +0000 (GMT) Received: from epcas5p4.samsung.com ( [182.195.41.42]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 76.00.09467.AA41FCE5; Thu, 28 May 2020 10:32:26 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20200528013226epcas5p1c73527c71424679443c10daf8bf561df~TDSUD0My00728507285epcas5p10; Thu, 28 May 2020 01:32:26 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200528013226epsmtrp2285c64bdb564c4513d91654752e6b269~TDSUC227J2107921079epsmtrp2d; Thu, 28 May 2020 01:32:26 +0000 (GMT) X-AuditID: b6c32a49-fba88a80000024fb-0d-5ecf14aa192c Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id D8.77.08303.9A41FCE5; Thu, 28 May 2020 10:32:25 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013223epsmtip1efd3432a48365af5ec1348fbaaf4812d~TDSSJ3bxJ1673116731epsmtip1k; Thu, 28 May 2020 01:32:23 +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 v10 01/10] scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr Date: Thu, 28 May 2020 06:46:49 +0530 Message-Id: <20200528011658.71590-2-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdlhTS3eVyPk4g7XnJS0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxouja1gKdgtU7P9wnLmB8TVvFyMnh4SAicTHD2vZuxi5OIQEdjNKHGx/zArh fGKUeLziDhOE85lRYvGUB4wwLSvWLGGBSOxilPhxajkrSEJIoIVJYsVsXRCbTUBb4u70LUwg toiAsMSRb21gzcwCN5gkHqx0AbGFBUIljuztZAexWQRUJa6dfgtWzytgI3F+z0ZWiGXyEqs3 HGDuYuTg4BSwldg7wQFkr4RAL4fEn7XT2SFqXCR+rfrNBGELS7w6vgUqLiXx+d1eNpBeCYFs iZ5dxhDhGoml846xQNj2EgeuzGEBKWEW0JRYv0sf4ko+id7fT5ggOnklOtqEIKpVJZrfXYXq lJaY2N0NdaSHxKpDB9kgITKBUWLbr7/sExhlZyFMXcDIuIpRMrWgODc9tdi0wDAvtVyvODG3 uDQvXS85P3cTIziZaHnuYLz74IPeIUYmDsZDjBIczEoivE5nT8cJ8aYkVlalFuXHF5XmpBYf YpTmYFES51X6cSZOSCA9sSQ1OzW1ILUIJsvEwSnVwDStxFvUST1otld5oEWxBwdf0d1ck2gt wXa2pM4CP8PkdTYTH98QY+s3sJwZcuHye/kTJY4JokvtHE4r6+0IFnutnLhvmcilWfHNClsb sjZ+vc29/ZWs+Je383u9jJrrJneEFllonvzRUXlc+9WP28y6c5pfiV2/tl3D67TFjtVy/urf olcaS71RvSt1Ty+S0+w/e9zjc/bKnesVhVgVdbR2HD64eE7t7ZWad56rztRZN617ZarQC75t nXVJX6uzA65lil+8fCirp5fv3m+51z/Fn8lIzo/M3shVv0DG5J7d5Cti1lzVynunySVnN7C4 vF6+pNlof5Zum8XdGznRp0716hl8uR57VFTccFOTEktxRqKhFnNRcSIAqIW44ZUDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSnO5KkfNxBidfmFk8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujBdH17AU7Bao2P/hOHMD42veLkZODgkBE4kVa5awdDFycQgJ7GCUeNP7gA0i IS1xfeMEdghbWGLlv+fsEEVNTBKdDxcwgiTYBLQl7k7fwgRiiwAVHfnWBhZnFnjGJHHqYSmI LSwQLHG67z8LiM0ioCpx7fRbsHpeARuJ83s2skIskJdYveEAcxcjBwengK3E3gkOIGEhoJIJ q/YyTmDkW8DIsIpRMrWgODc9t9iwwCgvtVyvODG3uDQvXS85P3cTIziYtbR2MO5Z9UHvECMT B+MhRgkOZiURXqezp+OEeFMSK6tSi/Lji0pzUosPMUpzsCiJ836dtTBOSCA9sSQ1OzW1ILUI JsvEwSnVwJTxSLjlzsKc9XKPWGZpbv98ZcEv/73uR20Cvi+/f5nxzceo03c2s+Zv5Os04fj/ dseaKkn27g/HFwQEyv7w15zmsH9Fg7j4nmtXPr1inMd3miXL5N7b/TExDSznvpYav2xauUAt Ii1x8QaXx+czah5Yh9212fP4VPO27nlRT/PWbLeMWLhgv4RrwsNL3Ndz2SyUzSqD2ydOFE2b WZp6XPpGbSXzx/MPdV1rGE3/r001VZq2+GQt16Fcw2AV940TjsbfilQJ5st0/eAvlH93ffub EMbpN77+3vfptm12+nyHF9/li7o4zHdIGlu+sz9zOuI6f3BOjIhquvoCdx5Fw00lTc8+PPug Nfl7snTfmRtKLMUZiYZazEXFiQAvvvT61QIAAA== X-CMS-MailID: 20200528013226epcas5p1c73527c71424679443c10daf8bf561df X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013226epcas5p1c73527c71424679443c10daf8bf561df References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574141 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 056AC159A for ; Thu, 28 May 2020 01:33:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E1CE12100A for ; Thu, 28 May 2020 01:33:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="uSGoa+ns" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726612AbgE1Bch (ORCPT ); Wed, 27 May 2020 21:32:37 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:63043 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726393AbgE1Bcc (ORCPT ); Wed, 27 May 2020 21:32:32 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200528013229epoutp01166d0c0dc7f4a2c2fa7ef5d6d4002318~TDSXq0eXV2174221742epoutp01k for ; Thu, 28 May 2020 01:32:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200528013229epoutp01166d0c0dc7f4a2c2fa7ef5d6d4002318~TDSXq0eXV2174221742epoutp01k DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629549; bh=aZlGHc5xTiWwAyuHWOUJ6KyldBblFcw6DUpelUfBEa8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uSGoa+nsQtvqb05cVlCYGTrzqDjboaEtV01OjRnkITuRkWFZ1hdK76RVKldMD6XtL aL7rlHFk5kH67eWCeEI5CXZL/JHAZQSjdeGDDB1G9w78mzfmetiyizIOBHgosgLqpO waFOcsFwaOAeXZFQ9cbsJX2d5OWT2EdsLwhzroqg= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p2.samsung.com (KnoxPortal) with ESMTP id 20200528013228epcas5p2fcbdc5778b4f1156ff32c6bf6271aeac~TDSWf9m_A0582105821epcas5p2T; Thu, 28 May 2020 01:32:28 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 1A.00.09467.CA41FCE5; Thu, 28 May 2020 10:32:28 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20200528013228epcas5p4641c271e319aaefc78d7bbd22b23c30f~TDSV_NUZl2137121371epcas5p4e; Thu, 28 May 2020 01:32:28 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200528013228epsmtrp1f07aee0488fcd41cd71921d3645e1825~TDSV81IwD0638506385epsmtrp1i; Thu, 28 May 2020 01:32:28 +0000 (GMT) X-AuditID: b6c32a49-a29ff700000024fb-16-5ecf14ac61e3 Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id CB.E7.08382.BA41FCE5; Thu, 28 May 2020 10:32:27 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013226epsmtip1781cc4df5f4a1a48d05ee63fe450e2b8~TDSUIVqMU1669416694epsmtip1k; Thu, 28 May 2020 01:32:25 +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 v10 02/10] scsi: ufs: add quirk to disallow reset of interrupt aggregation Date: Thu, 28 May 2020 06:46:50 +0530 Message-Id: <20200528011658.71590-3-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA0WSeUwTURCHfbvb7VKt2ZRGR8CrBm8LiJrVIBI1uph4x1vRChtQoK0teEUj QQShFqtRIYhFDIiChFIrQbBa8agIigQ5SgIUkRiMEa1aJRqPujX+95uZ73vz8vIoXJIq8KP2 KJM4jVKRICNFRNWDaVNn3ZA2RQVnlExinMYqkhkYaiUZV8VVAVPw8LmAaWoyCRmH5RHBmPva BExLTT7J5DbdxRhdezXJlNh/YsyvO9VCpviWA0WI2ZZsPcaaSzNJ9mbRMTat/h7BfuzvJNhs SyliP5nHsRk2HbaG2ioKi+ES9uznNEHhu0RxVbXvSXXniIMGeyeeglpEWciHAnoOXDuvJ7KQ iJLQtQhS3xRgfOFCYHVfJPnCjeCcdVD4T8kyuYX8wIqgI/Wi10/D4NGZQtxDkfQM6MqxYJ4s pX3hoTsdeTJOd2DgvL7Uk33p7fDK1P2HpyiCDoTWoo2etpgOg5wXRd5l46HMZPuL+NALwWqI 8KwCOpOC7mufCZ5ZCmXlNgGffeGt3eJ1/WDgdLrQ4wIdD6dqQvn2ESg2Pvaqi8D2Mp/wIDg9 DSpqgvhLjgT999cYb4rhZLqEpwPh+PtWr+kPZ3Q671IWes8+R/wjGBB0OYaQAY3N+3/qZYRK 0RhOrU2M5bRz1SFK7oBcq0jUJitj5dGqRDP6+02mR1ajLucHeR3CKFSHgMJlUvHiZw1REnGM 4tBhTqPaqUlO4LR1yJ8iZKPFsm+NURI6VpHExXOcmtP8m2KUj18Kxj3+0lOw4pg8dEdzZEDf BWu7yN6+97zGKW04eqlUqtq3MjSvcN3m+P7V206kfF6gX7utrs/UfKfidrQrd+KViVd+DGXu vmwvx3/sC2/e6zxXFXt6ru1tIwREBXyhI82VLmPglIGWUfeNFyonfNuOz8PIzXpi/tFhGTMr 88NGipDfq/HdfRGpExw3N8p1aYavi1lgbWvjDtRf2m1wHN7/rkcgQwKlar3FEpOztWu4Vrcy t3qJu2FZOZn0ZMns4qfZzOjBe2clZYeWR6ypnWQJFSQHq9tKOm1DM/0DVrl6i8JV4372BA1i wZuSJm/JSxvbizYEcyGzG1cbMeebwv7vsg8yQhunCJmOa7SK39u2meqVAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrILMWRmVeSWpSXmKPExsWy7bCSnO5qkfNxBnP2WFs8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujG2737EV3OKpmHD8FnMD42WuLkZODgkBE4muDd/Yuxi5OIQEdjNKPP/+nREi IS1xfeMEdghbWGLlv+dQRU1MEp3/17GCJNgEtCXuTt/CBGKLABUd+dYG1sws8IxJ4tTDUhBb WCBKouvaR6AaDg4WAVWJq0vCQMK8AjYS0y8sgZovL7F6wwFmkBJOAVuJvRMcQMJCQCUTVu1l nMDIt4CRYRWjZGpBcW56brFhgWFearlecWJucWleul5yfu4mRnAoa2nuYNy+6oPeIUYmDsZD jBIczEoivE5nT8cJ8aYkVlalFuXHF5XmpBYfYpTmYFES571RuDBOSCA9sSQ1OzW1ILUIJsvE wSnVwDT9uuTUHEMn/R5hlfL9vTvvSO7fpXNV/8fKvQY7ti9QZnXKLI7gPOT/8tTVT+lXYmfc mPYg70DdW80zZRWnWBTls/T0zrKkmXVc27tyoc/SNc33St4sqrgk8+eXevzTWXmzV7uzt0av WF8yh3Fz5oNvClolb/TyZlg+n7qj9VXCe/5dqes/uZ362nf8at654kka6tVxVwRjbW4dvdV6 5pGEFZPUFxfJ56p6dgYZM0Qv1B7/+eb93q3zzmp+OpNsuSX6+4rtpzaUzgipt7N8FuSUL/Ww 7JbMm/DTVUtlX8+6YpTmxSczYXul9tGww5WLGI17+BucjDO+1q9g846+zXo47BirenXVe0cV N/nGV9lKLMUZiYZazEXFiQCLL+Dq1AIAAA== X-CMS-MailID: 20200528013228epcas5p4641c271e319aaefc78d7bbd22b23c30f X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013228epcas5p4641c271e319aaefc78d7bbd22b23c30f References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574147 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 5D8D6166C for ; Thu, 28 May 2020 01:33:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 410EC20FC3 for ; Thu, 28 May 2020 01:33:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="XDH9WqF2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726487AbgE1Bcg (ORCPT ); Wed, 27 May 2020 21:32:36 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:50090 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726477AbgE1Bce (ORCPT ); Wed, 27 May 2020 21:32:34 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200528013230epoutp031e88f9f341cdcb8d928c439b80532519~TDSYr0CcH0196701967epoutp03G for ; Thu, 28 May 2020 01:32:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200528013230epoutp031e88f9f341cdcb8d928c439b80532519~TDSYr0CcH0196701967epoutp03G DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629551; bh=kDIy4u6dKypJDeZVrGE9ZKceZgeyPXJh8PvB97xxnQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XDH9WqF2XVgv2fAZSobHV0jEBZUg8zUWP5CmPHMWcs6ObsFvSHqaWXeqCC1cZ8HF2 D86OE99ZsZFARwE9Z3yH/0aL4UDN2pfO3ldUviJrvVr+ikKNhelfIPCTAD3a8Udelh Ve1qpNjCl6D8FJhZpTjjEHmSmXhvUQ4bCS5mwNC0= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200528013230epcas5p3487c2ce9cf64332b7a97d2e003ac2ace~TDSYNiVkK2924029240epcas5p36; Thu, 28 May 2020 01:32:30 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id 42.B2.09475.EA41FCE5; Thu, 28 May 2020 10:32:30 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200528013230epcas5p37b2d1980cfccf593242bef11e2076eb8~TDSX9DSz42924029240epcas5p33; Thu, 28 May 2020 01:32:30 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200528013230epsmtrp24c836ade0f2ab2669f265b3f7e59d5f7~TDSX74IUM2107921079epsmtrp2i; Thu, 28 May 2020 01:32:30 +0000 (GMT) X-AuditID: b6c32a4b-389ff70000002503-2b-5ecf14aee359 Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id F9.77.08303.EA41FCE5; Thu, 28 May 2020 10:32:30 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013228epsmtip14739227217a187ab1d3a87e17bf3f7ad~TDSWEnZGp1533515335epsmtip1V; Thu, 28 May 2020 01:32:28 +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 v10 03/10] scsi: ufs: add quirk to enable host controller without hce Date: Thu, 28 May 2020 06:46:51 +0530 Message-Id: <20200528011658.71590-4-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdlhTXXedyPk4gzO3JC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxqwXh9gKNshVNDV+YWpgPCXRxcjJISFgIrG1/wRzFyMXh5DAbkaJp1c2M0I4 nxglPv16zgLhfGaUWHx3KQtMy8zn19khErsYJZYunQbV0sIk8eXLRFaQKjYBbYm707cwgdgi AsISR761MYLYzAI3mCQerHQBsYUFwiWatsxnA7FZBFQl/pxbyQ5i8wrYSJzsaYfaJi+xesMB oAM5ODgFbCX2TnAA2SUh0Mohsej7FEaQuISAi8SRo9oQ5cISr45vYYewpSQ+v9vLBlGSLdGz yxgiXCOxdN4xqOn2EgeuzGEBKWEW0JRYv0sf4kg+id7fT5ggOnklOtqEIKpVJZrfXYXqlJaY 2N3NCmF7SFx6PB0aVBMYJc5NXM88gVF2FsLUBYyMqxglUwuKc9NTi00LjPNSy/WKE3OLS/PS 9ZLzczcxgpOJlvcOxkcPPugdYmTiYDzEKMHBrCTC63T2dJwQb0piZVVqUX58UWlOavEhRmkO FiVxXqUfZ+KEBNITS1KzU1MLUotgskwcnFINTHE108zkT5aznIr0uHfNZF5ymdMu4S8lydty pp7SUso7bVhiWrRNRGT74g+byo8min7dP+vquZ+sPm/q9qVfrdjv2xz3hP2MwOPH8s732srD EsS/6by3krxx99chPTNvXe8W/zfvf8nZnJ00kzu+5GEzw/y+76v+3TzuIdiQsbEz/W+S8HnW OxcYY7/LvJ64VU/6wBrhWfGfj2zhNf+887NqjcbC2X5/IqYyXhCZ1f/4hmKfSPOrZB+T8Dmd PE7yl2r8HL+Z7vRvnP2M27mIzUzJ+/Pb019ZfDl3TOY7fORVXqXQlnfibzkEpu2pKPjlOyk3 tu0663ullQ1dmYaJ/4pL8g3Zo9heH/jU7MLQo8RSnJFoqMVcVJwIAMJkcpuVAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSnO46kfNxBpMWs1g8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujFkvDrEVbJCraGr8wtTAeEqii5GTQ0LARGLm8+vsXYxcHEICOxgldnxfwwSR kJa4vnECO4QtLLHy33OooiYmiT+vDjCDJNgEtCXuTt8C1iACVHTkWxsjiM0s8IxJ4tTDUhBb WCBUYsX8LrBBLAKqEn/OrQSzeQVsJE72tLNALJCXWL0BZCYHB6eArcTeCQ4gYSGgkgmr9jJO YORbwMiwilEytaA4Nz232LDAKC+1XK84Mbe4NC9dLzk/dxMjOJi1tHYw7ln1Qe8QIxMH4yFG CQ5mJRFep7On44R4UxIrq1KL8uOLSnNSiw8xSnOwKInzfp21ME5IID2xJDU7NbUgtQgmy8TB KdXANFVO3uT3Lo5pwbw9l666Wud31e3apuHI3nTm/9szuunyk9jip+iL+bVbr3xh49TyJMNz 0b+vncvPv9WpfcN+bMaZrrMr5Fo+r5Gb+3lftm3J92Ihtzjxk1/9psl9+jlnV11owvawcy6O txynr65crn1bKW/L3fdffu+2467Weibez2B2ii3oq7W2Qc+KQHWh+TmXAwt9qyv+Les8sbf9 +ZIH66S+fpmw4IbWZJte/SKPXA7WC5LLpv+/XfrZKcnG2PuHUO70ivkibYX1hcv3PdqTvMCw WLYgcWMM78wjV81EQkV2dC15HOK7anGN1cPPxpzn7ly9XM1d8I/b0V97lVa691KviFDu2JAn PCJCSizFGYmGWsxFxYkA+hkfH9UCAAA= X-CMS-MailID: 20200528013230epcas5p37b2d1980cfccf593242bef11e2076eb8 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013230epcas5p37b2d1980cfccf593242bef11e2076eb8 References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574145 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 0F9311667 for ; Thu, 28 May 2020 01:33:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E754320FC3 for ; Thu, 28 May 2020 01:33:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="bRrQd0Le" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726578AbgE1BdO (ORCPT ); Wed, 27 May 2020 21:33:14 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:63099 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725896AbgE1Bcg (ORCPT ); Wed, 27 May 2020 21:32:36 -0400 Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200528013233epoutp0128bbda91abde7b9d7bee3f9de0245602~TDSbAjo4r2169721697epoutp01v for ; Thu, 28 May 2020 01:32:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200528013233epoutp0128bbda91abde7b9d7bee3f9de0245602~TDSbAjo4r2169721697epoutp01v DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629553; bh=nPCI6KtKTzdjjbh5jTvGpI1fKN6gjrCt7WH8b1I6htY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bRrQd0LeajYCAte3aAjCOZkZSJ1BskOV9DwBpoNSoZ6ECPPmtJy27XThrWZoGmLVw l7a7CjgqNwfNv69Fegj9GlqZsAUnJ8viOKK6zz7KKJuFdc54/k4VYaIauJyJb6QNg/ TQA/Hx4Fb+8Sk8qayaA1MFycK9V9GJwX/7hPZlxM= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p2.samsung.com (KnoxPortal) with ESMTP id 20200528013233epcas5p26c92f0b7581b5876dd2fcca5e40a41d9~TDSalIsZx3096230962epcas5p2D; Thu, 28 May 2020 01:32:33 +0000 (GMT) Received: from epcas5p4.samsung.com ( [182.195.41.42]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id E6.58.09703.0B41FCE5; Thu, 28 May 2020 10:32:32 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200528013232epcas5p32fecbbebc06909ff1fa7136481891dc1~TDSZ4QDgy1669616696epcas5p3v; Thu, 28 May 2020 01:32:32 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200528013232epsmtrp27b820d590b40f2cb85edddf2d38360a8~TDSZ3bBjY2193121931epsmtrp2C; Thu, 28 May 2020 01:32:32 +0000 (GMT) X-AuditID: b6c32a4a-4cbff700000025e7-cb-5ecf14b0f5b6 Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 9D.E7.08382.0B41FCE5; Thu, 28 May 2020 10:32:32 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013230epsmtip10d37aa13c3f1b2b8c6fc3854ac5b9c0a~TDSYBGXfv1640116401epsmtip1k; Thu, 28 May 2020 01:32:30 +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 v10 04/10] scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk Date: Thu, 28 May 2020 06:46:52 +0530 Message-Id: <20200528011658.71590-5-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpgleLIzCtJLcpLzFFi42LZdlhTS3eDyPk4g00vjS0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxsc/25gLtotWzGi5yt7AeFewi5GTQ0LAROJ+93L2LkYuDiGB3YwSk9bMYQRJ CAl8YpRYt4sDIvGNUeLZsvWMMB3fp+6D6tjLKPF1xU1mCKeFSeL+2242kCo2AW2Ju9O3MIHY IgLCEke+tYF1MwvcYJJ4sNIFxBYWCJb4e2shWJxFQFXiy7w57CA2r4CNxLHmE2wQ2+QlVm84 ALSAg4NTwFZi7wQHkF0SAp0cEq1TetlA4hICLhI/7qdBlAtLvDq+hR3ClpL4/G4vVEm2RM8u Y4hwjcTSecdYIGx7iQNX5rCAlDALaEqs36UPcSSfRO/vJ0wQnbwSHW1CENWqEs3vrkJ1SktM 7O5mhSjxACpPh4TBBEaJppvNTBMYZWchDF3AyLiKUTK1oDg3PbXYtMAoL7Vcrzgxt7g0L10v OT93EyM4kWh57WB8+OCD3iFGJg7GQ4wSHMxKIrxOZ0/HCfGmJFZWpRblxxeV5qQWH2KU5mBR EudV+nEmTkggPbEkNTs1tSC1CCbLxMEp1cDUnBHPY/tJiqm9n137QsuBS6cnXOHfbCx20+3i 5KdPHyzlzrsX9Fvb8NirldlZPRG33iXu6Gb0m2ogbKVvnaeeWyGnuHDSJdszdg/48n61nS95 +PLep6WeGh/Ns30fRx+ftT/X5cTvd/eZ1IM5z68+9zW7jKOcO6vIU37aYa+sl/+PRTvLz1gy 28ovSfdP+OHyjj1ykd8lrs5ken/iR/Nl5hgHYWafLSv3lEQe5Fobvktdb96Eb+ZrhR6eFmUT PrhjxeyI3Xc+VJzOmaRcLbi7vauq99yVy7/zJuQfnbFgvl/fxIA6w3ORUrF/29zMm2L59LPT Ra/qiHWxR1+2+br7q8oWS569Eg/uuaW+4Z+hxFKckWioxVxUnAgAufY/jJMDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrILMWRmVeSWpSXmKPExsWy7bCSnO4GkfNxBv+Pc1o8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujI9/tjEXbBetmNFylb2B8a5gFyMnh4SAicT3qfvYuxi5OIQEdjNK7G84wAKR kJa4vnECO4QtLLHy33OooiYmiZmTD4MVsQloS9ydvoUJxBYBKjryrY0RxGYWeMYkcephaRcj B4ewQKDEyV9cIGEWAVWJL/PmgM3kFbCRONZ8gg1ivrzE6g0HmEHKOQVsJfZOcAAJCwGVTFi1 l3ECI98CRoZVjJKpBcW56bnFhgWGeanlesWJucWleel6yfm5mxjBoayluYNx+6oPeocYmTgY DzFKcDArifA6nT0dJ8SbklhZlVqUH19UmpNafIhRmoNFSZz3RuHCOCGB9MSS1OzU1ILUIpgs EwenVANT+jElk+rcXNmMT1mSs67OFPC+P325iN/Sv//L/rgdv/jI7L6d9F6v/x6+13sjOeT8 kuaJ2Lr8tdxeIrmZL2SO5rMLJa/vrZIX2q24WLaRi+3VwcgrD6vZptyR6s3kOv1Y3ypexeCs ytODL7bfTTKPfl6ftzn/JK9ak+OjxluvCpkcPr5bX7O2Kn8l77UvhcabcrfWhcy2ZFtwPP/Y rYrQ+SItruc0ji11ry/4tPbRwal3PxyImPzRansop9O9nXdnbP3zqM+KVeya5xYrlZhzEyIF Vsy08s3MD3v67t32eTe1q1nfHimy0XL7ZxXYPUvR61Td8rAvlbwMauGdPBnzvyRPm1LyTdC7 5nR0wdN6JZbijERDLeai4kQAGrhjCdQCAAA= X-CMS-MailID: 20200528013232epcas5p32fecbbebc06909ff1fa7136481891dc1 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013232epcas5p32fecbbebc06909ff1fa7136481891dc1 References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574139 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 D2CFF912 for ; Thu, 28 May 2020 01:33:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B81E42100A for ; Thu, 28 May 2020 01:33:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="b3aNaUEh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726773AbgE1BdM (ORCPT ); Wed, 27 May 2020 21:33:12 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:50174 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726578AbgE1Bci (ORCPT ); Wed, 27 May 2020 21:32:38 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200528013235epoutp036dbcbd63a0250a62f517965a99cd3471~TDSdJ6qRA0196701967epoutp03N for ; Thu, 28 May 2020 01:32:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200528013235epoutp036dbcbd63a0250a62f517965a99cd3471~TDSdJ6qRA0196701967epoutp03N DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629555; bh=8GKVEUkWRCQ4oEzg+kXJtv/h4uSMVZoIRkh5wQhVTwY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b3aNaUEhzmMSu2ykXpSJq73LDGbPO2GWqpzdjSkMkO06/up7GJXKkGdxH/HubcjfB tPvLsFH2REMtguana0dqFyEM3otJS4R8r8mL+fRwLJTk5ZTb80CvR5RcCiwbmGK0sK nziviO57s20Qtcqkbk2ZJjZgkLtwKYGCrEAWHnro= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p2.samsung.com (KnoxPortal) with ESMTP id 20200528013234epcas5p21cb88759af4e3f23ff005cf0e87987ea~TDScNi_aT3096230962epcas5p2I; Thu, 28 May 2020 01:32:34 +0000 (GMT) Received: from epcas5p4.samsung.com ( [182.195.41.42]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 9B.58.09703.2B41FCE5; Thu, 28 May 2020 10:32:34 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20200528013234epcas5p2fe5412e2775ff9b28a1b29e8e30ab69c~TDSb0sP683096230962epcas5p2H; Thu, 28 May 2020 01:32:34 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200528013234epsmtrp1c36b17c2d81d989a82f9f7a72bcfa10e~TDSbz4oah0638506385epsmtrp1k; Thu, 28 May 2020 01:32:34 +0000 (GMT) X-AuditID: b6c32a4a-4b5ff700000025e7-d6-5ecf14b2003f Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 7B.77.08303.2B41FCE5; Thu, 28 May 2020 10:32:34 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013232epsmtip1a09102e03b8e80d37c4e285c8939a793~TDSZ9nwKx1673116731epsmtip1l; Thu, 28 May 2020 01:32:32 +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 v10 05/10] scsi: ufs: add quirk to fix abnormal ocs fatal error Date: Thu, 28 May 2020 06:46:53 +0530 Message-Id: <20200528011658.71590-6-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkleLIzCtJLcpLzFFi42LZdlhTS3eTyPk4g7svtCwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxqYjP9gK2vkq1l++yNzAeIa7i5GTQ0LARKLxwQ2WLkYuDiGB3YwSc492MYMk hAQ+MUo0rZWDSHxmlPjRMJ29i5EDrGPePx6I+C5Gie7/l5ghnBYmiU//D7OBdLMJaEvcnb6F CcQWERCWOPKtjRHEZha4wSTxYKULiC0sECixdP0dFhCbRUBV4uHmBrDNvAI2EqvWdrFDnCcv sXrDAWaQxZwCthJ7JziA7JIQ6OSQ+NbWwwJR4yKx6vtRVghbWOLV8S1QvVISL/vboI7OlujZ ZQwRrpFYOu8YVKu9xIErc1hASpgFNCXW79KHuJJPovf3EyaITl6JjjYhiGpVieZ3V6E6pSUm dndDLfWQeLr3LyskFCYAg+riFvYJjLKzEKYuYGRcxSiZWlCcm55abFpglJdarlecmFtcmpeu l5yfu4kRnEq0vHYwPnzwQe8QIxMH4yFGCQ5mJRFep7On44R4UxIrq1KL8uOLSnNSiw8xSnOw KInzKv04EyckkJ5YkpqdmlqQWgSTZeLglGpgYorKXXJGHaiusKT3u5jd/OPqXheOFR8+0x24 P37b3L/MTW/bSz/u5Tj85OP9fQuSU6SFTaN1nvn7PcvRM8mtMrz7sCfKOuF0l+/nqUmbNKc8 EUqvyp2/6QG/9XcDRvFqx6nhfAa8fdqXS+bm9HZZz5JaddumrkyjY85njcjtej9Z/PgFP2w6 FnzaxOMQf5y0893op8fuHxbY9c8/aIuvmbDLz5CN2SZnW24LWzscEecRPnLwdtsG/nNTuGyW tF/SyZgg9T30arqWCL/wJ7Gpse7vKkIu3L9yxWbLjfV9p1l71rhqazm/VZ0msvyUZefnVYbz VGevqnZpeXCxpEb1yE+Jt/az1Q+e8L0d8U+JpTgj0VCLuag4EQD6ahqblAMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrALMWRmVeSWpSXmKPExsWy7bCSnO4mkfNxBttv8Fk8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujE1HfrAVtPNVrL98kbmB8Qx3FyMHh4SAicS8fzxdjFwcQgI7GCUmXvzE2sXI CRSXlri+cQI7hC0ssfLfczBbSKCJSWLhsjoQm01AW+Lu9C1MILYIUM2Rb22MIDazwDMmiVMP S0FsYQF/iY7pLWBxFgFViYebG5hBbF4BG4lVa7ug5stLrN5wgBnkHk4BW4m9ExwgVtlITFi1 l3ECI98CRoZVjJKpBcW56bnFhgVGeanlesWJucWleel6yfm5mxjBgayltYNxz6oPeocYmTgY DzFKcDArifA6nT0dJ8SbklhZlVqUH19UmpNafIhRmoNFSZz366yFcUIC6YklqdmpqQWpRTBZ Jg5OqQYmswymRWf2/Hur7rzy4hyG/mWXu8sefjPe3/NKmPdIWd8Vp68P3ez/vApmm6dZf1yw WvtO5menk5KNn9qZXj4ok4prXHmtTYQh8H3h3Iwf72Ii2tOrFzxiX/M9SEXFqt8u9f2dE1JH peSfM/lmfCo92Jax5kFodvf90FRp0en3meSXL5p9yc95rVbKz9p/LfHlDIdPN6tvbLlmvrWB +Q57et6ESmlpmdV/O740heSZd8rNOX4oIv3itANnInq7Hr/I4ZxdaWD/gO9Xsf1SPZ6Xrz6L MffPkVTjbWD6liFxP9Vsgg//jdVBKq/9TI8bC1p97tmVeOltREfSIfmD51tWesoqzk8901jz 6PDhR2xKLMUZiYZazEXFiQDNqBCL0wIAAA== X-CMS-MailID: 20200528013234epcas5p2fe5412e2775ff9b28a1b29e8e30ab69c X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013234epcas5p2fe5412e2775ff9b28a1b29e8e30ab69c References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574117 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 116CC912 for ; Thu, 28 May 2020 01:32:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED0A520FC3 for ; Thu, 28 May 2020 01:32:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="uq14pIJP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726768AbgE1Bcl (ORCPT ); Wed, 27 May 2020 21:32:41 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:63150 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726718AbgE1Bcj (ORCPT ); Wed, 27 May 2020 21:32:39 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200528013237epoutp0119ce594331c29c1d61d18605119ff978~TDSe89tTs2169721697epoutp01z for ; Thu, 28 May 2020 01:32:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200528013237epoutp0119ce594331c29c1d61d18605119ff978~TDSe89tTs2169721697epoutp01z DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629557; bh=DDMCtAVCNOenQhQBx8fCmPqcdSKUIHqMO34BELtm7U8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uq14pIJPtuXOiBc7TNBrdOXS6i+FaNSVrYff9oL9jWh9lsOZAIMuKVUvIg61y7b2/ VO+SEOQZiidtnaNysCZdru9CXn4kCwTphO8phsHL8b5sl+mTIlXeNdNsgo5Bnzusc3 oCGWlXc4TxffSXOtwpm9lfhH3Y/EmMQGoIBmUsDQ= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200528013237epcas5p1d33a8234758f29086468dd2ebb10be8b~TDSeV0TKm1882918829epcas5p18; Thu, 28 May 2020 01:32:37 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id E5.10.09467.4B41FCE5; Thu, 28 May 2020 10:32:36 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200528013236epcas5p3cc936778eabd07450fbb7f03a17fe757~TDSdydN1D1669516695epcas5p37; Thu, 28 May 2020 01:32:36 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200528013236epsmtrp216d36acb80b09950b9885cd305b49901~TDSdxkZLP2193121931epsmtrp2J; Thu, 28 May 2020 01:32:36 +0000 (GMT) X-AuditID: b6c32a49-a3fff700000024fb-35-5ecf14b4874b Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 1D.77.08303.4B41FCE5; Thu, 28 May 2020 10:32:36 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013234epsmtip1e3fd93dcfdee5a19216a2deb6e262e03~TDSb5uWHK1672616726epsmtip1P; Thu, 28 May 2020 01:32:34 +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 v10 06/10] dt-bindings: phy: Document Samsung UFS PHY bindings Date: Thu, 28 May 2020 06:46:54 +0530 Message-Id: <20200528011658.71590-7-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrEKsWRmVeSWpSXmKPExsWy7bCmuu4WkfNxBpcOWVs8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujF99+xkLLohWtMw6z97AeE2gi5GTQ0LARGLPnp+sXYxcHEICuxklFv95yQLh fGKUWDnhEpTzmVFi86fV7DAtPecmMEEkdjFKnHx/jg3CaWGSuHPjDQtIFZuAtsTd6VuYQGwR AWGJI9/aGEFsZoEbTBIPVrqA2MICARIH/01mBrFZBFQlzr74D1bPK2AjceXCNGaIbfISqzcc ALI5ODgFbCX2TnCAKBGUODnzCQvESHmJ5q2zmUFukBDYwyFx7XAD1KUuEqf/f2CBsIUlXh3f AhWXkvj8bi8byEwJgWyJnl3GEOEaiaXzjkGV20scuDKHBaSEWUBTYv0ufYhVfBK9v58wQXTy SnS0CUFUq0o0v7sK1SktMbG7mxXC9pC4ef432CNCAhMYJZpXuUxglJ+F5IFZSB6YhbBsASPz KkbJ1ILi3PTUYtMCw7zUcr3ixNzi0rx0veT83E2M4GSl5bmD8e6DD3qHGJk4GA8xSnAwK4nw Op09HSfEm5JYWZValB9fVJqTWnyIUZqDRUmcV+nHmTghgfTEktTs1NSC1CKYLBMHp1QDE/+k J1Oz++t/lrUJ863SfLDKyb9e/vh0QcfwzOlmOyvn7CpdGbft6/3iJ5JzgmtmzGQwdo65u1lC ynVzgDy3Qlds9tnnrL8FFHuld3y3VkmLeswwIWPDJ8YFOl5PTY5w3XlqU173Rabl6Qw3H2Hd tf4fdr6V1Z9Qv6fU0rinLkjv7KHJXDJhnW9cdmeavtFwOZZzX/N7yob57UlRxoqp/LdE5s2a 8Eu7+UNet8CCl1oZaa98lmzs/B6xZ5Vfx7es1k1aG89o/a91/HYv3e9slY3rdWnzDXs05jCw qIvlnYl82NJ/zkF4me5J19KVKZuuyMzgOn26O8H/wbrdr6/v7YoVylZ1K36SeCm0X6hCiaU4 I9FQi7moOBEA+Wnk08UDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupgkeLIzCtJLcpLzFFi42LZdlhJTneLyPk4g6fnhS0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxq++/YwFF0QrWmadZ29gvCbQxcjJISFgItFzbgJTFyMXh5DADkaJrce+s0Ek pCWub5zADmELS6z895wdoqiJSWLB3G8sIAk2AW2Ju9O3MIHYIkBFR761MYLYzALPmCROPSwF sYUF/CQ2LHkCNohFQFXi7Iv/YPW8AjYSVy5MY4ZYIC+xesMBIJuDg1PAVmLvBAeQsBBQyYRV exkhygUlTs58wgJSwiygLrF+nhDEJnmJ5q2zmScwCs5CUjULoWoWkqoFjMyrGCVTC4pz03OL DQuM8lLL9YoTc4tL89L1kvNzNzGCI0tLawfjnlUf9A4xMnEwHmKU4GBWEuF1Ons6Tog3JbGy KrUoP76oNCe1+BCjNAeLkjjv11kL44QE0hNLUrNTUwtSi2CyTBycUg1MJwX/+pkx6f7/ZtbE cXVS+YTi7BYzg5NyD5e4eUgqG9z+u8ylbf2sZXGJS2ryQv4sn3VZbUbQ8yPSLOf3XEr7+WLF ra87eLdEXM367zbljPOf+YItk60in5x2+PVg6Tb1HEt3rlOSkt821uzeN61W2Ksk9ugEg3lF OyyjVgnHh+0zW1qwwtBDgSXybk2LttKuGxse/Qg5abbGmN1f9pRfbE72dwfeGf94MyqFSxy2 V7Z0ra+6uvTabedZ7HMfz2s9+KUssTjTO3vTz/msEyqNjZ0fWEftOnewwSyEoYmhb2prMnNW pHCd1LZ3f6+bH02Zyy++87FXrgtrcMsykWVtomlaHhHG7vtWPOI0MlynxFKckWioxVxUnAgA vtjbTBsDAAA= X-CMS-MailID: 20200528013236epcas5p3cc936778eabd07450fbb7f03a17fe757 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013236epcas5p3cc936778eabd07450fbb7f03a17fe757 References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574123 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 8EB80159A for ; Thu, 28 May 2020 01:32:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 688F721501 for ; Thu, 28 May 2020 01:32:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="en0Iag1U" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726831AbgE1Bcs (ORCPT ); Wed, 27 May 2020 21:32:48 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:50212 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726759AbgE1Bcr (ORCPT ); Wed, 27 May 2020 21:32:47 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200528013240epoutp03f9760ffe4381e3e23380f288894b1ec9~TDShIHwCP0188001880epoutp03e for ; Thu, 28 May 2020 01:32:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200528013240epoutp03f9760ffe4381e3e23380f288894b1ec9~TDShIHwCP0188001880epoutp03e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629560; bh=sK/hFncn11WBScvtcYDk7R7CcwFLxOCyulZMUjKu6sA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=en0Iag1UB7aEPKKuipNgo9pSt3hjIL7aGHYLXC9sP13dMgtMmWbOrGqwBANb1lOII Jc+HKo1e60tm/18+LDA5VQEVjnFIdDLX5XlCmB000u0Po0VxTUbMOC1Ag/AIUUAucV /z3W8QbuNjI9YMWYPs0aFp6YaouJ4Ep2UosXwilY= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200528013239epcas5p1b80d8ba86aca0ae5c3ee08a63829ccdf~TDSgOhBNB1882918829epcas5p1K; Thu, 28 May 2020 01:32:39 +0000 (GMT) Received: from epcas5p4.samsung.com ( [182.195.41.42]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id CF.58.09703.6B41FCE5; Thu, 28 May 2020 10:32:38 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200528013238epcas5p3c00d834dbb0b26cc683f293385d77178~TDSf2Jt8m1669516695epcas5p3A; Thu, 28 May 2020 01:32:38 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200528013238epsmtrp20a586e86ab57ed262ae03e8607edc1e2~TDSf1Lfwr2193121931epsmtrp2M; Thu, 28 May 2020 01:32:38 +0000 (GMT) X-AuditID: b6c32a4a-4b5ff700000025e7-ea-5ecf14b6aabf Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 8E.77.08303.6B41FCE5; Thu, 28 May 2020 10:32:38 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013236epsmtip16e45c259db61d4695c6f443f22468c8a~TDSd2FRq51669416694epsmtip1l; Thu, 28 May 2020 01:32:36 +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 v10 07/10] phy: samsung-ufs: add UFS PHY driver for samsung SoC Date: Thu, 28 May 2020 06:46:55 +0530 Message-Id: <20200528011658.71590-8-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA01SWUwTURT1zUyHKaZ1LKhPUNFGNKLiLiOhSFwnRI1oIIpaacoECFCaqSAa jbUSBAoIglqRIImWRlAhtZSmiiAWC0pBg6K4RUCIaxVwDXErU6N/59xz7jv33jwCFTXwfIgE xR6GVciSxLgnZr45J2C+2btDutBxYgX1osyMU6+/P8CpoeoKHnXW1s6j7vbn4lRHR40H1W1q xihjXxeP6rSW4pSu4zpCaR9acMpg/4lQv65ZPCh9bTcIE9Kd+XkIbazMxukr5w/RGa0NGD3Y /xij802VgLY/qkPoYeM0+mijFtnMj/YMiWWSEtIYdkFojGf89+NFqPJpKUgvO9/LU4NhDcgB fAKSS6E1+wsvB3gSIvIqgGrHRzcZAlCrycU5Mgzg26EW9G/LyffNKCdYATyhKQIcyUBg3vMe D5cLJ+fCZ6dMiAt7k17Q9iVz1ISSGhR+0mtwl+BFRsCjjs+jk2CkPxzoeTgaISBDYM67q+4J /WBVTeOfOkHwSQmsLwjjLONh6+mXmAujfyxHas+4p7tLwL4zIg6vgW3NZnfdC76xmzw47AOH nfW460lIJsJc6xKufADqy25hHF4JG++XYi4LSs6B1dYFXJIQ5o28RLhOAczKdAf5wyPOB+5O X1io1fI4TMOGi0b3qQoANI9cBwXAr+S/BUr+W6DkX1o5QCvBZEapSo5jVMuUixXM3kCVLFmV qogLlKckG8HoHwsIt4CeFx8DmwBCgCYACVTsLVjluCMVCWJl+/YzbMpuNjWJUTUBXwITTxKI v7VJRWScbA+TyDBKhv2rIgTfR41kBd6L2jRBb1tTlYZHHtZvL06xTXS2RrQPnpPIa6qfFGLq igsCrDxxni6kdgc/4WD0h8sxzEC92dfPPmbZh9uVWKhuUsuQLdJibus0kBUBerXO+j7ifvH0 Xad/4Lxe7bbiC4JZJ4WbV98I2ThDWZQ0e1DRKteF/SQXjou4FlyQWRu2db+vbeeNz+H6Jccv xRtWjNiljqp12UF5sUF196KzD6b/eN2+tWt9ueRAVsNMbUaX5FhaXXpMMDuwZcAwsjxmt78I lTilp6J+2eZueBYlDQ1+xaauNk2J7JR7OdfmhiPC3qaWBIsyyJC/Y4q2G+uTzwPp+VO/ju3v CRJGlrFiTBUvWxSAsirZb3dVfhvSAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprKIsWRmVeSWpSXmKPExsWy7bCSnO42kfNxBqunKVk8mLeNzeLlz6ts Fp/WL2O1mH/kHKvFhac9bBbnz29gt7i55SiLxabH11gtLu+aw2Yx4/w+Jovu6zvYLJYf/8dk 8X/PDnaLpVtvMjrweVzu62Xy2LSqk81j85J6j5aT+1k8Pj69xeLRt2UVo8fxG9uZPD5vkvNo P9DNFMAZxWWTkpqTWZZapG+XwJXxc9Jk5oI7cxgr5i15xNrA+LmJsYuRk0NCwERi2tujzF2M XBxCAjsYJW4/vMcMkZCWuL5xAjuELSyx8t9zdoiiJiaJ7VPngRWxCWhL3J2+hQnEFgEqOvKt jRGkiFlgArPE8l/fwFYIC/hLbPg9nRXEZhFQlXj28DpYM6+AjUTXm91QZ8hLrN5wACjOwcEp YCuxd4IDSFgIqGTCqr2MEOWCEidnPmEBKWEWUJdYP08IJMwM1Nm8dTbzBEbBWUiqZiFUzUJS tYCReRWjZGpBcW56brFhgVFearlecWJucWleul5yfu4mRnDMaWntYNyz6oPeIUYmDsZDjBIc zEoivE5nT8cJ8aYkVlalFuXHF5XmpBYfYpTmYFES5/06a2GckEB6YklqdmpqQWoRTJaJg1Oq gcl80rGSUP/TSS9L1m7r0PFf6P3v4MMlu0xTebTOFcofjmwQ/BzaMmlLa1/ovh83Dm/mN3+R VHZ7TwtLRHnj0dqgdQ47ZrN22t4pOiGSfJTt67tZ16X1MqVem5lm1bHYchglLZafuFi3M5Oj Zcr1qbPs7NQN/0l7pu8/ZbJO6SRPnc5rTReRdceXx10werStc7pU3iv+MuecF4tba98k+yqY av8QVDn7Ru2vuc0v349aB9m951moGrP/mST8tKom9xDruxrz3WFX2LdP/iX/yDx7tv6x3GIp Lw3Glknz/iWcnHPlm73Gif9KF6qmzGD7efPpx7RctuOH7d/c0HfjzLhh0nty31WPNROmcc37 U6bEUpyRaKjFXFScCAB+Jj3CKAMAAA== X-CMS-MailID: 20200528013238epcas5p3c00d834dbb0b26cc683f293385d77178 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013238epcas5p3c00d834dbb0b26cc683f293385d77178 References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574137 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 A763F159A for ; Thu, 28 May 2020 01:33:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8AE592100A for ; Thu, 28 May 2020 01:33:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="I7HuNFrc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726768AbgE1BdK (ORCPT ); Wed, 27 May 2020 21:33:10 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:63193 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726771AbgE1Bcn (ORCPT ); Wed, 27 May 2020 21:32:43 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200528013241epoutp017351c837643f2c2f6bc1ebe710927422~TDSip-GD32173821738epoutp010 for ; Thu, 28 May 2020 01:32:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200528013241epoutp017351c837643f2c2f6bc1ebe710927422~TDSip-GD32173821738epoutp010 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629561; bh=tic87tYGoP0wf8PhTKj7y0fX/KpDctpqswklLi69jbQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I7HuNFrc9lU1WrmK7s+waTTyfxgdfRfiygKnf9erQ1rU8ykAJYzfWbr7tdEkZdBA9 srFYY5Kn447Lg7n4o23ehRFVyaed+OL0sPb/u+QGxoFcPHh7ouIgJoRTU4MkJCBreq F7O6phqcXh4pjCnvW9r0EVP7PympT4t0i7E1E7CY= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200528013241epcas5p30be469cab73e2e648a32c533c0efb223~TDSiOyknR1669616696epcas5p3H; Thu, 28 May 2020 01:32:41 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id DB.B2.09475.9B41FCE5; Thu, 28 May 2020 10:32:41 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200528013240epcas5p38d53c6e320065b40bda434c49efad57a~TDShzl6bs1669616696epcas5p3G; Thu, 28 May 2020 01:32:40 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200528013240epsmtrp1237bf07c979619eabc8b4920344b08bb~TDShy2_sM0638506385epsmtrp1o; Thu, 28 May 2020 01:32:40 +0000 (GMT) X-AuditID: b6c32a4b-39fff70000002503-59-5ecf14b98927 Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 40.F7.08382.8B41FCE5; Thu, 28 May 2020 10:32:40 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013238epsmtip1c90958696256eb20def2426af912ec96~TDSf8n0mu1652016520epsmtip1k; Thu, 28 May 2020 01:32:38 +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 v10 08/10] dt-bindings: ufs: Add bindings for Samsung ufs host Date: Thu, 28 May 2020 06:46:56 +0530 Message-Id: <20200528011658.71590-9-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA0WSe0xSURzHO5cLXCnaDayOOrPhXFMX2qrtNu05q9vasq3Wqj80yiu6gBjX QqstK8JUEq00a05tYg9LU0MUjCQ0ynxQafaaxrIXVK6g7J2F19Z/n9/v9/me39nZwViCg+xg LF2RQakUEpmIw0NN7ZFz5poDnUmxluHJhKvcxCHc3x5wCO+Vc2yioqOXTTid9VzisfEmSjQO D7CJPksZhyh1XkeI/IctHOL8rd8IMXathUtUNz0Gy/hkX8ExhGysyeWQVw0HSE1nG0p+fPkE JQuMNYD0Nc4ic2z5yHpsKy8+hZKl76FUMUu28dIun+4EyjszMntKh0E2MEzLAwEYxBfA+i9m dh7gYQK8FcBSQy2LKbwA9l96NTEZBdB1XYv8i+g0OpQZWAFsHy3jMIUGgXUOK9dvcfBoOHjK OJ4IxIWwY1QL/MzCHyHQdTHBz0J8Pey1nRz3UTwCaurusvzMx+Nh0a8jLGZbGLxUb/vLGBaA L4bWwmVMOxeDNc/mMJwA23x2lGEh9NwychkOhm69luuPQnwn1FnmM+39sLrcMaEvhbb+MtSv sPBIeMUSw1xyKjz24wXCJPnwqFbA2BHw8MiDiWQILMrPZzMKCZuzw5k3KASw+qCZXQhCz/w/ tBKAGhBEKWm5lKIXKucrKLWYlsjp3QqpeMcueSMY/yVRa1vAc9cHsR0gGLADiLFEgfwVPV1J An6KJGsvpdqVrNoto2g7CMFQ0Uy+6Gt3kgCXSjKonRSlpFT/pggWEJyNTFp331AcGGNd/Ob1 In3owIzO960Xj6e+Wx1xfNDn/W7quqc/UfuzlsgZKC5JH9leEZ/VBT6X6J+2JU923WgI71a7 85odyXHJKGYKjpruVVqr61cuTC0bCp0SFhQr/qad3XQnM6rKG7Mu7+NmZdWZITHmUfLG6I2r plbRHpV5KKug/1PAFt9Re4Mlul0hTpfe3ljXbAxZrrsbck1G+yJbZM5DRboU9gUPanPIK4XR avmb1x2JCZbWs5lxhhxzJ7lVX1Ip3LBvNdolHVXvGDMFadYqM2I3TekfSR30hg2Hx6UVP7rs MU16uarK8dXnnq1+m/sl0d2QuKa3qRl+7xOhdJpkXhRLRUv+AMLZRYmUAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSnO4OkfNxBrNXaFo8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujDUzTzIWnBKrODvjMWMD4xLBLkZODgkBE4melh6WLkYuDiGB3YwS7bsa2CAS 0hLXN05gh7CFJVb+e84OUdTEJLHmSDMzSIJNQFvi7vQtTCC2CFDRkW9tjCA2s8AzJolTD0tB bGEBP4nDc86wgNgsAqoSLesugPXyCthITPzbygyxQF5i9YYDQDYHB6eArcTeCQ4gYSGgkgmr 9jJOYORbwMiwilEytaA4Nz232LDAMC+1XK84Mbe4NC9dLzk/dxMjOJi1NHcwbl/1Qe8QIxMH 4yFGCQ5mJRFep7On44R4UxIrq1KL8uOLSnNSiw8xSnOwKInz3ihcGCckkJ5YkpqdmlqQWgST ZeLglGpgmh4W+ftRNfPZQ6v+iVftedrLsDj5ht8Mr+/MbZn2s3+qPDBT5FrN7XdITFV6/bJK 07X/oibzCmd0C9UqXb2p2ZMvu7R7XYNRb2pz7XV1q/L3papaNfaN2+J4Xjvtam1QUOqWFt0+ LTvrrt9bpX+P/mxsETgSuPiD0pWKZxZz5yr1Hi0O3z6bLfndoQ0vnnvEMG85MnnCg+K7az6z ThD+J3+g5cwH44qXN7dIiyclyy0SrLTwbpQ8/NymKs3voNY+jwnfvybe+tiy80CbYsJU1Ytz fJIfs25+y8pRJ2h4IuxY/oeNkv9LHB6ceLO7cvmXq9vfbzv1i/+O/FKJs5/3TLR249U53nRo h8LMY95MZkosxRmJhlrMRcWJAIAiLSXVAgAA X-CMS-MailID: 20200528013240epcas5p38d53c6e320065b40bda434c49efad57a X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013240epcas5p38d53c6e320065b40bda434c49efad57a References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org This patch adds DT bindings for Samsung ufs hci Reviewed-by: Rob Herring Signed-off-by: Alim Akhtar --- .../bindings/ufs/samsung,exynos-ufs.yaml | 89 +++++++++++++++++++ 1 file changed, 89 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..38193975c9f1 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml @@ -0,0 +1,89 @@ +# 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: + items: + - description: ufs link core clock + - description: unipro main clock + + clock-names: + items: + - const: core_clk + - const: sclk_unipro_main + + interrupts: + maxItems: 1 + + phys: + maxItems: 1 + + phy-names: + const: ufs-phy + +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 28 01:16:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574125 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 18072912 for ; Thu, 28 May 2020 01:32:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D07722145D for ; Thu, 28 May 2020 01:32:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="EkQupREW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726853AbgE1Bcy (ORCPT ); Wed, 27 May 2020 21:32:54 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:50267 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725960AbgE1Bcx (ORCPT ); Wed, 27 May 2020 21:32:53 -0400 Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200528013243epoutp037986e871542b9a840f877fa3ccdfb494~TDSkuuI-10196701967epoutp03Y for ; Thu, 28 May 2020 01:32:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200528013243epoutp037986e871542b9a840f877fa3ccdfb494~TDSkuuI-10196701967epoutp03Y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629563; bh=PDMiJY/am/0bhgJyyZVMhqytx7f8PSCHMTlceMBvDDU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EkQupREWZZsZTh6A0Zsaet337cGcFGDg42iHmgB5hX5vCs6gwdHAS1SvxqeZCXc9v Xel8g3L/nMXzFEZ9q61KMIfXWljmSSoPPQib3ux8MCeRzdjIlyJCMCnyPpVdrWuVOX oVVigE7qMOnROOuMLPAaU0LIa5oFFCc6boP5Mr7I= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200528013243epcas5p1a4e0a58b7ed7a9915b91030607b0e5d6~TDSkVUGCX1882918829epcas5p1V; Thu, 28 May 2020 01:32:43 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 73.68.09703.BB41FCE5; Thu, 28 May 2020 10:32:43 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20200528013243epcas5p460a041d543b9acfbaa923f38709740b0~TDSj8dFkd2994029940epcas5p4U; Thu, 28 May 2020 01:32:43 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200528013243epsmtrp22f1e8612d450e4afae9efda48913d1fb~TDSj7ivMr2193121931epsmtrp2P; Thu, 28 May 2020 01:32:43 +0000 (GMT) X-AuditID: b6c32a4a-4b5ff700000025e7-fc-5ecf14bb5db6 Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id EF.77.08303.AB41FCE5; Thu, 28 May 2020 10:32:42 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013240epsmtip12b2a9f167665fc9fd805b7c77a2c2310~TDSh5ygIt1669416694epsmtip1m; Thu, 28 May 2020 01:32:40 +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 v10 09/10] scsi: ufs-exynos: add UFS host support for Exynos SoCs Date: Thu, 28 May 2020 06:46:57 +0530 Message-Id: <20200528011658.71590-10-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCKsWRmVeSWpSXmKPExsWy7bCmhu5ukfNxBn8miVo8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujFcbp7EW9E5kruhpe8PewPjxHFMXIyeHhICJxO+lHSxdjFwcQgK7GSVOL73H DOF8YpRYvKgXyvnMKPHk+yJ2mJaNDxugErsYJS7eOw/ltDBJNN19xAZSxSagLXF3+hawJSIC whJHvrUxgtjMAjeYJB6sdOli5OAQFgiWeL1UBCTMIqAqcXJNKwuIzStgK3Fu5y5WiGXyEqs3 HGAGKecEiu+d4ABRIihxcuYTFoiJ8hLNW2eDnSAhcIBDYtf2SVC/uUhM23cf6mhhiVfHt0DZ UhKf3+1lA5kpIZAt0bPLGCJcI7F03jEWCNte4sCVOSwgJcwCmhLrd+lDrOKT6P39hAmik1ei o00IolpVovndVahOaYmJ3d1Qx3tIzP4ziRUSOBMYJXqaV7JOYJSfheSDWUg+mIWwbQEj8ypG ydSC4tz01GLTAqO81HK94sTc4tK8dL3k/NxNjOCEpeW1g/Hhgw96hxiZOBgPMUpwMCuJ8Dqd PR0nxJuSWFmVWpQfX1Sak1p8iFGag0VJnFfpx5k4IYH0xJLU7NTUgtQimCwTB6dUA5ODU0+q luvt+p7jGRLzWEuUtjKeyPo+O+yskXJ642xnWZfYwO+KZvtWvDW+fHuFDndF4vkDMld3BU7c vkpUQdaftS8psf22zIw/k8vkU17Fr6y7U3lNmSVGZEpLWVgXi9fEhzt4D83Jjb5bL35sLu/b lr1fY1qdFX7eC3lu/2oby+Vrh57Lvapmv6qedqbwwsY939/Gyenkyx10XRmkUV4wff8GE+7M K5vLle5vXDxpX63as5lTVx3rajTb2LqoNOWHhK3cjCRmLeXWL+f6U+9Z+7t2leuZ/WbvPGl3 +VoOc9/Uld1HD6xcue5l7wMGXVvzqCZBZtETKk4e74+mXKiUy7K6uYOrS0z2x77FCkosxRmJ hlrMRcWJAGDuF7DHAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupkkeLIzCtJLcpLzFFi42LZdlhJTneXyPk4g64vZhYP5m1js3j58yqb xaf1y1gt5h85x2px/vwGdoubW46yWGx6fI3V4vKuOWwWM87vY7Lovr6DzWL58X9MFv/37GC3 WLr1JqMDr8flvl4mj02rOtk8Ni+p92g5uZ/F4+PTWywefVtWMXp83iTn0X6gmymAI4rLJiU1 J7MstUjfLoEr49XGaawFvROZK3ra3rA3MH48x9TFyMkhIWAisfFhA3MXIxeHkMAORolLf1dB JaQlrm+cwA5hC0us/PecHaKoiUni2e1JbCAJNgFtibvTt4A1iAAVHfnWxghiMws8Y5I49bC0 i5GDQ1ggUOLIc7ASFgFViZNrWllAbF4BW4lzO3exQsyXl1i94QAzSDknUHzvBAeQsJCAjcSE VXsZIcoFJU7OfMICUsIsoC6xfp4QxCJ5ieats5knMArOQlI1C6FqFpKqBYzMqxglUwuKc9Nz iw0LjPJSy/WKE3OLS/PS9ZLzczcxgmNLS2sH455VH/QOMTJxMB5ilOBgVhLhdTp7Ok6INyWx siq1KD++qDQntfgQozQHi5I479dZC+OEBNITS1KzU1MLUotgskwcnFINTGH7Hp/0sV6fX9Cw PCezrXd5yK5P11hTJGNjV585nG5eJS71MuTtJoHnG3zZ3LecDQnka/ppcjKmmHelyasdcd8t 5QXXmT20v3Tt7caLJWcqcnwKN/puZk97yiTNkJf25svikIj3QmeM9T0yw69VeIXmHPjz4O4W eVc+sx8xXD82qgVsvSa8L2ul6qYTfxfcE7h49di6dkP/FA7tv01N0yatru/XErOfmXbnZ4qx XvC9k5+OdF1pexbYWP43Pfxb3fQVR564OP19wHP/w60ca+miZ+fn6u9cHaZVfYj/bfH2mC8+ /R//WwicL1vFn77/wsePoYWTFt1uZv96XCxqgxO7s1RHltxHdqltL3U9/imxFGckGmoxFxUn AgAETKL3HAMAAA== X-CMS-MailID: 20200528013243epcas5p460a041d543b9acfbaa923f38709740b0 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013243epcas5p460a041d543b9acfbaa923f38709740b0 References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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 28 01:16:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11574127 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 409F4159A for ; Thu, 28 May 2020 01:32:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1F1602145D for ; Thu, 28 May 2020 01:32:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="tz5jcXY5" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726842AbgE1Bcw (ORCPT ); Wed, 27 May 2020 21:32:52 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:35219 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726827AbgE1Bcs (ORCPT ); Wed, 27 May 2020 21:32:48 -0400 Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20200528013246epoutp0243dc454fc476e0fb2ddb13cbdff65e62~TDSnBaDHT3030230302epoutp02u for ; Thu, 28 May 2020 01:32:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20200528013246epoutp0243dc454fc476e0fb2ddb13cbdff65e62~TDSnBaDHT3030230302epoutp02u DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1590629566; bh=YqesGE9QRWzbUFapaH4d6ciy/qj5O7BFUrBR3w8MJ14=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tz5jcXY5hipzfZ3eh1NCnkPzpSQIlJBgyxkI27ctPmIAhKlzJyqOLcGF8HbrIkkf8 STDaPUsrm4AZ+wZUkfx9MIv/En97YoiNfRyj4DzB0uv6K/Su8jvBEuAMr5nSKUjLDB 4vxD8LdFTfTW+4fDP3GDvu1qosod8L9Puv1twR8Q= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200528013245epcas5p38aa13d5d814a3fa69821a0fe32d92eae~TDSmTrT1u1669616696epcas5p3a; Thu, 28 May 2020 01:32:45 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 00.20.09467.DB41FCE5; Thu, 28 May 2020 10:32:45 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200528013245epcas5p37851891649512882c7b1ffb5f903c506~TDSl0hDU21669616696epcas5p3X; Thu, 28 May 2020 01:32:45 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200528013245epsmtrp157c7b006bc9e5ef5e23d76b2ebcf1cba~TDSlzfQkC0638506385epsmtrp1u; Thu, 28 May 2020 01:32:45 +0000 (GMT) X-AuditID: b6c32a49-a29ff700000024fb-5e-5ecf14bdaa52 Received: from epsmtip1.samsung.com ( [182.195.34.30]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 12.F7.08382.CB41FCE5; Thu, 28 May 2020 10:32:44 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20200528013243epsmtip1e2ac487d7a5b5c26119f98d65a37b08f~TDSj95nFz1371113711epsmtip1X; Thu, 28 May 2020 01:32:42 +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 v10 10/10] arm64: dts: Add node for ufs exynos7 Date: Thu, 28 May 2020 06:46:58 +0530 Message-Id: <20200528011658.71590-11-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA01Se0hTcRj1d3d3dxVntyn1peRqYOVK0+xxQ0srqxuhlARGkTbspuJ0ujkr CVovLTdzReSrXIUVrUSbU2w1s+U0qTRaZrkEQ6MHYdpbKqvrNeq/851zvu8cfvxIgaRW6E+m Z+Wy6iyFUkZ44Y13gueE2P26ksJ6LIF0f1UjQb8Z7SboD7UXhbSptVNId3XViehnVidOWwae CGmX7TRBl3U1Y7S+p4mgL7WPYfSvm00i+kLDMxQjZlzHijHGYj5KMPXV+5hDHbdwZuRlL84c s5oR89ESyBS26LEN5BavqB2sMj2PVc9fvt0rrfoVkV0Eu7+2W0Q6dM23CHmSQC2E0WEnUYS8 SAl1A4FzpFzEDx8QmBsvC/jhC4KHpmrB3xWX8T3iBTuCoWankBMk1CEMDpxL5DBBzYW+UivG YT/KF1q/FCAOC6inGPRfjuWwLxUNledHx3mcCoIfxuFxLKaWgb2qVciHSeFKXcufYJL05Hhj DG+ZDB3lgzh/UgoHGyrHiwJVQ4Ku1Sri/EDFwmdrAH/GF962czSH/eFNScGEJQMMtgie3gsX qtpwHkdDy+PTOGcRUMFQa5vPJ/lA8fdBjN8Uw5ECCe8OgoND3RObAXBcr5/ozsD9qw8x/m2M CGy1KUYkrfivf8V//Sv+hZ1FAjOaxmZrMlNZzaLs8Cx2V6hGkanRZqWGpqgyLWj8T8nXNaG+ /uFQB8JI5EBACmR+4pUP7iVJxDsUe/JZtSpZrVWyGgcKIHHZVLHs2/0kCZWqyGUzWDabVf9V MdLTX4eV1GhLG8Lk+pThTzGHFxm8zynnDc7BH0TE3Z3iPYg5ZhauD4k2N2GTNzhzQjrl8wLD PidXOlweRet+HO6f7fM42t7TtlM14u02/6rJX5gRuQSNbRo7n7/CXb96qbIgMcGxatbmd6cM L8p0vaatjvePYgdKc+NK3KdeR1bqrHtMCfa3cfa2+LD1nt2TPJq93enJweayjrwcQ+OLVaap 3T2SgZzmOunzSMJe6PqU0LKADU8ox7Wh18/4eRydtbJ4o6N+m2trg8/atqhlYMjYeYu0xZuF eRdvnwiSfp2+YMXP+CBX7/7rwhuqqDWLT+a7h9wb1xRr5S8TY/e+s4hVkXU/Z8hwTZoiXC5Q axS/AcbguGnCAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmplkeLIzCtJLcpLzFFi42LZdlhJTnePyPk4g23frC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxpLnbAVdEhXfj29ib2DcKNzFyMkhIWAicXnCe0YQW0hgN6PE5Gk5EHFpiesb J7BD2MISK/89Z4eoaWKSOHucB8RmE9CWuDt9CxOILQJUc+RbG9gcZoFnTBKnHpaC2MIC9hKz F/0Ei7MIqEr8mfABzOYVsJXYO+8IK8R8eYnVGw4wdzFycHCCxCc4QKyykZiwai9UuaDEyZlP WEBKmAXUJdbPE4LYJC/RvHU28wRGwVlIqmYhVM1CUrWAkXkVo2RqQXFuem6xYYFhXmq5XnFi bnFpXrpecn7uJkZwTGlp7mDcvuqD3iFGJg7GQ4wSHMxKIrxOZ0/HCfGmJFZWpRblxxeV5qQW H2KU5mBREue9UbgwTkggPbEkNTs1tSC1CCbLxMEp1cCkO6+7wUaOaZ5TrOPEd7PLnRKunnFb NU9T+XxN8q65Vy6qbdJezhbyZZJ2+XKhinPx3z4032Pb9Ct/yrL1GeoJXR/uHxe3yWiLtbcI uB995dPSkxbH/h5q8hPwcl1fleT5O89bee+7oy/jyy5rPszbHqEk9CVRrtU/Mjhs2sp9/Rfe h05dVBi492jW7AIDbrm7+kd1y9fblz2fepqPLX8X97qfzZqMx3hEuT5cM5//q+esO1vtRJNe njuTnQzcutxquz51CL8yW/OWKyGx4x2bBqPM4q1TVlo3c227czLvQ3i14CzB2SIXF7r8OSJg bKjcanr/4ZZtZvzbZm2tmPBg3Y9nJ0Ka+4+JLzxvotuvxFKckWioxVxUnAgAnWVK0BgDAAA= X-CMS-MailID: 20200528013245epcas5p37851891649512882c7b1ffb5f903c506 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200528013245epcas5p37851891649512882c7b1ffb5f903c506 References: <20200528011658.71590-1-alim.akhtar@samsung.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@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>;