2 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include "phy-qcom-ufs-qmp-14nm.h"
17 #define UFS_PHY_NAME "ufs_phy_qmp_14nm"
18 #define UFS_PHY_VDDA_PHY_UV (925000)
21 int ufs_qcom_phy_qmp_14nm_phy_calibrate(struct ufs_qcom_phy
*ufs_qcom_phy
,
24 int tbl_size_A
= ARRAY_SIZE(phy_cal_table_rate_A
);
25 int tbl_size_B
= ARRAY_SIZE(phy_cal_table_rate_B
);
28 err
= ufs_qcom_phy_calibrate(ufs_qcom_phy
, phy_cal_table_rate_A
,
29 tbl_size_A
, phy_cal_table_rate_B
, tbl_size_B
, is_rate_B
);
32 dev_err(ufs_qcom_phy
->dev
,
33 "%s: ufs_qcom_phy_calibrate() failed %d\n",
39 void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy
*phy_common
)
42 UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE
;
45 static int ufs_qcom_phy_qmp_14nm_init(struct phy
*generic_phy
)
47 struct ufs_qcom_phy
*phy_common
= get_ufs_qcom_phy(generic_phy
);
48 bool is_rate_B
= false;
51 if (phy_common
->mode
== PHY_MODE_UFS_HS_B
)
54 ret
= ufs_qcom_phy_qmp_14nm_phy_calibrate(phy_common
, is_rate_B
);
56 /* phy calibrated, but yet to be started */
57 phy_common
->is_started
= false;
62 static int ufs_qcom_phy_qmp_14nm_exit(struct phy
*generic_phy
)
68 int ufs_qcom_phy_qmp_14nm_set_mode(struct phy
*generic_phy
, enum phy_mode mode
)
70 struct ufs_qcom_phy
*phy_common
= get_ufs_qcom_phy(generic_phy
);
72 phy_common
->mode
= PHY_MODE_INVALID
;
75 phy_common
->mode
= mode
;
81 void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy
*phy
, bool val
)
83 writel_relaxed(val
? 0x1 : 0x0, phy
->mmio
+ UFS_PHY_POWER_DOWN_CONTROL
);
85 * Before any transactions involving PHY, ensure PHY knows
86 * that it's analog rail is powered ON (or OFF).
92 void ufs_qcom_phy_qmp_14nm_set_tx_lane_enable(struct ufs_qcom_phy
*phy
, u32 val
)
95 * 14nm PHY does not have TX_LANE_ENABLE register.
96 * Implement this function so as not to propagate error to caller.
100 static inline void ufs_qcom_phy_qmp_14nm_start_serdes(struct ufs_qcom_phy
*phy
)
104 tmp
= readl_relaxed(phy
->mmio
+ UFS_PHY_PHY_START
);
105 tmp
&= ~MASK_SERDES_START
;
106 tmp
|= (1 << OFFSET_SERDES_START
);
107 writel_relaxed(tmp
, phy
->mmio
+ UFS_PHY_PHY_START
);
108 /* Ensure register value is committed */
112 static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy
*phy_common
)
117 err
= readl_poll_timeout(phy_common
->mmio
+ UFS_PHY_PCS_READY_STATUS
,
118 val
, (val
& MASK_PCS_READY
), 10, 1000000);
120 dev_err(phy_common
->dev
, "%s: poll for pcs failed err = %d\n",
125 static const struct phy_ops ufs_qcom_phy_qmp_14nm_phy_ops
= {
126 .init
= ufs_qcom_phy_qmp_14nm_init
,
127 .exit
= ufs_qcom_phy_qmp_14nm_exit
,
128 .power_on
= ufs_qcom_phy_power_on
,
129 .power_off
= ufs_qcom_phy_power_off
,
130 .set_mode
= ufs_qcom_phy_qmp_14nm_set_mode
,
131 .owner
= THIS_MODULE
,
134 static struct ufs_qcom_phy_specific_ops phy_14nm_ops
= {
135 .start_serdes
= ufs_qcom_phy_qmp_14nm_start_serdes
,
136 .is_physical_coding_sublayer_ready
= ufs_qcom_phy_qmp_14nm_is_pcs_ready
,
137 .set_tx_lane_enable
= ufs_qcom_phy_qmp_14nm_set_tx_lane_enable
,
138 .power_control
= ufs_qcom_phy_qmp_14nm_power_control
,
141 static int ufs_qcom_phy_qmp_14nm_probe(struct platform_device
*pdev
)
143 struct device
*dev
= &pdev
->dev
;
144 struct phy
*generic_phy
;
145 struct ufs_qcom_phy_qmp_14nm
*phy
;
146 struct ufs_qcom_phy
*phy_common
;
149 phy
= devm_kzalloc(dev
, sizeof(*phy
), GFP_KERNEL
);
154 phy_common
= &phy
->common_cfg
;
156 generic_phy
= ufs_qcom_phy_generic_probe(pdev
, phy_common
,
157 &ufs_qcom_phy_qmp_14nm_phy_ops
, &phy_14nm_ops
);
164 err
= ufs_qcom_phy_init_clks(phy_common
);
168 err
= ufs_qcom_phy_init_vregulators(phy_common
);
172 phy_common
->vdda_phy
.max_uV
= UFS_PHY_VDDA_PHY_UV
;
173 phy_common
->vdda_phy
.min_uV
= UFS_PHY_VDDA_PHY_UV
;
175 ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common
);
177 phy_set_drvdata(generic_phy
, phy
);
179 strlcpy(phy_common
->name
, UFS_PHY_NAME
, sizeof(phy_common
->name
));
185 static const struct of_device_id ufs_qcom_phy_qmp_14nm_of_match
[] = {
186 {.compatible
= "qcom,ufs-phy-qmp-14nm"},
187 {.compatible
= "qcom,msm8996-ufs-phy-qmp-14nm"},
190 MODULE_DEVICE_TABLE(of
, ufs_qcom_phy_qmp_14nm_of_match
);
192 static struct platform_driver ufs_qcom_phy_qmp_14nm_driver
= {
193 .probe
= ufs_qcom_phy_qmp_14nm_probe
,
195 .of_match_table
= ufs_qcom_phy_qmp_14nm_of_match
,
196 .name
= "ufs_qcom_phy_qmp_14nm",
200 module_platform_driver(ufs_qcom_phy_qmp_14nm_driver
);
202 MODULE_DESCRIPTION("Universal Flash Storage (UFS) QCOM PHY QMP 14nm");
203 MODULE_LICENSE("GPL v2");