Lines Matching full:ufs

3  * UFS Host Controller driver for Exynos specific extensions
24 #include <ufs/ufshcd.h>
26 #include <ufs/ufshci.h>
27 #include <ufs/unipro.h>
29 #include "ufs-exynos.h"
95 /* UFS Shareability */
165 * UFS Protector registers
176 static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en);
177 static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en);
179 static inline void exynos_ufs_enable_auto_ctrl_hcc(struct exynos_ufs *ufs) in exynos_ufs_enable_auto_ctrl_hcc() argument
181 exynos_ufs_auto_ctrl_hcc(ufs, true); in exynos_ufs_enable_auto_ctrl_hcc()
184 static inline void exynos_ufs_disable_auto_ctrl_hcc(struct exynos_ufs *ufs) in exynos_ufs_disable_auto_ctrl_hcc() argument
186 exynos_ufs_auto_ctrl_hcc(ufs, false); in exynos_ufs_disable_auto_ctrl_hcc()
190 struct exynos_ufs *ufs, u32 *val) in exynos_ufs_disable_auto_ctrl_hcc_save() argument
192 *val = hci_readl(ufs, HCI_MISC); in exynos_ufs_disable_auto_ctrl_hcc_save()
193 exynos_ufs_auto_ctrl_hcc(ufs, false); in exynos_ufs_disable_auto_ctrl_hcc_save()
197 struct exynos_ufs *ufs, u32 *val) in exynos_ufs_auto_ctrl_hcc_restore() argument
199 hci_writel(ufs, *val, HCI_MISC); in exynos_ufs_auto_ctrl_hcc_restore()
202 static inline void exynos_ufs_gate_clks(struct exynos_ufs *ufs) in exynos_ufs_gate_clks() argument
204 exynos_ufs_ctrl_clkstop(ufs, true); in exynos_ufs_gate_clks()
207 static inline void exynos_ufs_ungate_clks(struct exynos_ufs *ufs) in exynos_ufs_ungate_clks() argument
209 exynos_ufs_ctrl_clkstop(ufs, false); in exynos_ufs_ungate_clks()
212 static int exynos_ufs_shareability(struct exynos_ufs *ufs) in exynos_ufs_shareability() argument
215 if (ufs->sysreg) { in exynos_ufs_shareability()
216 return regmap_update_bits(ufs->sysreg, in exynos_ufs_shareability()
217 ufs->iocc_offset, in exynos_ufs_shareability()
218 ufs->iocc_mask, ufs->iocc_val); in exynos_ufs_shareability()
224 static int gs101_ufs_drv_init(struct exynos_ufs *ufs) in gs101_ufs_drv_init() argument
226 struct ufs_hba *hba = ufs->hba; in gs101_ufs_drv_init()
236 reg = hci_readl(ufs, HCI_IOP_ACG_DISABLE); in gs101_ufs_drv_init()
237 hci_writel(ufs, reg & (~HCI_IOP_ACG_DISABLE_EN), HCI_IOP_ACG_DISABLE); in gs101_ufs_drv_init()
239 return exynos_ufs_shareability(ufs); in gs101_ufs_drv_init()
242 static int exynosauto_ufs_drv_init(struct exynos_ufs *ufs) in exynosauto_ufs_drv_init() argument
244 return exynos_ufs_shareability(ufs); in exynosauto_ufs_drv_init()
247 static int exynosauto_ufs_post_hce_enable(struct exynos_ufs *ufs) in exynosauto_ufs_post_hce_enable() argument
249 struct ufs_hba *hba = ufs->hba; in exynosauto_ufs_post_hce_enable()
254 hci_writel(ufs, ALLOW_TRANS_VH_DEFAULT, HCI_MH_ALLOWABLE_TRAN_OF_VH); in exynosauto_ufs_post_hce_enable()
256 hci_writel(ufs, 0x1, HCI_MH_IID_IN_TASK_TAG); in exynosauto_ufs_post_hce_enable()
261 static int exynosauto_ufs_pre_link(struct exynos_ufs *ufs) in exynosauto_ufs_pre_link() argument
263 struct ufs_hba *hba = ufs->hba; in exynosauto_ufs_pre_link()
267 rx_line_reset_period = (RX_LINE_RESET_TIME * ufs->mclk_rate) / NSEC_PER_MSEC; in exynosauto_ufs_pre_link()
268 tx_line_reset_period = (TX_LINE_RESET_TIME * ufs->mclk_rate) / NSEC_PER_MSEC; in exynosauto_ufs_pre_link()
271 for_each_ufs_rx_lane(ufs, i) { in exynosauto_ufs_pre_link()
273 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in exynosauto_ufs_pre_link()
288 for_each_ufs_tx_lane(ufs, i) { in exynosauto_ufs_pre_link()
290 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in exynosauto_ufs_pre_link()
315 static int exynosauto_ufs_pre_pwr_change(struct exynos_ufs *ufs, in exynosauto_ufs_pre_pwr_change() argument
318 struct ufs_hba *hba = ufs->hba; in exynosauto_ufs_pre_pwr_change()
328 static int exynosauto_ufs_post_pwr_change(struct exynos_ufs *ufs, in exynosauto_ufs_post_pwr_change() argument
331 struct ufs_hba *hba = ufs->hba; in exynosauto_ufs_post_pwr_change()
342 static int exynos7_ufs_pre_link(struct exynos_ufs *ufs) in exynos7_ufs_pre_link() argument
344 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos7_ufs_pre_link()
346 struct ufs_hba *hba = ufs->hba; in exynos7_ufs_pre_link()
350 for_each_ufs_tx_lane(ufs, i) in exynos7_ufs_pre_link()
352 for_each_ufs_rx_lane(ufs, i) { in exynos7_ufs_pre_link()
358 for_each_ufs_tx_lane(ufs, i) in exynos7_ufs_pre_link()
374 static int exynos7_ufs_post_link(struct exynos_ufs *ufs) in exynos7_ufs_post_link() argument
376 struct ufs_hba *hba = ufs->hba; in exynos7_ufs_post_link()
380 for_each_ufs_tx_lane(ufs, i) { in exynos7_ufs_post_link()
384 TX_LINERESET_N(exynos_ufs_calc_time_cntr(ufs, 200000))); in exynos7_ufs_post_link()
395 static int exynos7_ufs_pre_pwr_change(struct exynos_ufs *ufs, in exynos7_ufs_pre_pwr_change() argument
398 unipro_writel(ufs, 0x22, UNIPRO_DBG_FORCE_DME_CTRL_STATE); in exynos7_ufs_pre_pwr_change()
403 static int exynos7_ufs_post_pwr_change(struct exynos_ufs *ufs, in exynos7_ufs_post_pwr_change() argument
406 struct ufs_hba *hba = ufs->hba; in exynos7_ufs_post_pwr_change()
424 * - Access to UFS protector's register
426 static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en) in exynos_ufs_auto_ctrl_hcc() argument
428 u32 misc = hci_readl(ufs, HCI_MISC); in exynos_ufs_auto_ctrl_hcc()
431 hci_writel(ufs, misc | HCI_CORECLK_CTRL_EN, HCI_MISC); in exynos_ufs_auto_ctrl_hcc()
433 hci_writel(ufs, misc & ~HCI_CORECLK_CTRL_EN, HCI_MISC); in exynos_ufs_auto_ctrl_hcc()
436 static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en) in exynos_ufs_ctrl_clkstop() argument
438 u32 ctrl = hci_readl(ufs, HCI_CLKSTOP_CTRL); in exynos_ufs_ctrl_clkstop()
439 u32 misc = hci_readl(ufs, HCI_MISC); in exynos_ufs_ctrl_clkstop()
442 hci_writel(ufs, misc | CLK_CTRL_EN_MASK, HCI_MISC); in exynos_ufs_ctrl_clkstop()
443 hci_writel(ufs, ctrl | CLK_STOP_MASK, HCI_CLKSTOP_CTRL); in exynos_ufs_ctrl_clkstop()
445 hci_writel(ufs, ctrl & ~CLK_STOP_MASK, HCI_CLKSTOP_CTRL); in exynos_ufs_ctrl_clkstop()
446 hci_writel(ufs, misc & ~CLK_CTRL_EN_MASK, HCI_MISC); in exynos_ufs_ctrl_clkstop()
450 static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs) in exynos_ufs_get_clk_info() argument
452 struct ufs_hba *hba = ufs->hba; in exynos_ufs_get_clk_info()
466 ufs->clk_hci_core = clki->clk; in exynos_ufs_get_clk_info()
468 ufs->clk_unipro_main = clki->clk; in exynos_ufs_get_clk_info()
472 if (!ufs->clk_hci_core || !ufs->clk_unipro_main) { in exynos_ufs_get_clk_info()
478 ufs->mclk_rate = clk_get_rate(ufs->clk_unipro_main); in exynos_ufs_get_clk_info()
479 pclk_rate = clk_get_rate(ufs->clk_hci_core); in exynos_ufs_get_clk_info()
480 f_min = ufs->pclk_avail_min; in exynos_ufs_get_clk_info()
481 f_max = ufs->pclk_avail_max; in exynos_ufs_get_clk_info()
483 if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) { in exynos_ufs_get_clk_info()
499 ufs->pclk_rate = pclk_rate; in exynos_ufs_get_clk_info()
500 ufs->pclk_div = div; in exynos_ufs_get_clk_info()
506 static void exynos_ufs_set_unipro_pclk_div(struct exynos_ufs *ufs) in exynos_ufs_set_unipro_pclk_div() argument
508 if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) { in exynos_ufs_set_unipro_pclk_div()
511 val = hci_readl(ufs, HCI_UNIPRO_APB_CLK_CTRL); in exynos_ufs_set_unipro_pclk_div()
512 hci_writel(ufs, UNIPRO_APB_CLK(val, ufs->pclk_div), in exynos_ufs_set_unipro_pclk_div()
517 static void exynos_ufs_set_pwm_clk_div(struct exynos_ufs *ufs) in exynos_ufs_set_pwm_clk_div() argument
519 struct ufs_hba *hba = ufs->hba; in exynos_ufs_set_pwm_clk_div()
520 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_set_pwm_clk_div()
526 static void exynos_ufs_calc_pwm_clk_div(struct exynos_ufs *ufs) in exynos_ufs_calc_pwm_clk_div() argument
528 struct ufs_hba *hba = ufs->hba; in exynos_ufs_calc_pwm_clk_div()
529 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_calc_pwm_clk_div()
537 clk_period = UNIPRO_PCLK_PERIOD(ufs); in exynos_ufs_calc_pwm_clk_div()
557 long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period) in exynos_ufs_calc_time_cntr() argument
560 long pclk_rate = ufs->pclk_rate; in exynos_ufs_calc_time_cntr()
563 clk_period = UNIPRO_PCLK_PERIOD(ufs); in exynos_ufs_calc_time_cntr()
569 static void exynos_ufs_specify_phy_time_attr(struct exynos_ufs *ufs) in exynos_ufs_specify_phy_time_attr() argument
571 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_specify_phy_time_attr()
572 struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg; in exynos_ufs_specify_phy_time_attr()
574 if (ufs->opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR) in exynos_ufs_specify_phy_time_attr()
578 exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_p_nsec); in exynos_ufs_specify_phy_time_attr()
580 exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_n_nsec); in exynos_ufs_specify_phy_time_attr()
582 exynos_ufs_calc_time_cntr(ufs, attr->tx_high_z_cnt_nsec); in exynos_ufs_specify_phy_time_attr()
584 exynos_ufs_calc_time_cntr(ufs, attr->tx_base_unit_nsec); in exynos_ufs_specify_phy_time_attr()
586 exynos_ufs_calc_time_cntr(ufs, attr->tx_gran_unit_nsec); in exynos_ufs_specify_phy_time_attr()
588 exynos_ufs_calc_time_cntr(ufs, attr->tx_sleep_cnt); in exynos_ufs_specify_phy_time_attr()
591 exynos_ufs_calc_time_cntr(ufs, attr->rx_dif_p_nsec); in exynos_ufs_specify_phy_time_attr()
593 exynos_ufs_calc_time_cntr(ufs, attr->rx_hibern8_wait_nsec); in exynos_ufs_specify_phy_time_attr()
595 exynos_ufs_calc_time_cntr(ufs, attr->rx_base_unit_nsec); in exynos_ufs_specify_phy_time_attr()
597 exynos_ufs_calc_time_cntr(ufs, attr->rx_gran_unit_nsec); in exynos_ufs_specify_phy_time_attr()
599 exynos_ufs_calc_time_cntr(ufs, attr->rx_sleep_cnt); in exynos_ufs_specify_phy_time_attr()
601 exynos_ufs_calc_time_cntr(ufs, attr->rx_stall_cnt); in exynos_ufs_specify_phy_time_attr()
604 static void exynos_ufs_config_phy_time_attr(struct exynos_ufs *ufs) in exynos_ufs_config_phy_time_attr() argument
606 struct ufs_hba *hba = ufs->hba; in exynos_ufs_config_phy_time_attr()
607 struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg; in exynos_ufs_config_phy_time_attr()
610 exynos_ufs_set_pwm_clk_div(ufs); in exynos_ufs_config_phy_time_attr()
614 for_each_ufs_rx_lane(ufs, i) { in exynos_ufs_config_phy_time_attr()
616 ufs->drv_data->uic_attr->rx_filler_enable); in exynos_ufs_config_phy_time_attr()
633 for_each_ufs_tx_lane(ufs, i) { in exynos_ufs_config_phy_time_attr()
652 ufs->drv_data->uic_attr->tx_min_activatetime); in exynos_ufs_config_phy_time_attr()
658 static void exynos_ufs_config_phy_cap_attr(struct exynos_ufs *ufs) in exynos_ufs_config_phy_cap_attr() argument
660 struct ufs_hba *hba = ufs->hba; in exynos_ufs_config_phy_cap_attr()
661 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_config_phy_cap_attr()
666 for_each_ufs_rx_lane(ufs, i) { in exynos_ufs_config_phy_cap_attr()
688 for_each_ufs_rx_lane(ufs, i) { in exynos_ufs_config_phy_cap_attr()
704 for_each_ufs_rx_lane(ufs, i) { in exynos_ufs_config_phy_cap_attr()
728 static void exynos_ufs_establish_connt(struct exynos_ufs *ufs) in exynos_ufs_establish_connt() argument
730 struct ufs_hba *hba = ufs->hba; in exynos_ufs_establish_connt()
751 static void exynos_ufs_config_smu(struct exynos_ufs *ufs) in exynos_ufs_config_smu() argument
755 if (ufs->opts & EXYNOS_UFS_OPT_UFSPR_SECURE) in exynos_ufs_config_smu()
758 exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val); in exynos_ufs_config_smu()
761 reg = ufsp_readl(ufs, UFSPRSECURITY); in exynos_ufs_config_smu()
762 ufsp_writel(ufs, reg | NSSMU, UFSPRSECURITY); in exynos_ufs_config_smu()
763 ufsp_writel(ufs, 0x0, UFSPSBEGIN0); in exynos_ufs_config_smu()
764 ufsp_writel(ufs, 0xffffffff, UFSPSEND0); in exynos_ufs_config_smu()
765 ufsp_writel(ufs, 0xff, UFSPSLUN0); in exynos_ufs_config_smu()
766 ufsp_writel(ufs, 0xf1, UFSPSCTRL0); in exynos_ufs_config_smu()
768 exynos_ufs_auto_ctrl_hcc_restore(ufs, &val); in exynos_ufs_config_smu()
771 static void exynos_ufs_config_sync_pattern_mask(struct exynos_ufs *ufs, in exynos_ufs_config_sync_pattern_mask() argument
774 struct ufs_hba *hba = ufs->hba; in exynos_ufs_config_sync_pattern_mask()
793 mask = exynos_ufs_calc_time_cntr(ufs, sync_len); in exynos_ufs_config_sync_pattern_mask()
798 for_each_ufs_rx_lane(ufs, i) in exynos_ufs_config_sync_pattern_mask()
824 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_pre_pwr_mode() local
825 struct phy *generic_phy = ufs->phy; in exynos_ufs_pre_pwr_mode()
847 if (ufs->drv_data->pre_pwr_change) in exynos_ufs_pre_pwr_mode()
848 ufs->drv_data->pre_pwr_change(ufs, dev_req_params); in exynos_ufs_pre_pwr_mode()
851 exynos_ufs_config_sync_pattern_mask(ufs, dev_req_params); in exynos_ufs_pre_pwr_mode()
875 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_post_pwr_mode() local
876 struct phy *generic_phy = ufs->phy; in exynos_ufs_post_pwr_mode()
888 if (ufs->drv_data->post_pwr_change) in exynos_ufs_post_pwr_mode()
889 ufs->drv_data->post_pwr_change(ufs, pwr_req); in exynos_ufs_post_pwr_mode()
915 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_specify_nexus_t_xfer_req() local
918 type = hci_readl(ufs, HCI_UTRL_NEXUS_TYPE); in exynos_ufs_specify_nexus_t_xfer_req()
921 hci_writel(ufs, type | (1 << tag), HCI_UTRL_NEXUS_TYPE); in exynos_ufs_specify_nexus_t_xfer_req()
923 hci_writel(ufs, type & ~(1 << tag), HCI_UTRL_NEXUS_TYPE); in exynos_ufs_specify_nexus_t_xfer_req()
929 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_specify_nexus_t_tm_req() local
932 type = hci_readl(ufs, HCI_UTMRL_NEXUS_TYPE); in exynos_ufs_specify_nexus_t_tm_req()
937 hci_writel(ufs, type | (1 << tag), HCI_UTMRL_NEXUS_TYPE); in exynos_ufs_specify_nexus_t_tm_req()
943 hci_writel(ufs, type & ~(1 << tag), HCI_UTMRL_NEXUS_TYPE); in exynos_ufs_specify_nexus_t_tm_req()
948 static int exynos_ufs_phy_init(struct exynos_ufs *ufs) in exynos_ufs_phy_init() argument
950 struct ufs_hba *hba = ufs->hba; in exynos_ufs_phy_init()
951 struct phy *generic_phy = ufs->phy; in exynos_ufs_phy_init()
954 if (ufs->avail_ln_rx == 0 || ufs->avail_ln_tx == 0) { in exynos_ufs_phy_init()
956 &ufs->avail_ln_rx); in exynos_ufs_phy_init()
958 &ufs->avail_ln_tx); in exynos_ufs_phy_init()
959 WARN(ufs->avail_ln_rx != ufs->avail_ln_tx, in exynos_ufs_phy_init()
961 ufs->avail_ln_rx, ufs->avail_ln_tx); in exynos_ufs_phy_init()
964 phy_set_bus_width(generic_phy, ufs->avail_ln_rx); in exynos_ufs_phy_init()
990 static void exynos_ufs_config_unipro(struct exynos_ufs *ufs) in exynos_ufs_config_unipro() argument
992 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_config_unipro()
993 struct ufs_hba *hba = ufs->hba; in exynos_ufs_config_unipro()
997 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in exynos_ufs_config_unipro()
1000 ufs->drv_data->uic_attr->tx_trailingclks); in exynos_ufs_config_unipro()
1011 static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index) in exynos_ufs_config_intr() argument
1015 hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_PA_LAYER); in exynos_ufs_config_intr()
1018 hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DL_LAYER); in exynos_ufs_config_intr()
1021 hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_N_LAYER); in exynos_ufs_config_intr()
1024 hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_T_LAYER); in exynos_ufs_config_intr()
1027 hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DME_LAYER); in exynos_ufs_config_intr()
1035 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_setup_clocks() local
1037 if (!ufs) in exynos_ufs_setup_clocks()
1041 if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) in exynos_ufs_setup_clocks()
1042 exynos_ufs_disable_auto_ctrl_hcc(ufs); in exynos_ufs_setup_clocks()
1043 exynos_ufs_ungate_clks(ufs); in exynos_ufs_setup_clocks()
1045 exynos_ufs_gate_clks(ufs); in exynos_ufs_setup_clocks()
1046 if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) in exynos_ufs_setup_clocks()
1047 exynos_ufs_enable_auto_ctrl_hcc(ufs); in exynos_ufs_setup_clocks()
1055 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_pre_link() local
1058 exynos_ufs_config_intr(ufs, DFES_DEF_L2_ERRS, UNIPRO_L2); in exynos_ufs_pre_link()
1059 exynos_ufs_config_intr(ufs, DFES_DEF_L3_ERRS, UNIPRO_L3); in exynos_ufs_pre_link()
1060 exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4); in exynos_ufs_pre_link()
1061 exynos_ufs_set_unipro_pclk_div(ufs); in exynos_ufs_pre_link()
1064 exynos_ufs_config_unipro(ufs); in exynos_ufs_pre_link()
1067 exynos_ufs_phy_init(ufs); in exynos_ufs_pre_link()
1068 if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR)) { in exynos_ufs_pre_link()
1069 exynos_ufs_config_phy_time_attr(ufs); in exynos_ufs_pre_link()
1070 exynos_ufs_config_phy_cap_attr(ufs); in exynos_ufs_pre_link()
1075 if (ufs->drv_data->pre_link) in exynos_ufs_pre_link()
1076 ufs->drv_data->pre_link(ufs); in exynos_ufs_pre_link()
1081 static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs) in exynos_ufs_fit_aggr_timeout() argument
1086 if (ufs->opts & EXYNOS_UFS_OPT_TIMER_TICK_SELECT) { in exynos_ufs_fit_aggr_timeout()
1087 val = hci_readl(ufs, HCI_V2P1_CTRL); in exynos_ufs_fit_aggr_timeout()
1089 hci_writel(ufs, val, HCI_V2P1_CTRL); in exynos_ufs_fit_aggr_timeout()
1092 val = exynos_ufs_calc_time_cntr(ufs, IATOVAL_NSEC / CNTR_DIV_VAL); in exynos_ufs_fit_aggr_timeout()
1093 hci_writel(ufs, val & CNT_VAL_1US_MASK, HCI_1US_TO_CNT_VAL); in exynos_ufs_fit_aggr_timeout()
1098 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_post_link() local
1099 struct phy *generic_phy = ufs->phy; in exynos_ufs_post_link()
1100 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_post_link()
1102 exynos_ufs_establish_connt(ufs); in exynos_ufs_post_link()
1103 exynos_ufs_fit_aggr_timeout(ufs); in exynos_ufs_post_link()
1105 hci_writel(ufs, 0xa, HCI_DATA_REORDER); in exynos_ufs_post_link()
1106 hci_writel(ufs, ilog2(DATA_UNIT_SIZE), HCI_TXPRDT_ENTRY_SIZE); in exynos_ufs_post_link()
1107 hci_writel(ufs, ilog2(DATA_UNIT_SIZE), HCI_RXPRDT_ENTRY_SIZE); in exynos_ufs_post_link()
1108 hci_writel(ufs, (1 << hba->nutrs) - 1, HCI_UTRL_NEXUS_TYPE); in exynos_ufs_post_link()
1109 hci_writel(ufs, (1 << hba->nutmrs) - 1, HCI_UTMRL_NEXUS_TYPE); in exynos_ufs_post_link()
1110 hci_writel(ufs, 0xf, HCI_AXIDMA_RWDATA_BURST_LEN); in exynos_ufs_post_link()
1112 if (ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB) in exynos_ufs_post_link()
1126 !(ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER)) in exynos_ufs_post_link()
1131 if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) { in exynos_ufs_post_link()
1155 if (ufs->drv_data->post_link) in exynos_ufs_post_link()
1156 ufs->drv_data->post_link(ufs); in exynos_ufs_post_link()
1161 static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs) in exynos_ufs_parse_dt() argument
1167 ufs->drv_data = device_get_match_data(dev); in exynos_ufs_parse_dt()
1169 if (ufs->drv_data && ufs->drv_data->uic_attr) { in exynos_ufs_parse_dt()
1170 attr = ufs->drv_data->uic_attr; in exynos_ufs_parse_dt()
1177 ufs->sysreg = syscon_regmap_lookup_by_phandle(np, "samsung,sysreg"); in exynos_ufs_parse_dt()
1178 if (IS_ERR(ufs->sysreg)) in exynos_ufs_parse_dt()
1179 ufs->sysreg = NULL; in exynos_ufs_parse_dt()
1182 &ufs->iocc_offset)) { in exynos_ufs_parse_dt()
1184 ufs->iocc_offset = UFS_SHAREABILITY_OFFSET; in exynos_ufs_parse_dt()
1188 ufs->iocc_mask = ufs->drv_data->iocc_mask; in exynos_ufs_parse_dt()
1194 ufs->iocc_val = ufs->iocc_mask; in exynos_ufs_parse_dt()
1196 ufs->iocc_val = 0; in exynos_ufs_parse_dt()
1198 ufs->pclk_avail_min = PCLK_AVAIL_MIN; in exynos_ufs_parse_dt()
1199 ufs->pclk_avail_max = PCLK_AVAIL_MAX; in exynos_ufs_parse_dt()
1213 struct exynos_ufs *ufs) in exynos_ufs_priv_init() argument
1215 ufs->hba = hba; in exynos_ufs_priv_init()
1216 ufs->opts = ufs->drv_data->opts; in exynos_ufs_priv_init()
1217 ufs->rx_sel_idx = PA_MAXDATALANES; in exynos_ufs_priv_init()
1218 if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX) in exynos_ufs_priv_init()
1219 ufs->rx_sel_idx = 0; in exynos_ufs_priv_init()
1220 hba->priv = (void *)ufs; in exynos_ufs_priv_init()
1221 hba->quirks = ufs->drv_data->quirks; in exynos_ufs_priv_init()
1229 * not compatible with the standard UFS crypto. It requires that encryption be
1278 static void exynos_ufs_fmp_init(struct ufs_hba *hba, struct exynos_ufs *ufs) in exynos_ufs_fmp_init() argument
1305 if (!(ufs->opts & EXYNOS_UFS_OPT_UFSPR_SECURE)) in exynos_ufs_fmp_init()
1436 static void exynos_ufs_fmp_init(struct ufs_hba *hba, struct exynos_ufs *ufs) in exynos_ufs_fmp_init() argument
1452 struct exynos_ufs *ufs; in exynos_ufs_init() local
1455 ufs = devm_kzalloc(dev, sizeof(*ufs), GFP_KERNEL); in exynos_ufs_init()
1456 if (!ufs) in exynos_ufs_init()
1460 ufs->reg_hci = devm_platform_ioremap_resource_byname(pdev, "vs_hci"); in exynos_ufs_init()
1461 if (IS_ERR(ufs->reg_hci)) { in exynos_ufs_init()
1463 return PTR_ERR(ufs->reg_hci); in exynos_ufs_init()
1467 ufs->reg_unipro = devm_platform_ioremap_resource_byname(pdev, "unipro"); in exynos_ufs_init()
1468 if (IS_ERR(ufs->reg_unipro)) { in exynos_ufs_init()
1470 return PTR_ERR(ufs->reg_unipro); in exynos_ufs_init()
1473 /* ufs protector */ in exynos_ufs_init()
1474 ufs->reg_ufsp = devm_platform_ioremap_resource_byname(pdev, "ufsp"); in exynos_ufs_init()
1475 if (IS_ERR(ufs->reg_ufsp)) { in exynos_ufs_init()
1476 dev_err(dev, "cannot ioremap for ufs protector register\n"); in exynos_ufs_init()
1477 return PTR_ERR(ufs->reg_ufsp); in exynos_ufs_init()
1480 ret = exynos_ufs_parse_dt(dev, ufs); in exynos_ufs_init()
1486 ufs->phy = devm_phy_get(dev, "ufs-phy"); in exynos_ufs_init()
1487 if (IS_ERR(ufs->phy)) { in exynos_ufs_init()
1488 ret = PTR_ERR(ufs->phy); in exynos_ufs_init()
1489 dev_err(dev, "failed to get ufs-phy\n"); in exynos_ufs_init()
1493 exynos_ufs_priv_init(hba, ufs); in exynos_ufs_init()
1495 exynos_ufs_fmp_init(hba, ufs); in exynos_ufs_init()
1497 if (ufs->drv_data->drv_init) { in exynos_ufs_init()
1498 ret = ufs->drv_data->drv_init(ufs); in exynos_ufs_init()
1505 ret = exynos_ufs_get_clk_info(ufs); in exynos_ufs_init()
1508 exynos_ufs_specify_phy_time_attr(ufs); in exynos_ufs_init()
1510 exynos_ufs_config_smu(ufs); in exynos_ufs_init()
1522 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_host_reset() local
1527 exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val); in exynos_ufs_host_reset()
1529 hci_writel(ufs, UFS_SW_RST_MASK, HCI_SW_RST); in exynos_ufs_host_reset()
1532 if (!(hci_readl(ufs, HCI_SW_RST) & UFS_SW_RST_MASK)) in exynos_ufs_host_reset()
1540 exynos_ufs_auto_ctrl_hcc_restore(ufs, &val); in exynos_ufs_host_reset()
1546 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_dev_hw_reset() local
1548 hci_writel(ufs, 0 << 0, HCI_GPIO_OUT); in exynos_ufs_dev_hw_reset()
1550 hci_writel(ufs, 1 << 0, HCI_GPIO_OUT); in exynos_ufs_dev_hw_reset()
1555 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_pre_hibern8() local
1556 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in exynos_ufs_pre_hibern8()
1559 if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) in exynos_ufs_pre_hibern8()
1560 exynos_ufs_disable_auto_ctrl_hcc(ufs); in exynos_ufs_pre_hibern8()
1561 exynos_ufs_ungate_clks(ufs); in exynos_ufs_pre_hibern8()
1563 if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) { in exynos_ufs_pre_hibern8()
1574 ufs->entry_hibern8_t); in exynos_ufs_pre_hibern8()
1588 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_post_hibern8() local
1591 ufs->entry_hibern8_t = ktime_get(); in exynos_ufs_post_hibern8()
1592 exynos_ufs_gate_clks(ufs); in exynos_ufs_post_hibern8()
1593 if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) in exynos_ufs_post_hibern8()
1594 exynos_ufs_enable_auto_ctrl_hcc(ufs); in exynos_ufs_post_hibern8()
1601 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_hce_enable_notify() local
1614 if (ufs->drv_data->pre_hce_enable) { in exynos_ufs_hce_enable_notify()
1615 ret = ufs->drv_data->pre_hce_enable(ufs); in exynos_ufs_hce_enable_notify()
1626 exynos_ufs_calc_pwm_clk_div(ufs); in exynos_ufs_hce_enable_notify()
1627 if (!(ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)) in exynos_ufs_hce_enable_notify()
1628 exynos_ufs_enable_auto_ctrl_hcc(ufs); in exynos_ufs_hce_enable_notify()
1630 if (ufs->drv_data->post_hce_enable) in exynos_ufs_hce_enable_notify()
1631 ret = ufs->drv_data->post_hce_enable(ufs); in exynos_ufs_hce_enable_notify()
1693 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_suspend() local
1699 phy_power_off(ufs->phy); in exynos_ufs_suspend()
1706 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_resume() local
1709 phy_power_on(ufs->phy); in exynos_ufs_resume()
1711 exynos_ufs_config_smu(ufs); in exynos_ufs_resume()
1753 struct exynos_ufs *ufs; in exynosauto_ufs_vh_init() local
1756 ufs = devm_kzalloc(dev, sizeof(*ufs), GFP_KERNEL); in exynosauto_ufs_vh_init()
1757 if (!ufs) in exynosauto_ufs_vh_init()
1761 ufs->reg_hci = devm_platform_ioremap_resource_byname(pdev, "vs_hci"); in exynosauto_ufs_vh_init()
1762 if (IS_ERR(ufs->reg_hci)) { in exynosauto_ufs_vh_init()
1764 return PTR_ERR(ufs->reg_hci); in exynosauto_ufs_vh_init()
1771 ufs->drv_data = device_get_match_data(dev); in exynosauto_ufs_vh_init()
1772 if (!ufs->drv_data) in exynosauto_ufs_vh_init()
1775 exynos_ufs_priv_init(hba, ufs); in exynosauto_ufs_vh_init()
1780 static int fsd_ufs_pre_link(struct exynos_ufs *ufs) in fsd_ufs_pre_link() argument
1782 struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; in fsd_ufs_pre_link()
1783 struct ufs_hba *hba = ufs->hba; in fsd_ufs_pre_link()
1787 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in fsd_ufs_pre_link()
1791 for_each_ufs_tx_lane(ufs, i) { in fsd_ufs_pre_link()
1793 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in fsd_ufs_pre_link()
1797 for_each_ufs_rx_lane(ufs, i) { in fsd_ufs_pre_link()
1799 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in fsd_ufs_pre_link()
1815 exynos_ufs_establish_connt(ufs); in fsd_ufs_pre_link()
1820 static int fsd_ufs_post_link(struct exynos_ufs *ufs) in fsd_ufs_post_link() argument
1823 struct ufs_hba *hba = ufs->hba; in fsd_ufs_post_link()
1846 for_each_ufs_rx_lane(ufs, i) { in fsd_ufs_post_link()
1858 static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs, in fsd_ufs_pre_pwr_change() argument
1861 struct ufs_hba *hba = ufs->hba; in fsd_ufs_pre_pwr_change()
1869 unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0); in fsd_ufs_pre_pwr_change()
1870 unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1); in fsd_ufs_pre_pwr_change()
1871 unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2); in fsd_ufs_pre_pwr_change()
1876 static inline u32 get_mclk_period_unipro_18(struct exynos_ufs *ufs) in get_mclk_period_unipro_18() argument
1878 return (16 * 1000 * 1000000UL / ufs->mclk_rate); in get_mclk_period_unipro_18()
1881 static int gs101_ufs_pre_link(struct exynos_ufs *ufs) in gs101_ufs_pre_link() argument
1883 struct ufs_hba *hba = ufs->hba; in gs101_ufs_pre_link()
1887 rx_line_reset_period = (RX_LINE_RESET_TIME * ufs->mclk_rate) in gs101_ufs_pre_link()
1889 tx_line_reset_period = (TX_LINE_RESET_TIME * ufs->mclk_rate) in gs101_ufs_pre_link()
1892 unipro_writel(ufs, get_mclk_period_unipro_18(ufs), COMP_CLK_PERIOD); in gs101_ufs_pre_link()
1896 for_each_ufs_rx_lane(ufs, i) { in gs101_ufs_pre_link()
1898 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in gs101_ufs_pre_link()
1911 for_each_ufs_tx_lane(ufs, i) { in gs101_ufs_pre_link()
1913 DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate)); in gs101_ufs_pre_link()
1937 static int gs101_ufs_post_link(struct exynos_ufs *ufs) in gs101_ufs_post_link() argument
1939 struct ufs_hba *hba = ufs->hba; in gs101_ufs_post_link()
1945 hci_writel(ufs, WLU_EN | WLU_BURST_LEN(3), HCI_AXIDMA_RWDATA_BURST_LEN); in gs101_ufs_post_link()
1954 static int gs101_ufs_pre_pwr_change(struct exynos_ufs *ufs, in gs101_ufs_pre_pwr_change() argument
1957 struct ufs_hba *hba = ufs->hba; in gs101_ufs_pre_pwr_change()
1962 unipro_writel(ufs, 8064, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0); in gs101_ufs_pre_pwr_change()
1963 unipro_writel(ufs, 28224, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1); in gs101_ufs_pre_pwr_change()
1964 unipro_writel(ufs, 20160, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2); in gs101_ufs_pre_pwr_change()
1965 unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0); in gs101_ufs_pre_pwr_change()
1966 unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1); in gs101_ufs_pre_pwr_change()
1967 unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2); in gs101_ufs_pre_pwr_change()
2014 struct exynos_ufs *ufs = ufshcd_get_variant(hba); in exynos_ufs_remove() local
2018 phy_power_off(ufs->phy); in exynos_ufs_remove()
2019 phy_exit(ufs->phy); in exynos_ufs_remove()
2168 { .compatible = "google,gs101-ufs",
2170 { .compatible = "samsung,exynos7-ufs",
2172 { .compatible = "samsung,exynosautov9-ufs",
2174 { .compatible = "samsung,exynosautov9-ufs-vh",
2176 { .compatible = "tesla,fsd-ufs",
2202 MODULE_DESCRIPTION("Exynos UFS HCI Driver");