aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r--drivers/scsi/ufs/Kconfig2
-rw-r--r--drivers/scsi/ufs/ufs-qcom.c905
-rw-r--r--drivers/scsi/ufs/ufs-qcom.h68
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c98
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.h41
-rw-r--r--drivers/scsi/ufs/ufshcd.c130
-rw-r--r--drivers/scsi/ufs/ufshcd.h149
7 files changed, 1048 insertions, 345 deletions
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e94538362536..5f4530744e0a 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -72,7 +72,7 @@ config SCSI_UFSHCD_PLATFORM
72 If unsure, say N. 72 If unsure, say N.
73 73
74config SCSI_UFS_QCOM 74config SCSI_UFS_QCOM
75 bool "QCOM specific hooks to UFS controller platform driver" 75 tristate "QCOM specific hooks to UFS controller platform driver"
76 depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM 76 depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
77 select PHY_QCOM_UFS 77 select PHY_QCOM_UFS
78 help 78 help
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 4cdffa46d401..4f38d008bfb4 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -19,16 +19,44 @@
19 19
20#include <linux/phy/phy-qcom-ufs.h> 20#include <linux/phy/phy-qcom-ufs.h>
21#include "ufshcd.h" 21#include "ufshcd.h"
22#include "ufshcd-pltfrm.h"
22#include "unipro.h" 23#include "unipro.h"
23#include "ufs-qcom.h" 24#include "ufs-qcom.h"
24#include "ufshci.h" 25#include "ufshci.h"
26#define UFS_QCOM_DEFAULT_DBG_PRINT_EN \
27 (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
28
29enum {
30 TSTBUS_UAWM,
31 TSTBUS_UARM,
32 TSTBUS_TXUC,
33 TSTBUS_RXUC,
34 TSTBUS_DFC,
35 TSTBUS_TRLUT,
36 TSTBUS_TMRLUT,
37 TSTBUS_OCSC,
38 TSTBUS_UTP_HCI,
39 TSTBUS_COMBINED,
40 TSTBUS_WRAPPER,
41 TSTBUS_UNIPRO,
42 TSTBUS_MAX,
43};
25 44
26static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS]; 45static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];
27 46
28static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result);
29static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
30 const char *speed_mode);
31static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote); 47static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote);
48static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
49static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
50 u32 clk_cycles);
51
52static void ufs_qcom_dump_regs(struct ufs_hba *hba, int offset, int len,
53 char *prefix)
54{
55 print_hex_dump(KERN_ERR, prefix,
56 len > 4 ? DUMP_PREFIX_OFFSET : DUMP_PREFIX_NONE,
57 16, 4, (void __force *)hba->mmio_base + offset,
58 len * 4, false);
59}
32 60
33static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes) 61static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
34{ 62{
@@ -149,13 +177,14 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
149 177
150 err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk", 178 err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
151 &host->tx_l1_sync_clk); 179 &host->tx_l1_sync_clk);
180
152out: 181out:
153 return err; 182 return err;
154} 183}
155 184
156static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba) 185static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba)
157{ 186{
158 struct ufs_qcom_host *host = hba->priv; 187 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
159 struct phy *phy = host->generic_phy; 188 struct phy *phy = host->generic_phy;
160 u32 tx_lanes; 189 u32 tx_lanes;
161 int err = 0; 190 int err = 0;
@@ -181,7 +210,9 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
181 210
182 do { 211 do {
183 err = ufshcd_dme_get(hba, 212 err = ufshcd_dme_get(hba,
184 UIC_ARG_MIB(MPHY_TX_FSM_STATE), &tx_fsm_val); 213 UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
214 UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
215 &tx_fsm_val);
185 if (err || tx_fsm_val == TX_FSM_HIBERN8) 216 if (err || tx_fsm_val == TX_FSM_HIBERN8)
186 break; 217 break;
187 218
@@ -195,7 +226,9 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
195 */ 226 */
196 if (time_after(jiffies, timeout)) 227 if (time_after(jiffies, timeout))
197 err = ufshcd_dme_get(hba, 228 err = ufshcd_dme_get(hba,
198 UIC_ARG_MIB(MPHY_TX_FSM_STATE), &tx_fsm_val); 229 UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
230 UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
231 &tx_fsm_val);
199 232
200 if (err) { 233 if (err) {
201 dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", 234 dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
@@ -209,9 +242,18 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
209 return err; 242 return err;
210} 243}
211 244
245static void ufs_qcom_select_unipro_mode(struct ufs_qcom_host *host)
246{
247 ufshcd_rmwl(host->hba, QUNIPRO_SEL,
248 ufs_qcom_cap_qunipro(host) ? QUNIPRO_SEL : 0,
249 REG_UFS_CFG1);
250 /* make sure above configuration is applied before we return */
251 mb();
252}
253
212static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) 254static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
213{ 255{
214 struct ufs_qcom_host *host = hba->priv; 256 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
215 struct phy *phy = host->generic_phy; 257 struct phy *phy = host->generic_phy;
216 int ret = 0; 258 int ret = 0;
217 bool is_rate_B = (UFS_QCOM_LIMIT_HS_RATE == PA_HS_MODE_B) 259 bool is_rate_B = (UFS_QCOM_LIMIT_HS_RATE == PA_HS_MODE_B)
@@ -223,9 +265,11 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
223 usleep_range(1000, 1100); 265 usleep_range(1000, 1100);
224 266
225 ret = ufs_qcom_phy_calibrate_phy(phy, is_rate_B); 267 ret = ufs_qcom_phy_calibrate_phy(phy, is_rate_B);
268
226 if (ret) { 269 if (ret) {
227 dev_err(hba->dev, "%s: ufs_qcom_phy_calibrate_phy() failed, ret = %d\n", 270 dev_err(hba->dev,
228 __func__, ret); 271 "%s: ufs_qcom_phy_calibrate_phy()failed, ret = %d\n",
272 __func__, ret);
229 goto out; 273 goto out;
230 } 274 }
231 275
@@ -246,9 +290,12 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
246 290
247 ret = ufs_qcom_phy_is_pcs_ready(phy); 291 ret = ufs_qcom_phy_is_pcs_ready(phy);
248 if (ret) 292 if (ret)
249 dev_err(hba->dev, "%s: is_physical_coding_sublayer_ready() failed, ret = %d\n", 293 dev_err(hba->dev,
294 "%s: is_physical_coding_sublayer_ready() failed, ret = %d\n",
250 __func__, ret); 295 __func__, ret);
251 296
297 ufs_qcom_select_unipro_mode(host);
298
252out: 299out:
253 return ret; 300 return ret;
254} 301}
@@ -271,9 +318,10 @@ static void ufs_qcom_enable_hw_clk_gating(struct ufs_hba *hba)
271 mb(); 318 mb();
272} 319}
273 320
274static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba, bool status) 321static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
322 enum ufs_notify_change_status status)
275{ 323{
276 struct ufs_qcom_host *host = hba->priv; 324 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
277 int err = 0; 325 int err = 0;
278 326
279 switch (status) { 327 switch (status) {
@@ -301,13 +349,13 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba, bool status)
301} 349}
302 350
303/** 351/**
304 * Returns non-zero for success (which rate of core_clk) and 0 352 * Returns zero for success and non-zero in case of a failure
305 * in case of a failure
306 */ 353 */
307static unsigned long 354static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
308ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate) 355 u32 hs, u32 rate, bool update_link_startup_timer)
309{ 356{
310 struct ufs_qcom_host *host = hba->priv; 357 int ret = 0;
358 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
311 struct ufs_clk_info *clki; 359 struct ufs_clk_info *clki;
312 u32 core_clk_period_in_ns; 360 u32 core_clk_period_in_ns;
313 u32 tx_clk_cycles_per_us = 0; 361 u32 tx_clk_cycles_per_us = 0;
@@ -324,11 +372,13 @@ ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
324 static u32 hs_fr_table_rA[][2] = { 372 static u32 hs_fr_table_rA[][2] = {
325 {UFS_HS_G1, 0x1F}, 373 {UFS_HS_G1, 0x1F},
326 {UFS_HS_G2, 0x3e}, 374 {UFS_HS_G2, 0x3e},
375 {UFS_HS_G3, 0x7D},
327 }; 376 };
328 377
329 static u32 hs_fr_table_rB[][2] = { 378 static u32 hs_fr_table_rB[][2] = {
330 {UFS_HS_G1, 0x24}, 379 {UFS_HS_G1, 0x24},
331 {UFS_HS_G2, 0x49}, 380 {UFS_HS_G2, 0x49},
381 {UFS_HS_G3, 0x92},
332 }; 382 };
333 383
334 /* 384 /*
@@ -356,7 +406,17 @@ ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
356 core_clk_rate = DEFAULT_CLK_RATE_HZ; 406 core_clk_rate = DEFAULT_CLK_RATE_HZ;
357 407
358 core_clk_cycles_per_us = core_clk_rate / USEC_PER_SEC; 408 core_clk_cycles_per_us = core_clk_rate / USEC_PER_SEC;
359 ufshcd_writel(hba, core_clk_cycles_per_us, REG_UFS_SYS1CLK_1US); 409 if (ufshcd_readl(hba, REG_UFS_SYS1CLK_1US) != core_clk_cycles_per_us) {
410 ufshcd_writel(hba, core_clk_cycles_per_us, REG_UFS_SYS1CLK_1US);
411 /*
412 * make sure above write gets applied before we return from
413 * this function.
414 */
415 mb();
416 }
417
418 if (ufs_qcom_cap_qunipro(host))
419 goto out;
360 420
361 core_clk_period_in_ns = NSEC_PER_SEC / core_clk_rate; 421 core_clk_period_in_ns = NSEC_PER_SEC / core_clk_rate;
362 core_clk_period_in_ns <<= OFFSET_CLK_NS_REG; 422 core_clk_period_in_ns <<= OFFSET_CLK_NS_REG;
@@ -406,35 +466,59 @@ ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, u32 hs, u32 rate)
406 goto out_error; 466 goto out_error;
407 } 467 }
408 468
409 /* this register 2 fields shall be written at once */ 469 if (ufshcd_readl(hba, REG_UFS_TX_SYMBOL_CLK_NS_US) !=
410 ufshcd_writel(hba, core_clk_period_in_ns | tx_clk_cycles_per_us, 470 (core_clk_period_in_ns | tx_clk_cycles_per_us)) {
411 REG_UFS_TX_SYMBOL_CLK_NS_US); 471 /* this register 2 fields shall be written at once */
472 ufshcd_writel(hba, core_clk_period_in_ns | tx_clk_cycles_per_us,
473 REG_UFS_TX_SYMBOL_CLK_NS_US);
474 /*
475 * make sure above write gets applied before we return from
476 * this function.
477 */
478 mb();
479 }
480
481 if (update_link_startup_timer) {
482 ufshcd_writel(hba, ((core_clk_rate / MSEC_PER_SEC) * 100),
483 REG_UFS_PA_LINK_STARTUP_TIMER);
484 /*
485 * make sure that this configuration is applied before
486 * we return
487 */
488 mb();
489 }
412 goto out; 490 goto out;
413 491
414out_error: 492out_error:
415 core_clk_rate = 0; 493 ret = -EINVAL;
416out: 494out:
417 return core_clk_rate; 495 return ret;
418} 496}
419 497
420static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, bool status) 498static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
499 enum ufs_notify_change_status status)
421{ 500{
422 unsigned long core_clk_rate = 0; 501 int err = 0;
423 u32 core_clk_cycles_per_100ms; 502 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
424 503
425 switch (status) { 504 switch (status) {
426 case PRE_CHANGE: 505 case PRE_CHANGE:
427 core_clk_rate = ufs_qcom_cfg_timers(hba, UFS_PWM_G1, 506 if (ufs_qcom_cfg_timers(hba, UFS_PWM_G1, SLOWAUTO_MODE,
428 SLOWAUTO_MODE, 0); 507 0, true)) {
429 if (!core_clk_rate) {
430 dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n", 508 dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
431 __func__); 509 __func__);
432 return -EINVAL; 510 err = -EINVAL;
511 goto out;
433 } 512 }
434 core_clk_cycles_per_100ms = 513
435 (core_clk_rate / MSEC_PER_SEC) * 100; 514 if (ufs_qcom_cap_qunipro(host))
436 ufshcd_writel(hba, core_clk_cycles_per_100ms, 515 /*
437 REG_UFS_PA_LINK_STARTUP_TIMER); 516 * set unipro core clock cycles to 150 & clear clock
517 * divider
518 */
519 err = ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba,
520 150);
521
438 break; 522 break;
439 case POST_CHANGE: 523 case POST_CHANGE:
440 ufs_qcom_link_startup_post_change(hba); 524 ufs_qcom_link_startup_post_change(hba);
@@ -443,12 +527,13 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, bool status)
443 break; 527 break;
444 } 528 }
445 529
446 return 0; 530out:
531 return err;
447} 532}
448 533
449static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) 534static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
450{ 535{
451 struct ufs_qcom_host *host = hba->priv; 536 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
452 struct phy *phy = host->generic_phy; 537 struct phy *phy = host->generic_phy;
453 int ret = 0; 538 int ret = 0;
454 539
@@ -470,8 +555,10 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
470 * If UniPro link is not active, PHY ref_clk, main PHY analog power 555 * If UniPro link is not active, PHY ref_clk, main PHY analog power
471 * rail and low noise analog power rail for PLL can be switched off. 556 * rail and low noise analog power rail for PLL can be switched off.
472 */ 557 */
473 if (!ufs_qcom_is_link_active(hba)) 558 if (!ufs_qcom_is_link_active(hba)) {
559 ufs_qcom_disable_lane_clks(host);
474 phy_power_off(phy); 560 phy_power_off(phy);
561 }
475 562
476out: 563out:
477 return ret; 564 return ret;
@@ -479,7 +566,7 @@ out:
479 566
480static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) 567static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
481{ 568{
482 struct ufs_qcom_host *host = hba->priv; 569 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
483 struct phy *phy = host->generic_phy; 570 struct phy *phy = host->generic_phy;
484 int err; 571 int err;
485 572
@@ -490,6 +577,10 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
490 goto out; 577 goto out;
491 } 578 }
492 579
580 err = ufs_qcom_enable_lane_clks(host);
581 if (err)
582 goto out;
583
493 hba->is_sys_suspended = false; 584 hba->is_sys_suspended = false;
494 585
495out: 586out:
@@ -594,6 +685,81 @@ static int ufs_qcom_get_pwr_dev_param(struct ufs_qcom_dev_params *qcom_param,
594 return 0; 685 return 0;
595} 686}
596 687
688#ifdef CONFIG_MSM_BUS_SCALING
689static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
690 const char *speed_mode)
691{
692 struct device *dev = host->hba->dev;
693 struct device_node *np = dev->of_node;
694 int err;
695 const char *key = "qcom,bus-vector-names";
696
697 if (!speed_mode) {
698 err = -EINVAL;
699 goto out;
700 }
701
702 if (host->bus_vote.is_max_bw_needed && !!strcmp(speed_mode, "MIN"))
703 err = of_property_match_string(np, key, "MAX");
704 else
705 err = of_property_match_string(np, key, speed_mode);
706
707out:
708 if (err < 0)
709 dev_err(dev, "%s: Invalid %s mode %d\n",
710 __func__, speed_mode, err);
711 return err;
712}
713
714static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result)
715{
716 int gear = max_t(u32, p->gear_rx, p->gear_tx);
717 int lanes = max_t(u32, p->lane_rx, p->lane_tx);
718 int pwr;
719
720 /* default to PWM Gear 1, Lane 1 if power mode is not initialized */
721 if (!gear)
722 gear = 1;
723
724 if (!lanes)
725 lanes = 1;
726
727 if (!p->pwr_rx && !p->pwr_tx) {
728 pwr = SLOWAUTO_MODE;
729 snprintf(result, BUS_VECTOR_NAME_LEN, "MIN");
730 } else if (p->pwr_rx == FAST_MODE || p->pwr_rx == FASTAUTO_MODE ||
731 p->pwr_tx == FAST_MODE || p->pwr_tx == FASTAUTO_MODE) {
732 pwr = FAST_MODE;
733 snprintf(result, BUS_VECTOR_NAME_LEN, "%s_R%s_G%d_L%d", "HS",
734 p->hs_rate == PA_HS_MODE_B ? "B" : "A", gear, lanes);
735 } else {
736 pwr = SLOW_MODE;
737 snprintf(result, BUS_VECTOR_NAME_LEN, "%s_G%d_L%d",
738 "PWM", gear, lanes);
739 }
740}
741
742static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
743{
744 int err = 0;
745
746 if (vote != host->bus_vote.curr_vote) {
747 err = msm_bus_scale_client_update_request(
748 host->bus_vote.client_handle, vote);
749 if (err) {
750 dev_err(host->hba->dev,
751 "%s: msm_bus_scale_client_update_request() failed: bus_client_handle=0x%x, vote=%d, err=%d\n",
752 __func__, host->bus_vote.client_handle,
753 vote, err);
754 goto out;
755 }
756
757 host->bus_vote.curr_vote = vote;
758 }
759out:
760 return err;
761}
762
597static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host) 763static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
598{ 764{
599 int vote; 765 int vote;
@@ -615,13 +781,137 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
615 return err; 781 return err;
616} 782}
617 783
784static ssize_t
785show_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
786 char *buf)
787{
788 struct ufs_hba *hba = dev_get_drvdata(dev);
789 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
790
791 return snprintf(buf, PAGE_SIZE, "%u\n",
792 host->bus_vote.is_max_bw_needed);
793}
794
795static ssize_t
796store_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
797 const char *buf, size_t count)
798{
799 struct ufs_hba *hba = dev_get_drvdata(dev);
800 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
801 uint32_t value;
802
803 if (!kstrtou32(buf, 0, &value)) {
804 host->bus_vote.is_max_bw_needed = !!value;
805 ufs_qcom_update_bus_bw_vote(host);
806 }
807
808 return count;
809}
810
811static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
812{
813 int err;
814 struct msm_bus_scale_pdata *bus_pdata;
815 struct device *dev = host->hba->dev;
816 struct platform_device *pdev = to_platform_device(dev);
817 struct device_node *np = dev->of_node;
818
819 bus_pdata = msm_bus_cl_get_pdata(pdev);
820 if (!bus_pdata) {
821 dev_err(dev, "%s: failed to get bus vectors\n", __func__);
822 err = -ENODATA;
823 goto out;
824 }
825
826 err = of_property_count_strings(np, "qcom,bus-vector-names");
827 if (err < 0 || err != bus_pdata->num_usecases) {
828 dev_err(dev, "%s: qcom,bus-vector-names not specified correctly %d\n",
829 __func__, err);
830 goto out;
831 }
832
833 host->bus_vote.client_handle = msm_bus_scale_register_client(bus_pdata);
834 if (!host->bus_vote.client_handle) {
835 dev_err(dev, "%s: msm_bus_scale_register_client failed\n",
836 __func__);
837 err = -EFAULT;
838 goto out;
839 }
840
841 /* cache the vote index for minimum and maximum bandwidth */
842 host->bus_vote.min_bw_vote = ufs_qcom_get_bus_vote(host, "MIN");
843 host->bus_vote.max_bw_vote = ufs_qcom_get_bus_vote(host, "MAX");
844
845 host->bus_vote.max_bus_bw.show = show_ufs_to_mem_max_bus_bw;
846 host->bus_vote.max_bus_bw.store = store_ufs_to_mem_max_bus_bw;
847 sysfs_attr_init(&host->bus_vote.max_bus_bw.attr);
848 host->bus_vote.max_bus_bw.attr.name = "max_bus_bw";
849 host->bus_vote.max_bus_bw.attr.mode = S_IRUGO | S_IWUSR;
850 err = device_create_file(dev, &host->bus_vote.max_bus_bw);
851out:
852 return err;
853}
854#else /* CONFIG_MSM_BUS_SCALING */
855static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
856{
857 return 0;
858}
859
860static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
861{
862 return 0;
863}
864
865static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
866{
867 return 0;
868}
869#endif /* CONFIG_MSM_BUS_SCALING */
870
871static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_qcom_host *host, bool enable)
872{
873 if (host->dev_ref_clk_ctrl_mmio &&
874 (enable ^ host->is_dev_ref_clk_enabled)) {
875 u32 temp = readl_relaxed(host->dev_ref_clk_ctrl_mmio);
876
877 if (enable)
878 temp |= host->dev_ref_clk_en_mask;
879 else
880 temp &= ~host->dev_ref_clk_en_mask;
881
882 /*
883 * If we are here to disable this clock it might be immediately
884 * after entering into hibern8 in which case we need to make
885 * sure that device ref_clk is active at least 1us after the
886 * hibern8 enter.
887 */
888 if (!enable)
889 udelay(1);
890
891 writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio);
892
893 /* ensure that ref_clk is enabled/disabled before we return */
894 wmb();
895
896 /*
897 * If we call hibern8 exit after this, we need to make sure that
898 * device ref_clk is stable for at least 1us before the hibern8
899 * exit command.
900 */
901 if (enable)
902 udelay(1);
903
904 host->is_dev_ref_clk_enabled = enable;
905 }
906}
907
618static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, 908static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
619 bool status, 909 enum ufs_notify_change_status status,
620 struct ufs_pa_layer_attr *dev_max_params, 910 struct ufs_pa_layer_attr *dev_max_params,
621 struct ufs_pa_layer_attr *dev_req_params) 911 struct ufs_pa_layer_attr *dev_req_params)
622{ 912{
623 u32 val; 913 u32 val;
624 struct ufs_qcom_host *host = hba->priv; 914 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
625 struct phy *phy = host->generic_phy; 915 struct phy *phy = host->generic_phy;
626 struct ufs_qcom_dev_params ufs_qcom_cap; 916 struct ufs_qcom_dev_params ufs_qcom_cap;
627 int ret = 0; 917 int ret = 0;
@@ -649,6 +939,20 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
649 ufs_qcom_cap.desired_working_mode = 939 ufs_qcom_cap.desired_working_mode =
650 UFS_QCOM_LIMIT_DESIRED_MODE; 940 UFS_QCOM_LIMIT_DESIRED_MODE;
651 941
942 if (host->hw_ver.major == 0x1) {
943 /*
944 * HS-G3 operations may not reliably work on legacy QCOM
945 * UFS host controller hardware even though capability
946 * exchange during link startup phase may end up
947 * negotiating maximum supported gear as G3.
948 * Hence downgrade the maximum supported gear to HS-G2.
949 */
950 if (ufs_qcom_cap.hs_tx_gear > UFS_HS_G2)
951 ufs_qcom_cap.hs_tx_gear = UFS_HS_G2;
952 if (ufs_qcom_cap.hs_rx_gear > UFS_HS_G2)
953 ufs_qcom_cap.hs_rx_gear = UFS_HS_G2;
954 }
955
652 ret = ufs_qcom_get_pwr_dev_param(&ufs_qcom_cap, 956 ret = ufs_qcom_get_pwr_dev_param(&ufs_qcom_cap,
653 dev_max_params, 957 dev_max_params,
654 dev_req_params); 958 dev_req_params);
@@ -660,9 +964,9 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
660 964
661 break; 965 break;
662 case POST_CHANGE: 966 case POST_CHANGE:
663 if (!ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx, 967 if (ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
664 dev_req_params->pwr_rx, 968 dev_req_params->pwr_rx,
665 dev_req_params->hs_rate)) { 969 dev_req_params->hs_rate, false)) {
666 dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n", 970 dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
667 __func__); 971 __func__);
668 /* 972 /*
@@ -696,7 +1000,7 @@ out:
696 1000
697static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba) 1001static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
698{ 1002{
699 struct ufs_qcom_host *host = hba->priv; 1003 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
700 1004
701 if (host->hw_ver.major == 0x1) 1005 if (host->hw_ver.major == 0x1)
702 return UFSHCI_VERSION_11; 1006 return UFSHCI_VERSION_11;
@@ -715,7 +1019,7 @@ static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
715 */ 1019 */
716static void ufs_qcom_advertise_quirks(struct ufs_hba *hba) 1020static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
717{ 1021{
718 struct ufs_qcom_host *host = hba->priv; 1022 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
719 1023
720 if (host->hw_ver.major == 0x01) { 1024 if (host->hw_ver.major == 0x01) {
721 hba->quirks |= UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS 1025 hba->quirks |= UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
@@ -724,10 +1028,11 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
724 1028
725 if (host->hw_ver.minor == 0x0001 && host->hw_ver.step == 0x0001) 1029 if (host->hw_ver.minor == 0x0001 && host->hw_ver.step == 0x0001)
726 hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR; 1030 hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR;
1031
1032 hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
727 } 1033 }
728 1034
729 if (host->hw_ver.major >= 0x2) { 1035 if (host->hw_ver.major >= 0x2) {
730 hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
731 hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION; 1036 hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
732 1037
733 if (!ufs_qcom_cap_qunipro(host)) 1038 if (!ufs_qcom_cap_qunipro(host))
@@ -740,79 +1045,29 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
740 1045
741static void ufs_qcom_set_caps(struct ufs_hba *hba) 1046static void ufs_qcom_set_caps(struct ufs_hba *hba)
742{ 1047{
743 struct ufs_qcom_host *host = hba->priv; 1048 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
744 1049
745 if (host->hw_ver.major >= 0x2) 1050 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
746 host->caps = UFS_QCOM_CAP_QUNIPRO; 1051 hba->caps |= UFSHCD_CAP_CLK_SCALING;
747} 1052 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
748
749static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
750 const char *speed_mode)
751{
752 struct device *dev = host->hba->dev;
753 struct device_node *np = dev->of_node;
754 int err;
755 const char *key = "qcom,bus-vector-names";
756
757 if (!speed_mode) {
758 err = -EINVAL;
759 goto out;
760 }
761
762 if (host->bus_vote.is_max_bw_needed && !!strcmp(speed_mode, "MIN"))
763 err = of_property_match_string(np, key, "MAX");
764 else
765 err = of_property_match_string(np, key, speed_mode);
766
767out:
768 if (err < 0)
769 dev_err(dev, "%s: Invalid %s mode %d\n",
770 __func__, speed_mode, err);
771 return err;
772}
773
774static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote)
775{
776 int err = 0;
777
778 if (vote != host->bus_vote.curr_vote)
779 host->bus_vote.curr_vote = vote;
780
781 return err;
782}
783
784static void ufs_qcom_get_speed_mode(struct ufs_pa_layer_attr *p, char *result)
785{
786 int gear = max_t(u32, p->gear_rx, p->gear_tx);
787 int lanes = max_t(u32, p->lane_rx, p->lane_tx);
788 int pwr;
789
790 /* default to PWM Gear 1, Lane 1 if power mode is not initialized */
791 if (!gear)
792 gear = 1;
793
794 if (!lanes)
795 lanes = 1;
796 1053
797 if (!p->pwr_rx && !p->pwr_tx) { 1054 if (host->hw_ver.major >= 0x2) {
798 pwr = SLOWAUTO_MODE; 1055 host->caps = UFS_QCOM_CAP_QUNIPRO |
799 snprintf(result, BUS_VECTOR_NAME_LEN, "MIN"); 1056 UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
800 } else if (p->pwr_rx == FAST_MODE || p->pwr_rx == FASTAUTO_MODE ||
801 p->pwr_tx == FAST_MODE || p->pwr_tx == FASTAUTO_MODE) {
802 pwr = FAST_MODE;
803 snprintf(result, BUS_VECTOR_NAME_LEN, "%s_R%s_G%d_L%d", "HS",
804 p->hs_rate == PA_HS_MODE_B ? "B" : "A", gear, lanes);
805 } else {
806 pwr = SLOW_MODE;
807 snprintf(result, BUS_VECTOR_NAME_LEN, "%s_G%d_L%d",
808 "PWM", gear, lanes);
809 } 1057 }
810} 1058}
811 1059
1060/**
1061 * ufs_qcom_setup_clocks - enables/disable clocks
1062 * @hba: host controller instance
1063 * @on: If true, enable clocks else disable them.
1064 *
1065 * Returns 0 on success, non-zero on failure.
1066 */
812static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on) 1067static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
813{ 1068{
814 struct ufs_qcom_host *host = hba->priv; 1069 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
815 int err = 0; 1070 int err;
816 int vote = 0; 1071 int vote = 0;
817 1072
818 /* 1073 /*
@@ -835,20 +1090,18 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
835 ufs_qcom_phy_disable_iface_clk(host->generic_phy); 1090 ufs_qcom_phy_disable_iface_clk(host->generic_phy);
836 goto out; 1091 goto out;
837 } 1092 }
838 /* enable the device ref clock */
839 ufs_qcom_phy_enable_dev_ref_clk(host->generic_phy);
840 vote = host->bus_vote.saved_vote; 1093 vote = host->bus_vote.saved_vote;
841 if (vote == host->bus_vote.min_bw_vote) 1094 if (vote == host->bus_vote.min_bw_vote)
842 ufs_qcom_update_bus_bw_vote(host); 1095 ufs_qcom_update_bus_bw_vote(host);
1096
843 } else { 1097 } else {
1098
844 /* M-PHY RMMI interface clocks can be turned off */ 1099 /* M-PHY RMMI interface clocks can be turned off */
845 ufs_qcom_phy_disable_iface_clk(host->generic_phy); 1100 ufs_qcom_phy_disable_iface_clk(host->generic_phy);
846 if (!ufs_qcom_is_link_active(hba)) { 1101 if (!ufs_qcom_is_link_active(hba))
847 /* turn off UFS local PHY ref_clk */
848 ufs_qcom_phy_disable_ref_clk(host->generic_phy);
849 /* disable device ref_clk */ 1102 /* disable device ref_clk */
850 ufs_qcom_phy_disable_dev_ref_clk(host->generic_phy); 1103 ufs_qcom_dev_ref_clk_ctrl(host, false);
851 } 1104
852 vote = host->bus_vote.min_bw_vote; 1105 vote = host->bus_vote.min_bw_vote;
853 } 1106 }
854 1107
@@ -861,68 +1114,17 @@ out:
861 return err; 1114 return err;
862} 1115}
863 1116
864static ssize_t
865show_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
866 char *buf)
867{
868 struct ufs_hba *hba = dev_get_drvdata(dev);
869 struct ufs_qcom_host *host = hba->priv;
870
871 return snprintf(buf, PAGE_SIZE, "%u\n",
872 host->bus_vote.is_max_bw_needed);
873}
874
875static ssize_t
876store_ufs_to_mem_max_bus_bw(struct device *dev, struct device_attribute *attr,
877 const char *buf, size_t count)
878{
879 struct ufs_hba *hba = dev_get_drvdata(dev);
880 struct ufs_qcom_host *host = hba->priv;
881 uint32_t value;
882
883 if (!kstrtou32(buf, 0, &value)) {
884 host->bus_vote.is_max_bw_needed = !!value;
885 ufs_qcom_update_bus_bw_vote(host);
886 }
887
888 return count;
889}
890
891static int ufs_qcom_bus_register(struct ufs_qcom_host *host)
892{
893 int err;
894 struct device *dev = host->hba->dev;
895 struct device_node *np = dev->of_node;
896
897 err = of_property_count_strings(np, "qcom,bus-vector-names");
898 if (err < 0 ) {
899 dev_err(dev, "%s: qcom,bus-vector-names not specified correctly %d\n",
900 __func__, err);
901 goto out;
902 }
903
904 /* cache the vote index for minimum and maximum bandwidth */
905 host->bus_vote.min_bw_vote = ufs_qcom_get_bus_vote(host, "MIN");
906 host->bus_vote.max_bw_vote = ufs_qcom_get_bus_vote(host, "MAX");
907
908 host->bus_vote.max_bus_bw.show = show_ufs_to_mem_max_bus_bw;
909 host->bus_vote.max_bus_bw.store = store_ufs_to_mem_max_bus_bw;
910 sysfs_attr_init(&host->bus_vote.max_bus_bw.attr);
911 host->bus_vote.max_bus_bw.attr.name = "max_bus_bw";
912 host->bus_vote.max_bus_bw.attr.mode = S_IRUGO | S_IWUSR;
913 err = device_create_file(dev, &host->bus_vote.max_bus_bw);
914out:
915 return err;
916}
917
918#define ANDROID_BOOT_DEV_MAX 30 1117#define ANDROID_BOOT_DEV_MAX 30
919static char android_boot_dev[ANDROID_BOOT_DEV_MAX]; 1118static char android_boot_dev[ANDROID_BOOT_DEV_MAX];
920static int get_android_boot_dev(char *str) 1119
1120#ifndef MODULE
1121static int __init get_android_boot_dev(char *str)
921{ 1122{
922 strlcpy(android_boot_dev, str, ANDROID_BOOT_DEV_MAX); 1123 strlcpy(android_boot_dev, str, ANDROID_BOOT_DEV_MAX);
923 return 1; 1124 return 1;
924} 1125}
925__setup("androidboot.bootdevice=", get_android_boot_dev); 1126__setup("androidboot.bootdevice=", get_android_boot_dev);
1127#endif
926 1128
927/** 1129/**
928 * ufs_qcom_init - bind phy with controller 1130 * ufs_qcom_init - bind phy with controller
@@ -938,7 +1140,9 @@ static int ufs_qcom_init(struct ufs_hba *hba)
938{ 1140{
939 int err; 1141 int err;
940 struct device *dev = hba->dev; 1142 struct device *dev = hba->dev;
1143 struct platform_device *pdev = to_platform_device(dev);
941 struct ufs_qcom_host *host; 1144 struct ufs_qcom_host *host;
1145 struct resource *res;
942 1146
943 if (strlen(android_boot_dev) && strcmp(android_boot_dev, dev_name(dev))) 1147 if (strlen(android_boot_dev) && strcmp(android_boot_dev, dev_name(dev)))
944 return -ENODEV; 1148 return -ENODEV;
@@ -950,9 +1154,15 @@ static int ufs_qcom_init(struct ufs_hba *hba)
950 goto out; 1154 goto out;
951 } 1155 }
952 1156
1157 /* Make a two way bind between the qcom host and the hba */
953 host->hba = hba; 1158 host->hba = hba;
954 hba->priv = (void *)host; 1159 ufshcd_set_variant(hba, host);
955 1160
1161 /*
1162 * voting/devoting device ref_clk source is time consuming hence
1163 * skip devoting it during aggressive clock gating. This clock
1164 * will still be gated off during runtime suspend.
1165 */
956 host->generic_phy = devm_phy_get(dev, "ufsphy"); 1166 host->generic_phy = devm_phy_get(dev, "ufsphy");
957 1167
958 if (IS_ERR(host->generic_phy)) { 1168 if (IS_ERR(host->generic_phy)) {
@@ -968,6 +1178,30 @@ static int ufs_qcom_init(struct ufs_hba *hba)
968 ufs_qcom_get_controller_revision(hba, &host->hw_ver.major, 1178 ufs_qcom_get_controller_revision(hba, &host->hw_ver.major,
969 &host->hw_ver.minor, &host->hw_ver.step); 1179 &host->hw_ver.minor, &host->hw_ver.step);
970 1180
1181 /*
1182 * for newer controllers, device reference clock control bit has
1183 * moved inside UFS controller register address space itself.
1184 */
1185 if (host->hw_ver.major >= 0x02) {
1186 host->dev_ref_clk_ctrl_mmio = hba->mmio_base + REG_UFS_CFG1;
1187 host->dev_ref_clk_en_mask = BIT(26);
1188 } else {
1189 /* "dev_ref_clk_ctrl_mem" is optional resource */
1190 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1191 if (res) {
1192 host->dev_ref_clk_ctrl_mmio =
1193 devm_ioremap_resource(dev, res);
1194 if (IS_ERR(host->dev_ref_clk_ctrl_mmio)) {
1195 dev_warn(dev,
1196 "%s: could not map dev_ref_clk_ctrl_mmio, err %ld\n",
1197 __func__,
1198 PTR_ERR(host->dev_ref_clk_ctrl_mmio));
1199 host->dev_ref_clk_ctrl_mmio = NULL;
1200 }
1201 host->dev_ref_clk_en_mask = BIT(5);
1202 }
1203 }
1204
971 /* update phy revision information before calling phy_init() */ 1205 /* update phy revision information before calling phy_init() */
972 ufs_qcom_phy_save_controller_version(host->generic_phy, 1206 ufs_qcom_phy_save_controller_version(host->generic_phy,
973 host->hw_ver.major, host->hw_ver.minor, host->hw_ver.step); 1207 host->hw_ver.major, host->hw_ver.minor, host->hw_ver.step);
@@ -984,14 +1218,20 @@ static int ufs_qcom_init(struct ufs_hba *hba)
984 ufs_qcom_set_caps(hba); 1218 ufs_qcom_set_caps(hba);
985 ufs_qcom_advertise_quirks(hba); 1219 ufs_qcom_advertise_quirks(hba);
986 1220
987 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_CLK_SCALING;
988 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
989
990 ufs_qcom_setup_clocks(hba, true); 1221 ufs_qcom_setup_clocks(hba, true);
991 1222
992 if (hba->dev->id < MAX_UFS_QCOM_HOSTS) 1223 if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
993 ufs_qcom_hosts[hba->dev->id] = host; 1224 ufs_qcom_hosts[hba->dev->id] = host;
994 1225
1226 host->dbg_print_en |= UFS_QCOM_DEFAULT_DBG_PRINT_EN;
1227 ufs_qcom_get_default_testbus_cfg(host);
1228 err = ufs_qcom_testbus_config(host);
1229 if (err) {
1230 dev_warn(dev, "%s: failed to configure the testbus %d\n",
1231 __func__, err);
1232 err = 0;
1233 }
1234
995 goto out; 1235 goto out;
996 1236
997out_disable_phy: 1237out_disable_phy:
@@ -1000,40 +1240,266 @@ out_unregister_bus:
1000 phy_exit(host->generic_phy); 1240 phy_exit(host->generic_phy);
1001out_host_free: 1241out_host_free:
1002 devm_kfree(dev, host); 1242 devm_kfree(dev, host);
1003 hba->priv = NULL; 1243 ufshcd_set_variant(hba, NULL);
1004out: 1244out:
1005 return err; 1245 return err;
1006} 1246}
1007 1247
1008static void ufs_qcom_exit(struct ufs_hba *hba) 1248static void ufs_qcom_exit(struct ufs_hba *hba)
1009{ 1249{
1010 struct ufs_qcom_host *host = hba->priv; 1250 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1011 1251
1012 ufs_qcom_disable_lane_clks(host); 1252 ufs_qcom_disable_lane_clks(host);
1013 phy_power_off(host->generic_phy); 1253 phy_power_off(host->generic_phy);
1014} 1254}
1015 1255
1016static 1256static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
1017void ufs_qcom_clk_scale_notify(struct ufs_hba *hba) 1257 u32 clk_cycles)
1258{
1259 int err;
1260 u32 core_clk_ctrl_reg;
1261
1262 if (clk_cycles > DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK)
1263 return -EINVAL;
1264
1265 err = ufshcd_dme_get(hba,
1266 UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
1267 &core_clk_ctrl_reg);
1268 if (err)
1269 goto out;
1270
1271 core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK;
1272 core_clk_ctrl_reg |= clk_cycles;
1273
1274 /* Clear CORE_CLK_DIV_EN */
1275 core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
1276
1277 err = ufshcd_dme_set(hba,
1278 UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
1279 core_clk_ctrl_reg);
1280out:
1281 return err;
1282}
1283
1284static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba)
1285{
1286 /* nothing to do as of now */
1287 return 0;
1288}
1289
1290static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
1291{
1292 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1293
1294 if (!ufs_qcom_cap_qunipro(host))
1295 return 0;
1296
1297 /* set unipro core clock cycles to 150 and clear clock divider */
1298 return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150);
1299}
1300
1301static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
1302{
1303 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1304 int err;
1305 u32 core_clk_ctrl_reg;
1306
1307 if (!ufs_qcom_cap_qunipro(host))
1308 return 0;
1309
1310 err = ufshcd_dme_get(hba,
1311 UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
1312 &core_clk_ctrl_reg);
1313
1314 /* make sure CORE_CLK_DIV_EN is cleared */
1315 if (!err &&
1316 (core_clk_ctrl_reg & DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT)) {
1317 core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
1318 err = ufshcd_dme_set(hba,
1319 UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
1320 core_clk_ctrl_reg);
1321 }
1322
1323 return err;
1324}
1325
1326static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba)
1327{
1328 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1329
1330 if (!ufs_qcom_cap_qunipro(host))
1331 return 0;
1332
1333 /* set unipro core clock cycles to 75 and clear clock divider */
1334 return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 75);
1335}
1336
1337static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
1338 bool scale_up, enum ufs_notify_change_status status)
1018{ 1339{
1019 struct ufs_qcom_host *host = hba->priv; 1340 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1020 struct ufs_pa_layer_attr *dev_req_params = &host->dev_req_params; 1341 struct ufs_pa_layer_attr *dev_req_params = &host->dev_req_params;
1342 int err = 0;
1021 1343
1022 if (!dev_req_params) 1344 if (status == PRE_CHANGE) {
1023 return; 1345 if (scale_up)
1346 err = ufs_qcom_clk_scale_up_pre_change(hba);
1347 else
1348 err = ufs_qcom_clk_scale_down_pre_change(hba);
1349 } else {
1350 if (scale_up)
1351 err = ufs_qcom_clk_scale_up_post_change(hba);
1352 else
1353 err = ufs_qcom_clk_scale_down_post_change(hba);
1024 1354
1025 ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx, 1355 if (err || !dev_req_params)
1026 dev_req_params->pwr_rx, 1356 goto out;
1027 dev_req_params->hs_rate); 1357
1358 ufs_qcom_cfg_timers(hba,
1359 dev_req_params->gear_rx,
1360 dev_req_params->pwr_rx,
1361 dev_req_params->hs_rate,
1362 false);
1363 ufs_qcom_update_bus_bw_vote(host);
1364 }
1365
1366out:
1367 return err;
1028} 1368}
1029 1369
1370static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host)
1371{
1372 /* provide a legal default configuration */
1373 host->testbus.select_major = TSTBUS_UAWM;
1374 host->testbus.select_minor = 1;
1375}
1376
1377static bool ufs_qcom_testbus_cfg_is_ok(struct ufs_qcom_host *host)
1378{
1379 if (host->testbus.select_major >= TSTBUS_MAX) {
1380 dev_err(host->hba->dev,
1381 "%s: UFS_CFG1[TEST_BUS_SEL} may not equal 0x%05X\n",
1382 __func__, host->testbus.select_major);
1383 return false;
1384 }
1385
1386 /*
1387 * Not performing check for each individual select_major
1388 * mappings of select_minor, since there is no harm in
1389 * configuring a non-existent select_minor
1390 */
1391 if (host->testbus.select_minor > 0x1F) {
1392 dev_err(host->hba->dev,
1393 "%s: 0x%05X is not a legal testbus option\n",
1394 __func__, host->testbus.select_minor);
1395 return false;
1396 }
1397
1398 return true;
1399}
1400
1401int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
1402{
1403 int reg;
1404 int offset;
1405 u32 mask = TEST_BUS_SUB_SEL_MASK;
1406
1407 if (!host)
1408 return -EINVAL;
1409
1410 if (!ufs_qcom_testbus_cfg_is_ok(host))
1411 return -EPERM;
1412
1413 switch (host->testbus.select_major) {
1414 case TSTBUS_UAWM:
1415 reg = UFS_TEST_BUS_CTRL_0;
1416 offset = 24;
1417 break;
1418 case TSTBUS_UARM:
1419 reg = UFS_TEST_BUS_CTRL_0;
1420 offset = 16;
1421 break;
1422 case TSTBUS_TXUC:
1423 reg = UFS_TEST_BUS_CTRL_0;
1424 offset = 8;
1425 break;
1426 case TSTBUS_RXUC:
1427 reg = UFS_TEST_BUS_CTRL_0;
1428 offset = 0;
1429 break;
1430 case TSTBUS_DFC:
1431 reg = UFS_TEST_BUS_CTRL_1;
1432 offset = 24;
1433 break;
1434 case TSTBUS_TRLUT:
1435 reg = UFS_TEST_BUS_CTRL_1;
1436 offset = 16;
1437 break;
1438 case TSTBUS_TMRLUT:
1439 reg = UFS_TEST_BUS_CTRL_1;
1440 offset = 8;
1441 break;
1442 case TSTBUS_OCSC:
1443 reg = UFS_TEST_BUS_CTRL_1;
1444 offset = 0;
1445 break;
1446 case TSTBUS_WRAPPER:
1447 reg = UFS_TEST_BUS_CTRL_2;
1448 offset = 16;
1449 break;
1450 case TSTBUS_COMBINED:
1451 reg = UFS_TEST_BUS_CTRL_2;
1452 offset = 8;
1453 break;
1454 case TSTBUS_UTP_HCI:
1455 reg = UFS_TEST_BUS_CTRL_2;
1456 offset = 0;
1457 break;
1458 case TSTBUS_UNIPRO:
1459 reg = UFS_UNIPRO_CFG;
1460 offset = 1;
1461 break;
1462 /*
1463 * No need for a default case, since
1464 * ufs_qcom_testbus_cfg_is_ok() checks that the configuration
1465 * is legal
1466 */
1467 }
1468 mask <<= offset;
1469
1470 pm_runtime_get_sync(host->hba->dev);
1471 ufshcd_hold(host->hba, false);
1472 ufshcd_rmwl(host->hba, TEST_BUS_SEL,
1473 (u32)host->testbus.select_major << 19,
1474 REG_UFS_CFG1);
1475 ufshcd_rmwl(host->hba, mask,
1476 (u32)host->testbus.select_minor << offset,
1477 reg);
1478 ufshcd_release(host->hba);
1479 pm_runtime_put_sync(host->hba->dev);
1480
1481 return 0;
1482}
1483
1484static void ufs_qcom_testbus_read(struct ufs_hba *hba)
1485{
1486 ufs_qcom_dump_regs(hba, UFS_TEST_BUS, 1, "UFS_TEST_BUS ");
1487}
1488
1489static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
1490{
1491 ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 16,
1492 "HCI Vendor Specific Registers ");
1493
1494 ufs_qcom_testbus_read(hba);
1495}
1030/** 1496/**
1031 * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations 1497 * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
1032 * 1498 *
1033 * The variant operations configure the necessary controller and PHY 1499 * The variant operations configure the necessary controller and PHY
1034 * handshake during initialization. 1500 * handshake during initialization.
1035 */ 1501 */
1036static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { 1502static struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
1037 .name = "qcom", 1503 .name = "qcom",
1038 .init = ufs_qcom_init, 1504 .init = ufs_qcom_init,
1039 .exit = ufs_qcom_exit, 1505 .exit = ufs_qcom_exit,
@@ -1045,5 +1511,66 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
1045 .pwr_change_notify = ufs_qcom_pwr_change_notify, 1511 .pwr_change_notify = ufs_qcom_pwr_change_notify,
1046 .suspend = ufs_qcom_suspend, 1512 .suspend = ufs_qcom_suspend,
1047 .resume = ufs_qcom_resume, 1513 .resume = ufs_qcom_resume,
1514 .dbg_register_dump = ufs_qcom_dump_dbg_regs,
1515};
1516
1517/**
1518 * ufs_qcom_probe - probe routine of the driver
1519 * @pdev: pointer to Platform device handle
1520 *
1521 * Return zero for success and non-zero for failure
1522 */
1523static int ufs_qcom_probe(struct platform_device *pdev)
1524{
1525 int err;
1526 struct device *dev = &pdev->dev;
1527
1528 /* Perform generic probe */
1529 err = ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_vops);
1530 if (err)
1531 dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
1532
1533 return err;
1534}
1535
1536/**
1537 * ufs_qcom_remove - set driver_data of the device to NULL
1538 * @pdev: pointer to platform device handle
1539 *
1540 * Always return 0
1541 */
1542static int ufs_qcom_remove(struct platform_device *pdev)
1543{
1544 struct ufs_hba *hba = platform_get_drvdata(pdev);
1545
1546 pm_runtime_get_sync(&(pdev)->dev);
1547 ufshcd_remove(hba);
1548 return 0;
1549}
1550
1551static const struct of_device_id ufs_qcom_of_match[] = {
1552 { .compatible = "qcom,ufshc"},
1553 {},
1554};
1555
1556static const struct dev_pm_ops ufs_qcom_pm_ops = {
1557 .suspend = ufshcd_pltfrm_suspend,
1558 .resume = ufshcd_pltfrm_resume,
1559 .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
1560 .runtime_resume = ufshcd_pltfrm_runtime_resume,
1561 .runtime_idle = ufshcd_pltfrm_runtime_idle,
1048}; 1562};
1049EXPORT_SYMBOL(ufs_hba_qcom_vops); 1563
1564static struct platform_driver ufs_qcom_pltform = {
1565 .probe = ufs_qcom_probe,
1566 .remove = ufs_qcom_remove,
1567 .shutdown = ufshcd_pltfrm_shutdown,
1568 .driver = {
1569 .name = "ufshcd-qcom",
1570 .pm = &ufs_qcom_pm_ops,
1571 .of_match_table = of_match_ptr(ufs_qcom_of_match),
1572 },
1573};
1574module_platform_driver(ufs_qcom_pltform);
1575
1576MODULE_LICENSE("GPL v2");
diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h
index db2c0a00e846..36249b35f858 100644
--- a/drivers/scsi/ufs/ufs-qcom.h
+++ b/drivers/scsi/ufs/ufs-qcom.h
@@ -35,8 +35,8 @@
35 35
36#define UFS_QCOM_LIMIT_NUM_LANES_RX 2 36#define UFS_QCOM_LIMIT_NUM_LANES_RX 2
37#define UFS_QCOM_LIMIT_NUM_LANES_TX 2 37#define UFS_QCOM_LIMIT_NUM_LANES_TX 2
38#define UFS_QCOM_LIMIT_HSGEAR_RX UFS_HS_G2 38#define UFS_QCOM_LIMIT_HSGEAR_RX UFS_HS_G3
39#define UFS_QCOM_LIMIT_HSGEAR_TX UFS_HS_G2 39#define UFS_QCOM_LIMIT_HSGEAR_TX UFS_HS_G3
40#define UFS_QCOM_LIMIT_PWMGEAR_RX UFS_PWM_G4 40#define UFS_QCOM_LIMIT_PWMGEAR_RX UFS_PWM_G4
41#define UFS_QCOM_LIMIT_PWMGEAR_TX UFS_PWM_G4 41#define UFS_QCOM_LIMIT_PWMGEAR_TX UFS_PWM_G4
42#define UFS_QCOM_LIMIT_RX_PWR_PWM SLOW_MODE 42#define UFS_QCOM_LIMIT_RX_PWR_PWM SLOW_MODE
@@ -58,6 +58,21 @@ enum {
58 REG_UFS_CFG2 = 0xE0, 58 REG_UFS_CFG2 = 0xE0,
59 REG_UFS_HW_VERSION = 0xE4, 59 REG_UFS_HW_VERSION = 0xE4,
60 60
61 UFS_TEST_BUS = 0xE8,
62 UFS_TEST_BUS_CTRL_0 = 0xEC,
63 UFS_TEST_BUS_CTRL_1 = 0xF0,
64 UFS_TEST_BUS_CTRL_2 = 0xF4,
65 UFS_UNIPRO_CFG = 0xF8,
66
67 /*
68 * QCOM UFS host controller vendor specific registers
69 * added in HW Version 3.0.0
70 */
71 UFS_AH8_CFG = 0xFC,
72};
73
74/* QCOM UFS host controller vendor specific debug registers */
75enum {
61 UFS_DBG_RD_REG_UAWM = 0x100, 76 UFS_DBG_RD_REG_UAWM = 0x100,
62 UFS_DBG_RD_REG_UARM = 0x200, 77 UFS_DBG_RD_REG_UARM = 0x200,
63 UFS_DBG_RD_REG_TXUC = 0x300, 78 UFS_DBG_RD_REG_TXUC = 0x300,
@@ -73,6 +88,14 @@ enum {
73 UFS_UFS_DBG_RD_EDTL_RAM = 0x1900, 88 UFS_UFS_DBG_RD_EDTL_RAM = 0x1900,
74}; 89};
75 90
91#define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x) (0x000 + x)
92#define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x) (0x400 + x)
93
94/* bit definitions for REG_UFS_CFG1 register */
95#define QUNIPRO_SEL UFS_BIT(0)
96#define TEST_BUS_EN BIT(18)
97#define TEST_BUS_SEL GENMASK(22, 19)
98
76/* bit definitions for REG_UFS_CFG2 register */ 99/* bit definitions for REG_UFS_CFG2 register */
77#define UAWM_HW_CGC_EN (1 << 0) 100#define UAWM_HW_CGC_EN (1 << 0)
78#define UARM_HW_CGC_EN (1 << 1) 101#define UARM_HW_CGC_EN (1 << 1)
@@ -83,6 +106,9 @@ enum {
83#define TMRLUT_HW_CGC_EN (1 << 6) 106#define TMRLUT_HW_CGC_EN (1 << 6)
84#define OCSC_HW_CGC_EN (1 << 7) 107#define OCSC_HW_CGC_EN (1 << 7)
85 108
109/* bit definition for UFS_UFS_TEST_BUS_CTRL_n */
110#define TEST_BUS_SUB_SEL_MASK 0x1F /* All XXX_SEL fields are 5 bits wide */
111
86#define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\ 112#define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\
87 TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\ 113 TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\
88 DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\ 114 DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\
@@ -106,6 +132,21 @@ enum ufs_qcom_phy_init_type {
106 UFS_PHY_INIT_CFG_RESTORE, 132 UFS_PHY_INIT_CFG_RESTORE,
107}; 133};
108 134
135/* QCOM UFS debug print bit mask */
136#define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0)
137#define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1)
138#define UFS_QCOM_DBG_PRINT_TEST_BUS_EN BIT(2)
139
140#define UFS_QCOM_DBG_PRINT_ALL \
141 (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_ICE_REGS_EN | \
142 UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
143
144/* QUniPro Vendor specific attributes */
145#define DME_VS_CORE_CLK_CTRL 0xD002
146/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
147#define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8)
148#define DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK 0xFF
149
109static inline void 150static inline void
110ufs_qcom_get_controller_revision(struct ufs_hba *hba, 151ufs_qcom_get_controller_revision(struct ufs_hba *hba,
111 u8 *major, u16 *minor, u16 *step) 152 u8 *major, u16 *minor, u16 *step)
@@ -157,8 +198,13 @@ struct ufs_hw_version {
157 u16 minor; 198 u16 minor;
158 u8 major; 199 u8 major;
159}; 200};
160struct ufs_qcom_host {
161 201
202struct ufs_qcom_testbus {
203 u8 select_major;
204 u8 select_minor;
205};
206
207struct ufs_qcom_host {
162 /* 208 /*
163 * Set this capability if host controller supports the QUniPro mode 209 * Set this capability if host controller supports the QUniPro mode
164 * and if driver wants the Host controller to operate in QUniPro mode. 210 * and if driver wants the Host controller to operate in QUniPro mode.
@@ -166,6 +212,12 @@ struct ufs_qcom_host {
166 * controller supports the QUniPro mode. 212 * controller supports the QUniPro mode.
167 */ 213 */
168 #define UFS_QCOM_CAP_QUNIPRO UFS_BIT(0) 214 #define UFS_QCOM_CAP_QUNIPRO UFS_BIT(0)
215
216 /*
217 * Set this capability if host controller can retain the secure
218 * configuration even after UFS controller core power collapse.
219 */
220 #define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE UFS_BIT(1)
169 u32 caps; 221 u32 caps;
170 222
171 struct phy *generic_phy; 223 struct phy *generic_phy;
@@ -178,13 +230,23 @@ struct ufs_qcom_host {
178 struct clk *tx_l1_sync_clk; 230 struct clk *tx_l1_sync_clk;
179 bool is_lane_clks_enabled; 231 bool is_lane_clks_enabled;
180 232
233 void __iomem *dev_ref_clk_ctrl_mmio;
234 bool is_dev_ref_clk_enabled;
181 struct ufs_hw_version hw_ver; 235 struct ufs_hw_version hw_ver;
236
237 u32 dev_ref_clk_en_mask;
238
239 /* Bitmask for enabling debug prints */
240 u32 dbg_print_en;
241 struct ufs_qcom_testbus testbus;
182}; 242};
183 243
184#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba) 244#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba)
185#define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba) 245#define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba)
186#define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba) 246#define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba)
187 247
248int ufs_qcom_testbus_config(struct ufs_qcom_host *host);
249
188static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host) 250static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host)
189{ 251{
190 if (host->caps & UFS_QCOM_CAP_QUNIPRO) 252 if (host->caps & UFS_QCOM_CAP_QUNIPRO)
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 7db9564f507d..9714f2a8b329 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -38,20 +38,7 @@
38#include <linux/of.h> 38#include <linux/of.h>
39 39
40#include "ufshcd.h" 40#include "ufshcd.h"
41 41#include "ufshcd-pltfrm.h"
42static const struct of_device_id ufs_of_match[];
43static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev)
44{
45 if (dev->of_node) {
46 const struct of_device_id *match;
47
48 match = of_match_node(ufs_of_match, dev->of_node);
49 if (match)
50 return (struct ufs_hba_variant_ops *)match->data;
51 }
52
53 return NULL;
54}
55 42
56static int ufshcd_parse_clock_info(struct ufs_hba *hba) 43static int ufshcd_parse_clock_info(struct ufs_hba *hba)
57{ 44{
@@ -245,10 +232,11 @@ out:
245 * Returns 0 if successful 232 * Returns 0 if successful
246 * Returns non-zero otherwise 233 * Returns non-zero otherwise
247 */ 234 */
248static int ufshcd_pltfrm_suspend(struct device *dev) 235int ufshcd_pltfrm_suspend(struct device *dev)
249{ 236{
250 return ufshcd_system_suspend(dev_get_drvdata(dev)); 237 return ufshcd_system_suspend(dev_get_drvdata(dev));
251} 238}
239EXPORT_SYMBOL_GPL(ufshcd_pltfrm_suspend);
252 240
253/** 241/**
254 * ufshcd_pltfrm_resume - resume power management function 242 * ufshcd_pltfrm_resume - resume power management function
@@ -257,43 +245,47 @@ static int ufshcd_pltfrm_suspend(struct device *dev)
257 * Returns 0 if successful 245 * Returns 0 if successful
258 * Returns non-zero otherwise 246 * Returns non-zero otherwise
259 */ 247 */
260static int ufshcd_pltfrm_resume(struct device *dev) 248int ufshcd_pltfrm_resume(struct device *dev)
261{ 249{
262 return ufshcd_system_resume(dev_get_drvdata(dev)); 250 return ufshcd_system_resume(dev_get_drvdata(dev));
263} 251}
252EXPORT_SYMBOL_GPL(ufshcd_pltfrm_resume);
264 253
265static int ufshcd_pltfrm_runtime_suspend(struct device *dev) 254int ufshcd_pltfrm_runtime_suspend(struct device *dev)
266{ 255{
267 return ufshcd_runtime_suspend(dev_get_drvdata(dev)); 256 return ufshcd_runtime_suspend(dev_get_drvdata(dev));
268} 257}
269static int ufshcd_pltfrm_runtime_resume(struct device *dev) 258EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_suspend);
259
260int ufshcd_pltfrm_runtime_resume(struct device *dev)
270{ 261{
271 return ufshcd_runtime_resume(dev_get_drvdata(dev)); 262 return ufshcd_runtime_resume(dev_get_drvdata(dev));
272} 263}
273static int ufshcd_pltfrm_runtime_idle(struct device *dev) 264EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_resume);
265
266int ufshcd_pltfrm_runtime_idle(struct device *dev)
274{ 267{
275 return ufshcd_runtime_idle(dev_get_drvdata(dev)); 268 return ufshcd_runtime_idle(dev_get_drvdata(dev));
276} 269}
277#else /* !CONFIG_PM */ 270EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_idle);
278#define ufshcd_pltfrm_suspend NULL 271
279#define ufshcd_pltfrm_resume NULL
280#define ufshcd_pltfrm_runtime_suspend NULL
281#define ufshcd_pltfrm_runtime_resume NULL
282#define ufshcd_pltfrm_runtime_idle NULL
283#endif /* CONFIG_PM */ 272#endif /* CONFIG_PM */
284 273
285static void ufshcd_pltfrm_shutdown(struct platform_device *pdev) 274void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
286{ 275{
287 ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev)); 276 ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev));
288} 277}
278EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown);
289 279
290/** 280/**
291 * ufshcd_pltfrm_probe - probe routine of the driver 281 * ufshcd_pltfrm_init - probe routine of the driver
292 * @pdev: pointer to Platform device handle 282 * @pdev: pointer to Platform device handle
283 * @vops: pointer to variant ops
293 * 284 *
294 * Returns 0 on success, non-zero value on failure 285 * Returns 0 on success, non-zero value on failure
295 */ 286 */
296static int ufshcd_pltfrm_probe(struct platform_device *pdev) 287int ufshcd_pltfrm_init(struct platform_device *pdev,
288 struct ufs_hba_variant_ops *vops)
297{ 289{
298 struct ufs_hba *hba; 290 struct ufs_hba *hba;
299 void __iomem *mmio_base; 291 void __iomem *mmio_base;
@@ -321,19 +313,19 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
321 goto out; 313 goto out;
322 } 314 }
323 315
324 hba->vops = get_variant_ops(&pdev->dev); 316 hba->vops = vops;
325 317
326 err = ufshcd_parse_clock_info(hba); 318 err = ufshcd_parse_clock_info(hba);
327 if (err) { 319 if (err) {
328 dev_err(&pdev->dev, "%s: clock parse failed %d\n", 320 dev_err(&pdev->dev, "%s: clock parse failed %d\n",
329 __func__, err); 321 __func__, err);
330 goto out; 322 goto dealloc_host;
331 } 323 }
332 err = ufshcd_parse_regulator_info(hba); 324 err = ufshcd_parse_regulator_info(hba);
333 if (err) { 325 if (err) {
334 dev_err(&pdev->dev, "%s: regulator init failed %d\n", 326 dev_err(&pdev->dev, "%s: regulator init failed %d\n",
335 __func__, err); 327 __func__, err);
336 goto out; 328 goto dealloc_host;
337 } 329 }
338 330
339 pm_runtime_set_active(&pdev->dev); 331 pm_runtime_set_active(&pdev->dev);
@@ -352,50 +344,12 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
352out_disable_rpm: 344out_disable_rpm:
353 pm_runtime_disable(&pdev->dev); 345 pm_runtime_disable(&pdev->dev);
354 pm_runtime_set_suspended(&pdev->dev); 346 pm_runtime_set_suspended(&pdev->dev);
347dealloc_host:
348 ufshcd_dealloc_host(hba);
355out: 349out:
356 return err; 350 return err;
357} 351}
358 352EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);
359/**
360 * ufshcd_pltfrm_remove - remove platform driver routine
361 * @pdev: pointer to platform device handle
362 *
363 * Returns 0 on success, non-zero value on failure
364 */
365static int ufshcd_pltfrm_remove(struct platform_device *pdev)
366{
367 struct ufs_hba *hba = platform_get_drvdata(pdev);
368
369 pm_runtime_get_sync(&(pdev)->dev);
370 ufshcd_remove(hba);
371 return 0;
372}
373
374static const struct of_device_id ufs_of_match[] = {
375 { .compatible = "jedec,ufs-1.1"},
376 {},
377};
378
379static const struct dev_pm_ops ufshcd_dev_pm_ops = {
380 .suspend = ufshcd_pltfrm_suspend,
381 .resume = ufshcd_pltfrm_resume,
382 .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
383 .runtime_resume = ufshcd_pltfrm_runtime_resume,
384 .runtime_idle = ufshcd_pltfrm_runtime_idle,
385};
386
387static struct platform_driver ufshcd_pltfrm_driver = {
388 .probe = ufshcd_pltfrm_probe,
389 .remove = ufshcd_pltfrm_remove,
390 .shutdown = ufshcd_pltfrm_shutdown,
391 .driver = {
392 .name = "ufshcd",
393 .pm = &ufshcd_dev_pm_ops,
394 .of_match_table = ufs_of_match,
395 },
396};
397
398module_platform_driver(ufshcd_pltfrm_driver);
399 353
400MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>"); 354MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
401MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>"); 355MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h
new file mode 100644
index 000000000000..df64c4180340
--- /dev/null
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.h
@@ -0,0 +1,41 @@
1/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#ifndef UFSHCD_PLTFRM_H_
15#define UFSHCD_PLTFRM_H_
16
17#include "ufshcd.h"
18
19int ufshcd_pltfrm_init(struct platform_device *pdev,
20 struct ufs_hba_variant_ops *vops);
21void ufshcd_pltfrm_shutdown(struct platform_device *pdev);
22
23#ifdef CONFIG_PM
24
25int ufshcd_pltfrm_suspend(struct device *dev);
26int ufshcd_pltfrm_resume(struct device *dev);
27int ufshcd_pltfrm_runtime_suspend(struct device *dev);
28int ufshcd_pltfrm_runtime_resume(struct device *dev);
29int ufshcd_pltfrm_runtime_idle(struct device *dev);
30
31#else /* !CONFIG_PM */
32
33#define ufshcd_pltfrm_suspend NULL
34#define ufshcd_pltfrm_resume NULL
35#define ufshcd_pltfrm_runtime_suspend NULL
36#define ufshcd_pltfrm_runtime_resume NULL
37#define ufshcd_pltfrm_runtime_idle NULL
38
39#endif /* CONFIG_PM */
40
41#endif /* UFSHCD_PLTFRM_H_ */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index b0ade73f8c6a..85cd2564c157 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -271,10 +271,8 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
271 */ 271 */
272static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) 272static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba)
273{ 273{
274 if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) { 274 if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION)
275 if (hba->vops && hba->vops->get_ufs_hci_version) 275 return ufshcd_vops_get_ufs_hci_version(hba);
276 return hba->vops->get_ufs_hci_version(hba);
277 }
278 276
279 return ufshcd_readl(hba, REG_UFS_VERSION); 277 return ufshcd_readl(hba, REG_UFS_VERSION);
280} 278}
@@ -627,6 +625,7 @@ start:
627out: 625out:
628 return rc; 626 return rc;
629} 627}
628EXPORT_SYMBOL_GPL(ufshcd_hold);
630 629
631static void ufshcd_gate_work(struct work_struct *work) 630static void ufshcd_gate_work(struct work_struct *work)
632{ 631{
@@ -714,6 +713,7 @@ void ufshcd_release(struct ufs_hba *hba)
714 __ufshcd_release(hba); 713 __ufshcd_release(hba);
715 spin_unlock_irqrestore(hba->host->host_lock, flags); 714 spin_unlock_irqrestore(hba->host->host_lock, flags);
716} 715}
716EXPORT_SYMBOL_GPL(ufshcd_release);
717 717
718static ssize_t ufshcd_clkgate_delay_show(struct device *dev, 718static ssize_t ufshcd_clkgate_delay_show(struct device *dev,
719 struct device_attribute *attr, char *buf) 719 struct device_attribute *attr, char *buf)
@@ -2473,9 +2473,8 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba,
2473 dev_err(hba->dev, 2473 dev_err(hba->dev,
2474 "%s: power mode change failed %d\n", __func__, ret); 2474 "%s: power mode change failed %d\n", __func__, ret);
2475 } else { 2475 } else {
2476 if (hba->vops && hba->vops->pwr_change_notify) 2476 ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, NULL,
2477 hba->vops->pwr_change_notify(hba, 2477 pwr_mode);
2478 POST_CHANGE, NULL, pwr_mode);
2479 2478
2480 memcpy(&hba->pwr_info, pwr_mode, 2479 memcpy(&hba->pwr_info, pwr_mode,
2481 sizeof(struct ufs_pa_layer_attr)); 2480 sizeof(struct ufs_pa_layer_attr));
@@ -2495,10 +2494,10 @@ static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
2495 struct ufs_pa_layer_attr final_params = { 0 }; 2494 struct ufs_pa_layer_attr final_params = { 0 };
2496 int ret; 2495 int ret;
2497 2496
2498 if (hba->vops && hba->vops->pwr_change_notify) 2497 ret = ufshcd_vops_pwr_change_notify(hba, PRE_CHANGE,
2499 hba->vops->pwr_change_notify(hba, 2498 desired_pwr_mode, &final_params);
2500 PRE_CHANGE, desired_pwr_mode, &final_params); 2499
2501 else 2500 if (ret)
2502 memcpy(&final_params, desired_pwr_mode, sizeof(final_params)); 2501 memcpy(&final_params, desired_pwr_mode, sizeof(final_params));
2503 2502
2504 ret = ufshcd_change_power_mode(hba, &final_params); 2503 ret = ufshcd_change_power_mode(hba, &final_params);
@@ -2647,8 +2646,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
2647 /* UniPro link is disabled at this point */ 2646 /* UniPro link is disabled at this point */
2648 ufshcd_set_link_off(hba); 2647 ufshcd_set_link_off(hba);
2649 2648
2650 if (hba->vops && hba->vops->hce_enable_notify) 2649 ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE);
2651 hba->vops->hce_enable_notify(hba, PRE_CHANGE);
2652 2650
2653 /* start controller initialization sequence */ 2651 /* start controller initialization sequence */
2654 ufshcd_hba_start(hba); 2652 ufshcd_hba_start(hba);
@@ -2681,8 +2679,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
2681 /* enable UIC related interrupts */ 2679 /* enable UIC related interrupts */
2682 ufshcd_enable_intr(hba, UFSHCD_UIC_MASK); 2680 ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
2683 2681
2684 if (hba->vops && hba->vops->hce_enable_notify) 2682 ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
2685 hba->vops->hce_enable_notify(hba, POST_CHANGE);
2686 2683
2687 return 0; 2684 return 0;
2688} 2685}
@@ -2735,8 +2732,7 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
2735 int retries = DME_LINKSTARTUP_RETRIES; 2732 int retries = DME_LINKSTARTUP_RETRIES;
2736 2733
2737 do { 2734 do {
2738 if (hba->vops && hba->vops->link_startup_notify) 2735 ufshcd_vops_link_startup_notify(hba, PRE_CHANGE);
2739 hba->vops->link_startup_notify(hba, PRE_CHANGE);
2740 2736
2741 ret = ufshcd_dme_link_startup(hba); 2737 ret = ufshcd_dme_link_startup(hba);
2742 2738
@@ -2767,11 +2763,9 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
2767 } 2763 }
2768 2764
2769 /* Include any host controller configuration via UIC commands */ 2765 /* Include any host controller configuration via UIC commands */
2770 if (hba->vops && hba->vops->link_startup_notify) { 2766 ret = ufshcd_vops_link_startup_notify(hba, POST_CHANGE);
2771 ret = hba->vops->link_startup_notify(hba, POST_CHANGE); 2767 if (ret)
2772 if (ret) 2768 goto out;
2773 goto out;
2774 }
2775 2769
2776 ret = ufshcd_make_hba_operational(hba); 2770 ret = ufshcd_make_hba_operational(hba);
2777out: 2771out:
@@ -4355,7 +4349,6 @@ static struct scsi_host_template ufshcd_driver_template = {
4355 .cmd_per_lun = UFSHCD_CMD_PER_LUN, 4349 .cmd_per_lun = UFSHCD_CMD_PER_LUN,
4356 .can_queue = UFSHCD_CAN_QUEUE, 4350 .can_queue = UFSHCD_CAN_QUEUE,
4357 .max_host_blocked = 1, 4351 .max_host_blocked = 1,
4358 .use_blk_tags = 1,
4359 .track_queue_depth = 1, 4352 .track_queue_depth = 1,
4360}; 4353};
4361 4354
@@ -4578,8 +4571,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
4578 } 4571 }
4579 } 4572 }
4580 4573
4581 if (hba->vops && hba->vops->setup_clocks) 4574 ret = ufshcd_vops_setup_clocks(hba, on);
4582 ret = hba->vops->setup_clocks(hba, on);
4583out: 4575out:
4584 if (ret) { 4576 if (ret) {
4585 list_for_each_entry(clki, head, list) { 4577 list_for_each_entry(clki, head, list) {
@@ -4645,27 +4637,22 @@ static int ufshcd_variant_hba_init(struct ufs_hba *hba)
4645 if (!hba->vops) 4637 if (!hba->vops)
4646 goto out; 4638 goto out;
4647 4639
4648 if (hba->vops->init) { 4640 err = ufshcd_vops_init(hba);
4649 err = hba->vops->init(hba); 4641 if (err)
4650 if (err) 4642 goto out;
4651 goto out;
4652 }
4653 4643
4654 if (hba->vops->setup_regulators) { 4644 err = ufshcd_vops_setup_regulators(hba, true);
4655 err = hba->vops->setup_regulators(hba, true); 4645 if (err)
4656 if (err) 4646 goto out_exit;
4657 goto out_exit;
4658 }
4659 4647
4660 goto out; 4648 goto out;
4661 4649
4662out_exit: 4650out_exit:
4663 if (hba->vops->exit) 4651 ufshcd_vops_exit(hba);
4664 hba->vops->exit(hba);
4665out: 4652out:
4666 if (err) 4653 if (err)
4667 dev_err(hba->dev, "%s: variant %s init failed err %d\n", 4654 dev_err(hba->dev, "%s: variant %s init failed err %d\n",
4668 __func__, hba->vops ? hba->vops->name : "", err); 4655 __func__, ufshcd_get_var_name(hba), err);
4669 return err; 4656 return err;
4670} 4657}
4671 4658
@@ -4674,14 +4661,11 @@ static void ufshcd_variant_hba_exit(struct ufs_hba *hba)
4674 if (!hba->vops) 4661 if (!hba->vops)
4675 return; 4662 return;
4676 4663
4677 if (hba->vops->setup_clocks) 4664 ufshcd_vops_setup_clocks(hba, false);
4678 hba->vops->setup_clocks(hba, false);
4679 4665
4680 if (hba->vops->setup_regulators) 4666 ufshcd_vops_setup_regulators(hba, false);
4681 hba->vops->setup_regulators(hba, false);
4682 4667
4683 if (hba->vops->exit) 4668 ufshcd_vops_exit(hba);
4684 hba->vops->exit(hba);
4685} 4669}
4686 4670
4687static int ufshcd_hba_init(struct ufs_hba *hba) 4671static int ufshcd_hba_init(struct ufs_hba *hba)
@@ -5058,17 +5042,13 @@ disable_clks:
5058 * vendor specific host controller register space call them before the 5042 * vendor specific host controller register space call them before the
5059 * host clocks are ON. 5043 * host clocks are ON.
5060 */ 5044 */
5061 if (hba->vops && hba->vops->suspend) { 5045 ret = ufshcd_vops_suspend(hba, pm_op);
5062 ret = hba->vops->suspend(hba, pm_op); 5046 if (ret)
5063 if (ret) 5047 goto set_link_active;
5064 goto set_link_active;
5065 }
5066 5048
5067 if (hba->vops && hba->vops->setup_clocks) { 5049 ret = ufshcd_vops_setup_clocks(hba, false);
5068 ret = hba->vops->setup_clocks(hba, false); 5050 if (ret)
5069 if (ret) 5051 goto vops_resume;
5070 goto vops_resume;
5071 }
5072 5052
5073 if (!ufshcd_is_link_active(hba)) 5053 if (!ufshcd_is_link_active(hba))
5074 ufshcd_setup_clocks(hba, false); 5054 ufshcd_setup_clocks(hba, false);
@@ -5079,7 +5059,7 @@ disable_clks:
5079 hba->clk_gating.state = CLKS_OFF; 5059 hba->clk_gating.state = CLKS_OFF;
5080 /* 5060 /*
5081 * Disable the host irq as host controller as there won't be any 5061 * Disable the host irq as host controller as there won't be any
5082 * host controller trasanction expected till resume. 5062 * host controller transaction expected till resume.
5083 */ 5063 */
5084 ufshcd_disable_irq(hba); 5064 ufshcd_disable_irq(hba);
5085 /* Put the host controller in low power mode if possible */ 5065 /* Put the host controller in low power mode if possible */
@@ -5087,8 +5067,7 @@ disable_clks:
5087 goto out; 5067 goto out;
5088 5068
5089vops_resume: 5069vops_resume:
5090 if (hba->vops && hba->vops->resume) 5070 ufshcd_vops_resume(hba, pm_op);
5091 hba->vops->resume(hba, pm_op);
5092set_link_active: 5071set_link_active:
5093 ufshcd_vreg_set_hpm(hba); 5072 ufshcd_vreg_set_hpm(hba);
5094 if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) 5073 if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba))
@@ -5144,11 +5123,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
5144 * vendor specific host controller register space call them when the 5123 * vendor specific host controller register space call them when the
5145 * host clocks are ON. 5124 * host clocks are ON.
5146 */ 5125 */
5147 if (hba->vops && hba->vops->resume) { 5126 ret = ufshcd_vops_resume(hba, pm_op);
5148 ret = hba->vops->resume(hba, pm_op); 5127 if (ret)
5149 if (ret) 5128 goto disable_vreg;
5150 goto disable_vreg;
5151 }
5152 5129
5153 if (ufshcd_is_link_hibern8(hba)) { 5130 if (ufshcd_is_link_hibern8(hba)) {
5154 ret = ufshcd_uic_hibern8_exit(hba); 5131 ret = ufshcd_uic_hibern8_exit(hba);
@@ -5189,8 +5166,7 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
5189set_old_link_state: 5166set_old_link_state:
5190 ufshcd_link_state_transition(hba, old_link_state, 0); 5167 ufshcd_link_state_transition(hba, old_link_state, 0);
5191vendor_suspend: 5168vendor_suspend:
5192 if (hba->vops && hba->vops->suspend) 5169 ufshcd_vops_suspend(hba, pm_op);
5193 hba->vops->suspend(hba, pm_op);
5194disable_vreg: 5170disable_vreg:
5195 ufshcd_vreg_set_lpm(hba); 5171 ufshcd_vreg_set_lpm(hba);
5196disable_irq_and_vops_clks: 5172disable_irq_and_vops_clks:
@@ -5373,6 +5349,16 @@ void ufshcd_remove(struct ufs_hba *hba)
5373EXPORT_SYMBOL_GPL(ufshcd_remove); 5349EXPORT_SYMBOL_GPL(ufshcd_remove);
5374 5350
5375/** 5351/**
5352 * ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA)
5353 * @hba: pointer to Host Bus Adapter (HBA)
5354 */
5355void ufshcd_dealloc_host(struct ufs_hba *hba)
5356{
5357 scsi_host_put(hba->host);
5358}
5359EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
5360
5361/**
5376 * ufshcd_set_dma_mask - Set dma mask based on the controller 5362 * ufshcd_set_dma_mask - Set dma mask based on the controller
5377 * addressing capability 5363 * addressing capability
5378 * @hba: per adapter instance 5364 * @hba: per adapter instance
@@ -5433,6 +5419,10 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
5433 if (!head || list_empty(head)) 5419 if (!head || list_empty(head))
5434 goto out; 5420 goto out;
5435 5421
5422 ret = ufshcd_vops_clk_scale_notify(hba, scale_up, PRE_CHANGE);
5423 if (ret)
5424 return ret;
5425
5436 list_for_each_entry(clki, head, list) { 5426 list_for_each_entry(clki, head, list) {
5437 if (!IS_ERR_OR_NULL(clki->clk)) { 5427 if (!IS_ERR_OR_NULL(clki->clk)) {
5438 if (scale_up && clki->max_freq) { 5428 if (scale_up && clki->max_freq) {
@@ -5463,8 +5453,9 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
5463 dev_dbg(hba->dev, "%s: clk: %s, rate: %lu\n", __func__, 5453 dev_dbg(hba->dev, "%s: clk: %s, rate: %lu\n", __func__,
5464 clki->name, clk_get_rate(clki->clk)); 5454 clki->name, clk_get_rate(clki->clk));
5465 } 5455 }
5466 if (hba->vops->clk_scale_notify) 5456
5467 hba->vops->clk_scale_notify(hba); 5457 ret = ufshcd_vops_clk_scale_notify(hba, scale_up, POST_CHANGE);
5458
5468out: 5459out:
5469 return ret; 5460 return ret;
5470} 5461}
@@ -5619,13 +5610,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
5619 hba->is_irq_enabled = true; 5610 hba->is_irq_enabled = true;
5620 } 5611 }
5621 5612
5622 /* Enable SCSI tag mapping */
5623 err = scsi_init_shared_tag_map(host, host->can_queue);
5624 if (err) {
5625 dev_err(hba->dev, "init shared queue failed\n");
5626 goto exit_gating;
5627 }
5628
5629 err = scsi_add_host(host, hba->dev); 5613 err = scsi_add_host(host, hba->dev);
5630 if (err) { 5614 if (err) {
5631 dev_err(hba->dev, "scsi_add_host failed\n"); 5615 dev_err(hba->dev, "scsi_add_host failed\n");
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c40a0e78a6c4..2570d9477b37 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -223,8 +223,10 @@ struct ufs_clk_info {
223 bool enabled; 223 bool enabled;
224}; 224};
225 225
226#define PRE_CHANGE 0 226enum ufs_notify_change_status {
227#define POST_CHANGE 1 227 PRE_CHANGE,
228 POST_CHANGE,
229};
228 230
229struct ufs_pa_layer_attr { 231struct ufs_pa_layer_attr {
230 u32 gear_rx; 232 u32 gear_rx;
@@ -259,22 +261,28 @@ struct ufs_pwr_mode_info {
259 * to be set. 261 * to be set.
260 * @suspend: called during host controller PM callback 262 * @suspend: called during host controller PM callback
261 * @resume: called during host controller PM callback 263 * @resume: called during host controller PM callback
264 * @dbg_register_dump: used to dump controller debug information
262 */ 265 */
263struct ufs_hba_variant_ops { 266struct ufs_hba_variant_ops {
264 const char *name; 267 const char *name;
265 int (*init)(struct ufs_hba *); 268 int (*init)(struct ufs_hba *);
266 void (*exit)(struct ufs_hba *); 269 void (*exit)(struct ufs_hba *);
267 u32 (*get_ufs_hci_version)(struct ufs_hba *); 270 u32 (*get_ufs_hci_version)(struct ufs_hba *);
268 void (*clk_scale_notify)(struct ufs_hba *); 271 int (*clk_scale_notify)(struct ufs_hba *, bool,
269 int (*setup_clocks)(struct ufs_hba *, bool); 272 enum ufs_notify_change_status);
273 int (*setup_clocks)(struct ufs_hba *, bool);
270 int (*setup_regulators)(struct ufs_hba *, bool); 274 int (*setup_regulators)(struct ufs_hba *, bool);
271 int (*hce_enable_notify)(struct ufs_hba *, bool); 275 int (*hce_enable_notify)(struct ufs_hba *,
272 int (*link_startup_notify)(struct ufs_hba *, bool); 276 enum ufs_notify_change_status);
277 int (*link_startup_notify)(struct ufs_hba *,
278 enum ufs_notify_change_status);
273 int (*pwr_change_notify)(struct ufs_hba *, 279 int (*pwr_change_notify)(struct ufs_hba *,
274 bool, struct ufs_pa_layer_attr *, 280 enum ufs_notify_change_status status,
281 struct ufs_pa_layer_attr *,
275 struct ufs_pa_layer_attr *); 282 struct ufs_pa_layer_attr *);
276 int (*suspend)(struct ufs_hba *, enum ufs_pm_op); 283 int (*suspend)(struct ufs_hba *, enum ufs_pm_op);
277 int (*resume)(struct ufs_hba *, enum ufs_pm_op); 284 int (*resume)(struct ufs_hba *, enum ufs_pm_op);
285 void (*dbg_register_dump)(struct ufs_hba *hba);
278}; 286};
279 287
280/* clock gating state */ 288/* clock gating state */
@@ -576,6 +584,7 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg)
576} 584}
577 585
578int ufshcd_alloc_host(struct device *, struct ufs_hba **); 586int ufshcd_alloc_host(struct device *, struct ufs_hba **);
587void ufshcd_dealloc_host(struct ufs_hba *);
579int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); 588int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int);
580void ufshcd_remove(struct ufs_hba *); 589void ufshcd_remove(struct ufs_hba *);
581 590
@@ -594,6 +603,27 @@ static inline void check_upiu_size(void)
594 GENERAL_UPIU_REQUEST_SIZE + QUERY_DESC_MAX_SIZE); 603 GENERAL_UPIU_REQUEST_SIZE + QUERY_DESC_MAX_SIZE);
595} 604}
596 605
606/**
607 * ufshcd_set_variant - set variant specific data to the hba
608 * @hba - per adapter instance
609 * @variant - pointer to variant specific data
610 */
611static inline void ufshcd_set_variant(struct ufs_hba *hba, void *variant)
612{
613 BUG_ON(!hba);
614 hba->priv = variant;
615}
616
617/**
618 * ufshcd_get_variant - get variant specific data from the hba
619 * @hba - per adapter instance
620 */
621static inline void *ufshcd_get_variant(struct ufs_hba *hba)
622{
623 BUG_ON(!hba);
624 return hba->priv;
625}
626
597extern int ufshcd_runtime_suspend(struct ufs_hba *hba); 627extern int ufshcd_runtime_suspend(struct ufs_hba *hba);
598extern int ufshcd_runtime_resume(struct ufs_hba *hba); 628extern int ufshcd_runtime_resume(struct ufs_hba *hba);
599extern int ufshcd_runtime_idle(struct ufs_hba *hba); 629extern int ufshcd_runtime_idle(struct ufs_hba *hba);
@@ -653,4 +683,109 @@ static inline int ufshcd_dme_peer_get(struct ufs_hba *hba,
653 683
654int ufshcd_hold(struct ufs_hba *hba, bool async); 684int ufshcd_hold(struct ufs_hba *hba, bool async);
655void ufshcd_release(struct ufs_hba *hba); 685void ufshcd_release(struct ufs_hba *hba);
686
687/* Wrapper functions for safely calling variant operations */
688static inline const char *ufshcd_get_var_name(struct ufs_hba *hba)
689{
690 if (hba->vops)
691 return hba->vops->name;
692 return "";
693}
694
695static inline int ufshcd_vops_init(struct ufs_hba *hba)
696{
697 if (hba->vops && hba->vops->init)
698 return hba->vops->init(hba);
699
700 return 0;
701}
702
703static inline void ufshcd_vops_exit(struct ufs_hba *hba)
704{
705 if (hba->vops && hba->vops->exit)
706 return hba->vops->exit(hba);
707}
708
709static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
710{
711 if (hba->vops && hba->vops->get_ufs_hci_version)
712 return hba->vops->get_ufs_hci_version(hba);
713
714 return ufshcd_readl(hba, REG_UFS_VERSION);
715}
716
717static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba,
718 bool up, enum ufs_notify_change_status status)
719{
720 if (hba->vops && hba->vops->clk_scale_notify)
721 return hba->vops->clk_scale_notify(hba, up, status);
722 return 0;
723}
724
725static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on)
726{
727 if (hba->vops && hba->vops->setup_clocks)
728 return hba->vops->setup_clocks(hba, on);
729 return 0;
730}
731
732static inline int ufshcd_vops_setup_regulators(struct ufs_hba *hba, bool status)
733{
734 if (hba->vops && hba->vops->setup_regulators)
735 return hba->vops->setup_regulators(hba, status);
736
737 return 0;
738}
739
740static inline int ufshcd_vops_hce_enable_notify(struct ufs_hba *hba,
741 bool status)
742{
743 if (hba->vops && hba->vops->hce_enable_notify)
744 return hba->vops->hce_enable_notify(hba, status);
745
746 return 0;
747}
748static inline int ufshcd_vops_link_startup_notify(struct ufs_hba *hba,
749 bool status)
750{
751 if (hba->vops && hba->vops->link_startup_notify)
752 return hba->vops->link_startup_notify(hba, status);
753
754 return 0;
755}
756
757static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba,
758 bool status,
759 struct ufs_pa_layer_attr *dev_max_params,
760 struct ufs_pa_layer_attr *dev_req_params)
761{
762 if (hba->vops && hba->vops->pwr_change_notify)
763 return hba->vops->pwr_change_notify(hba, status,
764 dev_max_params, dev_req_params);
765
766 return -ENOTSUPP;
767}
768
769static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
770{
771 if (hba->vops && hba->vops->suspend)
772 return hba->vops->suspend(hba, op);
773
774 return 0;
775}
776
777static inline int ufshcd_vops_resume(struct ufs_hba *hba, enum ufs_pm_op op)
778{
779 if (hba->vops && hba->vops->resume)
780 return hba->vops->resume(hba, op);
781
782 return 0;
783}
784
785static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
786{
787 if (hba->vops && hba->vops->dbg_register_dump)
788 hba->vops->dbg_register_dump(hba);
789}
790
656#endif /* End of Header */ 791#endif /* End of Header */