Message ID | 20210917065436.145629-9-chanho61.park@samsung.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v3,01/17] scsi: ufs: add quirk to handle broken UIC command | expand |
>-----Original Message----- >From: Chanho Park [mailto:chanho61.park@samsung.com] >Sent: Friday, September 17, 2021 12:24 PM >To: Alim Akhtar <alim.akhtar@samsung.com>; Avri Altman ><avri.altman@wdc.com>; James E . J . Bottomley <jejb@linux.ibm.com>; Martin >K . Petersen <martin.petersen@oracle.com>; Krzysztof Kozlowski ><krzysztof.kozlowski@canonical.com> >Cc: Bean Huo <beanhuo@micron.com>; Bart Van Assche ><bvanassche@acm.org>; Adrian Hunter <adrian.hunter@intel.com>; Christoph >Hellwig <hch@infradead.org>; Can Guo <cang@codeaurora.org>; Jaegeuk Kim ><jaegeuk@kernel.org>; Gyunghoon Kwon <goodjob.kwon@samsung.com>; >linux-samsung-soc@vger.kernel.org; linux-scsi@vger.kernel.org; Chanho Park ><chanho61.park@samsung.com>; Kiwoong Kim <kwmad.kim@samsung.com> >Subject: [PATCH v3 08/17] scsi: ufs: ufs-exynos: add setup_clocks callback > >This patch adds setup_clocks callback to control/gate clocks by ufshcd. >To avoid calling before initialization, it needs to check whether ufs is null or not >and call it initially from pre_link callback. > >Cc: Alim Akhtar <alim.akhtar@samsung.com> >Cc: Kiwoong Kim <kwmad.kim@samsung.com> >Cc: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> >Signed-off-by: Chanho Park <chanho61.park@samsung.com> >--- > drivers/scsi/ufs/ufs-exynos.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > >diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index >627edef4fbeb..2024e44a09d7 100644 >--- a/drivers/scsi/ufs/ufs-exynos.c >+++ b/drivers/scsi/ufs/ufs-exynos.c >@@ -795,6 +795,27 @@ static void exynos_ufs_config_intr(struct exynos_ufs >*ufs, u32 errs, u8 index) > } > } > >+static int exynos_ufs_setup_clocks(struct ufs_hba *hba, bool on, >+ enum ufs_notify_change_status status) { >+ struct exynos_ufs *ufs = ufshcd_get_variant(hba); >+ >+ if (!ufs) >+ return 0; >+ >+ if (on) { >+ if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) >+ exynos_ufs_disable_auto_ctrl_hcc(ufs); >+ exynos_ufs_ungate_clks(ufs); >+ } else { >+ exynos_ufs_gate_clks(ufs); >+ if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) >+ exynos_ufs_enable_auto_ctrl_hcc(ufs); >+ } >+ >+ return 0; >+} >+ > static int exynos_ufs_pre_link(struct ufs_hba *hba) { > struct exynos_ufs *ufs = ufshcd_get_variant(hba); @@ -813,6 +834,8 >@@ static int exynos_ufs_pre_link(struct ufs_hba *hba) > exynos_ufs_config_phy_time_attr(ufs); > exynos_ufs_config_phy_cap_attr(ufs); > >+ exynos_ufs_setup_clocks(hba, true, POST_CHANGE); For consistency and better understanding, may be PRE_CHANGE? >+ > if (ufs->drv_data->pre_link) > ufs->drv_data->pre_link(ufs); > >@@ -1203,6 +1226,7 @@ static struct ufs_hba_variant_ops ufs_hba_exynos_ops >= { > .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_clocks = exynos_ufs_setup_clocks, > .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, >-- >2.33.0
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index 627edef4fbeb..2024e44a09d7 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -795,6 +795,27 @@ static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index) } } +static int exynos_ufs_setup_clocks(struct ufs_hba *hba, bool on, + enum ufs_notify_change_status status) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + if (!ufs) + return 0; + + if (on) { + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) + exynos_ufs_disable_auto_ctrl_hcc(ufs); + exynos_ufs_ungate_clks(ufs); + } else { + exynos_ufs_gate_clks(ufs); + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) + exynos_ufs_enable_auto_ctrl_hcc(ufs); + } + + return 0; +} + static int exynos_ufs_pre_link(struct ufs_hba *hba) { struct exynos_ufs *ufs = ufshcd_get_variant(hba); @@ -813,6 +834,8 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba) exynos_ufs_config_phy_time_attr(ufs); exynos_ufs_config_phy_cap_attr(ufs); + exynos_ufs_setup_clocks(hba, true, POST_CHANGE); + if (ufs->drv_data->pre_link) ufs->drv_data->pre_link(ufs); @@ -1203,6 +1226,7 @@ static struct ufs_hba_variant_ops ufs_hba_exynos_ops = { .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_clocks = exynos_ufs_setup_clocks, .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,
This patch adds setup_clocks callback to control/gate clocks by ufshcd. To avoid calling before initialization, it needs to check whether ufs is null or not and call it initially from pre_link callback. Cc: Alim Akhtar <alim.akhtar@samsung.com> Cc: Kiwoong Kim <kwmad.kim@samsung.com> Cc: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Signed-off-by: Chanho Park <chanho61.park@samsung.com> --- drivers/scsi/ufs/ufs-exynos.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)