]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
scsi: ufs: exynos: Add support for ExynosAutov920 SoC
authorSowon Na <sowon.na@samsung.com>
Fri, 17 Apr 2026 12:14:51 +0000 (17:44 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 30 Apr 2026 16:06:10 +0000 (12:06 -0400)
Add a dedicated compatible and drv_data with associated hooks for
ExynosAutov920 SoC.

ExynosAutov920 has a different mask of UFS sharability from
ExynosAutov9, so add related changes for the same.

Signed-off-by: Sowon Na <sowon.na@samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
[Alim: fixed unintended changes, other fixes]
Link: https://patch.msgid.link/20260417121452.827054-4-alim.akhtar@samsung.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/host/ufs-exynos.c

index 77a6c8e44485be8433916880f0526ba64dbfb85a..b2f65c4655251db905face4b569a704480ac786f 100644 (file)
 #define UFS_EXYNOSAUTO_RD_SHARABLE     BIT(1)
 #define UFS_EXYNOSAUTO_SHARABLE                (UFS_EXYNOSAUTO_WR_SHARABLE | \
                                         UFS_EXYNOSAUTO_RD_SHARABLE)
+#define UFS_EXYNOSAUTOV920_WR_SHARABLE BIT(3)
+#define UFS_EXYNOSAUTOV920_RD_SHARABLE BIT(2)
+#define UFS_EXYNOSAUTOV920_SHARABLE    (UFS_EXYNOSAUTOV920_WR_SHARABLE |\
+                                        UFS_EXYNOSAUTOV920_RD_SHARABLE)
 #define UFS_GS101_WR_SHARABLE          BIT(1)
 #define UFS_GS101_RD_SHARABLE          BIT(0)
 #define UFS_GS101_SHARABLE             (UFS_GS101_WR_SHARABLE | \
@@ -417,6 +421,95 @@ static int exynos7_ufs_post_pwr_change(struct exynos_ufs *ufs,
        return 0;
 }
 
+static int exynosautov920_ufs_pre_link(struct exynos_ufs *ufs)
+{
+       struct ufs_hba *hba = ufs->hba;
+       int i;
+       u32 tx_line_reset_period, rx_line_reset_period;
+
+       rx_line_reset_period = (RX_LINE_RESET_TIME * ufs->mclk_rate)
+                               / NSEC_PER_MSEC;
+       tx_line_reset_period = (TX_LINE_RESET_TIME * ufs->mclk_rate)
+                               / NSEC_PER_MSEC;
+
+       unipro_writel(ufs, 0x5f, 0x44);
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x202), 0x02);
+
+       for_each_ufs_rx_lane(ufs, i) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_CLK_PRD, i),
+                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_CLK_PRD_EN, i), 0x0);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE2, i),
+                              (rx_line_reset_period >> 16) & 0xFF);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE1, i),
+                              (rx_line_reset_period >> 8) & 0xFF);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE0, i),
+                              (rx_line_reset_period) & 0xFF);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x69);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);
+       }
+
+       for_each_ufs_tx_lane(ufs, i) {
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_CLK_PRD, i),
+                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_CLK_PRD_EN, i),
+                              0x02);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE2, i),
+                              (tx_line_reset_period >> 16) & 0xFF);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE1, i),
+                              (tx_line_reset_period >> 8) & 0xFF);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE0, i),
+                              (tx_line_reset_period) & 0xFF);
+
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 0x1);
+               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x7f, i), 0x0);
+       }
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0xa011), 0x8000);
+
+       return 0;
+}
+
+static int exynosautov920_ufs_post_link(struct exynos_ufs *ufs)
+{
+       struct ufs_hba *hba = ufs->hba;
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x9529), 0x1);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x15a4), 0x3e8);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x9529), 0x0);
+
+       return 0;
+}
+
+static int exynosautov920_ufs_pre_pwr_change(struct exynos_ufs *ufs,
+                                            struct ufs_pa_layer_attr *pwr)
+{
+       struct ufs_hba *hba = ufs->hba;
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(0x15d4), 0x1);
+
+       ufshcd_dme_set(hba, UIC_ARG_MIB(DL_FC0PROTTIMEOUTVAL), 8064);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(DL_TC0REPLAYTIMEOUTVAL), 28224);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(DL_AFC0REQTIMEOUTVAL), 20160);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
+       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
+
+       unipro_writel(ufs, 8064, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0);
+       unipro_writel(ufs, 28224, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1);
+       unipro_writel(ufs, 20160, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2);
+       unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0);
+       unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1);
+       unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2);
+
+       return 0;
+}
+
 /*
  * exynos_ufs_auto_ctrl_hcc - HCI core clock control by h/w
  * Control should be disabled in the below cases
@@ -2201,6 +2294,21 @@ static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
        .suspend                = gs101_ufs_suspend,
 };
 
+static const struct exynos_ufs_drv_data exynosautov920_ufs_drvs = {
+       .uic_attr               = &exynos7_uic_attr,
+       .quirks                 = UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,
+       .opts                   = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
+                                 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
+                                 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX |
+                                 EXYNOS_UFS_OPT_TIMER_TICK_SELECT,
+       .iocc_mask              = UFS_EXYNOSAUTOV920_SHARABLE,
+       .drv_init               = exynosauto_ufs_drv_init,
+       .post_hce_enable        = exynosauto_ufs_post_hce_enable,
+       .pre_link               = exynosautov920_ufs_pre_link,
+       .post_link              = exynosautov920_ufs_post_link,
+       .pre_pwr_change         = exynosautov920_ufs_pre_pwr_change,
+};
+
 static const struct of_device_id exynos_ufs_of_match[] = {
        { .compatible = "google,gs101-ufs",
          .data       = &gs101_ufs_drvs },
@@ -2210,6 +2318,8 @@ static const struct of_device_id exynos_ufs_of_match[] = {
          .data       = &exynosauto_ufs_drvs },
        { .compatible = "samsung,exynosautov9-ufs-vh",
          .data       = &exynosauto_ufs_vh_drvs },
+       { .compatible = "samsung,exynosautov920-ufs",
+         .data       = &exynosautov920_ufs_drvs },
        { .compatible = "tesla,fsd-ufs",
          .data       = &fsd_ufs_drvs },
        {},