5050#define HCI_ERR_EN_N_LAYER 0x80
5151#define HCI_ERR_EN_T_LAYER 0x84
5252#define HCI_ERR_EN_DME_LAYER 0x88
53+ #define HCI_V2P1_CTRL 0x8C
54+ #define IA_TICK_SEL BIT(16)
5355#define HCI_CLKSTOP_CTRL 0xB0
5456#define REFCLKOUT_STOP BIT(4)
5557#define MPHY_APBCLK_STOP BIT(3)
5961#define CLK_STOP_MASK (REFCLKOUT_STOP | REFCLK_STOP |\
6062 UNIPRO_MCLK_STOP | MPHY_APBCLK_STOP|\
6163 UNIPRO_PCLK_STOP)
64+ /* HCI_MISC is also known as HCI_FORCE_HCS */
6265#define HCI_MISC 0xB4
6366#define REFCLK_CTRL_EN BIT(7)
6467#define UNIPRO_PCLK_CTRL_EN BIT(6)
@@ -136,6 +139,9 @@ enum {
136139/*
137140 * UNIPRO registers
138141 */
142+ #define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0 0x7888
143+ #define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1 0x788c
144+ #define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2 0x7890
139145#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0 0x78B8
140146#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1 0x78BC
141147#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2 0x78C0
@@ -306,8 +312,9 @@ static int exynosauto_ufs_post_pwr_change(struct exynos_ufs *ufs,
306312
307313static int exynos7_ufs_pre_link (struct exynos_ufs * ufs )
308314{
315+ struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
316+ u32 val = attr -> pa_dbg_opt_suite1_val ;
309317 struct ufs_hba * hba = ufs -> hba ;
310- u32 val = ufs -> drv_data -> uic_attr -> pa_dbg_option_suite ;
311318 int i ;
312319
313320 exynos_ufs_enable_ov_tm (hba );
@@ -324,12 +331,13 @@ static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
324331 UIC_ARG_MIB_SEL (TX_HIBERN8_CONTROL , i ), 0x0 );
325332 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_TXPHY_CFGUPDT ), 0x1 );
326333 udelay (1 );
327- ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_OPTION_SUITE ), val | (1 << 12 ));
334+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_opt_suite1_off ),
335+ val | (1 << 12 ));
328336 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_SKIP_RESET_PHY ), 0x1 );
329337 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_SKIP_LINE_RESET ), 0x1 );
330338 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_LINE_RESET_REQ ), 0x1 );
331339 udelay (1600 );
332- ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_OPTION_SUITE ), val );
340+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_opt_suite1_off ), val );
333341
334342 return 0 ;
335343}
@@ -921,14 +929,23 @@ static int exynos_ufs_phy_init(struct exynos_ufs *ufs)
921929
922930static void exynos_ufs_config_unipro (struct exynos_ufs * ufs )
923931{
932+ struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
924933 struct ufs_hba * hba = ufs -> hba ;
925934
926- ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_CLK_PERIOD ),
927- DIV_ROUND_UP (NSEC_PER_SEC , ufs -> mclk_rate ));
935+ if (attr -> pa_dbg_clk_period_off )
936+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_clk_period_off ),
937+ DIV_ROUND_UP (NSEC_PER_SEC , ufs -> mclk_rate ));
938+
928939 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_TXTRAILINGCLOCKS ),
929940 ufs -> drv_data -> uic_attr -> tx_trailingclks );
930- ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_OPTION_SUITE ),
931- ufs -> drv_data -> uic_attr -> pa_dbg_option_suite );
941+
942+ if (attr -> pa_dbg_opt_suite1_off )
943+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_opt_suite1_off ),
944+ attr -> pa_dbg_opt_suite1_val );
945+
946+ if (attr -> pa_dbg_opt_suite2_off )
947+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_opt_suite2_off ),
948+ attr -> pa_dbg_opt_suite2_val );
932949}
933950
934951static void exynos_ufs_config_intr (struct exynos_ufs * ufs , u32 errs , u8 index )
@@ -1005,6 +1022,13 @@ static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs)
10051022{
10061023 u32 val ;
10071024
1025+ /* Select function clock (mclk) for timer tick */
1026+ if (ufs -> opts & EXYNOS_UFS_OPT_TIMER_TICK_SELECT ) {
1027+ val = hci_readl (ufs , HCI_V2P1_CTRL );
1028+ val |= IA_TICK_SEL ;
1029+ hci_writel (ufs , val , HCI_V2P1_CTRL );
1030+ }
1031+
10081032 val = exynos_ufs_calc_time_cntr (ufs , IATOVAL_NSEC / CNTR_DIV_VAL );
10091033 hci_writel (ufs , val & CNT_VAL_1US_MASK , HCI_1US_TO_CNT_VAL );
10101034}
@@ -1186,7 +1210,8 @@ static int exynos_ufs_init(struct ufs_hba *hba)
11861210 if (ret )
11871211 goto out ;
11881212 exynos_ufs_specify_phy_time_attr (ufs );
1189- exynos_ufs_config_smu (ufs );
1213+ if (!(ufs -> opts & EXYNOS_UFS_OPT_UFSPR_SECURE ))
1214+ exynos_ufs_config_smu (ufs );
11901215
11911216 hba -> host -> dma_alignment = SZ_4K - 1 ;
11921217 return 0 ;
@@ -1477,10 +1502,11 @@ static int exynosauto_ufs_vh_init(struct ufs_hba *hba)
14771502
14781503static int fsd_ufs_pre_link (struct exynos_ufs * ufs )
14791504{
1480- int i ;
1505+ struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
14811506 struct ufs_hba * hba = ufs -> hba ;
1507+ int i ;
14821508
1483- ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_CLK_PERIOD ),
1509+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_clk_period_off ),
14841510 DIV_ROUND_UP (NSEC_PER_SEC , ufs -> mclk_rate ));
14851511 ufshcd_dme_set (hba , UIC_ARG_MIB (0x201 ), 0x12 );
14861512 ufshcd_dme_set (hba , UIC_ARG_MIB (0x200 ), 0x40 );
@@ -1504,7 +1530,9 @@ static int fsd_ufs_pre_link(struct exynos_ufs *ufs)
15041530
15051531 ufshcd_dme_set (hba , UIC_ARG_MIB (0x200 ), 0x0 );
15061532 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_AUTOMODE_THLD ), 0x4E20 );
1507- ufshcd_dme_set (hba , UIC_ARG_MIB (PA_DBG_OPTION_SUITE ), 0x2e820183 );
1533+
1534+ ufshcd_dme_set (hba , UIC_ARG_MIB (attr -> pa_dbg_opt_suite1_off ),
1535+ 0x2e820183 );
15081536 ufshcd_dme_set (hba , UIC_ARG_MIB (PA_LOCAL_TX_LCC_ENABLE ), 0x0 );
15091537
15101538 exynos_ufs_establish_connt (ufs );
@@ -1568,6 +1596,96 @@ static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
15681596 return 0 ;
15691597}
15701598
1599+ static inline u32 get_mclk_period_unipro_18 (struct exynos_ufs * ufs )
1600+ {
1601+ return (16 * 1000 * 1000000UL / ufs -> mclk_rate );
1602+ }
1603+
1604+ static int gs101_ufs_pre_link (struct exynos_ufs * ufs )
1605+ {
1606+ struct ufs_hba * hba = ufs -> hba ;
1607+ int i ;
1608+ u32 tx_line_reset_period , rx_line_reset_period ;
1609+
1610+ rx_line_reset_period = (RX_LINE_RESET_TIME * ufs -> mclk_rate )
1611+ / NSEC_PER_MSEC ;
1612+ tx_line_reset_period = (TX_LINE_RESET_TIME * ufs -> mclk_rate )
1613+ / NSEC_PER_MSEC ;
1614+
1615+ unipro_writel (ufs , get_mclk_period_unipro_18 (ufs ), COMP_CLK_PERIOD );
1616+
1617+ ufshcd_dme_set (hba , UIC_ARG_MIB (0x200 ), 0x40 );
1618+
1619+ for_each_ufs_rx_lane (ufs , i ) {
1620+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_RX_CLK_PRD , i ),
1621+ DIV_ROUND_UP (NSEC_PER_SEC , ufs -> mclk_rate ));
1622+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_RX_CLK_PRD_EN , i ), 0x0 );
1623+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_RX_LINERESET_VALUE2 , i ),
1624+ (rx_line_reset_period >> 16 ) & 0xFF );
1625+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_RX_LINERESET_VALUE1 , i ),
1626+ (rx_line_reset_period >> 8 ) & 0xFF );
1627+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_RX_LINERESET_VALUE0 , i ),
1628+ (rx_line_reset_period ) & 0xFF );
1629+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (0x2f , i ), 0x69 );
1630+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (0x84 , i ), 0x1 );
1631+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (0x25 , i ), 0xf6 );
1632+ }
1633+
1634+ for_each_ufs_tx_lane (ufs , i ) {
1635+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_TX_CLK_PRD , i ),
1636+ DIV_ROUND_UP (NSEC_PER_SEC , ufs -> mclk_rate ));
1637+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_TX_CLK_PRD_EN , i ),
1638+ 0x02 );
1639+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_TX_LINERESET_PVALUE2 , i ),
1640+ (tx_line_reset_period >> 16 ) & 0xFF );
1641+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_TX_LINERESET_PVALUE1 , i ),
1642+ (tx_line_reset_period >> 8 ) & 0xFF );
1643+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (VND_TX_LINERESET_PVALUE0 , i ),
1644+ (tx_line_reset_period ) & 0xFF );
1645+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (0x04 , i ), 1 );
1646+ ufshcd_dme_set (hba , UIC_ARG_MIB_SEL (0x7F , i ), 0 );
1647+ }
1648+
1649+ ufshcd_dme_set (hba , UIC_ARG_MIB (0x200 ), 0x0 );
1650+ ufshcd_dme_set (hba , UIC_ARG_MIB (PA_LOCAL_TX_LCC_ENABLE ), 0x0 );
1651+ ufshcd_dme_set (hba , UIC_ARG_MIB (N_DEVICEID ), 0x0 );
1652+ ufshcd_dme_set (hba , UIC_ARG_MIB (N_DEVICEID_VALID ), 0x1 );
1653+ ufshcd_dme_set (hba , UIC_ARG_MIB (T_PEERDEVICEID ), 0x1 );
1654+ ufshcd_dme_set (hba , UIC_ARG_MIB (T_CONNECTIONSTATE ), CPORT_CONNECTED );
1655+ ufshcd_dme_set (hba , UIC_ARG_MIB (0xA006 ), 0x8000 );
1656+
1657+ return 0 ;
1658+ }
1659+
1660+ static int gs101_ufs_post_link (struct exynos_ufs * ufs )
1661+ {
1662+ struct ufs_hba * hba = ufs -> hba ;
1663+
1664+ exynos_ufs_enable_dbg_mode (hba );
1665+ ufshcd_dme_set (hba , UIC_ARG_MIB (PA_SAVECONFIGTIME ), 0x3e8 );
1666+ exynos_ufs_disable_dbg_mode (hba );
1667+
1668+ return 0 ;
1669+ }
1670+
1671+ static int gs101_ufs_pre_pwr_change (struct exynos_ufs * ufs ,
1672+ struct ufs_pa_layer_attr * pwr )
1673+ {
1674+ struct ufs_hba * hba = ufs -> hba ;
1675+
1676+ ufshcd_dme_set (hba , UIC_ARG_MIB (PA_PWRMODEUSERDATA0 ), 12000 );
1677+ ufshcd_dme_set (hba , UIC_ARG_MIB (PA_PWRMODEUSERDATA1 ), 32000 );
1678+ ufshcd_dme_set (hba , UIC_ARG_MIB (PA_PWRMODEUSERDATA2 ), 16000 );
1679+ unipro_writel (ufs , 8064 , UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0 );
1680+ unipro_writel (ufs , 28224 , UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1 );
1681+ unipro_writel (ufs , 20160 , UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2 );
1682+ unipro_writel (ufs , 12000 , UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0 );
1683+ unipro_writel (ufs , 32000 , UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1 );
1684+ unipro_writel (ufs , 16000 , UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2 );
1685+
1686+ return 0 ;
1687+ }
1688+
15711689static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
15721690 .name = "exynos_ufs" ,
15731691 .init = exynos_ufs_init ,
@@ -1640,7 +1758,9 @@ static struct exynos_ufs_uic_attr exynos7_uic_attr = {
16401758 .rx_hs_g1_prep_sync_len_cap = PREP_LEN (0xf ),
16411759 .rx_hs_g2_prep_sync_len_cap = PREP_LEN (0xf ),
16421760 .rx_hs_g3_prep_sync_len_cap = PREP_LEN (0xf ),
1643- .pa_dbg_option_suite = 0x30103 ,
1761+ .pa_dbg_clk_period_off = PA_DBG_CLK_PERIOD ,
1762+ .pa_dbg_opt_suite1_val = 0x30103 ,
1763+ .pa_dbg_opt_suite1_off = PA_DBG_OPTION_SUITE ,
16441764};
16451765
16461766static const struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
@@ -1692,6 +1812,34 @@ static const struct exynos_ufs_drv_data exynos_ufs_drvs = {
16921812 .post_pwr_change = exynos7_ufs_post_pwr_change ,
16931813};
16941814
1815+ static struct exynos_ufs_uic_attr gs101_uic_attr = {
1816+ .tx_trailingclks = 0xff ,
1817+ .tx_dif_p_nsec = 3000000 , /* unit: ns */
1818+ .tx_dif_n_nsec = 1000000 , /* unit: ns */
1819+ .tx_high_z_cnt_nsec = 20000 , /* unit: ns */
1820+ .tx_base_unit_nsec = 100000 , /* unit: ns */
1821+ .tx_gran_unit_nsec = 4000 , /* unit: ns */
1822+ .tx_sleep_cnt = 1000 , /* unit: ns */
1823+ .tx_min_activatetime = 0xa ,
1824+ .rx_filler_enable = 0x2 ,
1825+ .rx_dif_p_nsec = 1000000 , /* unit: ns */
1826+ .rx_hibern8_wait_nsec = 4000000 , /* unit: ns */
1827+ .rx_base_unit_nsec = 100000 , /* unit: ns */
1828+ .rx_gran_unit_nsec = 4000 , /* unit: ns */
1829+ .rx_sleep_cnt = 1280 , /* unit: ns */
1830+ .rx_stall_cnt = 320 , /* unit: ns */
1831+ .rx_hs_g1_sync_len_cap = SYNC_LEN_COARSE (0xf ),
1832+ .rx_hs_g2_sync_len_cap = SYNC_LEN_COARSE (0xf ),
1833+ .rx_hs_g3_sync_len_cap = SYNC_LEN_COARSE (0xf ),
1834+ .rx_hs_g1_prep_sync_len_cap = PREP_LEN (0xf ),
1835+ .rx_hs_g2_prep_sync_len_cap = PREP_LEN (0xf ),
1836+ .rx_hs_g3_prep_sync_len_cap = PREP_LEN (0xf ),
1837+ .pa_dbg_opt_suite1_val = 0x90913C1C ,
1838+ .pa_dbg_opt_suite1_off = PA_GS101_DBG_OPTION_SUITE1 ,
1839+ .pa_dbg_opt_suite2_val = 0xE01C115F ,
1840+ .pa_dbg_opt_suite2_off = PA_GS101_DBG_OPTION_SUITE2 ,
1841+ };
1842+
16951843static struct exynos_ufs_uic_attr fsd_uic_attr = {
16961844 .tx_trailingclks = 0x10 ,
16971845 .tx_dif_p_nsec = 3000000 , /* unit: ns */
@@ -1714,7 +1862,9 @@ static struct exynos_ufs_uic_attr fsd_uic_attr = {
17141862 .rx_hs_g1_prep_sync_len_cap = PREP_LEN (0xf ),
17151863 .rx_hs_g2_prep_sync_len_cap = PREP_LEN (0xf ),
17161864 .rx_hs_g3_prep_sync_len_cap = PREP_LEN (0xf ),
1717- .pa_dbg_option_suite = 0x2E820183 ,
1865+ .pa_dbg_clk_period_off = PA_DBG_CLK_PERIOD ,
1866+ .pa_dbg_opt_suite1_val = 0x2E820183 ,
1867+ .pa_dbg_opt_suite1_off = PA_DBG_OPTION_SUITE ,
17181868};
17191869
17201870static const struct exynos_ufs_drv_data fsd_ufs_drvs = {
@@ -1733,7 +1883,27 @@ static const struct exynos_ufs_drv_data fsd_ufs_drvs = {
17331883 .pre_pwr_change = fsd_ufs_pre_pwr_change ,
17341884};
17351885
1886+ static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
1887+ .uic_attr = & gs101_uic_attr ,
1888+ .quirks = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
1889+ UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
1890+ UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
1891+ UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
1892+ UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL |
1893+ UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING ,
1894+ .opts = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
1895+ EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
1896+ EXYNOS_UFS_OPT_UFSPR_SECURE |
1897+ EXYNOS_UFS_OPT_TIMER_TICK_SELECT ,
1898+ .drv_init = exynosauto_ufs_drv_init ,
1899+ .pre_link = gs101_ufs_pre_link ,
1900+ .post_link = gs101_ufs_post_link ,
1901+ .pre_pwr_change = gs101_ufs_pre_pwr_change ,
1902+ };
1903+
17361904static const struct of_device_id exynos_ufs_of_match [] = {
1905+ { .compatible = "google,gs101-ufs" ,
1906+ .data = & gs101_ufs_drvs },
17371907 { .compatible = "samsung,exynos7-ufs" ,
17381908 .data = & exynos_ufs_drvs },
17391909 { .compatible = "samsung,exynosautov9-ufs" ,
0 commit comments