root/drivers/scsi/ufs/ufs-hisi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ufs_hisi_check_hibern8
  2. ufs_hisi_clk_init
  3. ufs_hisi_soc_init
  4. ufs_hisi_link_startup_pre_change
  5. ufs_hisi_link_startup_post_change
  6. ufs_hisi_link_startup_notify
  7. ufs_hisi_set_dev_cap
  8. ufs_hisi_pwr_change_pre_change
  9. ufs_hisi_pwr_change_notify
  10. ufs_hisi_suspend
  11. ufs_hisi_resume
  12. ufs_hisi_get_resource
  13. ufs_hisi_set_pm_lvl
  14. ufs_hisi_init_common
  15. ufs_hi3660_init
  16. ufs_hi3670_init
  17. ufs_hisi_probe
  18. ufs_hisi_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * HiSilicon Hixxxx UFS Driver
   4  *
   5  * Copyright (c) 2016-2017 Linaro Ltd.
   6  * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
   7  */
   8 
   9 #include <linux/time.h>
  10 #include <linux/of.h>
  11 #include <linux/of_address.h>
  12 #include <linux/dma-mapping.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/reset.h>
  15 
  16 #include "ufshcd.h"
  17 #include "ufshcd-pltfrm.h"
  18 #include "unipro.h"
  19 #include "ufs-hisi.h"
  20 #include "ufshci.h"
  21 #include "ufs_quirks.h"
  22 
  23 static int ufs_hisi_check_hibern8(struct ufs_hba *hba)
  24 {
  25         int err = 0;
  26         u32 tx_fsm_val_0 = 0;
  27         u32 tx_fsm_val_1 = 0;
  28         unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
  29 
  30         do {
  31                 err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
  32                                       &tx_fsm_val_0);
  33                 err |= ufshcd_dme_get(hba,
  34                     UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1);
  35                 if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 &&
  36                         tx_fsm_val_1 == TX_FSM_HIBERN8))
  37                         break;
  38 
  39                 /* sleep for max. 200us */
  40                 usleep_range(100, 200);
  41         } while (time_before(jiffies, timeout));
  42 
  43         /*
  44          * we might have scheduled out for long during polling so
  45          * check the state again.
  46          */
  47         if (time_after(jiffies, timeout)) {
  48                 err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
  49                                      &tx_fsm_val_0);
  50                 err |= ufshcd_dme_get(hba,
  51                  UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1);
  52         }
  53 
  54         if (err) {
  55                 dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
  56                         __func__, err);
  57         } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 ||
  58                          tx_fsm_val_1 != TX_FSM_HIBERN8) {
  59                 err = -1;
  60                 dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n",
  61                         __func__, tx_fsm_val_0, tx_fsm_val_1);
  62         }
  63 
  64         return err;
  65 }
  66 
  67 static void ufs_hisi_clk_init(struct ufs_hba *hba)
  68 {
  69         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
  70 
  71         ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
  72         if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN)
  73                 mdelay(1);
  74         /* use abb clk */
  75         ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL);
  76         ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN);
  77         /* open mphy ref clk */
  78         ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
  79 }
  80 
  81 static void ufs_hisi_soc_init(struct ufs_hba *hba)
  82 {
  83         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
  84         u32 reg;
  85 
  86         if (!IS_ERR(host->rst))
  87                 reset_control_assert(host->rst);
  88 
  89         /* HC_PSW powerup */
  90         ufs_sys_ctrl_set_bits(host, BIT_UFS_PSW_MTCMOS_EN, PSW_POWER_CTRL);
  91         udelay(10);
  92         /* notify PWR ready */
  93         ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_PWR_READY, HC_LP_CTRL);
  94         ufs_sys_ctrl_writel(host, MASK_UFS_DEVICE_RESET | 0,
  95                 UFS_DEVICE_RESET_CTRL);
  96 
  97         reg = ufs_sys_ctrl_readl(host, PHY_CLK_CTRL);
  98         reg = (reg & ~MASK_SYSCTRL_CFG_CLOCK_FREQ) | UFS_FREQ_CFG_CLK;
  99         /* set cfg clk freq */
 100         ufs_sys_ctrl_writel(host, reg, PHY_CLK_CTRL);
 101         /* set ref clk freq */
 102         ufs_sys_ctrl_clr_bits(host, MASK_SYSCTRL_REF_CLOCK_SEL, PHY_CLK_CTRL);
 103         /* bypass ufs clk gate */
 104         ufs_sys_ctrl_set_bits(host, MASK_UFS_CLK_GATE_BYPASS,
 105                                                  CLOCK_GATE_BYPASS);
 106         ufs_sys_ctrl_set_bits(host, MASK_UFS_SYSCRTL_BYPASS, UFS_SYSCTRL);
 107 
 108         /* open psw clk */
 109         ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_PSW_CLK_EN, PSW_CLK_CTRL);
 110         /* disable ufshc iso */
 111         ufs_sys_ctrl_clr_bits(host, BIT_UFS_PSW_ISO_CTRL, PSW_POWER_CTRL);
 112         /* disable phy iso */
 113         ufs_sys_ctrl_clr_bits(host, BIT_UFS_PHY_ISO_CTRL, PHY_ISO_EN);
 114         /* notice iso disable */
 115         ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_LP_ISOL_EN, HC_LP_CTRL);
 116 
 117         /* disable lp_reset_n */
 118         ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_LP_RESET_N, RESET_CTRL_EN);
 119         mdelay(1);
 120 
 121         ufs_sys_ctrl_writel(host, MASK_UFS_DEVICE_RESET | BIT_UFS_DEVICE_RESET,
 122                 UFS_DEVICE_RESET_CTRL);
 123 
 124         msleep(20);
 125 
 126         /*
 127          * enable the fix of linereset recovery,
 128          * and enable rx_reset/tx_rest beat
 129          * enable ref_clk_en override(bit5) &
 130          * override value = 1(bit4), with mask
 131          */
 132         ufs_sys_ctrl_writel(host, 0x03300330, UFS_DEVICE_RESET_CTRL);
 133 
 134         if (!IS_ERR(host->rst))
 135                 reset_control_deassert(host->rst);
 136 }
 137 
 138 static int ufs_hisi_link_startup_pre_change(struct ufs_hba *hba)
 139 {
 140         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
 141         int err;
 142         uint32_t value;
 143         uint32_t reg;
 144 
 145         /* Unipro VS_mphy_disable */
 146         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD0C1, 0x0), 0x1);
 147         /* PA_HSSeries */
 148         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x156A, 0x0), 0x2);
 149         /* MPHY CBRATESEL */
 150         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8114, 0x0), 0x1);
 151         /* MPHY CBOVRCTRL2 */
 152         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8121, 0x0), 0x2D);
 153         /* MPHY CBOVRCTRL3 */
 154         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8122, 0x0), 0x1);
 155 
 156         if (host->caps & UFS_HISI_CAP_PHY10nm) {
 157                 /* MPHY CBOVRCTRL4 */
 158                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8127, 0x0), 0x98);
 159                 /* MPHY CBOVRCTRL5 */
 160                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8128, 0x0), 0x1);
 161         }
 162 
 163         /* Unipro VS_MphyCfgUpdt */
 164         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD085, 0x0), 0x1);
 165         /* MPHY RXOVRCTRL4 rx0 */
 166         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x800D, 0x4), 0x58);
 167         /* MPHY RXOVRCTRL4 rx1 */
 168         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x800D, 0x5), 0x58);
 169         /* MPHY RXOVRCTRL5 rx0 */
 170         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x800E, 0x4), 0xB);
 171         /* MPHY RXOVRCTRL5 rx1 */
 172         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x800E, 0x5), 0xB);
 173         /* MPHY RXSQCONTROL rx0 */
 174         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8009, 0x4), 0x1);
 175         /* MPHY RXSQCONTROL rx1 */
 176         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8009, 0x5), 0x1);
 177         /* Unipro VS_MphyCfgUpdt */
 178         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD085, 0x0), 0x1);
 179 
 180         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8113, 0x0), 0x1);
 181         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD085, 0x0), 0x1);
 182 
 183         if (host->caps & UFS_HISI_CAP_PHY10nm) {
 184                 /* RX_Hibern8Time_Capability*/
 185                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0092, 0x4), 0xA);
 186                 /* RX_Hibern8Time_Capability*/
 187                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0092, 0x5), 0xA);
 188                 /* RX_Min_ActivateTime */
 189                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x008f, 0x4), 0xA);
 190                 /* RX_Min_ActivateTime*/
 191                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x008f, 0x5), 0xA);
 192         } else {
 193                 /* Tactive RX */
 194                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x008F, 0x4), 0x7);
 195                 /* Tactive RX */
 196                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x008F, 0x5), 0x7);
 197         }
 198 
 199         /* Gear3 Synclength */
 200         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0095, 0x4), 0x4F);
 201         /* Gear3 Synclength */
 202         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0095, 0x5), 0x4F);
 203         /* Gear2 Synclength */
 204         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0094, 0x4), 0x4F);
 205         /* Gear2 Synclength */
 206         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0094, 0x5), 0x4F);
 207         /* Gear1 Synclength */
 208         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x008B, 0x4), 0x4F);
 209         /* Gear1 Synclength */
 210         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x008B, 0x5), 0x4F);
 211         /* Thibernate Tx */
 212         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x000F, 0x0), 0x5);
 213         /* Thibernate Tx */
 214         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x000F, 0x1), 0x5);
 215 
 216         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD085, 0x0), 0x1);
 217         /* Unipro VS_mphy_disable */
 218         ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(0xD0C1, 0x0), &value);
 219         if (value != 0x1)
 220                 dev_info(hba->dev,
 221                     "Warring!!! Unipro VS_mphy_disable is 0x%x\n", value);
 222 
 223         /* Unipro VS_mphy_disable */
 224         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD0C1, 0x0), 0x0);
 225         err = ufs_hisi_check_hibern8(hba);
 226         if (err)
 227                 dev_err(hba->dev, "ufs_hisi_check_hibern8 error\n");
 228 
 229         if (!(host->caps & UFS_HISI_CAP_PHY10nm))
 230                 ufshcd_writel(hba, UFS_HCLKDIV_NORMAL_VALUE, UFS_REG_HCLKDIV);
 231 
 232         /* disable auto H8 */
 233         reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
 234         reg = reg & (~UFS_AHIT_AH8ITV_MASK);
 235         ufshcd_writel(hba, reg, REG_AUTO_HIBERNATE_IDLE_TIMER);
 236 
 237         /* Unipro PA_Local_TX_LCC_Enable */
 238         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x155E, 0x0), 0x0);
 239         /* close Unipro VS_Mk2ExtnSupport */
 240         ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xD0AB, 0x0), 0x0);
 241         ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(0xD0AB, 0x0), &value);
 242         if (value != 0) {
 243                 /* Ensure close success */
 244                 dev_info(hba->dev, "WARN: close VS_Mk2ExtnSupport failed\n");
 245         }
 246 
 247         return err;
 248 }
 249 
 250 static int ufs_hisi_link_startup_post_change(struct ufs_hba *hba)
 251 {
 252         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
 253 
 254         /* Unipro DL_AFC0CreditThreshold */
 255         ufshcd_dme_set(hba, UIC_ARG_MIB(0x2044), 0x0);
 256         /* Unipro DL_TC0OutAckThreshold */
 257         ufshcd_dme_set(hba, UIC_ARG_MIB(0x2045), 0x0);
 258         /* Unipro DL_TC0TXFCThreshold */
 259         ufshcd_dme_set(hba, UIC_ARG_MIB(0x2040), 0x9);
 260 
 261         /* not bypass ufs clk gate */
 262         ufs_sys_ctrl_clr_bits(host, MASK_UFS_CLK_GATE_BYPASS,
 263                                                 CLOCK_GATE_BYPASS);
 264         ufs_sys_ctrl_clr_bits(host, MASK_UFS_SYSCRTL_BYPASS,
 265                                                 UFS_SYSCTRL);
 266 
 267         /* select received symbol cnt */
 268         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd09a), 0x80000000);
 269          /* reset counter0 and enable */
 270         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd09c), 0x00000005);
 271 
 272         return 0;
 273 }
 274 
 275 static int ufs_hisi_link_startup_notify(struct ufs_hba *hba,
 276                                           enum ufs_notify_change_status status)
 277 {
 278         int err = 0;
 279 
 280         switch (status) {
 281         case PRE_CHANGE:
 282                 err = ufs_hisi_link_startup_pre_change(hba);
 283                 break;
 284         case POST_CHANGE:
 285                 err = ufs_hisi_link_startup_post_change(hba);
 286                 break;
 287         default:
 288                 break;
 289         }
 290 
 291         return err;
 292 }
 293 
 294 static void ufs_hisi_set_dev_cap(struct ufs_dev_params *hisi_param)
 295 {
 296         hisi_param->rx_lanes = UFS_HISI_LIMIT_NUM_LANES_RX;
 297         hisi_param->tx_lanes = UFS_HISI_LIMIT_NUM_LANES_TX;
 298         hisi_param->hs_rx_gear = UFS_HISI_LIMIT_HSGEAR_RX;
 299         hisi_param->hs_tx_gear = UFS_HISI_LIMIT_HSGEAR_TX;
 300         hisi_param->pwm_rx_gear = UFS_HISI_LIMIT_PWMGEAR_RX;
 301         hisi_param->pwm_tx_gear = UFS_HISI_LIMIT_PWMGEAR_TX;
 302         hisi_param->rx_pwr_pwm = UFS_HISI_LIMIT_RX_PWR_PWM;
 303         hisi_param->tx_pwr_pwm = UFS_HISI_LIMIT_TX_PWR_PWM;
 304         hisi_param->rx_pwr_hs = UFS_HISI_LIMIT_RX_PWR_HS;
 305         hisi_param->tx_pwr_hs = UFS_HISI_LIMIT_TX_PWR_HS;
 306         hisi_param->hs_rate = UFS_HISI_LIMIT_HS_RATE;
 307         hisi_param->desired_working_mode = UFS_HISI_LIMIT_DESIRED_MODE;
 308 }
 309 
 310 static void ufs_hisi_pwr_change_pre_change(struct ufs_hba *hba)
 311 {
 312         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
 313 
 314         if (host->caps & UFS_HISI_CAP_PHY10nm) {
 315                 /*
 316                  * Boston platform need to set SaveConfigTime to 0x13,
 317                  * and change sync length to maximum value
 318                  */
 319                 /* VS_DebugSaveConfigTime */
 320                 ufshcd_dme_set(hba, UIC_ARG_MIB((u32)0xD0A0), 0x13);
 321                 /* g1 sync length */
 322                 ufshcd_dme_set(hba, UIC_ARG_MIB((u32)0x1552), 0x4f);
 323                 /* g2 sync length */
 324                 ufshcd_dme_set(hba, UIC_ARG_MIB((u32)0x1554), 0x4f);
 325                 /* g3 sync length */
 326                 ufshcd_dme_set(hba, UIC_ARG_MIB((u32)0x1556), 0x4f);
 327                 /* PA_Hibern8Time */
 328                 ufshcd_dme_set(hba, UIC_ARG_MIB((u32)0x15a7), 0xA);
 329                 /* PA_Tactivate */
 330                 ufshcd_dme_set(hba, UIC_ARG_MIB((u32)0x15a8), 0xA);
 331                 ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xd085, 0x0), 0x01);
 332         }
 333 
 334         if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_VS_DEBUGSAVECONFIGTIME) {
 335                 pr_info("ufs flash device must set VS_DebugSaveConfigTime 0x10\n");
 336                 /* VS_DebugSaveConfigTime */
 337                 ufshcd_dme_set(hba, UIC_ARG_MIB(0xD0A0), 0x10);
 338                 /* sync length */
 339                 ufshcd_dme_set(hba, UIC_ARG_MIB(0x1556), 0x48);
 340         }
 341 
 342         /* update */
 343         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15A8), 0x1);
 344         /* PA_TxSkip */
 345         ufshcd_dme_set(hba, UIC_ARG_MIB(0x155c), 0x0);
 346         /*PA_PWRModeUserData0 = 8191, default is 0*/
 347         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15b0), 8191);
 348         /*PA_PWRModeUserData1 = 65535, default is 0*/
 349         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15b1), 65535);
 350         /*PA_PWRModeUserData2 = 32767, default is 0*/
 351         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15b2), 32767);
 352         /*DME_FC0ProtectionTimeOutVal = 8191, default is 0*/
 353         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd041), 8191);
 354         /*DME_TC0ReplayTimeOutVal = 65535, default is 0*/
 355         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd042), 65535);
 356         /*DME_AFC0ReqTimeOutVal = 32767, default is 0*/
 357         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd043), 32767);
 358         /*PA_PWRModeUserData3 = 8191, default is 0*/
 359         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15b3), 8191);
 360         /*PA_PWRModeUserData4 = 65535, default is 0*/
 361         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15b4), 65535);
 362         /*PA_PWRModeUserData5 = 32767, default is 0*/
 363         ufshcd_dme_set(hba, UIC_ARG_MIB(0x15b5), 32767);
 364         /*DME_FC1ProtectionTimeOutVal = 8191, default is 0*/
 365         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd044), 8191);
 366         /*DME_TC1ReplayTimeOutVal = 65535, default is 0*/
 367         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd045), 65535);
 368         /*DME_AFC1ReqTimeOutVal = 32767, default is 0*/
 369         ufshcd_dme_set(hba, UIC_ARG_MIB(0xd046), 32767);
 370 }
 371 
 372 static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba,
 373                                        enum ufs_notify_change_status status,
 374                                        struct ufs_pa_layer_attr *dev_max_params,
 375                                        struct ufs_pa_layer_attr *dev_req_params)
 376 {
 377         struct ufs_dev_params ufs_hisi_cap;
 378         int ret = 0;
 379 
 380         if (!dev_req_params) {
 381                 dev_err(hba->dev,
 382                             "%s: incoming dev_req_params is NULL\n", __func__);
 383                 ret = -EINVAL;
 384                 goto out;
 385         }
 386 
 387         switch (status) {
 388         case PRE_CHANGE:
 389                 ufs_hisi_set_dev_cap(&ufs_hisi_cap);
 390                 ret = ufshcd_get_pwr_dev_param(&ufs_hisi_cap,
 391                                                dev_max_params, dev_req_params);
 392                 if (ret) {
 393                         dev_err(hba->dev,
 394                             "%s: failed to determine capabilities\n", __func__);
 395                         goto out;
 396                 }
 397 
 398                 ufs_hisi_pwr_change_pre_change(hba);
 399                 break;
 400         case POST_CHANGE:
 401                 break;
 402         default:
 403                 ret = -EINVAL;
 404                 break;
 405         }
 406 out:
 407         return ret;
 408 }
 409 
 410 static int ufs_hisi_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 411 {
 412         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
 413 
 414         if (ufshcd_is_runtime_pm(pm_op))
 415                 return 0;
 416 
 417         if (host->in_suspend) {
 418                 WARN_ON(1);
 419                 return 0;
 420         }
 421 
 422         ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
 423         udelay(10);
 424         /* set ref_dig_clk override of PHY PCS to 0 */
 425         ufs_sys_ctrl_writel(host, 0x00100000, UFS_DEVICE_RESET_CTRL);
 426 
 427         host->in_suspend = true;
 428 
 429         return 0;
 430 }
 431 
 432 static int ufs_hisi_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 433 {
 434         struct ufs_hisi_host *host = ufshcd_get_variant(hba);
 435 
 436         if (!host->in_suspend)
 437                 return 0;
 438 
 439         /* set ref_dig_clk override of PHY PCS to 1 */
 440         ufs_sys_ctrl_writel(host, 0x00100010, UFS_DEVICE_RESET_CTRL);
 441         udelay(10);
 442         ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
 443 
 444         host->in_suspend = false;
 445         return 0;
 446 }
 447 
 448 static int ufs_hisi_get_resource(struct ufs_hisi_host *host)
 449 {
 450         struct device *dev = host->hba->dev;
 451         struct platform_device *pdev = to_platform_device(dev);
 452 
 453         /* get resource of ufs sys ctrl */
 454         host->ufs_sys_ctrl = devm_platform_ioremap_resource(pdev, 1);
 455         if (IS_ERR(host->ufs_sys_ctrl))
 456                 return PTR_ERR(host->ufs_sys_ctrl);
 457 
 458         return 0;
 459 }
 460 
 461 static void ufs_hisi_set_pm_lvl(struct ufs_hba *hba)
 462 {
 463         hba->rpm_lvl = UFS_PM_LVL_1;
 464         hba->spm_lvl = UFS_PM_LVL_3;
 465 }
 466 
 467 /**
 468  * ufs_hisi_init_common
 469  * @hba: host controller instance
 470  */
 471 static int ufs_hisi_init_common(struct ufs_hba *hba)
 472 {
 473         int err = 0;
 474         struct device *dev = hba->dev;
 475         struct ufs_hisi_host *host;
 476 
 477         host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
 478         if (!host)
 479                 return -ENOMEM;
 480 
 481         host->hba = hba;
 482         ufshcd_set_variant(hba, host);
 483 
 484         host->rst  = devm_reset_control_get(dev, "rst");
 485         if (IS_ERR(host->rst)) {
 486                 dev_err(dev, "%s: failed to get reset control\n", __func__);
 487                 return PTR_ERR(host->rst);
 488         }
 489 
 490         ufs_hisi_set_pm_lvl(hba);
 491 
 492         err = ufs_hisi_get_resource(host);
 493         if (err) {
 494                 ufshcd_set_variant(hba, NULL);
 495                 return err;
 496         }
 497 
 498         return 0;
 499 }
 500 
 501 static int ufs_hi3660_init(struct ufs_hba *hba)
 502 {
 503         int ret = 0;
 504         struct device *dev = hba->dev;
 505 
 506         ret = ufs_hisi_init_common(hba);
 507         if (ret) {
 508                 dev_err(dev, "%s: ufs common init fail\n", __func__);
 509                 return ret;
 510         }
 511 
 512         ufs_hisi_clk_init(hba);
 513 
 514         ufs_hisi_soc_init(hba);
 515 
 516         return 0;
 517 }
 518 
 519 static int ufs_hi3670_init(struct ufs_hba *hba)
 520 {
 521         int ret = 0;
 522         struct device *dev = hba->dev;
 523         struct ufs_hisi_host *host;
 524 
 525         ret = ufs_hisi_init_common(hba);
 526         if (ret) {
 527                 dev_err(dev, "%s: ufs common init fail\n", __func__);
 528                 return ret;
 529         }
 530 
 531         ufs_hisi_clk_init(hba);
 532 
 533         ufs_hisi_soc_init(hba);
 534 
 535         /* Add cap for 10nm PHY variant on HI3670 SoC */
 536         host = ufshcd_get_variant(hba);
 537         host->caps |= UFS_HISI_CAP_PHY10nm;
 538 
 539         return 0;
 540 }
 541 
 542 static const struct ufs_hba_variant_ops ufs_hba_hi3660_vops = {
 543         .name = "hi3660",
 544         .init = ufs_hi3660_init,
 545         .link_startup_notify = ufs_hisi_link_startup_notify,
 546         .pwr_change_notify = ufs_hisi_pwr_change_notify,
 547         .suspend = ufs_hisi_suspend,
 548         .resume = ufs_hisi_resume,
 549 };
 550 
 551 static const struct ufs_hba_variant_ops ufs_hba_hi3670_vops = {
 552         .name = "hi3670",
 553         .init = ufs_hi3670_init,
 554         .link_startup_notify = ufs_hisi_link_startup_notify,
 555         .pwr_change_notify = ufs_hisi_pwr_change_notify,
 556         .suspend = ufs_hisi_suspend,
 557         .resume = ufs_hisi_resume,
 558 };
 559 
 560 static const struct of_device_id ufs_hisi_of_match[] = {
 561         { .compatible = "hisilicon,hi3660-ufs", .data = &ufs_hba_hi3660_vops },
 562         { .compatible = "hisilicon,hi3670-ufs", .data = &ufs_hba_hi3670_vops },
 563         {},
 564 };
 565 
 566 MODULE_DEVICE_TABLE(of, ufs_hisi_of_match);
 567 
 568 static int ufs_hisi_probe(struct platform_device *pdev)
 569 {
 570         const struct of_device_id *of_id;
 571 
 572         of_id = of_match_node(ufs_hisi_of_match, pdev->dev.of_node);
 573 
 574         return ufshcd_pltfrm_init(pdev, of_id->data);
 575 }
 576 
 577 static int ufs_hisi_remove(struct platform_device *pdev)
 578 {
 579         struct ufs_hba *hba =  platform_get_drvdata(pdev);
 580 
 581         ufshcd_remove(hba);
 582         return 0;
 583 }
 584 
 585 static const struct dev_pm_ops ufs_hisi_pm_ops = {
 586         .suspend        = ufshcd_pltfrm_suspend,
 587         .resume         = ufshcd_pltfrm_resume,
 588         .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
 589         .runtime_resume  = ufshcd_pltfrm_runtime_resume,
 590         .runtime_idle    = ufshcd_pltfrm_runtime_idle,
 591 };
 592 
 593 static struct platform_driver ufs_hisi_pltform = {
 594         .probe  = ufs_hisi_probe,
 595         .remove = ufs_hisi_remove,
 596         .shutdown = ufshcd_pltfrm_shutdown,
 597         .driver = {
 598                 .name   = "ufshcd-hisi",
 599                 .pm     = &ufs_hisi_pm_ops,
 600                 .of_match_table = of_match_ptr(ufs_hisi_of_match),
 601         },
 602 };
 603 module_platform_driver(ufs_hisi_pltform);
 604 
 605 MODULE_LICENSE("GPL");
 606 MODULE_ALIAS("platform:ufshcd-hisi");
 607 MODULE_DESCRIPTION("HiSilicon Hixxxx UFS Driver");

/* [<][>][^][v][top][bottom][index][help] */