From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753290AbbKCLoa (ORCPT ); Tue, 3 Nov 2015 06:44:30 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:37684 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752179AbbKCLo0 (ORCPT ); Tue, 3 Nov 2015 06:44:26 -0500 X-AuditID: cbfee68f-f796f6d0000014a4-d1-56389e18cb83 Message-id: <56389E3A.7060004@samsung.com> Date: Tue, 03 Nov 2015 17:14:58 +0530 From: Alim Akhtar User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-version: 1.0 To: Kishon Vijay Abraham I , Alim Akhtar Cc: linux-scsi@vger.kernel.org, "linux-kernel@vger.kernel.org" , "James E.J. Bottomley" , vinayak holikatti , Seungwon Jeon , "devicetree@vger.kernel.org" , Arnd Bergmann Subject: Re: [PATCH v4 11/11] scsi: ufs-exynos: add UFS host support for Exynos SoCs References: <1444827351-24128-1-git-send-email-alim.akhtar@samsung.com> <1444827351-24128-12-git-send-email-alim.akhtar@samsung.com> <561F18C5.10406@samsung.com> <562A4FE3.9080200@ti.com> <5630C55D.80800@ti.com> In-reply-to: <5630C55D.80800@ti.com> Content-type: text/plain; charset=UTF-8; format=flowed Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrNIsWRmVeSWpSXmKPExsWyRsSkTldinkWYwckX3BZLb1Vb/J10jN1i /pFzrBbLLyxhsvi//jaLxYWnPWwWl3fNYbPovr6DzWLHwioHTo/fvyYxeuycdZfd4/CPH8we x29sZ/L4vEkugDWKyyYlNSezLLVI3y6BK2Pypr3MBQ8tKmZNW8DUwHhYu4uRk0NCwERi+v8+ ZghbTOLCvfVsXYxcHEICKxglZv44wtrFyAFWNKUvFyK+lFHi/a9PrBDOA0aJm33fGUG6eQW0 JFouHGACsVkEVCXuzP/KCmKzCWhL3J2+hQlkkKhAhMTjC0IQ5YISPybfYwGxRQT8JZa0zGcH mckssJdJ4uCzM2AzhQXCJH4/3wK1bAGTxNRLT9hABnEKqEhMPcwFUsMsYCbxqGUdM4QtL7F5 zVtmkHoJgUfsEhdOrmGDOEhA4tvkQywQ38hKbDoA9bGkxMEVN1gmMIrNQnLTLCRjZyEZu4CR eRWjaGpBckFxUnqRsV5xYm5xaV66XnJ+7iZGYBye/vesfwfj3QPWhxgFOBiVeHgXLjEPE2JN LCuuzD3EaAp0xURmKdHkfGC055XEGxqbGVmYmpgaG5lbmimJ8y6U+hksJJCeWJKanZpakFoU X1Sak1p8iJGJg1OqgZE1dWmCm1bu3fxObie9/v967f8Tm+Xsfs+I+nNe31Hy8jy3FHvzltX3 xDhPLIicc+xLtd+yBa2syWmKFxZ8/vxSIybQ64Drt4/FDyq+7ct2+jx9tWnN/9rZLA8bKrUj v6czuBcxPGHT39kTuX7mnPBdZj9/zJ5bdF7CI173zpyYnxu3KR1646vEUpyRaKjFXFScCABf ifVjvgIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrBIsWRmVeSWpSXmKPExsVy+t9jAV2JeRZhBlMXMVosvVVt8XfSMXaL +UfOsVosv7CEyeL/+tssFhee9rBZXN41h82i+/oONosdC6scOD1+/5rE6LFz1l12j8M/fjB7 HL+xncnj8ya5ANaoBkabjNTElNQihdS85PyUzLx0WyXv4HjneFMzA0NdQ0sLcyWFvMTcVFsl F58AXbfMHKB7lBTKEnNKgUIBicXFSvp2mCaEhrjpWsA0Ruj6hgTB9RgZoIGENYwZkzftZS54 aFExa9oCpgbGw9pdjBwcEgImElP6crsYOYFMMYkL99azdTFycQgJLGWUeP/rEyuE84BR4mbf d0aQKl4BLYmWCweYQGwWAVWJO/O/soLYbALaEnenb2ECGSoqECHx+IIQRLmgxI/J91hAbBEB f4klLfPZQWYyC+xlkjj47AzYTGGBMInfz7dALVvAJDH10hM2kEGcAioSUw9zgdQwC5hJPGpZ xwxhy0tsXvOWeQKjwCwkO2YhKZuFpGwBI/MqRonUguSC4qT0XKO81HK94sTc4tK8dL3k/NxN jOBYfya9g/HwLvdDjAIcjEo8vAuWmIcJsSaWFVfmHmKU4GBWEuFNnWwRJsSbklhZlVqUH19U mpNafIjRFBgIE5mlRJPzgWkoryTe0NjE3NTY1NLEwsTMUkmcV9/TKExIID2xJDU7NbUgtQim j4mDU6qBMeLi/D1SKYISm1vE3O0Xz10ZdoZtsvHiB95h1cf3cS2ePp2LqevV9PLywLqA1jk+ OvLpjNoPBPrahLs31/k4L1O5HeL4uqdbuzLl0cxtcX0GHWt6HP6ErlHrKj+/1XM+w04Bb1GL /x7JnNcuemxy+Bcavt0nRbB64xrbbXYrrKewxhmGVuoosRRnJBpqMRcVJwIArgLV0QsDAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Kishon, Thanks for your time. On 10/28/2015 06:23 PM, Kishon Vijay Abraham I wrote: > Hi, > > On Sunday 25 October 2015 05:34 PM, Alim Akhtar wrote: >> Hi Kishon >> Thanks again for you review. >> >> On Fri, Oct 23, 2015 at 8:48 PM, Kishon Vijay Abraham I wrote: >>> Hi, >>> >>> On Thursday 15 October 2015 08:38 AM, Alim Akhtar wrote: >>>> +CCing kishon Vijay, >>>> >>>> On 10/14/2015 06:25 PM, Alim Akhtar wrote: >>>>> From: Seungwon Jeon >>>>> >>>>> This patch introduces Exynos UFS host controller driver, >>>>> which mainly handles vendor-specific operations including >>>>> link startup, power mode change and hibernation/unhibernation. >>>>> >>>>> Signed-off-by: Seungwon Jeon >>>>> Signed-off-by: Alim Akhtar >>>>> --- >>>>> drivers/scsi/ufs/Kconfig | 12 + >>>>> drivers/scsi/ufs/Makefile | 1 + >>>>> drivers/scsi/ufs/ufs-exynos-hw.c | 131 ++++ >>>>> drivers/scsi/ufs/ufs-exynos-hw.h | 43 ++ >>>>> drivers/scsi/ufs/ufs-exynos.c | 1317 >>>>> ++++++++++++++++++++++++++++++++++++++ >>>>> drivers/scsi/ufs/ufs-exynos.h | 247 +++++++ >>>>> drivers/scsi/ufs/ufshci.h | 26 +- >>>>> drivers/scsi/ufs/unipro.h | 47 ++ >>>>> 8 files changed, 1823 insertions(+), 1 deletion(-) >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos-hw.c >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos-hw.h >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos.c >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos.h >>>>> >>> . >>> . >>> >>> . >>> . >>>>> diff --git a/drivers/scsi/ufs/ufs-exynos-hw.c >>>>> b/drivers/scsi/ufs/ufs-exynos-hw.c >>>>> new file mode 100644 >>>>> index 000000000000..be6c61541a8f >>>>> --- /dev/null >>>>> +++ b/drivers/scsi/ufs/ufs-exynos-hw.c >>>>> @@ -0,0 +1,131 @@ >>> . >>> . >>> >>> . >>> . >>>>> + >>>>> +#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 = to_exynos_ufs(hba); >>>>> + struct exynos_ufs_phy_info *phy_info = phy_get_drvdata(ufs->phy); >>> >>> This is abusing the interface. phy_get_drvdata is meant to be used only >>> by the PHY driver. >>>>> + struct exynos_ufs_phy_specific_ops *phy_ops = >>>>> + phy_info->phy_specific_ops; >>> >>> I'm really not happy about having platform specific ops for PHY. We have >>> to see if existing PHY ops can be used for this or in worst case add new >>> PHY ops. >> Well you said you like the controller driver to use only PHY ops[1], I >> am sorry If I misunderstood that point, can you please help me to >> understand that? > > I meant PHY generic ops and not PHY ops. Ok, got it, will use only generic phy here in controller driver. - Will remove the platform specific PHY ops from phy driver introduce in this series (patch 02/11) >> [1]-> https://lkml.org/lkml/2015/9/18/29 >> >>>>> + struct uic_pwr_mode *pwr = &ufs->pwr_act; >>>>> + char pwr_str[PWR_MODE_STR_LEN] = ""; >>>>> + int ret = 0; >>>>> + >>>>> + if (ufs->drv_data->post_pwr_change) >>>>> + ufs->drv_data->post_pwr_change(ufs, pwr); >>>>> + >>>>> + if (IS_UFS_PWR_MODE_HS(pwr->mode)) { >>>>> + switch (pwr->hs_series) { >>>>> + case PA_HS_MODE_A: >>>>> + case PA_HS_MODE_B: >>>>> + phy_ops->calibrate_phy(ufs->phy, CFG_POST_PWR_HS, >>>>> + PWR_MODE_HS(pwr->gear, pwr->hs_series)); >>>>> + break; >>>>> + } >>>>> + >>>>> + ret = phy_ops->wait_for_lock_acq(ufs->phy); >>>>> + snprintf(pwr_str, sizeof(pwr_str), "Fast%s series_%s G_%d L_%d", >>>>> + pwr->mode == FASTAUTO_MODE ? "_Auto" : "", >>>>> + pwr->hs_series == PA_HS_MODE_A ? "A" : "B", >>>>> + pwr->gear, pwr->lane); >>>>> + } else if (IS_UFS_PWR_MODE_PWM(pwr->mode)) { >>>>> + snprintf(pwr_str, sizeof(pwr_str), "Slow%s G_%d L_%d", >>>>> + pwr->mode == SLOWAUTO_MODE ? "_Auto" : "", >>>>> + pwr->gear, pwr->lane); >>>>> + } >>>>> + >>>>> + dev_info(hba->dev, "Power mode change %d : %s\n", ret, pwr_str); >>>>> + return ret; >>>>> +} >>>>> + >>>>> +static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba, >>>>> + int tag, struct scsi_cmnd *cmd) >>>>> +{ >>>>> + struct exynos_ufs *ufs = to_exynos_ufs(hba); >>>>> + u32 type; >>>>> + >>>>> + type = hci_readl(ufs, HCI_UTRL_NEXUS_TYPE); >>>>> + >>>>> + if (cmd) >>>>> + 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 = to_exynos_ufs(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 void exynos_ufs_phy_init(struct exynos_ufs *ufs) >>>>> +{ >>>>> + struct ufs_hba *hba = ufs->hba; >>>>> + struct exynos_ufs_phy_info *phy_info = phy_get_drvdata(ufs->phy); >>>>> + struct exynos_ufs_phy_specific_ops *phy_ops = >>>>> + phy_info->phy_specific_ops; >>>>> + >>>>> + 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_ops->set_lane_cnt(ufs->phy, ufs->avail_ln_rx); >>> >>> can't bus_width attribute in phy core be reused for this? >>> >> I will take a look on it. >> >>>>> + phy_ops->calibrate_phy(ufs->phy, CFG_PRE_INIT, PWR_MODE_ANY); >>> >>> Why can't calibrate PHY be directly done in phy_init? >>> >> This is just one instance, need to calibrate PHY when the ufs pwr mode changes. > > Then maybe we should check when the power mode changes and see if it > makes sense to calibrate PHY in other generic PHY ops like phy_power_on > etc.. > I did explore this but looks like in current situation it is not the best option. Will post next revision after I am done with modifications, PTAL. > Thanks > Kishon > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alim Akhtar Subject: Re: [PATCH v4 11/11] scsi: ufs-exynos: add UFS host support for Exynos SoCs Date: Tue, 03 Nov 2015 17:14:58 +0530 Message-ID: <56389E3A.7060004@samsung.com> References: <1444827351-24128-1-git-send-email-alim.akhtar@samsung.com> <1444827351-24128-12-git-send-email-alim.akhtar@samsung.com> <561F18C5.10406@samsung.com> <562A4FE3.9080200@ti.com> <5630C55D.80800@ti.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Return-path: In-reply-to: <5630C55D.80800-l0cyMroinI0@public.gmane.org> Sender: devicetree-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Kishon Vijay Abraham I , Alim Akhtar Cc: linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, "linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , "James E.J. Bottomley" , vinayak holikatti , Seungwon Jeon , "devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , Arnd Bergmann List-Id: devicetree@vger.kernel.org Hi Kishon, Thanks for your time. On 10/28/2015 06:23 PM, Kishon Vijay Abraham I wrote: > Hi, > > On Sunday 25 October 2015 05:34 PM, Alim Akhtar wrote: >> Hi Kishon >> Thanks again for you review. >> >> On Fri, Oct 23, 2015 at 8:48 PM, Kishon Vijay Abraham I wrote: >>> Hi, >>> >>> On Thursday 15 October 2015 08:38 AM, Alim Akhtar wrote: >>>> +CCing kishon Vijay, >>>> >>>> On 10/14/2015 06:25 PM, Alim Akhtar wrote: >>>>> From: Seungwon Jeon >>>>> >>>>> This patch introduces Exynos UFS host controller driver, >>>>> which mainly handles vendor-specific operations including >>>>> link startup, power mode change and hibernation/unhibernation. >>>>> >>>>> Signed-off-by: Seungwon Jeon >>>>> Signed-off-by: Alim Akhtar >>>>> --- >>>>> drivers/scsi/ufs/Kconfig | 12 + >>>>> drivers/scsi/ufs/Makefile | 1 + >>>>> drivers/scsi/ufs/ufs-exynos-hw.c | 131 ++++ >>>>> drivers/scsi/ufs/ufs-exynos-hw.h | 43 ++ >>>>> drivers/scsi/ufs/ufs-exynos.c | 1317 >>>>> ++++++++++++++++++++++++++++++++++++++ >>>>> drivers/scsi/ufs/ufs-exynos.h | 247 +++++++ >>>>> drivers/scsi/ufs/ufshci.h | 26 +- >>>>> drivers/scsi/ufs/unipro.h | 47 ++ >>>>> 8 files changed, 1823 insertions(+), 1 deletion(-) >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos-hw.c >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos-hw.h >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos.c >>>>> create mode 100644 drivers/scsi/ufs/ufs-exynos.h >>>>> >>> . >>> . >>> >>> . >>> . >>>>> diff --git a/drivers/scsi/ufs/ufs-exynos-hw.c >>>>> b/drivers/scsi/ufs/ufs-exynos-hw.c >>>>> new file mode 100644 >>>>> index 000000000000..be6c61541a8f >>>>> --- /dev/null >>>>> +++ b/drivers/scsi/ufs/ufs-exynos-hw.c >>>>> @@ -0,0 +1,131 @@ >>> . >>> . >>> >>> . >>> . >>>>> + >>>>> +#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 = to_exynos_ufs(hba); >>>>> + struct exynos_ufs_phy_info *phy_info = phy_get_drvdata(ufs->phy); >>> >>> This is abusing the interface. phy_get_drvdata is meant to be used only >>> by the PHY driver. >>>>> + struct exynos_ufs_phy_specific_ops *phy_ops = >>>>> + phy_info->phy_specific_ops; >>> >>> I'm really not happy about having platform specific ops for PHY. We have >>> to see if existing PHY ops can be used for this or in worst case add new >>> PHY ops. >> Well you said you like the controller driver to use only PHY ops[1], I >> am sorry If I misunderstood that point, can you please help me to >> understand that? > > I meant PHY generic ops and not PHY ops. Ok, got it, will use only generic phy here in controller driver. - Will remove the platform specific PHY ops from phy driver introduce in this series (patch 02/11) >> [1]-> https://lkml.org/lkml/2015/9/18/29 >> >>>>> + struct uic_pwr_mode *pwr = &ufs->pwr_act; >>>>> + char pwr_str[PWR_MODE_STR_LEN] = ""; >>>>> + int ret = 0; >>>>> + >>>>> + if (ufs->drv_data->post_pwr_change) >>>>> + ufs->drv_data->post_pwr_change(ufs, pwr); >>>>> + >>>>> + if (IS_UFS_PWR_MODE_HS(pwr->mode)) { >>>>> + switch (pwr->hs_series) { >>>>> + case PA_HS_MODE_A: >>>>> + case PA_HS_MODE_B: >>>>> + phy_ops->calibrate_phy(ufs->phy, CFG_POST_PWR_HS, >>>>> + PWR_MODE_HS(pwr->gear, pwr->hs_series)); >>>>> + break; >>>>> + } >>>>> + >>>>> + ret = phy_ops->wait_for_lock_acq(ufs->phy); >>>>> + snprintf(pwr_str, sizeof(pwr_str), "Fast%s series_%s G_%d L_%d", >>>>> + pwr->mode == FASTAUTO_MODE ? "_Auto" : "", >>>>> + pwr->hs_series == PA_HS_MODE_A ? "A" : "B", >>>>> + pwr->gear, pwr->lane); >>>>> + } else if (IS_UFS_PWR_MODE_PWM(pwr->mode)) { >>>>> + snprintf(pwr_str, sizeof(pwr_str), "Slow%s G_%d L_%d", >>>>> + pwr->mode == SLOWAUTO_MODE ? "_Auto" : "", >>>>> + pwr->gear, pwr->lane); >>>>> + } >>>>> + >>>>> + dev_info(hba->dev, "Power mode change %d : %s\n", ret, pwr_str); >>>>> + return ret; >>>>> +} >>>>> + >>>>> +static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba, >>>>> + int tag, struct scsi_cmnd *cmd) >>>>> +{ >>>>> + struct exynos_ufs *ufs = to_exynos_ufs(hba); >>>>> + u32 type; >>>>> + >>>>> + type = hci_readl(ufs, HCI_UTRL_NEXUS_TYPE); >>>>> + >>>>> + if (cmd) >>>>> + 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 = to_exynos_ufs(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 void exynos_ufs_phy_init(struct exynos_ufs *ufs) >>>>> +{ >>>>> + struct ufs_hba *hba = ufs->hba; >>>>> + struct exynos_ufs_phy_info *phy_info = phy_get_drvdata(ufs->phy); >>>>> + struct exynos_ufs_phy_specific_ops *phy_ops = >>>>> + phy_info->phy_specific_ops; >>>>> + >>>>> + 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_ops->set_lane_cnt(ufs->phy, ufs->avail_ln_rx); >>> >>> can't bus_width attribute in phy core be reused for this? >>> >> I will take a look on it. >> >>>>> + phy_ops->calibrate_phy(ufs->phy, CFG_PRE_INIT, PWR_MODE_ANY); >>> >>> Why can't calibrate PHY be directly done in phy_init? >>> >> This is just one instance, need to calibrate PHY when the ufs pwr mode changes. > > Then maybe we should check when the power mode changes and see if it > makes sense to calibrate PHY in other generic PHY ops like phy_power_on > etc.. > I did explore this but looks like in current situation it is not the best option. Will post next revision after I am done with modifications, PTAL. > Thanks > Kishon > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html