From patchwork Mon May 11 02:00:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539575 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 0BC6F139A for ; Mon, 11 May 2020 02:14:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3F942495C for ; Mon, 11 May 2020 02:14:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="ckaOAs0g" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729393AbgEKCNy (ORCPT ); Sun, 10 May 2020 22:13:54 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:33783 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729255AbgEKCNx (ORCPT ); Sun, 10 May 2020 22:13:53 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20200511021351epoutp044e3c0ab54d26d29546a2d7e7fe7b6a3a~N14nzP_WM1313513135epoutp04O for ; Mon, 11 May 2020 02:13:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20200511021351epoutp044e3c0ab54d26d29546a2d7e7fe7b6a3a~N14nzP_WM1313513135epoutp04O DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163231; bh=HK/1/VP5ov7EOoNpQ0X08DtlhI52O+2EyAZ3cTvlQkI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ckaOAs0gsGJq81PVuaGOhgqOx9Ycv9S6e53dGdsD0n3HYUOnHTbnkZfqnMtMouHSD ZmzUU7jW7SadxqzB44K2daFcf1vI4OfbIBFudMmOdiHle+WiJ7cyWNJ6DObKpXspaz HEiQZkvbnCwfyLaEDtL2/oGSeyWhmM1mPhpwNcX8= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200511021350epcas5p3deba4bf4bfed536e912be972a6c1e503~N14nEAQah1506415064epcas5p33; Mon, 11 May 2020 02:13:50 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id F9.9E.23569.ED4B8BE5; Mon, 11 May 2020 11:13:50 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20200511021349epcas5p107f296543fe2c1e13a9e5cbffdab43d3~N14mq56c21462014620epcas5p1b; Mon, 11 May 2020 02:13:49 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200511021349epsmtrp295b330462cb70980d26fc6c99382fffa~N14mk2MeC1467414674epsmtrp2M; Mon, 11 May 2020 02:13:49 +0000 (GMT) X-AuditID: b6c32a4a-3c7ff70000005c11-e1-5eb8b4de483a Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id A7.E6.18461.DD4B8BE5; Mon, 11 May 2020 11:13:49 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021347epsmtip2ee551f9828ade523b0deff03136d02ff~N14knFANd0194601946epsmtip2l; Mon, 11 May 2020 02:13:47 +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 v8 01/10] scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr Date: Mon, 11 May 2020 07:30:22 +0530 Message-Id: <20200511020031.25730-2-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42LZdlhTU/felh1xBjtucVg8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujBdH17AU7Bao2P/hOHMD42veLkYODgkBE4k/i826GLk4hAR2M0osajzPBuF8 YpToWHWdEcL5xihxYvFGoAwnWMfs7wuZIRJ7GSXmNk5lgnBamCTO7fnHCFLFJqAtcXf6FiYQ W0RAWOLItzawOLPADSaJBytdQGxhgRCJJzca2EFsFgFViTnPT4Bt4BWwkdjz6iIrxDZ5idUb DjCD2JwCthLTGrazgCyTEGjkkFj38jM7RJGLxNOby5ghbGGJV8e3QMWlJD6/28sG8Wi2RM8u Y4hwjcTSecdYIGx7iQNX5rCAlDALaEqs36UPcSafRO/vJ0wQnbwSHW1CENWqEs3vrkJ1SktM 7O6GutJDomV+DzskGCYwSqy708M+gVF2FsLUBYyMqxglUwuKc9NTi00LjPJSy/WKE3OLS/PS 9ZLzczcxgtOJltcOxocPPugdYmTiYDzEKMHBrCTCuzx3R5wQb0piZVVqUX58UWlOavEhRmkO FiVx3qTGLXFCAumJJanZqakFqUUwWSYOTqkGpl3+CYdDTOJ0N7aaTXz66Fh/ovrbh87Oavs/ TNq0/H/F7Wn60o55Xzz3ck4PtvWIKy44V/3TPPIx8/z7kSlvOnv9/c9e6f8ceHeJ/dYDYgsk d6VdzUy01OjUF/K4OzO/8fdW+w/a505V1zIFzek9X3Xee/lupYSyx3MND2xrNCi0f5+3foaP 4Nc0fjO95lna4Wd2THKZInXgb+DTyGntOzf8PegSnXJObfUyf/b9qfFX5NhLqs6emViz1Seo dbOm8exfv1fc5Xm29MH53pAPJhFcvv+827nLD52aGWLI9+rRHym+xPnznWzzlVfXNnMcz97t c/ynTsvspJmX43WvB+rPiypaHavpz/7uur2vmxJLcUaioRZzUXEiAK7XXCCWAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrILMWRmVeSWpSXmKPExsWy7bCSvO7dLTviDO4dVLN4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaL8+c3sFvc3HKUxWLT42usFpd3zWGzmHF+H5NF9/UdbBbLj/9jsvi/Zwe7 xdKtNxkdeD0u9/UyeWxa1cnmsXlJvUfLyf0sHh+f3mLx6NuyitHj8yY5j/YD3UwBHFFcNimp OZllqUX6dglcGS+OrmEp2C1Qsf/DceYGxte8XYycHBICJhKzvy9kBrGFBHYzSizfGQcRl5a4 vnECO4QtLLHy33N2iJomJok9rVkgNpuAtsTd6VuYQGwRoJoj39oYQWxmgWdMEqceloLYwgJB ErcOdoL1sgioSsx5foINxOYVsJHY8+oiK8R8eYnVGw6A3cApYCsxrWE7C8QuG4kZmzazTmDk W8DIsIpRMrWgODc9t9iwwDAvtVyvODG3uDQvXS85P3cTIziUtTR3MG5f9UHvECMTB+MhRgkO ZiUR3uW5O+KEeFMSK6tSi/Lji0pzUosPMUpzsCiJ894oXBgnJJCeWJKanZpakFoEk2Xi4JRq YCr8USzEKG/560ph5nLB+9vPGenNnnHw3Z+1t6r8ZE+us1w50X3rhFfHS0SvP12nsFztkG/Q nNuZTLN/ZW51ZV414VD5r7Kpp4X6Jaa8Wih4cU2mOvvLa8kevTwbUj05F+3ucYxtfuncxPJV 9LVMRcT0oF0n7kiaCBz8fSKuW1ctUOT82bm/9TZsL4o7Z8FZ/z7N7oFT59GOtiUbxPKXqVfH nbja75vOZGRqEn9zgUXRrYxvfB3Gl8W1k84yy7deLz722si8esY23mOVKeHizxcF6qTJ3Wze FlfeKeittHdqkdSlQ+mHwqt1+3q5KyV3ur9reKE+q3yZghv7rhmil4RPet1ePXG39due6FSr ACWW4oxEQy3mouJEADAj0o/UAgAA X-CMS-MailID: 20200511021349epcas5p107f296543fe2c1e13a9e5cbffdab43d3 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021349epcas5p107f296543fe2c1e13a9e5cbffdab43d3 References: <20200511020031.25730-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 Mon May 11 02:00:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539571 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 7355B92A for ; Mon, 11 May 2020 02:14:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A0902495A for ; Mon, 11 May 2020 02:14:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="DoB42yWm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729388AbgEKCOs (ORCPT ); Sun, 10 May 2020 22:14:48 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:34194 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729379AbgEKCN4 (ORCPT ); Sun, 10 May 2020 22:13:56 -0400 Received: from epcas5p2.samsung.com (unknown [182.195.41.40]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20200511021353epoutp02338243c3ab1dda73977b54e85efe9304~N14qDyItc3178831788epoutp02n for ; Mon, 11 May 2020 02:13:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20200511021353epoutp02338243c3ab1dda73977b54e85efe9304~N14qDyItc3178831788epoutp02n DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163233; bh=aZlGHc5xTiWwAyuHWOUJ6KyldBblFcw6DUpelUfBEa8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DoB42yWmUyX2kuPqwB4/QQ2eeb5Sdic2W6Av2V8OjbpfQYdNQ4/s7/Phggc50uYl5 OYb9dsEtehX0MjWHKevQHEI15LOCkL8B2035RpN8RUY2Dt7eB3/mKnoVOLxxr0eM8C nZAARzCpy9KjXuhiMhtwYKdJsW/FYorLbGGvQ7Gk= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200511021352epcas5p1c18a8a0ea5dd4d15a0bc11bb5af50383~N14pk_q_C1462014620epcas5p1g; Mon, 11 May 2020 02:13:52 +0000 (GMT) Received: from epcas5p4.samsung.com ( [182.195.41.42]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 27.B5.10010.0E4B8BE5; Mon, 11 May 2020 11:13:52 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20200511021352epcas5p4c6f356db30fbd4905d2c8285ae2aabe6~N14o3_dTa2308823088epcas5p4k; Mon, 11 May 2020 02:13:52 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200511021352epsmtrp232d42672481326603c70e2d5b753e9aa~N14o2-bLs1467414674epsmtrp2O; Mon, 11 May 2020 02:13:52 +0000 (GMT) X-AuditID: b6c32a49-71fff7000000271a-70-5eb8b4e0ae09 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 7E.54.25866.FD4B8BE5; Mon, 11 May 2020 11:13:52 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021349epsmtip2612251130d76d763b1136a148c5aab91~N14mtxlx20183901839epsmtip21; Mon, 11 May 2020 02:13:49 +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 v8 02/10] scsi: ufs: add quirk to disallow reset of interrupt aggregation Date: Mon, 11 May 2020 07:30:23 +0530 Message-Id: <20200511020031.25730-3-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdlhTS/fBlh1xBot3GVg8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujG2737EV3OKpmHD8FnMD42WuLkZODgkBE4nbh78wgthCArsZJZZOF+ti5AKy PzFKvG97xgKR+Mwo8aE3F6bh6pIVzBBFuxglXj57ygLhtDBJNC+8wAZSxSagLXF3+hYmEFtE QFjiyLc2sBXMAjeYJB6sdAGxhQWiJXacXgG2gUVAVeLEslYwm1fARuLTiulsENvkJVZvOMAM YnMK2EpMa9gOtkxCoJNDouf3bBaIIheJlRcPQjUIS7w6voUdwpaS+PxuL1CcA8jOlujZZQwR rpFYOu8YVKu9xIErc1hASpgFNCXW79KHOJNPovf3EyaITl6JjjYhiGpVieZ3V6E6pSUmdnez QtgeEvd/bGWCBMMERonOJedYJzDKzkKYuoCRcRWjZGpBcW56arFpgWFearlecWJucWleul5y fu4mRnAy0fLcwXj3wQe9Q4xMHIyHGCU4mJVEeJfn7ogT4k1JrKxKLcqPLyrNSS0+xCjNwaIk zns6bUuckEB6YklqdmpqQWoRTJaJg1OqgSnsx+n4bWd3689Na16fvHO1wsmuQxOtuH7XuMTv ++ReZPoihmXzY6s9T058iiz03jRHurnqL4va9gjBoJXuThuXx0iX/FtR/vf0g51uT65VPPp1 6avn7gkCn5ck3Psn/7WPQ+t4bF0cc/vVG63PRdbEn23Zeclt4rLOGytCN9ibTGvc/+EN34HK r0Ve67X+mJVZTHq/LycrI2XXhVzzwNV2VoK1fyI3+13dv9dF4t2J/rmb72lmCjFITOfgSTz+ 7+qaBreTi1yqWMXrXu7kz2GU/qGyd457wYbLhil/7jVVGyoe8Ov10tsxvcT/3OlnkhZ7848u ttbepeQn0s6+wfDfrLSs/u0b06R8vxUk6uoqsRRnJBpqMRcVJwIABVaw7ZUDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvO6DLTviDO5vY7R4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaL8+c3sFvc3HKUxWLT42usFpd3zWGzmHF+H5NF9/UdbBbLj/9jsvi/Zwe7 xdKtNxkdeD0u9/UyeWxa1cnmsXlJvUfLyf0sHh+f3mLx6NuyitHj8yY5j/YD3UwBHFFcNimp OZllqUX6dglcGdt2v2MruMVTMeH4LeYGxstcXYycHBICJhJXl6xg7mLk4hAS2MEoceHCcSaI hLTE9Y0T2CFsYYmV/56zQxQ1MUn8uLaKFSTBJqAtcXf6FrAGEaCiI9/aGEFsZoFnTBKnHpaC 2MICkRI/9k8BG8QioCpxYlkrC4jNK2Aj8WnFdDaIBfISqzccYAaxOQVsJaY1bAerEQKqmbFp M+sERr4FjAyrGCVTC4pz03OLDQuM8lLL9YoTc4tL89L1kvNzNzGCw1lLawfjnlUf9A4xMnEw HmKU4GBWEuFdnrsjTog3JbGyKrUoP76oNCe1+BCjNAeLkjjv11kL44QE0hNLUrNTUwtSi2Cy TBycUg1MC22mqp3/525ltLDz+Oboo2K1jP7/RbPd6+WZdbkapz07lN683yx46+Iq3zeV1893 MyxZm+oTJcLdfKRX+qEaT9Z5hll3HC/zinr8MOffIMu2O/pEsxd3yy/LquPLXRqYjjOtP3rv R4d+7+Fj5sVyhkUNb4TP5FslNT59/VTWVbiKZcZzS3llE8+rcXur/RPycybP2nBbXktivvUR bbErX9U32xr/TOKcuJlPy/IB51xuD5Yp+usjHqq2TZH2PxZ49XwHN0fXMuOm3S7vky6ZvzJa uiFv9tXEsA3ulh8dBH51/AptL4u7l/V2WsAUBYtfN3dP/mh9kFFqgezCV216iWqfa4r/x7hU 2s+s/aPEUpyRaKjFXFScCABTjJeQ1gIAAA== X-CMS-MailID: 20200511021352epcas5p4c6f356db30fbd4905d2c8285ae2aabe6 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021352epcas5p4c6f356db30fbd4905d2c8285ae2aabe6 References: <20200511020031.25730-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 Mon May 11 02:00:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539535 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 4AB0E912 for ; Mon, 11 May 2020 02:14:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D5302496A for ; Mon, 11 May 2020 02:14:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="j/N0e4ZJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729459AbgEKCOD (ORCPT ); Sun, 10 May 2020 22:14:03 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:34213 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729406AbgEKCN6 (ORCPT ); Sun, 10 May 2020 22:13:58 -0400 Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20200511021355epoutp027a5b2874c1cb5f226cdd3ab00f5bdbe1~N14r0NNS93178531785epoutp02o for ; Mon, 11 May 2020 02:13:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20200511021355epoutp027a5b2874c1cb5f226cdd3ab00f5bdbe1~N14r0NNS93178531785epoutp02o DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163235; bh=kDIy4u6dKypJDeZVrGE9ZKceZgeyPXJh8PvB97xxnQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j/N0e4ZJOxdfce1QxDUkeKwgvZ82q3uEcyVKOoK5bCXp4FPaVxrQZzgvG3kZIbUGC 3OmCVzGH4B62qRf5V0AIcI2YxRIe0thmS6k4EWJLOeruyg6CLFebkCVniBhsaNNiBi lSJrNS27Nhi0Ev8jWF7DCLzzhSls5GYcUXwfFPTA= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200511021354epcas5p308719ba70e90ce1f09f9c4c5e63ca496~N14rXE55D1506415064epcas5p3D; Mon, 11 May 2020 02:13:54 +0000 (GMT) Received: from epcas5p4.samsung.com ( [182.195.41.42]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id AC.9E.23569.2E4B8BE5; Mon, 11 May 2020 11:13:54 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20200511021354epcas5p1a3f7fe0cf17e7ecc586aaf29eb0d2d7f~N14rBqvJx1717517175epcas5p1N; Mon, 11 May 2020 02:13:54 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200511021354epsmtrp257f1a9a5a4c6fbae7c643c380b6034a7~N14rAUzqM1467414674epsmtrp2Q; Mon, 11 May 2020 02:13:54 +0000 (GMT) X-AuditID: b6c32a4a-3b1ff70000005c11-ee-5eb8b4e2123b Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id BF.54.25866.2E4B8BE5; Mon, 11 May 2020 11:13:54 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021352epsmtip2002c8385977cb91f9bc2d00ec0aa7749~N14o8G-Gb0135501355epsmtip20; Mon, 11 May 2020 02:13:52 +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 v8 03/10] scsi: ufs: add quirk to enable host controller without hce Date: Mon, 11 May 2020 07:30:24 +0530 Message-Id: <20200511020031.25730-4-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdlhTS/fRlh1xBu379SwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxqwXh9gKNshVNDV+YWpgPCXRxcjJISFgIrFv4ktWEFtIYDejxMNPfF2MXED2 J0aJyfO3sEI4nxklbv04xw7TcenVahaIxC5Gibs//rJDOC1MEufXnWEBqWIT0Ja4O30LE4gt IiAsceRbGyOIzSxwg0niwUoXEFtYIEziybz9bF2MHBwsAqoS2/fmgYR5BWwk2i5/YYVYJi+x esMBZhCbU8BWYlrDdrDFEgK9HBL/X/UxQxS5SPRse8sGYQtLvDq+BepSKYnP7/aCzZcQyJbo 2WUMEa6RWDrvGAuEbS9x4MocFpASZgFNifW79CGu5JPo/f2ECaKTV6KjTQiiWlWi+d1VqE5p iYnd3VBXekisvH2cCRIKExgl2pa/ZpvAKDsLYeoCRsZVjJKpBcW56anFpgVGeanlesWJucWl eel6yfm5mxjByUTLawfjwwcf9A4xMnEwHmKU4GBWEuFdnrsjTog3JbGyKrUoP76oNCe1+BCj NAeLkjhvUuOWOCGB9MSS1OzU1ILUIpgsEwenVAPTEmMWl0WfHn9hvz7x+tWvfh1+c17zihrk Fvefyd5qKDNR+9fyNS03Wjw2e508fMvdTuKqkHdVjRy3T9mbdCtGhs3lrMbmPZFP808/ZJsd ffVBpH52rlKdbb3wQ9mc7VkaLN8cVghtE2XlK9t/Skmu9UedsOlZ9b/PPx9Jjdp4Tna94ozD T2yDwyrvqeVpGScVmy1l5jYp+NnPaRBu61SiJ/rp7KTFpU3fNn25uVH/8ZfaPToz1a1W3fv4 lKFa3+XxgmPHLp3NlDbKkvm/4/u0puPzfna+LEnaHaRcdkO/44C7YOfTcxeY7hXEOk/XX99v 8otNUsrzt03K2tlCspyVJsd4Hz3pk73+WdPy3TIlluKMREMt5qLiRACudnnQlQMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSvO6jLTviDPqOSVg8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujFkvDrEVbJCraGr8wtTAeEqii5GTQ0LAROLSq9UsXYxcHEICOxglZkz+yA6R kJa4vnEClC0ssfLfc3aIoiYmiSlzjjKCJNgEtCXuTt/CBGKLABUd+dYGFmcWeMYkcephKYgt LBAisbZ7KXMXIwcHi4CqxPa9eSBhXgEbibbLX1gh5stLrN5wgBnE5hSwlZjWsJ0FxBYCqpmx aTPrBEa+BYwMqxglUwuKc9Nziw0LjPJSy/WKE3OLS/PS9ZLzczcxgoNZS2sH455VH/QOMTJx MB5ilOBgVhLhXZ67I06INyWxsiq1KD++qDQntfgQozQHi5I479dZC+OEBNITS1KzU1MLUotg skwcnFINTG4Pv1z1vJl6h1fj+5zSJbWnex4ynDjV/tFz363Esy0teWtKFr74u3Hz16XnjBpW fSifNDHCurZ91uflE4IeuCYrXlfLt1w8ge3PbEGzHemsG40WP9u8JSPli9YrqexfZpt/uFpM y7zfXllfz2naErA6Jny5S1nHpdbLzYsOvvXVf/1lw/Kw6hdzpkmHvLaYwDsx509szSSrUKOl 3yTkOxZ4JTf/zzw97c3HjbJdYslzbYWMPEoYVnjaO9ziLz1dmT1Fbc+B7+INbZq+Ntfcy/0s j+ekJu7UWOe59tylluUcVX1zDwkfvLNz3pq58y7K3rt1umSXflghoyWHHbvHtNlblWvXn5vZ y7uSc0eF3AUlluKMREMt5qLiRAAK4Xpw1QIAAA== X-CMS-MailID: 20200511021354epcas5p1a3f7fe0cf17e7ecc586aaf29eb0d2d7f X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021354epcas5p1a3f7fe0cf17e7ecc586aaf29eb0d2d7f References: <20200511020031.25730-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 Mon May 11 02:00:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539561 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 E156D139A for ; Mon, 11 May 2020 02:14:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C592F24962 for ; Mon, 11 May 2020 02:14:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="mP7SePy0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729479AbgEKCOI (ORCPT ); Sun, 10 May 2020 22:14:08 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:33861 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729439AbgEKCOD (ORCPT ); Sun, 10 May 2020 22:14:03 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20200511021358epoutp04e2f9ca259c86406b89290dd093890805~N14vF_ozY1437514375epoutp04M for ; Mon, 11 May 2020 02:13:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20200511021358epoutp04e2f9ca259c86406b89290dd093890805~N14vF_ozY1437514375epoutp04M DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163238; bh=nPCI6KtKTzdjjbh5jTvGpI1fKN6gjrCt7WH8b1I6htY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mP7SePy03rDnsqEWNKKDxUFk35ngwtwzBL5MA3nLxcAPwRO1maCXf8EDcZ6Ky8JdS i8NUrwpkv+LEOSGGAqfybLv2QNiSEcWNo3zXgqxKSIlpBWondPX8GcoEh7gDtT8qZ8 Q1h19EL1ePB9MYZFBwEzQ/V2QxBCUKtfetSvDZIo= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200511021357epcas5p3b9ebc4be44662f2a9c3cc143b5ab86d3~N14t_O96x1506415064epcas5p3P; Mon, 11 May 2020 02:13:57 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id CD.0A.23389.5E4B8BE5; Mon, 11 May 2020 11:13:57 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200511021357epcas5p31ca197c25742a50359b076f10d4938cd~N14tezyBe2929029290epcas5p3B; Mon, 11 May 2020 02:13:57 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200511021356epsmtrp20e8a952fd61f692aad30c99a3c57a5fb~N14tVYRlg1520815208epsmtrp2I; Mon, 11 May 2020 02:13:56 +0000 (GMT) X-AuditID: b6c32a4b-7adff70000005b5d-30-5eb8b4e58333 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 5C.E6.18461.4E4B8BE5; Mon, 11 May 2020 11:13:56 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021354epsmtip2df48f4cdf9d3437091391a5eeeebdb6d~N14rJxPbn3209532095epsmtip2i; Mon, 11 May 2020 02:13:54 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v8 04/10] scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk Date: Mon, 11 May 2020 07:30:25 +0530 Message-Id: <20200511020031.25730-5-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA0WSeUwTURDGfbvb7bZaXQviQD0xRMVQD5SsNzEGN8ErRo1RAza6AuFqWrwP EOrVChZFIYqKilTqhbjQBjygFhA0xYSighIrKCoaVIiN91G2xv9+M/N975tMHoXL00UBVFxS CqdJUiUEklKi/O74sSGveGvUpLfO0YzrdDnJvP3aTDI914pEzBm7Q8Q0NpaImRa+hmBKOx6J mKaKfJLJa7yNMYbHVpIx1f3CmN83rWLmQlkLCpexTVmZGFtqPkiyNwpTWV39HYL99KqVYLN4 M2J7S0ew+6sM2FJqtXTWBi4hbjOnmThnnTT2049yXG0ZsjVP1yxOQ22D9UhCAT0VrtYXER6W 05UIGjPG6JH0L/cgKPniJIXCjcB+sAv/57jyqNM7uIWg8uRzJBQ6DB6015MeFUlPgLZcHvOw L+0Ddvc+5GGcfoKBq3i+HlGUD70MjKfGedoEHQSHjlzuW0NGzwKL5bBYCBsJl0qq+oIl9Gw4 nmYhPFlA76XA+ew8IYjmw/fbdq/BB7rqeC8HQG/3LdKTBXQ8HKoIFdo74cLpWq91LlQ58wmP BKfHw7WKicKWAyHz+0tMcMrgwD65oA6CjO5mr1MB2QaDSGAWGtqLxMIVjAgePrQgIxp+4v+r BQiZkT+n1ibGcNpp6tAkbotSq0rUbkqKUa5PTixFfd8kONKK2l0flTaEUciGgMIDfWWmRGuU XLZBtW07p0mO1mxK4LQ2pKCIwKGyjj18lJyOUaVw8Ryn5jT/phglCUjDBrvDsyKMTkf5kJyb 10cvS88x+azrXlxbrXSbJkyqG+XvT4rGZHeOcoszM3rttv6p5qOGvMJF74tDG8JjCynFLsPc J5/XXH2z8s2lSqtJYZ6mCsutOZUa/XOQ6efCpjX6jBA2ZFFE7ccI8bglMzbG890134xl+sie 6i8j+z3I0QdVNkzHV10/9uJ9Qeix1+fhZNxju3lq15T7uzouRraN3XnuxbwFr51pHxZ3tvjl Eo5VufkD3kHxwrN+Vam8Yo5DsrwteNjarXd8hw4L4Ir4zRK/Aoce+LCWHa3BFl56ZJsxOd3l Qq1heLTtpXrFDUyasrZQ2Vqtu/f09+4r6pkry3SBhDZWNTkY12hVfwCxpD2RlQMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsWy7bCSvO6TLTviDG5MMrd4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaL8+c3sFvc3HKUxWLT42usFpd3zWGzmHF+H5NF9/UdbBbLj/9jsvi/Zwe7 xdKtNxkdeD0u9/UyeWxa1cnmsXlJvUfLyf0sHh+f3mLx6NuyitHj8yY5j/YD3UwBHFFcNimp OZllqUX6dglcGR//bGMu2C5aMaPlKnsD413BLkZODgkBE4m1156xdTFycQgJ7GaU6Li5gxki IS1xfeMEdghbWGLlv+fsEEVNTBKNv5tZQBJsAtoSd6dvYQKxRYCKjnxrYwSxmQWeMUmcelgK YgsLBEgs/T0frJ5FQFWiZ9IaMJtXwEZi+/Z+qAXyEqs3HABbzClgKzGtYTtYjRBQzYxNm1kn MPItYGRYxSiZWlCcm55bbFhgmJdarlecmFtcmpeul5yfu4kRHM5amjsYt6/6oHeIkYmD8RCj BAezkgjv8twdcUK8KYmVValF+fFFpTmpxYcYpTlYlMR5bxQujBMSSE8sSc1OTS1ILYLJMnFw SjUw+S/ID024fTtx+YEF5h0rNi07kB2yvYarWlpf36abY/XZH0cUD57LPr5y4xyf27vEOP2b nsgkPan0nbb0j/w7xdhH/v4lcRNWxrhM158+M2WfxoW3666odd3a2m7ewrDd0yCSIyVQK/Hy /aWCtVYb62b4mHXcOd3AfGWJT6fclbgbSsyH18nVK7yQ+ZbuG25vwnxrfnmT+NosRRte+VwZ DimjU4ftw7bsPH670KB0qmvLi09MfzhuH0jUXWhd0mrzpbzo5rFevb/imcEyfTwfpr0yPK3Q uULzSqyg6dzQGdcfuugJNKw+PdXF5LbfO16V5wE56bpMM/tV1FclPso46G+21VVcWDjWZpvC 5QYlluKMREMt5qLiRACW9gw11gIAAA== X-CMS-MailID: 20200511021357epcas5p31ca197c25742a50359b076f10d4938cd X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021357epcas5p31ca197c25742a50359b076f10d4938cd References: <20200511020031.25730-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 Mon May 11 02:00:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539533 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 3B85092A for ; Mon, 11 May 2020 02:14:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 225C62495E for ; Mon, 11 May 2020 02:14:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="NSAnM0lN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729471AbgEKCOE (ORCPT ); Sun, 10 May 2020 22:14:04 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:33875 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729445AbgEKCOD (ORCPT ); Sun, 10 May 2020 22:14:03 -0400 Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20200511021400epoutp040be7298a1b4d298ed41f89a0cf3983a4~N14wvVvo11313513135epoutp04Z for ; Mon, 11 May 2020 02:14:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20200511021400epoutp040be7298a1b4d298ed41f89a0cf3983a4~N14wvVvo11313513135epoutp04Z DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163240; bh=4V8Pkuf0es9YJ6H7KkLlM7j/1ZRe4U2UUspvwS7zT7Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NSAnM0lNfOUdkwgh0y3SrPHGd9Df8IkTp2x6qohH2OMp7w06ug2HnkfnhgitYP7Vm Fp0CvkF8qjKgSG9t46nj7E6V0AxywUYXH7d3jCKMDcM3jIJLBn22j+ujcxmKkOwemp zV8mrxIHVS/ys01NMC76XXF7KoxpDe9mfx30Mi14= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200511021359epcas5p4d12cce62311338b30fcef63a4dede3f4~N14v6j7V03064630646epcas5p4U; Mon, 11 May 2020 02:13:59 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 31.AE.23569.7E4B8BE5; Mon, 11 May 2020 11:13:59 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20200511021359epcas5p24f652fd652a7b55c1ba90d01c03e8336~N14vlygp72932329323epcas5p2P; Mon, 11 May 2020 02:13:59 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200511021359epsmtrp1dd7e5f81707f209a2fccc300938b48e6~N14vjs64Q0628006280epsmtrp1S; Mon, 11 May 2020 02:13:59 +0000 (GMT) X-AuditID: b6c32a4a-3b1ff70000005c11-04-5eb8b4e7d9b0 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id A1.64.25866.7E4B8BE5; Mon, 11 May 2020 11:13:59 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021357epsmtip2f950cf834419353a9dc84e4ee51a79fe~N14te59Y30194601946epsmtip2p; Mon, 11 May 2020 02:13:56 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v8 05/10] scsi: ufs: add quirk to fix abnormal ocs fatal error Date: Mon, 11 May 2020 07:30:26 +0530 Message-Id: <20200511020031.25730-6-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42LZdlhTQ/f5lh1xBrPbNC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxsonb5kL2vkq5l0qaGA8w93FyMkhIWAi0bj8NmsXIxeHkMBuRom1V+eyQzif GCVe/drFDOF8ZpTY8v0zK0zLnQ/zGCESuxgldrfsg2ppYZJ4NfUxO0gVm4C2xN3pW5hAbBEB YYkj39oYQWxmgRtMEg9WuoDYwgIBEm13f4JNZRFQlTg0eQZYL6+AjcTZs+eZIbbJS6zecADM 5hSwlZjWsJ0FZJmEQCeHxJ6729khilwkTk9pZISwhSVeHd8CFZeSeNnfBmRzANnZEj27jCHC NRJL5x1jgbDtJQ5cmcMCUsIsoCmxfpc+xJl8Er2/nzBBdPJKdLQJQVSrSjS/uwrVKS0xsbsb GiYeEt8nLIaGyQRGiUfNT9knMMrOQpi6gJFxFaNkakFxbnpqsWmBUV5quV5xYm5xaV66XnJ+ 7iZGcDrR8trB+PDBB71DjEwcjIcYJTiYlUR4l+fuiBPiTUmsrEotyo8vKs1JLT7EKM3BoiTO m9S4JU5IID2xJDU7NbUgtQgmy8TBKdXAtNZ8rdFf/243jQsNyy0T+8MKU9lz4rxcGr2COidP ux4R+UtEXEZis/v9bf7zg9xE/3gvZf+nvkkxclXS2tBnSufXd+YUu1at4f723XvmNOlnFfun Lc+8+27SnnSHndx3hGo4u46si9gopb7wyvfq3GuNSqqcUfJHxWrONc6b9fLKXq3Tf4RT+tlW 694Mkj6/4BODY+vDazeece9+/v/Xwt3bvnyoPmF8ymBFt8J2QZUtLj8K1De4TmwO+/jH8bLW 8V1W6kcnv7h6w9tcpWTN8WMfM26aTfNvMUn9HrU3+alxvl70M2GBNdZ/2RvvBjDse/llIsvz r39db05jXzuRsflLrLVzZpvX9vknGgu2sSixFGckGmoxFxUnAgDR3uHRlgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSvO7zLTviDFYeELR4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaL8+c3sFvc3HKUxWLT42usFpd3zWGzmHF+H5NF9/UdbBbLj/9jsvi/Zwe7 xdKtNxkdeD0u9/UyeWxa1cnmsXlJvUfLyf0sHh+f3mLx6NuyitHj8yY5j/YD3UwBHFFcNimp OZllqUX6dglcGSufvGUuaOermHepoIHxDHcXIyeHhICJxJ0P8xi7GLk4hAR2MErcOP+FESIh LXF94wR2CFtYYuW/5+wQRU1MEndW7wRLsAloS9ydvoUJxBYBKjryrQ2smVngGZPEqYelILaw gJ/E5fPb2EBsFgFViUOTZ4D18grYSJw9e54ZYoG8xOoNB8BsTgFbiWkN21lAbCGgmhmbNrNO YORbwMiwilEytaA4Nz232LDAKC+1XK84Mbe4NC9dLzk/dxMjOJi1tHYw7ln1Qe8QIxMH4yFG CQ5mJRHe5bk74oR4UxIrq1KL8uOLSnNSiw8xSnOwKInzfp21ME5IID2xJDU7NbUgtQgmy8TB KdXAZB7Cuv3p4bWcF1pvGhySKIn40vrh/rTPaQl7lEU1G5wdJk6foJ7h3h4o0M5wS6fASINt 2Rzp+af/S+XHPkl/EP3XhzNUj3XR71SmyzkFf77E9Au+dOTij2YVMTl2bcveu++e6F8/WyQU avB7fa7bfbvdCfZMP8/FXqkwVPd7XWp+scfuvvbSf43ul99aH7mx1FFNZrXv5Bmbw5Zw7miu WqUi+MCq/Y2ORK8u96aZp759clwqc+pehsf63YvFvjhtvSi8YPopDdOwpuy9a/j/v1/D9OP4 b7bDt+I7DsV1LPpwomx2+q6Lf2bEr/j+UcJXfOdKz3jnkxdEPO+zznaq8ne3m3NWpmh11B+7 Vd9bXiqxFGckGmoxFxUnAgASi6fY1QIAAA== X-CMS-MailID: 20200511021359epcas5p24f652fd652a7b55c1ba90d01c03e8336 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021359epcas5p24f652fd652a7b55c1ba90d01c03e8336 References: <20200511020031.25730-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. Reviewed-by: Avri Altman Signed-off-by: Kiwoong Kim Signed-off-by: Alim Akhtar --- 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 Mon May 11 02:00:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539563 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 B71D5139A for ; Mon, 11 May 2020 02:14:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 998B2208CA for ; Mon, 11 May 2020 02:14:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="Fk4Hlj10" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729555AbgEKCOk (ORCPT ); Sun, 10 May 2020 22:14:40 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:52113 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729466AbgEKCOH (ORCPT ); Sun, 10 May 2020 22:14:07 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20200511021403epoutp030399c18e728e4720e58263ae2be37d6b~N14zB9ZL02320523205epoutp03Y for ; Mon, 11 May 2020 02:14:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20200511021403epoutp030399c18e728e4720e58263ae2be37d6b~N14zB9ZL02320523205epoutp03Y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163243; bh=DDMCtAVCNOenQhQBx8fCmPqcdSKUIHqMO34BELtm7U8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fk4Hlj10Qkl6Sv5uKI9a585+h1YaJfpcH3MAd9OdVWtXjF//Vhy6QanjAcE9jtRL0 TPT0YP1+6Koapu8kXRRxZeDhJodOAAJ60U4HMYff1O+Epbz9zgLv2mWuRsVqKgQlgC dxXXGtugOn3jgmrwKpfu4TJdrkBtyINLKnDSht0s= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200511021402epcas5p1c80ab5279772b7eceb4f0e67c488ad97~N14yj3qY61717717177epcas5p1l; Mon, 11 May 2020 02:14:02 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 74.C5.10010.AE4B8BE5; Mon, 11 May 2020 11:14:02 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200511021401epcas5p3b86ec5772ad700736eba6472e1fce8f6~N14x1Vfab1506415064epcas5p3Y; Mon, 11 May 2020 02:14:01 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200511021401epsmtrp1113f2a9df789233e02eb4520c15ca9d8~N14xyitFi0628006280epsmtrp1c; Mon, 11 May 2020 02:14:01 +0000 (GMT) X-AuditID: b6c32a49-735ff7000000271a-91-5eb8b4ea14a5 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id E3.64.25866.9E4B8BE5; Mon, 11 May 2020 11:14:01 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021359epsmtip24cae2f65c2139bb5ef13ca192ba52d0c~N14vs5dhD0185501855epsmtip2S; Mon, 11 May 2020 02:13:59 +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 v8 06/10] dt-bindings: phy: Document Samsung UFS PHY bindings Date: Mon, 11 May 2020 07:30:27 +0530 Message-Id: <20200511020031.25730-7-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrEKsWRmVeSWpSXmKPExsWy7bCmpu6rLTviDJrfy1o8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujF99+xkLLohWtMw6z97AeE2gi5GTQ0LARGLBgx0sILaQwG5GiasLfLoYuYDs T4wSzRd/sUE4nxklPnfuYIbpOPHoOTtEYhejxLKzv1ggnBYmiQOXb7GBVLEJaEvcnb6FCcQW ERCWOPKtjRHEZha4wSTxYKULiC0s4C/x+eUasN0sAqoSn/4fZAexeQVsJH40HmCF2CYvsXrD AbDNnAK2EtMatrNA1AhKnJz5hAViprxE89bZzCBHSAjs4ZA4fv4UG0Szi8S8p2+gzhaWeHV8 CzuELSXxsr8NyOYAsrMlenYZQ4RrJJbOO8YCYdtLHLgyhwWkhFlAU2L9Ln2IVXwSvb+fMEF0 8kp0tAlBVKtKNL+7CtUpLTGxu5sVosRD4tLJekjoTGCUWP/hCesERvlZSB6YheSBWQjLFjAy r2KUTC0ozk1PLTYtMMxLLdcrTswtLs1L10vOz93ECE5WWp47GO8++KB3iJGJg/EQowQHs5II 7/LcHXFCvCmJlVWpRfnxRaU5qcWHGKU5WJTEeU+nbYkTEkhPLEnNTk0tSC2CyTJxcEo1MHG8 du4/8y1p0urzRnzXXkhf+t+95ertHmsBn//rL3ee3dTKOiVJNuX+lA4WNc3lvobsCavT5FdJ ZP8t9f7a/uzF5xzGL+9V7211Wmu72u6DrdJipV45hoQ7e0wU+5YqP5xiWZaoW6BrkjNZf7JC m+ydM83/mu4e2smeFnCghr30+FL1j6a1bAcEjKLPbFz3TWH66yNJW94LJ74R5/jyk9mynP2c walpl7u5ItNcsu6fazh8dUnHfFZBq8NsjSXtTKemJjC7bPn0OOLSgfIrye1+vn4f/q9vi2rd PHXNNzlXxdVPHP0DXpYeC33dyuz7otT0nZaeC/fZI7ZyD/bM3tcX437U2qukOs+Qb1VLnBJL cUaioRZzUXEiAARVaGvFAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupgkeLIzCtJLcpLzFFi42LZdlhJXvfllh1xBtN7tSwezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxq++/YwFF0QrWmadZ29gvCbQxcjJISFgInHi0XP2LkYuDiGBHYwSG2deY4ZI SEtc3ziBHcIWllj5D6aoiUli5YdnrCAJNgFtibvTtzCB2CJARUe+tTGC2MwCz5gkTj0s7WLk 4BAW8JX42iENEmYRUJX49P8g2ExeARuJH40HWCHmy0us3nAAbC+ngK3EtIbtLCC2EFDNjE2b WSHqBSVOznzCAjKSWUBdYv08IYhN8hLNW2czT2AUnIWkahZC1SwkVQsYmVcxSqYWFOem5xYb FhjlpZbrFSfmFpfmpesl5+duYgRHlpbWDsY9qz7oHWJk4mA8xCjBwawkwrs8d0ecEG9KYmVV alF+fFFpTmrxIUZpDhYlcd6vsxbGCQmkJ5akZqemFqQWwWSZODilGpgOP/yn8L1ivup6xSvP re9fNv9Vc2yixgPfWZ7Pb95w/WanmPQ2qb/sw+/rpf8vO0VWdF5Tzqu/9IXL7uZRmzTrBAOe tXMlrK5MzDpra6PZVSv8cU9uRL1Jy9Ut6yW9efbJ5OTPdZPNsPvmOGXzzcxvLmnNoraz/xw2 81ofHRZmpz/J0FbpwRyZxVO2PKk0eBF+IFcwaGk98/MXkmu+sO/q15ya8TFl+hmb1N2NbL9K U59r+6+0CGm9t7hHQjvh2sUbn76sdtpx/dJ6ps7tE5g3Gchd09fcE7JvvzS7kHZC5k6dpFLm ZekTdvoHL1PiaPzxRlvmzLxjjDHib4ymuzq05Zj8k+RuyE31eJrYGKPEUpyRaKjFXFScCABa JaKMGwMAAA== X-CMS-MailID: 20200511021401epcas5p3b86ec5772ad700736eba6472e1fce8f6 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021401epcas5p3b86ec5772ad700736eba6472e1fce8f6 References: <20200511020031.25730-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 Mon May 11 02:00:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539539 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 47E4C92A for ; Mon, 11 May 2020 02:14:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 165A82192A for ; Mon, 11 May 2020 02:14:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="EtWZFerv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729495AbgEKCOK (ORCPT ); Sun, 10 May 2020 22:14:10 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:34307 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729445AbgEKCOI (ORCPT ); Sun, 10 May 2020 22:14:08 -0400 Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20200511021405epoutp02566d10473081de77093f8cbfce24eba6~N141VX1Yv3178831788epoutp020 for ; Mon, 11 May 2020 02:14:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20200511021405epoutp02566d10473081de77093f8cbfce24eba6~N141VX1Yv3178831788epoutp020 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163245; bh=sK/hFncn11WBScvtcYDk7R7CcwFLxOCyulZMUjKu6sA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EtWZFervDtFPFJJgmtlTMV8e5Ray9vbrWRSd8a5pBdj2HsKPt9v0eF6HR0S+DTQA1 k8M8FVK3/7ENFWPI12+ebgXYWX8Q9wqkWNfFF+Somc8eT8Xyq4uFsAWiDTqbrrHiOj 6mLk89DDUBWgtfjzHwKYsmpgA66OzysxtsjIqQwI= Received: from epsmges5p2new.samsung.com (unknown [182.195.42.74]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200511021405epcas5p49cb13d6c6d5468d46e9e54b980264a56~N1404RRmN2308823088epcas5p43; Mon, 11 May 2020 02:14:05 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 7A.AE.23569.CE4B8BE5; Mon, 11 May 2020 11:14:04 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20200511021404epcas5p1ffee7cc59a191d1ebd81eaaec498821a~N140WUgdd1717517175epcas5p1d; Mon, 11 May 2020 02:14:04 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200511021404epsmtrp19076783850f88632144110e18217282f~N140VRlin0628006280epsmtrp1k; Mon, 11 May 2020 02:14:04 +0000 (GMT) X-AuditID: b6c32a4a-3c7ff70000005c11-17-5eb8b4ec8085 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 95.64.25866.CE4B8BE5; Mon, 11 May 2020 11:14:04 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021401epsmtip20833bdaf59b23896c8a488f89588245e~N14x8Hlpv3209932099epsmtip2d; Mon, 11 May 2020 02:14:01 +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 v8 07/10] phy: samsung-ufs: add UFS PHY driver for samsung SoC Date: Mon, 11 May 2020 07:30:28 +0530 Message-Id: <20200511020031.25730-8-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrPKsWRmVeSWpSXmKPExsWy7bCmpu6bLTviDP7+t7J4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaLC0972CzOn9/AbnFzy1EWi02Pr7FaXN41h81ixvl9TBbd13ewWSw//o/J 4v+eHewWS7feZHTg87jc18vksWlVJ5vH5iX1Hi0n97N4fHx6i8Wjb8sqRo/jN7YzeXzeJOfR fqCbKYAzissmJTUnsyy1SN8ugSvj56TJzAV35jBWzFvyiLWB8XMTYxcjJ4eEgInEmUNTmbsY uTiEBHYzSrzYvoIFwvnEKHFnzV0o5zOjxM+9N5lgWq4fb4dK7GKUeN81kw3CaWGSePXpAQtI FZuAtsTd6VvAOkQEhCWOfGtjBCliFmhilviytIkNJCEsECCxcc11sAYWAVWJ7TeegzXwCthI tB/9yAKxTl5i9YYDzCA2p4CtxLSG7SwQNYISJ2c+AbOZgWqat84G+0JC4AyHRPvU1WwQzS4S T/bvYIewhSVeHd8CZUtJvOxvA7I5gOxsiZ5dxhDhGoml845B7bWXOHBlDgtICbOApsT6XfoQ q/gken8/YYLo5JXoaBOCqFaVaH53FapTWmJidzcrRImHxJImsJ1CAhMYJc6uLpjAKD8Lyf2z kNw/C2HXAkbmVYySqQXFuempxaYFRnmp5XrFibnFpXnpesn5uZsYwWlMy2sH48MHH/QOMTJx MB5ilOBgVhLhXZ67I06INyWxsiq1KD++qDQntfgQozQHi5I4b1LjljghgfTEktTs1NSC1CKY LBMHp1QDE4viLie+hVnvfNz5566RV5yUMeV050ZtB5clK/Oq9afdXxIn1pCr+ajwwUm7n5fO nPb1rJaPt/frXsDLd3Qvw/Vjf/83l+1X27alQJVhXsdcp9rszpY5M1TnznSYdKTvpr/s2Vv9 02fPqJl6baHTpKgp/5wlrz/fWccqs3163LSoJrfLe47O+BE9fweXlqWvYq5ihIr+1sNSAoxC fs9Ud3i+3WI3O9rJIL3N8wD3/TNmjWtLBNMWJgneaVb4fbl5xVvuPforzjDIbDgWH5x5/OHK vC+OL733LJkbWO6sWi1wehlT3dXfWtrTrqSlSZVFe3dETs3QqDKLdjvJ/GBnweK20+LByqE3 JhfKTLrDpcRSnJFoqMVcVJwIAInD7EvSAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprGIsWRmVeSWpSXmKPExsWy7bCSvO6bLTviDFb+F7V4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaLC0972CzOn9/AbnFzy1EWi02Pr7FaXN41h81ixvl9TBbd13ewWSw//o/J 4v+eHewWS7feZHTg87jc18vksWlVJ5vH5iX1Hi0n97N4fHx6i8Wjb8sqRo/jN7YzeXzeJOfR fqCbKYAzissmJTUnsyy1SN8ugSvj56TJzAV35jBWzFvyiLWB8XMTYxcjJ4eEgInE9ePtLF2M XBxCAjsYJa78ucYMkZCWuL5xAjuELSyx8t9zdoiiJiaJj9/fsoIk2AS0Je5O38IEYosAFR35 1sYIUsQsMIFZYvmvb2ArhAX8JA7M/8EGYrMIqEpsv/EcrIFXwEai/ehHFogN8hKrNxwA28wp YCsxrWE7WFwIqGbGps2sEPWCEidnPgGKcwAtUJdYP08IJMwM1Nq8dTbzBEbBWUiqZiFUzUJS tYCReRWjZGpBcW56brFhgVFearlecWJucWleul5yfu4mRnDUaWntYNyz6oPeIUYmDsZDjBIc zEoivMtzd8QJ8aYkVlalFuXHF5XmpBYfYpTmYFES5/06a2GckEB6YklqdmpqQWoRTJaJg1Oq gWlt/+s/93W2GpfdfGWb2uppMDdf/a2rTpG7+E5b7weVbFYPM1V37pzmKM1kz/vqmWj7a17G 5H8WssfdV9UnvGfhiVhwZsrqxPy9S9YnMqgvyn44M+q3oM1XrXhLvSv9qy8qTzwm+rDHTi/g 1Mk7/15m6n2O4GX4ZqrM0hl4+O6uZwGs7LF2v8/JyM3KvO+2nOMQs8qkCwVxub/PbFMtV/xo ICU864H++q0VossVWc217vjmp+b+qnm8SVUostSyh+2p7iqrwmjJnU1zb60q4pvWe0yQI9pi bfBNC/Uy79dzM5+/zrf5XhKZ3n5+ZR/H+y25yUkx6aXKmVlVnLe/bpJ7PW2zUwyL9aGvD779 V2Ipzkg01GIuKk4EAHr2RXEpAwAA X-CMS-MailID: 20200511021404epcas5p1ffee7cc59a191d1ebd81eaaec498821a X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021404epcas5p1ffee7cc59a191d1ebd81eaaec498821a References: <20200511020031.25730-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 Mon May 11 02:00:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539553 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 00A9792A for ; Mon, 11 May 2020 02:14:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DD1B324962 for ; Mon, 11 May 2020 02:14:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="MPxSZbl4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729506AbgEKCON (ORCPT ); Sun, 10 May 2020 22:14:13 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:36363 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729487AbgEKCOK (ORCPT ); Sun, 10 May 2020 22:14:10 -0400 Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200511021408epoutp01e59a1ff29566578c871331aa6cac62a1~N1430t-jk2365623656epoutp015 for ; Mon, 11 May 2020 02:14:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200511021408epoutp01e59a1ff29566578c871331aa6cac62a1~N1430t-jk2365623656epoutp015 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163248; bh=Sjo2Sj1S7d70JVxw6eTgCHnZ/EiW76oG21OsjWYCQfM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MPxSZbl4RwVX4A4jkzwUfbhlLT0GhxvWv/hjnMnDDybqjPo9yEc6R0cdKrmGvaMzv JpHViFWBltd3ONpNj6vfBNNutE9CdH3IH1KfznMYnRzoMshS0Y8BjQTHqxSQa5n5Vb Dc4rPtaNGVsjTUobFnWDrAAT7p++0GDLC8r5vmKA= Received: from epsmges5p1new.samsung.com (unknown [182.195.42.73]) by epcas5p4.samsung.com (KnoxPortal) with ESMTP id 20200511021407epcas5p47d41152fcfdbf6766481e212d705036f~N142-BSTm2083520835epcas5p4J; Mon, 11 May 2020 02:14:07 +0000 (GMT) Received: from epcas5p2.samsung.com ( [182.195.41.40]) by epsmges5p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 30.D5.10010.FE4B8BE5; Mon, 11 May 2020 11:14:07 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20200511021406epcas5p229fb46815d3c29ae06709fa6160e0308~N142pGjtn1638516385epcas5p2Q; Mon, 11 May 2020 02:14:06 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200511021406epsmtrp140579ea0a754f339916fccf4d5aab33f~N142oV1mk0628006280epsmtrp1o; Mon, 11 May 2020 02:14:06 +0000 (GMT) X-AuditID: b6c32a49-71fff7000000271a-a0-5eb8b4efcb8d Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id 81.F6.18461.EE4B8BE5; Mon, 11 May 2020 11:14:06 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021404epsmtip2826cd2568c416bac3779cc2b35773864~N140bQAEO0194601946epsmtip2t; Mon, 11 May 2020 02:14:04 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v8 08/10] dt-bindings: ufs: Add DT binding documentation for ufs Date: Mon, 11 May 2020 07:30:29 +0530 Message-Id: <20200511020031.25730-9-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdlhTQ/f9lh1xBu2zeC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxsoVa9kLvopVTL++kbmBcZdgFyMHh4SAicTKXRxdjFwcQgK7GSVa/y5ihXA+ MUrM/LKGBcL5xihxtqOHrYuRE6zj84OFjBCJvYwS3ZsWsUM4LUwSu26cAKtiE9CWuDt9CxOI LSIgLHHkWxsjiM0scINJ4sFKFxBbWCBIYvX2gywgNouAqsSKudvBbF4BG4nLWxYyQWyTl1i9 4QAziM0pYCsxrWE72EkSAp0cEn/XbYAqcpHYu72VBcIWlnh1fAs7hC0l8bK/jR3i0WyJnl3G EOEaiaXzjkGV20scuDKHBaSEWUBTYv0ufYgz+SR6fz9hgujklehoE4KoVpVofncVqlNaYmJ3 NytEiYfE84PCkFCYAAzFT69ZJzDKzkIYuoCRcRWjZGpBcW56arFpgWFearlecWJucWleul5y fu4mRnAy0fLcwXj3wQe9Q4xMHIyHGCU4mJVEeJfn7ogT4k1JrKxKLcqPLyrNSS0+xCjNwaIk zns6bUuckEB6YklqdmpqQWoRTJaJg1OqgWmbRd+rFxelutmZnlhXVRqc3Z6pVPmd0z3+s1HR n1rx34cEymTqns5sTFj7RaWjb9Mn5xxx3cv1Ntk+nDKNE2VjfHPOXd2ue/DbtZfRptOK//DG cXo37M/yPbjA716224qL5bZzLHz6LnIe3DhP4N385w9195io11gd5jsU4r3238+WGx6LfCS+ P+KO965Ov/eK993Wa67vNLiOHhf5HCISOUcx09m34YLR/PuJbd27vmfZ3+fxP/PL1f8Ma1Jf bxlP1kP+zTGnMxb1pZaYN6Rqbl7W98f1+27Lo4dMZ6z7tUrpuCtzZIki/4nHCXx+H+89fvex OCtVY+OBCOnXrbsNTTtzblzOFdi618LrsRJLcUaioRZzUXEiAGaoI92VAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWy7bCSvO67LTviDLa90bN4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaL8+c3sFvc3HKUxWLT42usFpd3zWGzmHF+H5NF9/UdbBbLj/9jsvi/Zwe7 xdKtNxkdeD0u9/UyeWxa1cnmsXlJvUfLyf0sHh+f3mLx6NuyitHj8yY5j/YD3UwBHFFcNimp OZllqUX6dglcGStXrGUv+CpWMf36RuYGxl2CXYycHBICJhKfHyxk7GLk4hAS2M0ose3CVSaI hLTE9Y0T2CFsYYmV/56zQxQ1MUnMvbKXGSTBJqAtcXf6FrAGEaCiI9/aGEFsZoFnTBKnHpZ2 MXJwCAsESOx8HQASZhFQlVgxdzsLiM0rYCNxectCqF3yEqs3HAAbySlgKzGtAaJGCKhmxqbN rBMY+RYwMqxilEwtKM5Nzy02LDDMSy3XK07MLS7NS9dLzs/dxAgOZi3NHYzbV33QO8TIxMF4 iFGCg1lJhHd57o44Id6UxMqq1KL8+KLSnNTiQ4zSHCxK4rw3ChfGCQmkJ5akZqemFqQWwWSZ ODilGpj6vk3YXztjS/gPUZHPX246r/g54bKb77HmzyrSXZV72qZFNSRc/3tkF692389f+z4X z3l82kf72UaXqXemJqgxt614J8ds9fHBeqWkpM1zP+vsL+iMOLPqQNXR6xXKm00czBr6Cm8v OsAR92zp66zHBaslXD32uAkuf7s/+GGm48QpctNC4rlUmAUP7v73V1Xeu7n9zg/v99vE1dKL srWXZsxY2dn78sqyr6GfllraOXoV6lgfPMb33nGSqnl6+F07rWsPshq/Sn2Y1/lqWlFUxt6l k/8ynN33b0nWRFHZPW7lF37b624oVHlucDOsjDMj5zGTtPSNzUu77+15K/On8/x2ube9jF1z vr+M92z8qcRSnJFoqMVcVJwIAEs9FtTVAgAA X-CMS-MailID: 20200511021406epcas5p229fb46815d3c29ae06709fa6160e0308 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021406epcas5p229fb46815d3c29ae06709fa6160e0308 References: <20200511020031.25730-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 binding for samsung ufs hci Signed-off-by: Alim Akhtar --- .../bindings/ufs/samsung,exynos-ufs.yaml | 92 +++++++++++++++++++ 1 file changed, 92 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..0c50f5cb4619 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/samsung,exynos-ufs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung SoC series UFS host controller Device Tree Bindings + +maintainers: + - Alim Akhtar + +description: | + Each Samsung UFS host controller instance should have its own node. + This binding define Samsung specific binding other then what is used + in the common ufshcd bindings + [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt + +properties: + + compatible: + enum: + - samsung,exynos7-ufs + + reg: + items: + - description: HCI register + - description: vendor specific register + - description: unipro register + - description: UFS protector register + + reg-names: + items: + - const: hci + - const: vs_hci + - const: unipro + - const: ufsp + + clocks: + maxItems: 2 + items: + - description: ufs link core clock + - description: unipro main clock + + clock-names: + maxItems: 2 + items: + - const: core_clk + - const: sclk_unipro_main + + interrupts: + maxItems: 1 + + phys: + maxItems: 1 + + phy-names: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - phys + - phy-names + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + + ufs: ufs@15570000 { + compatible = "samsung,exynos7-ufs"; + reg = <0x15570000 0x100>, + <0x15570100 0x100>, + <0x15571000 0x200>, + <0x15572000 0x300>; + reg-names = "hci", "vs_hci", "unipro", "ufsp"; + interrupts = ; + clocks = <&clock_fsys1 ACLK_UFS20_LINK>, + <&clock_fsys1 SCLK_UFSUNIPRO20_USER>; + clock-names = "core_clk", "sclk_unipro_main"; + pinctrl-names = "default"; + pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>; + pclk-freq-avail-range = <70000000 133000000>; + phys = <&ufs_phy>; + phy-names = "ufs-phy"; + }; +... From patchwork Mon May 11 02:00:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539551 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 B5B3692A for ; Mon, 11 May 2020 02:14:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 888D2206D7 for ; Mon, 11 May 2020 02:14:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="oG9/xisu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729510AbgEKCOX (ORCPT ); Sun, 10 May 2020 22:14:23 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:36403 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729502AbgEKCOV (ORCPT ); Sun, 10 May 2020 22:14:21 -0400 Received: from epcas5p1.samsung.com (unknown [182.195.41.39]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20200511021410epoutp0188d202178ccc03125d99ca2c7c22038e~N146SqGSX2365623656epoutp01_ for ; Mon, 11 May 2020 02:14:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20200511021410epoutp0188d202178ccc03125d99ca2c7c22038e~N146SqGSX2365623656epoutp01_ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163250; bh=ArElBjUiROLPXdpPQRWMsrovb+3XfW41quw3VIbNfZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oG9/xisu4xVNb9Mng6Cn/GgVh0XUeEwRt4Qml8UcLZk6BUOQpEZwQOGN9nHSQFTi5 bo6wNsdIbHHoHsGiDZyyt9q1eEjVdXSYcuXGP888kguO+t07oZrY0JRd7jKHfGNUMJ sX/vw1qJxoGudf+3Dyfj0TIUj6j9F7D7KnYiykh8= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p3.samsung.com (KnoxPortal) with ESMTP id 20200511021410epcas5p38acfc883541ddf3b26b081df23581a53~N145wDpf51506415064epcas5p3o; Mon, 11 May 2020 02:14:10 +0000 (GMT) Received: from epcas5p3.samsung.com ( [182.195.41.41]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id 87.1A.23389.2F4B8BE5; Mon, 11 May 2020 11:14:10 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20200511021409epcas5p3b78fe59669f13ffae481b57a944da675~N144_pL362929029290epcas5p3d; Mon, 11 May 2020 02:14:09 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200511021409epsmtrp249eb0022f74331b3a5b7dca688779d2a~N1449n5yU1467414674epsmtrp2h; Mon, 11 May 2020 02:14:09 +0000 (GMT) X-AuditID: b6c32a4b-7adff70000005b5d-54-5eb8b4f286e8 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id E2.F6.18461.1F4B8BE5; Mon, 11 May 2020 11:14:09 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021406epsmtip2af951e98cd97b97e9b3bf052192b9917~N142pgL6v0183901839epsmtip28; Mon, 11 May 2020 02:14:06 +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 v8 09/10] scsi: ufs-exynos: add UFS host support for Exynos SoCs Date: Mon, 11 May 2020 07:30:30 +0530 Message-Id: <20200511020031.25730-10-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCKsWRmVeSWpSXmKPExsWy7bCmpu6nLTviDKaf4rF4MG8bm8XLn1fZ LD6tX8ZqMf/IOVaL8+c3sFvc3HKUxWLT42usFpd3zWGzmHF+H5NF9/UdbBbLj/9jsvi/Zwe7 xdKtNxkdeD0u9/UyeWxa1cnmsXlJvUfLyf0sHh+f3mLx6NuyitHj8yY5j/YD3UwBHFFcNimp OZllqUX6dglcGf2r5rIUdE5irni1cDF7A+Pp80xdjJwcEgImErNuHAGyuTiEBHYzSnRcugzl fGKUuN9xgw3C+cYo8XzfbkaYlg2POthBbCGBvYwS547ZQRS1MEksvtPIBpJgE9CWuDt9C9gO EQFhiSPf2sCamQVuMEk8WOkCYgsLBEnsbt0AFOfgYBFQlZh7lRUkzCtgK/Hn2UYWiF3yEqs3 HGAGsTmB4tMatrNA1AhKnJz5hAVipLxE89bZzCA3SAjs4JB4/bWfHaLZRWJr3xwoW1ji1fEt ULaUxOd3e9lA9koIZEv07DKGCNdILJ13DGqvvcSBK3NYQEqYBTQl1u/Sh1jFJ9H7+wkTRCev REebEES1qkTzu6tQndISE7u7WSFsD4n2r5+g4TmBUaL57j3GCYzys5B8MAvJB7MQti1gZF7F KJlaUJybnlpsWmCcl1quV5yYW1yal66XnJ+7iRGcsLS8dzA+evBB7xAjEwfjIUYJDmYlEd7l uTvihHhTEiurUovy44tKc1KLDzFKc7AoifM+btwSJySQnliSmp2aWpBaBJNl4uCUamBS/chq O9n+bdbnWS5TU3bu+bR27+f6ftmER0JBh15U7g1OsMkVldY2Wmj24KVW06JLsZwb9XNTUiM5 0mOfPZHNM/DKU0ytWOPykzc1s9bK/ub206buLNGKV4PsUteqtxWlq8hm+uUXKsn/lOG4nmhc uevEsbvGHxdtj/myc+60s0Hrf3+t87x48B27TH3tp5t+u47YftCKfuGTqa/bPkNfJnwW02fz u/ExVkoTC9sftEuWyvYuOnPmQs6DkyvesM53FghZ3rv2mpqS+Lq3DI/3lbpk775kvbztney/ pEbG0g9h7JlR//0+vN8tU5Xh6rpouZHy8ih/9/8Xny9bu+tj/dHGrS4eze/3Kqi4H1NiKc5I NNRiLipOBAAeUxhYxwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupikeLIzCtJLcpLzFFi42LZdlhJXvfjlh1xBv3nBC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXRv+quSwFnZOYK14tXMzewHj6PFMXIyeHhICJxIZHHexdjFwcQgK7GSXObvnH CpGQlri+cQI7hC0ssfLfc6iiJiaJb0+2sIAk2AS0Je5O3wI2SQSo6Mi3NkYQm1ngGZPEqYel ILawQIDEl85lQHEODhYBVYm5V8Hm8wrYSvx5tpEFYr68xOoNB5hBbE6g+LSG7WBxIQEbiRmb NkPVC0qcnPmEBWQMs4C6xPp5QhCb5CWat85mnsAoOAtJ1SyEqllIqhYwMq9ilEwtKM5Nzy02 LDDMSy3XK07MLS7NS9dLzs/dxAiOLi3NHYzbV33QO8TIxMF4iFGCg1lJhHd57o44Id6UxMqq 1KL8+KLSnNTiQ4zSHCxK4rw3ChfGCQmkJ5akZqemFqQWwWSZODilGphWsb8vmjltnytbtPSH D1XJxu3V563fbjq+W/djoXSWorGGtI/tonuzy/6U7Db4OGXNblvPZIFem5JHap41O3mvF905 YjJ9h7XjPrfpJlXq0ULqv9mmfP003XCCcGCaPguPysZXscniywp+87pyBPh+9BCytfvSnaPH WJbAqz/HM9mto/6oSnN/enW8C8ONvcZHTicZdLm3LHomuyPt9ZLVtvNnXblULdvnqivAv/5U d3/49xfzpu3dMXnr3EClCVY3Zd9/MuacqTs9f+rVIzkyJ3fEcJ+1nW51oDyf9/71ogaxuxum 67sHnXSq9SlxmmBhvLVAeKO+1LPODT9WRNQuE+Ji2uW+s1WypSy9RomlOCPRUIu5qDgRAFL5 CmAdAwAA X-CMS-MailID: 20200511021409epcas5p3b78fe59669f13ffae481b57a944da675 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021409epcas5p3b78fe59669f13ffae481b57a944da675 References: <20200511020031.25730-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 | 1300 +++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-exynos.h | 284 +++++++ drivers/scsi/ufs/unipro.h | 33 + 5 files changed, 1630 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..cc7e29c8c24f 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..edfde7038cfd --- /dev/null +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -0,0 +1,1300 @@ +// 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; + u32 freq[2]; + int ret; + + 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; + } + + ret = of_property_read_u32_array(np, + "pclk-freq-avail-range", freq, ARRAY_SIZE(freq)); + if (!ret) { + ufs->pclk_avail_min = freq[0]; + ufs->pclk_avail_max = freq[1]; + } else { + dev_err(dev, "failed to get available pclk range\n"); + goto out; + } + + 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..813b286afd9d --- /dev/null +++ b/drivers/scsi/ufs/ufs-exynos.h @@ -0,0 +1,284 @@ +/* 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 + +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 Mon May 11 02:00:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 11539545 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 2045D92A for ; Mon, 11 May 2020 02:14:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0474E2192A for ; Mon, 11 May 2020 02:14:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="YybkYe0s" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729520AbgEKCOQ (ORCPT ); Sun, 10 May 2020 22:14:16 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:34005 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729508AbgEKCOP (ORCPT ); Sun, 10 May 2020 22:14:15 -0400 Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20200511021413epoutp0469cbd7c46623a2779b5d830847dc49e3~N148RXuF31437514375epoutp04a for ; Mon, 11 May 2020 02:14:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20200511021413epoutp0469cbd7c46623a2779b5d830847dc49e3~N148RXuF31437514375epoutp04a DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1589163253; bh=/EgM78BRgJhvlBHBSPq8WNIKV3DNSoRwOkIucDKKIZA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YybkYe0swUUWkOcC5mfYo5Q/sCoZKNwGUp5uqlGiZlQIK51OkXQhdcCtZZGPGBY3I S2W6BNeUHI+oQQNMeYakIgKxTFgA+4CxgOocZaV5IDayk8Vwhic98DOf3XQdyCCjTW I0arAYxmkwJ6jr1Dfgpbc9kPRmx4GlkfY9z2NMUQ= Received: from epsmges5p3new.samsung.com (unknown [182.195.42.75]) by epcas5p1.samsung.com (KnoxPortal) with ESMTP id 20200511021412epcas5p1a66fa185ff0d312bfca4886658c338f3~N147yrPuA1717517175epcas5p1t; Mon, 11 May 2020 02:14:12 +0000 (GMT) Received: from epcas5p1.samsung.com ( [182.195.41.39]) by epsmges5p3new.samsung.com (Symantec Messaging Gateway) with SMTP id 0A.1A.23389.4F4B8BE5; Mon, 11 May 2020 11:14:12 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas5p4.samsung.com (KnoxPortal) with ESMTPA id 20200511021411epcas5p40282690d856ef9d9541506967fd0e764~N147KhXcc3064630646epcas5p4p; Mon, 11 May 2020 02:14:11 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20200511021411epsmtrp22e18468f1f819f1ad659dd0038675ef4~N147JQh9w1467414674epsmtrp2j; Mon, 11 May 2020 02:14:11 +0000 (GMT) X-AuditID: b6c32a4b-7adff70000005b5d-5c-5eb8b4f401f7 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 58.64.25866.3F4B8BE5; Mon, 11 May 2020 11:14:11 +0900 (KST) Received: from Jaguar.sa.corp.samsungelectronics.net (unknown [107.108.73.139]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200511021409epsmtip238e517c47b32ebc72cb65f4fa03b0bec~N145Al4i70185501855epsmtip2V; Mon, 11 May 2020 02:14:09 +0000 (GMT) From: Alim Akhtar To: robh@kernel.org Cc: devicetree@vger.kernel.org, linux-scsi@vger.kernel.org, krzk@kernel.org, avri.altman@wdc.com, martin.petersen@oracle.com, kwmad.kim@samsung.com, stanley.chu@mediatek.com, cang@codeaurora.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Alim Akhtar Subject: [PATCH v8 10/10] arm64: dts: Add node for ufs exynos7 Date: Mon, 11 May 2020 07:30:31 +0530 Message-Id: <20200511020031.25730-11-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200511020031.25730-1-alim.akhtar@samsung.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrIKsWRmVeSWpSXmKPExsWy7bCmuu6XLTviDHp7pC0ezNvGZvHy51U2 i0/rl7FazD9yjtXi/PkN7BY3txxlsdj0+BqrxeVdc9gsZpzfx2TRfX0Hm8Xy4/+YLP7v2cFu sXTrTUYHXo/Lfb1MHptWdbJ5bF5S79Fycj+Lx8ent1g8+rasYvT4vEnOo/1AN1MARxSXTUpq TmZZapG+XQJXxrZpmgV7JSpevO9lbmC8I9zFyMkhIWAisej7XrYuRi4OIYHdjBLvv19gAkkI CXxilLg03xsi8ZlRov3WYiaYjulXz7JDJHYxSrx+dYcJwmlhkvi16gojSBWbgLbE3elbwDpE BIQljnxrA4szC9xgkniw0qWLkYNDWMBO4t55VpAwi4CqxI+Tm1hAbF4BW4kDU78zQyyTl1i9 4QCYzQkUn9awHapGUOLkzCcsECPlJZq3zmYGuUFCYAeHxOqdW9kgml0kln3aygJhC0u8Or6F HcKWkvj8DuRnDiA7W6JnlzFEuEZi6bxjUOX2EgeuzGEBKWEW0JRYv0sfYhWfRO/vJ0wQnbwS HW1CENWqEs3vrkJ1SktM7O5mhbA9JK4enwQNqgmMEjv+vGCawCg/C8kHs5B8MAth2wJG5lWM kqkFxbnpqcWmBcZ5qeV6xYm5xaV56XrJ+bmbGMGpSst7B+OjBx/0DjEycTAeYpTgYFYS4V2e uyNOiDclsbIqtSg/vqg0J7X4EKM0B4uSOO/jxi1xQgLpiSWp2ampBalFMFkmDk6pBiaDxoiy zT23zywMm8H/fdYXw5TGSYlC7cneS542ONr4tF8635Fg9PZS93YJx1Npm4J0nPxmyYt62W4I FC3wKGs4fL7/uZrCH4WpCeI1CXf4/W/ESkS0HO9dfras7Prew8b80tcaVldb2U6vWvLA8ozm Eb7zM3793sKRtGZqdb+R0XPjrOtOCyZEZcm6fBT+kr5I9Mr1BrNtqX/nvbxaazV3TXU092xD 2+tf1q2QvPM56Gx8zcPqf8t6q79U6yp/8mBs+Fl3+La9b3GkQ77FgdeZTzdGXfRbpnN7duEe lhrWhp/Pvy1r3Pw7Kz9WZiZbb8D3BZcjdy5tT53jm3gl+86EG5MDuva7v1m7OrTkiI8SS3FG oqEWc1FxIgDP3nB/xAMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeLIzCtJLcpLzFFi42LZdlhJXvfzlh1xBndealg8mLeNzeLlz6ts Fp/WL2O1mH/kHKvF+fMb2C1ubjnKYrHp8TVWi8u75rBZzDi/j8mi+/oONovlx/8xWfzfs4Pd YunWm4wOvB6X+3qZPDat6mTz2Lyk3qPl5H4Wj49Pb7F49G1ZxejxeZOcR/uBbqYAjigum5TU nMyy1CJ9uwSujG3TNAv2SlS8eN/L3MB4R7iLkZNDQsBEYvrVs+xdjFwcQgI7GCX2d+9igkhI S1zfOIEdwhaWWPnvOZgtJNDEJLF5ZgCIzSagLXF3+hawehGgmiPf2hhBbGaBZ0wSpx6WdjFy cAgL2EncO88KEmYRUJX4cXITC4jNK2ArcWDqd2aI8fISqzccALM5geLTGrazQKyykZixaTMr RL2gxMmZT1hARjILqEusnycEsUleonnrbOYJjIKzkFTNQqiahaRqASPzKkbJ1ILi3PTcYsMC o7zUcr3ixNzi0rx0veT83E2M4KjS0trBuGfVB71DjEwcjIcYJTiYlUR4l+fuiBPiTUmsrEot yo8vKs1JLT7EKM3BoiTO+3XWwjghgfTEktTs1NSC1CKYLBMHp1QDUx+rNNvNRbobnl8Xcf/h eGjq5DmTD7qWPdlyn8WxL/jFkjOi325feaC1fLk7W7XzB703kxcW+Dxtl/wcFZA8+aDfOteH 8RXNUx7aimfvOPMmlmHmPqO2bNbK/33NGnILox+9WXpUnrF6D3eHGodyRbPSo8r2E/cclOSm /PfWvLa2+PyWFcWOs2sd2YsyUqYWWqToeDV92P5lhV+xh32GrMm/gzJFTy4oy//h75nI+iDG QHb5buFX4ptmve/2MX2VlJy+wYfr75FNSt8nrJusnaXeryF78qz/MitFhUsnlhZFStRK2yzx 8OrLUPhWKp145Zmsl59d+c3PlgyiPSWbOkvW1tz4kdF3ZuffdkcvJZbijERDLeai4kQAwLrM ZBkDAAA= X-CMS-MailID: 20200511021411epcas5p40282690d856ef9d9541506967fd0e764 X-Msg-Generator: CA CMS-TYPE: 105P X-CMS-RootMailID: 20200511021411epcas5p40282690d856ef9d9541506967fd0e764 References: <20200511020031.25730-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 | 44 ++++++++++++++++++- 2 files changed, 46 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..759ffd024aba 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,41 @@ }; }; + 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>; + pclk-freq-avail-range = <70000000 133000000>; + 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>;