4848#define HCI_UNIPRO_APB_CLK_CTRL 0x68
4949#define UNIPRO_APB_CLK (v , x ) (((v) & ~0xF) | ((x) & 0xF))
5050#define HCI_AXIDMA_RWDATA_BURST_LEN 0x6C
51+ #define WLU_EN BIT(31)
52+ #define WLU_BURST_LEN (x ) ((x) << 27 | ((x) & 0xF))
5153#define HCI_GPIO_OUT 0x70
5254#define HCI_ERR_EN_PA_LAYER 0x78
5355#define HCI_ERR_EN_DL_LAYER 0x7C
7476#define CLK_CTRL_EN_MASK (REFCLK_CTRL_EN |\
7577 UNIPRO_PCLK_CTRL_EN |\
7678 UNIPRO_MCLK_CTRL_EN)
79+
80+ #define HCI_IOP_ACG_DISABLE 0x100
81+ #define HCI_IOP_ACG_DISABLE_EN BIT(0)
82+
7783/* Device fatal error */
7884#define DFES_ERR_EN BIT(31)
7985#define DFES_DEF_L2_ERRS (UIC_DATA_LINK_LAYER_ERROR_RX_BUF_OF |\
@@ -198,27 +204,41 @@ static inline void exynos_ufs_ungate_clks(struct exynos_ufs *ufs)
198204 exynos_ufs_ctrl_clkstop (ufs , false);
199205}
200206
201- static int exynos7_ufs_drv_init (struct device * dev , struct exynos_ufs * ufs )
202- {
203- return 0 ;
204- }
205-
206- static int exynosauto_ufs_drv_init (struct device * dev , struct exynos_ufs * ufs )
207+ static int exynos_ufs_shareability (struct exynos_ufs * ufs )
207208{
208- struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
209-
210209 /* IO Coherency setting */
211210 if (ufs -> sysreg ) {
212211 return regmap_update_bits (ufs -> sysreg ,
213212 ufs -> shareability_reg_offset ,
214213 UFS_SHARABLE , UFS_SHARABLE );
215214 }
216215
217- attr -> tx_dif_p_nsec = 3200000 ;
218-
219216 return 0 ;
220217}
221218
219+ static int gs101_ufs_drv_init (struct exynos_ufs * ufs )
220+ {
221+ struct ufs_hba * hba = ufs -> hba ;
222+ u32 reg ;
223+
224+ /* Enable WriteBooster */
225+ hba -> caps |= UFSHCD_CAP_WB_EN ;
226+
227+ /* Enable clock gating and hibern8 */
228+ hba -> caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING ;
229+
230+ /* set ACG to be controlled by UFS_ACG_DISABLE */
231+ reg = hci_readl (ufs , HCI_IOP_ACG_DISABLE );
232+ hci_writel (ufs , reg & (~HCI_IOP_ACG_DISABLE_EN ), HCI_IOP_ACG_DISABLE );
233+
234+ return exynos_ufs_shareability (ufs );
235+ }
236+
237+ static int exynosauto_ufs_drv_init (struct exynos_ufs * ufs )
238+ {
239+ return exynos_ufs_shareability (ufs );
240+ }
241+
222242static int exynosauto_ufs_post_hce_enable (struct exynos_ufs * ufs )
223243{
224244 struct ufs_hba * hba = ufs -> hba ;
@@ -546,6 +566,9 @@ static void exynos_ufs_specify_phy_time_attr(struct exynos_ufs *ufs)
546566 struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
547567 struct ufs_phy_time_cfg * t_cfg = & ufs -> t_cfg ;
548568
569+ if (ufs -> opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR )
570+ return ;
571+
549572 t_cfg -> tx_linereset_p =
550573 exynos_ufs_calc_time_cntr (ufs , attr -> tx_dif_p_nsec );
551574 t_cfg -> tx_linereset_n =
@@ -724,6 +747,9 @@ static void exynos_ufs_config_smu(struct exynos_ufs *ufs)
724747{
725748 u32 reg , val ;
726749
750+ if (ufs -> opts & EXYNOS_UFS_OPT_UFSPR_SECURE )
751+ return ;
752+
727753 exynos_ufs_disable_auto_ctrl_hcc_save (ufs , & val );
728754
729755 /* make encryption disabled by default */
@@ -771,6 +797,21 @@ static void exynos_ufs_config_sync_pattern_mask(struct exynos_ufs *ufs,
771797 exynos_ufs_disable_ov_tm (hba );
772798}
773799
800+ #define UFS_HW_VER_MAJOR_MASK GENMASK(15, 8)
801+
802+ static u32 exynos_ufs_get_hs_gear (struct ufs_hba * hba )
803+ {
804+ u8 major ;
805+
806+ major = FIELD_GET (UFS_HW_VER_MAJOR_MASK , hba -> ufs_version );
807+
808+ if (major >= 3 )
809+ return UFS_HS_G4 ;
810+
811+ /* Default is HS-G3 */
812+ return UFS_HS_G3 ;
813+ }
814+
774815static int exynos_ufs_pre_pwr_mode (struct ufs_hba * hba ,
775816 struct ufs_pa_layer_attr * dev_max_params ,
776817 struct ufs_pa_layer_attr * dev_req_params )
@@ -788,6 +829,10 @@ static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
788829
789830 ufshcd_init_host_params (& host_params );
790831
832+ /* This driver only support symmetric gear setting e.g. hs_tx_gear == hs_rx_gear */
833+ host_params .hs_tx_gear = exynos_ufs_get_hs_gear (hba );
834+ host_params .hs_rx_gear = exynos_ufs_get_hs_gear (hba );
835+
791836 ret = ufshcd_negotiate_pwr_params (& host_params , dev_max_params , dev_req_params );
792837 if (ret ) {
793838 pr_err ("%s: failed to determine capabilities\n" , __func__ );
@@ -1429,7 +1474,7 @@ static int exynos_ufs_init(struct ufs_hba *hba)
14291474 exynos_ufs_fmp_init (hba , ufs );
14301475
14311476 if (ufs -> drv_data -> drv_init ) {
1432- ret = ufs -> drv_data -> drv_init (dev , ufs );
1477+ ret = ufs -> drv_data -> drv_init (ufs );
14331478 if (ret ) {
14341479 dev_err (dev , "failed to init drv-data\n" );
14351480 goto out ;
@@ -1440,8 +1485,8 @@ static int exynos_ufs_init(struct ufs_hba *hba)
14401485 if (ret )
14411486 goto out ;
14421487 exynos_ufs_specify_phy_time_attr (ufs );
1443- if (!( ufs -> opts & EXYNOS_UFS_OPT_UFSPR_SECURE ))
1444- exynos_ufs_config_smu (ufs );
1488+
1489+ exynos_ufs_config_smu (ufs );
14451490
14461491 hba -> host -> dma_alignment = DATA_UNIT_SIZE - 1 ;
14471492 return 0 ;
@@ -1484,12 +1529,12 @@ static void exynos_ufs_dev_hw_reset(struct ufs_hba *hba)
14841529 hci_writel (ufs , 1 << 0 , HCI_GPIO_OUT );
14851530}
14861531
1487- static void exynos_ufs_pre_hibern8 (struct ufs_hba * hba , u8 enter )
1532+ static void exynos_ufs_pre_hibern8 (struct ufs_hba * hba , enum uic_cmd_dme cmd )
14881533{
14891534 struct exynos_ufs * ufs = ufshcd_get_variant (hba );
14901535 struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
14911536
1492- if (! enter ) {
1537+ if (cmd == UIC_CMD_DME_HIBER_EXIT ) {
14931538 if (ufs -> opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL )
14941539 exynos_ufs_disable_auto_ctrl_hcc (ufs );
14951540 exynos_ufs_ungate_clks (ufs );
@@ -1517,30 +1562,11 @@ static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter)
15171562 }
15181563}
15191564
1520- static void exynos_ufs_post_hibern8 (struct ufs_hba * hba , u8 enter )
1565+ static void exynos_ufs_post_hibern8 (struct ufs_hba * hba , enum uic_cmd_dme cmd )
15211566{
15221567 struct exynos_ufs * ufs = ufshcd_get_variant (hba );
15231568
1524- if (!enter ) {
1525- u32 cur_mode = 0 ;
1526- u32 pwrmode ;
1527-
1528- if (ufshcd_is_hs_mode (& ufs -> dev_req_params ))
1529- pwrmode = FAST_MODE ;
1530- else
1531- pwrmode = SLOW_MODE ;
1532-
1533- ufshcd_dme_get (hba , UIC_ARG_MIB (PA_PWRMODE ), & cur_mode );
1534- if (cur_mode != (pwrmode << 4 | pwrmode )) {
1535- dev_warn (hba -> dev , "%s: power mode change\n" , __func__ );
1536- hba -> pwr_info .pwr_rx = (cur_mode >> 4 ) & 0xf ;
1537- hba -> pwr_info .pwr_tx = cur_mode & 0xf ;
1538- ufshcd_config_pwr_mode (hba , & hba -> max_pwr_info .info );
1539- }
1540-
1541- if (!(ufs -> opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB ))
1542- exynos_ufs_establish_connt (ufs );
1543- } else {
1569+ if (cmd == UIC_CMD_DME_HIBER_ENTER ) {
15441570 ufs -> entry_hibern8_t = ktime_get ();
15451571 exynos_ufs_gate_clks (ufs );
15461572 if (ufs -> opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL )
@@ -1627,15 +1653,15 @@ static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba,
16271653}
16281654
16291655static void exynos_ufs_hibern8_notify (struct ufs_hba * hba ,
1630- enum uic_cmd_dme enter ,
1656+ enum uic_cmd_dme cmd ,
16311657 enum ufs_notify_change_status notify )
16321658{
16331659 switch ((u8 )notify ) {
16341660 case PRE_CHANGE :
1635- exynos_ufs_pre_hibern8 (hba , enter );
1661+ exynos_ufs_pre_hibern8 (hba , cmd );
16361662 break ;
16371663 case POST_CHANGE :
1638- exynos_ufs_post_hibern8 (hba , enter );
1664+ exynos_ufs_post_hibern8 (hba , cmd );
16391665 break ;
16401666 }
16411667}
@@ -1891,6 +1917,12 @@ static int gs101_ufs_post_link(struct exynos_ufs *ufs)
18911917{
18921918 struct ufs_hba * hba = ufs -> hba ;
18931919
1920+ /*
1921+ * Enable Write Line Unique. This field has to be 0x3
1922+ * to support Write Line Unique transaction on gs101.
1923+ */
1924+ hci_writel (ufs , WLU_EN | WLU_BURST_LEN (3 ), HCI_AXIDMA_RWDATA_BURST_LEN );
1925+
18941926 exynos_ufs_enable_dbg_mode (hba );
18951927 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_SAVECONFIGTIME ), 0x3e8 );
18961928 exynos_ufs_disable_dbg_mode (hba );
@@ -2036,7 +2068,6 @@ static const struct exynos_ufs_drv_data exynos_ufs_drvs = {
20362068 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX |
20372069 EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB |
20382070 EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER ,
2039- .drv_init = exynos7_ufs_drv_init ,
20402071 .pre_link = exynos7_ufs_pre_link ,
20412072 .post_link = exynos7_ufs_post_link ,
20422073 .pre_pwr_change = exynos7_ufs_pre_pwr_change ,
@@ -2045,26 +2076,6 @@ static const struct exynos_ufs_drv_data exynos_ufs_drvs = {
20452076
20462077static struct exynos_ufs_uic_attr gs101_uic_attr = {
20472078 .tx_trailingclks = 0xff ,
2048- .tx_dif_p_nsec = 3000000 , /* unit: ns */
2049- .tx_dif_n_nsec = 1000000 , /* unit: ns */
2050- .tx_high_z_cnt_nsec = 20000 , /* unit: ns */
2051- .tx_base_unit_nsec = 100000 , /* unit: ns */
2052- .tx_gran_unit_nsec = 4000 , /* unit: ns */
2053- .tx_sleep_cnt = 1000 , /* unit: ns */
2054- .tx_min_activatetime = 0xa ,
2055- .rx_filler_enable = 0x2 ,
2056- .rx_dif_p_nsec = 1000000 , /* unit: ns */
2057- .rx_hibern8_wait_nsec = 4000000 , /* unit: ns */
2058- .rx_base_unit_nsec = 100000 , /* unit: ns */
2059- .rx_gran_unit_nsec = 4000 , /* unit: ns */
2060- .rx_sleep_cnt = 1280 , /* unit: ns */
2061- .rx_stall_cnt = 320 , /* unit: ns */
2062- .rx_hs_g1_sync_len_cap = SYNC_LEN_COARSE (0xf ),
2063- .rx_hs_g2_sync_len_cap = SYNC_LEN_COARSE (0xf ),
2064- .rx_hs_g3_sync_len_cap = SYNC_LEN_COARSE (0xf ),
2065- .rx_hs_g1_prep_sync_len_cap = PREP_LEN (0xf ),
2066- .rx_hs_g2_prep_sync_len_cap = PREP_LEN (0xf ),
2067- .rx_hs_g3_prep_sync_len_cap = PREP_LEN (0xf ),
20682079 .pa_dbg_opt_suite1_val = 0x90913C1C ,
20692080 .pa_dbg_opt_suite1_off = PA_GS101_DBG_OPTION_SUITE1 ,
20702081 .pa_dbg_opt_suite2_val = 0xE01C115F ,
@@ -2122,11 +2133,10 @@ static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
21222133 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
21232134 UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL |
21242135 UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING ,
2125- .opts = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
2126- EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
2136+ .opts = EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
21272137 EXYNOS_UFS_OPT_UFSPR_SECURE |
21282138 EXYNOS_UFS_OPT_TIMER_TICK_SELECT ,
2129- .drv_init = exynosauto_ufs_drv_init ,
2139+ .drv_init = gs101_ufs_drv_init ,
21302140 .pre_link = gs101_ufs_pre_link ,
21312141 .post_link = gs101_ufs_post_link ,
21322142 .pre_pwr_change = gs101_ufs_pre_pwr_change ,
0 commit comments