3434 * Exynos's Vendor specific registers for UFSHCI
3535 */
3636#define HCI_TXPRDT_ENTRY_SIZE 0x00
37- #define PRDT_PREFECT_EN BIT(31)
37+ #define PRDT_PREFETCH_EN BIT(31)
3838#define HCI_RXPRDT_ENTRY_SIZE 0x04
3939#define HCI_1US_TO_CNT_VAL 0x0C
4040#define CNT_VAL_1US_MASK 0x3FF
9292 UIC_TRANSPORT_NO_CONNECTION_RX |\
9393 UIC_TRANSPORT_BAD_TC)
9494
95- /* FSYS UFS Shareability */
96- #define UFS_WR_SHARABLE BIT(2)
97- #define UFS_RD_SHARABLE BIT(1)
98- #define UFS_SHARABLE (UFS_WR_SHARABLE | UFS_RD_SHARABLE)
99- #define UFS_SHAREABILITY_OFFSET 0x710
95+ /* UFS Shareability */
96+ #define UFS_EXYNOSAUTO_WR_SHARABLE BIT(2)
97+ #define UFS_EXYNOSAUTO_RD_SHARABLE BIT(1)
98+ #define UFS_EXYNOSAUTO_SHARABLE (UFS_EXYNOSAUTO_WR_SHARABLE | \
99+ UFS_EXYNOSAUTO_RD_SHARABLE)
100+ #define UFS_GS101_WR_SHARABLE BIT(1)
101+ #define UFS_GS101_RD_SHARABLE BIT(0)
102+ #define UFS_GS101_SHARABLE (UFS_GS101_WR_SHARABLE | \
103+ UFS_GS101_RD_SHARABLE)
104+ #define UFS_SHAREABILITY_OFFSET 0x710
100105
101106/* Multi-host registers */
102107#define MHCTRL 0xC4
@@ -209,8 +214,8 @@ static int exynos_ufs_shareability(struct exynos_ufs *ufs)
209214 /* IO Coherency setting */
210215 if (ufs -> sysreg ) {
211216 return regmap_update_bits (ufs -> sysreg ,
212- ufs -> shareability_reg_offset ,
213- UFS_SHARABLE , UFS_SHARABLE );
217+ ufs -> iocc_offset ,
218+ ufs -> iocc_mask , ufs -> iocc_val );
214219 }
215220
216221 return 0 ;
@@ -957,6 +962,12 @@ static int exynos_ufs_phy_init(struct exynos_ufs *ufs)
957962 }
958963
959964 phy_set_bus_width (generic_phy , ufs -> avail_ln_rx );
965+
966+ if (generic_phy -> power_count ) {
967+ phy_power_off (generic_phy );
968+ phy_exit (generic_phy );
969+ }
970+
960971 ret = phy_init (generic_phy );
961972 if (ret ) {
962973 dev_err (hba -> dev , "%s: phy init failed, ret = %d\n" ,
@@ -1049,21 +1060,21 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba)
10491060 exynos_ufs_config_intr (ufs , DFES_DEF_L4_ERRS , UNIPRO_L4 );
10501061 exynos_ufs_set_unipro_pclk_div (ufs );
10511062
1063+ exynos_ufs_setup_clocks (hba , true, PRE_CHANGE );
1064+
10521065 /* unipro */
10531066 exynos_ufs_config_unipro (ufs );
10541067
1068+ if (ufs -> drv_data -> pre_link )
1069+ ufs -> drv_data -> pre_link (ufs );
1070+
10551071 /* m-phy */
10561072 exynos_ufs_phy_init (ufs );
10571073 if (!(ufs -> opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR )) {
10581074 exynos_ufs_config_phy_time_attr (ufs );
10591075 exynos_ufs_config_phy_cap_attr (ufs );
10601076 }
10611077
1062- exynos_ufs_setup_clocks (hba , true, PRE_CHANGE );
1063-
1064- if (ufs -> drv_data -> pre_link )
1065- ufs -> drv_data -> pre_link (ufs );
1066-
10671078 return 0 ;
10681079}
10691080
@@ -1087,12 +1098,17 @@ static int exynos_ufs_post_link(struct ufs_hba *hba)
10871098 struct exynos_ufs * ufs = ufshcd_get_variant (hba );
10881099 struct phy * generic_phy = ufs -> phy ;
10891100 struct exynos_ufs_uic_attr * attr = ufs -> drv_data -> uic_attr ;
1101+ u32 val = ilog2 (DATA_UNIT_SIZE );
10901102
10911103 exynos_ufs_establish_connt (ufs );
10921104 exynos_ufs_fit_aggr_timeout (ufs );
10931105
10941106 hci_writel (ufs , 0xa , HCI_DATA_REORDER );
1095- hci_writel (ufs , ilog2 (DATA_UNIT_SIZE ), HCI_TXPRDT_ENTRY_SIZE );
1107+
1108+ if (hba -> caps & UFSHCD_CAP_CRYPTO )
1109+ val |= PRDT_PREFETCH_EN ;
1110+ hci_writel (ufs , val , HCI_TXPRDT_ENTRY_SIZE );
1111+
10961112 hci_writel (ufs , ilog2 (DATA_UNIT_SIZE ), HCI_RXPRDT_ENTRY_SIZE );
10971113 hci_writel (ufs , (1 << hba -> nutrs ) - 1 , HCI_UTRL_NEXUS_TYPE );
10981114 hci_writel (ufs , (1 << hba -> nutmrs ) - 1 , HCI_UTMRL_NEXUS_TYPE );
@@ -1168,12 +1184,22 @@ static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs)
11681184 ufs -> sysreg = NULL ;
11691185 else {
11701186 if (of_property_read_u32_index (np , "samsung,sysreg" , 1 ,
1171- & ufs -> shareability_reg_offset )) {
1187+ & ufs -> iocc_offset )) {
11721188 dev_warn (dev , "can't get an offset from sysreg. Set to default value\n" );
1173- ufs -> shareability_reg_offset = UFS_SHAREABILITY_OFFSET ;
1189+ ufs -> iocc_offset = UFS_SHAREABILITY_OFFSET ;
11741190 }
11751191 }
11761192
1193+ ufs -> iocc_mask = ufs -> drv_data -> iocc_mask ;
1194+ /*
1195+ * no 'dma-coherent' property means the descriptors are
1196+ * non-cacheable so iocc shareability should be disabled.
1197+ */
1198+ if (of_dma_is_coherent (dev -> of_node ))
1199+ ufs -> iocc_val = ufs -> iocc_mask ;
1200+ else
1201+ ufs -> iocc_val = 0 ;
1202+
11771203 ufs -> pclk_avail_min = PCLK_AVAIL_MIN ;
11781204 ufs -> pclk_avail_max = PCLK_AVAIL_MAX ;
11791205
@@ -1496,6 +1522,14 @@ static int exynos_ufs_init(struct ufs_hba *hba)
14961522 return ret ;
14971523}
14981524
1525+ static void exynos_ufs_exit (struct ufs_hba * hba )
1526+ {
1527+ struct exynos_ufs * ufs = ufshcd_get_variant (hba );
1528+
1529+ phy_power_off (ufs -> phy );
1530+ phy_exit (ufs -> phy );
1531+ }
1532+
14991533static int exynos_ufs_host_reset (struct ufs_hba * hba )
15001534{
15011535 struct exynos_ufs * ufs = ufshcd_get_variant (hba );
@@ -1666,6 +1700,12 @@ static void exynos_ufs_hibern8_notify(struct ufs_hba *hba,
16661700 }
16671701}
16681702
1703+ static int gs101_ufs_suspend (struct exynos_ufs * ufs )
1704+ {
1705+ hci_writel (ufs , 0 << 0 , HCI_GPIO_OUT );
1706+ return 0 ;
1707+ }
1708+
16691709static int exynos_ufs_suspend (struct ufs_hba * hba , enum ufs_pm_op pm_op ,
16701710 enum ufs_notify_change_status status )
16711711{
@@ -1674,6 +1714,9 @@ static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
16741714 if (status == PRE_CHANGE )
16751715 return 0 ;
16761716
1717+ if (ufs -> drv_data -> suspend )
1718+ ufs -> drv_data -> suspend (ufs );
1719+
16771720 if (!ufshcd_is_link_active (hba ))
16781721 phy_power_off (ufs -> phy );
16791722
@@ -1951,6 +1994,7 @@ static int gs101_ufs_pre_pwr_change(struct exynos_ufs *ufs,
19511994static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
19521995 .name = "exynos_ufs" ,
19531996 .init = exynos_ufs_init ,
1997+ .exit = exynos_ufs_exit ,
19541998 .hce_enable_notify = exynos_ufs_hce_enable_notify ,
19551999 .link_startup_notify = exynos_ufs_link_startup_notify ,
19562000 .pwr_change_notify = exynos_ufs_pwr_change_notify ,
@@ -1989,13 +2033,7 @@ static int exynos_ufs_probe(struct platform_device *pdev)
19892033
19902034static void exynos_ufs_remove (struct platform_device * pdev )
19912035{
1992- struct ufs_hba * hba = platform_get_drvdata (pdev );
1993- struct exynos_ufs * ufs = ufshcd_get_variant (hba );
1994-
19952036 ufshcd_pltfrm_remove (pdev );
1996-
1997- phy_power_off (ufs -> phy );
1998- phy_exit (ufs -> phy );
19992037}
20002038
20012039static struct exynos_ufs_uic_attr exynos7_uic_attr = {
@@ -2034,6 +2072,7 @@ static const struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
20342072 .opts = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
20352073 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
20362074 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX ,
2075+ .iocc_mask = UFS_EXYNOSAUTO_SHARABLE ,
20372076 .drv_init = exynosauto_ufs_drv_init ,
20382077 .post_hce_enable = exynosauto_ufs_post_hce_enable ,
20392078 .pre_link = exynosauto_ufs_pre_link ,
@@ -2135,10 +2174,12 @@ static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
21352174 .opts = EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
21362175 EXYNOS_UFS_OPT_UFSPR_SECURE |
21372176 EXYNOS_UFS_OPT_TIMER_TICK_SELECT ,
2177+ .iocc_mask = UFS_GS101_SHARABLE ,
21382178 .drv_init = gs101_ufs_drv_init ,
21392179 .pre_link = gs101_ufs_pre_link ,
21402180 .post_link = gs101_ufs_post_link ,
21412181 .pre_pwr_change = gs101_ufs_pre_pwr_change ,
2182+ .suspend = gs101_ufs_suspend ,
21422183};
21432184
21442185static const struct of_device_id exynos_ufs_of_match [] = {
0 commit comments