@@ -2059,7 +2059,6 @@ static int qcom_qmp_phy_usb_serdes_init(struct qmp_phy *qphy)
struct qcom_qmp *qmp = qphy->qmp;
const struct qmp_phy_cfg *cfg = qphy->cfg;
void __iomem *serdes = qphy->serdes;
- const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
int serdes_tbl_num = cfg->serdes_tbl_num;
int ret;
@@ -2069,35 +2068,6 @@ static int qcom_qmp_phy_usb_serdes_init(struct qmp_phy *qphy)
qcom_qmp_phy_usb_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
cfg->serdes_tbl_num_sec);
- if (cfg->type == PHY_TYPE_DP) {
- switch (dp_opts->link_rate) {
- case 1620:
- qcom_qmp_phy_usb_configure(serdes, cfg->regs,
- cfg->serdes_tbl_rbr,
- cfg->serdes_tbl_rbr_num);
- break;
- case 2700:
- qcom_qmp_phy_usb_configure(serdes, cfg->regs,
- cfg->serdes_tbl_hbr,
- cfg->serdes_tbl_hbr_num);
- break;
- case 5400:
- qcom_qmp_phy_usb_configure(serdes, cfg->regs,
- cfg->serdes_tbl_hbr2,
- cfg->serdes_tbl_hbr2_num);
- break;
- case 8100:
- qcom_qmp_phy_usb_configure(serdes, cfg->regs,
- cfg->serdes_tbl_hbr3,
- cfg->serdes_tbl_hbr3_num);
- break;
- default:
- /* Other link rates aren't supported */
- return -EINVAL;
- }
- }
-
-
if (cfg->has_phy_com_ctrl) {
void __iomem *status;
unsigned int mask, val;
@@ -2121,32 +2091,6 @@ static int qcom_qmp_phy_usb_serdes_init(struct qmp_phy *qphy)
return 0;
}
-static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
-{
- const struct phy_configure_opts_dp *dp_opts = &opts->dp;
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- const struct qmp_phy_cfg *cfg = qphy->cfg;
-
- memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
- if (qphy->dp_opts.set_voltages) {
- cfg->configure_dp_tx(qphy);
- qphy->dp_opts.set_voltages = 0;
- }
-
- return 0;
-}
-
-static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
-{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- const struct qmp_phy_cfg *cfg = qphy->cfg;
-
- if (cfg->calibrate_dp_phy)
- return cfg->calibrate_dp_phy(qphy);
-
- return 0;
-}
-
static int qcom_qmp_phy_usb_com_init(struct qmp_phy *qphy)
{
struct qcom_qmp *qmp = qphy->qmp;
@@ -2316,9 +2260,6 @@ static int qcom_qmp_phy_usb_init(struct phy *phy)
if (ret)
return ret;
- if (cfg->type == PHY_TYPE_DP)
- cfg->dp_aux_init(qphy);
-
return 0;
}
@@ -2369,10 +2310,6 @@ static int qcom_qmp_phy_usb_power_on(struct phy *phy)
cfg->tx_tbl_num_sec, 2);
}
- /* Configure special DP tx tunings */
- if (cfg->type == PHY_TYPE_DP)
- cfg->configure_dp_tx(qphy);
-
qcom_qmp_phy_usb_configure_lane(rx, cfg->regs,
cfg->rx_tbl, cfg->rx_tbl_num, 1);
if (cfg->rx_tbl_sec)
@@ -2389,14 +2326,10 @@ static int qcom_qmp_phy_usb_power_on(struct phy *phy)
}
/* Configure link rate, swing, etc. */
- if (cfg->type == PHY_TYPE_DP) {
- cfg->configure_dp_phy(qphy);
- } else {
- qcom_qmp_phy_usb_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
- if (cfg->pcs_tbl_sec)
- qcom_qmp_phy_usb_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
- cfg->pcs_tbl_num_sec);
- }
+ qcom_qmp_phy_usb_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+ if (cfg->pcs_tbl_sec)
+ qcom_qmp_phy_usb_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
+ cfg->pcs_tbl_num_sec);
ret = reset_control_deassert(qmp->ufs_reset);
if (ret)
@@ -2408,40 +2341,26 @@ static int qcom_qmp_phy_usb_power_on(struct phy *phy)
qcom_qmp_phy_usb_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
cfg->pcs_misc_tbl_num_sec);
- /*
- * Pull out PHY from POWER DOWN state.
- * This is active low enable signal to power-down PHY.
- */
- if(cfg->type == PHY_TYPE_PCIE)
- qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
-
if (cfg->has_pwrdn_delay)
usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
- if (cfg->type != PHY_TYPE_DP) {
- /* Pull PHY out of reset state */
- if (!cfg->no_pcs_sw_reset)
- qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
- /* start SerDes and Phy-Coding-Sublayer */
- qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
-
- if (cfg->type == PHY_TYPE_UFS) {
- status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
- mask = PCS_READY;
- ready = PCS_READY;
- } else {
- status = pcs + cfg->regs[QPHY_PCS_STATUS];
- mask = cfg->phy_status;
- ready = 0;
- }
+ /* Pull PHY out of reset state */
+ if (!cfg->no_pcs_sw_reset)
+ qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+ /* start SerDes and Phy-Coding-Sublayer */
+ qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
- ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
- PHY_INIT_COMPLETE_TIMEOUT);
- if (ret) {
- dev_err(qmp->dev, "phy initialization timed-out\n");
- goto err_disable_pipe_clk;
- }
+ status = pcs + cfg->regs[QPHY_PCS_STATUS];
+ mask = cfg->phy_status;
+ ready = 0;
+
+ ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
+ PHY_INIT_COMPLETE_TIMEOUT);
+ if (ret) {
+ dev_err(qmp->dev, "phy initialization timed-out\n");
+ goto err_disable_pipe_clk;
}
+
return 0;
err_disable_pipe_clk:
@@ -2460,25 +2379,20 @@ static int qcom_qmp_phy_usb_power_off(struct phy *phy)
clk_disable_unprepare(qphy->pipe_clk);
- if (cfg->type == PHY_TYPE_DP) {
- /* Assert DP PHY power down */
- writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
- } else {
- /* PHY reset */
- if (!cfg->no_pcs_sw_reset)
- qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+ /* PHY reset */
+ if (!cfg->no_pcs_sw_reset)
+ qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
- /* stop SerDes and Phy-Coding-Sublayer */
- qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
+ /* stop SerDes and Phy-Coding-Sublayer */
+ qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
- /* Put PHY into POWER DOWN state: active low */
- if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
- qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
- cfg->pwrdn_ctrl);
- } else {
- qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
- cfg->pwrdn_ctrl);
- }
+ /* Put PHY into POWER DOWN state: active low */
+ if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
+ qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+ cfg->pwrdn_ctrl);
+ } else {
+ qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
+ cfg->pwrdn_ctrl);
}
return 0;
@@ -2755,223 +2669,13 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
}
-/*
- * Display Port PLL driver block diagram for branch clocks
- *
- * +------------------------------+
- * | DP_VCO_CLK |
- * | |
- * | +-------------------+ |
- * | | (DP PLL/VCO) | |
- * | +---------+---------+ |
- * | v |
- * | +----------+-----------+ |
- * | | hsclk_divsel_clk_src | |
- * | +----------+-----------+ |
- * +------------------------------+
- * |
- * +---------<---------v------------>----------+
- * | |
- * +--------v----------------+ |
- * | dp_phy_pll_link_clk | |
- * | link_clk | |
- * +--------+----------------+ |
- * | |
- * | |
- * v v
- * Input to DISPCC block |
- * for link clk, crypto clk |
- * and interface clock |
- * |
- * |
- * +--------<------------+-----------------+---<---+
- * | | |
- * +----v---------+ +--------v-----+ +--------v------+
- * | vco_divided | | vco_divided | | vco_divided |
- * | _clk_src | | _clk_src | | _clk_src |
- * | | | | | |
- * |divsel_six | | divsel_two | | divsel_four |
- * +-------+------+ +-----+--------+ +--------+------+
- * | | |
- * v---->----------v-------------<------v
- * |
- * +----------+-----------------+
- * | dp_phy_pll_vco_div_clk |
- * +---------+------------------+
- * |
- * v
- * Input to DISPCC block
- * for DP pixel clock
- *
- */
-static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- switch (req->rate) {
- case 1620000000UL / 2:
- case 2700000000UL / 2:
- /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static unsigned long
-qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- const struct qmp_phy_dp_clks *dp_clks;
- const struct qmp_phy *qphy;
- const struct phy_configure_opts_dp *dp_opts;
-
- dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw);
- qphy = dp_clks->qphy;
- dp_opts = &qphy->dp_opts;
-
- switch (dp_opts->link_rate) {
- case 1620:
- return 1620000000UL / 2;
- case 2700:
- return 2700000000UL / 2;
- case 5400:
- return 5400000000UL / 4;
- case 8100:
- return 8100000000UL / 6;
- default:
- return 0;
- }
-}
-
-static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = {
- .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate,
- .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate,
-};
-
-static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- switch (req->rate) {
- case 162000000:
- case 270000000:
- case 540000000:
- case 810000000:
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static unsigned long
-qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- const struct qmp_phy_dp_clks *dp_clks;
- const struct qmp_phy *qphy;
- const struct phy_configure_opts_dp *dp_opts;
-
- dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw);
- qphy = dp_clks->qphy;
- dp_opts = &qphy->dp_opts;
-
- switch (dp_opts->link_rate) {
- case 1620:
- case 2700:
- case 5400:
- case 8100:
- return dp_opts->link_rate * 100000;
- default:
- return 0;
- }
-}
-
-static const struct clk_ops qcom_qmp_dp_link_clk_ops = {
- .determine_rate = qcom_qmp_dp_link_clk_determine_rate,
- .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate,
-};
-
-static struct clk_hw *
-qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
-{
- struct qmp_phy_dp_clks *dp_clks = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx >= 2) {
- pr_err("%s: invalid index %u\n", __func__, idx);
- return ERR_PTR(-EINVAL);
- }
-
- if (idx == 0)
- return &dp_clks->dp_link_hw;
-
- return &dp_clks->dp_pixel_hw;
-}
-
-static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
- struct device_node *np)
-{
- struct clk_init_data init = { };
- struct qmp_phy_dp_clks *dp_clks;
- char name[64];
- int ret;
-
- dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL);
- if (!dp_clks)
- return -ENOMEM;
-
- dp_clks->qphy = qphy;
- qphy->dp_clks = dp_clks;
-
- snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
- init.ops = &qcom_qmp_dp_link_clk_ops;
- init.name = name;
- dp_clks->dp_link_hw.init = &init;
- ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw);
- if (ret)
- return ret;
-
- snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
- init.ops = &qcom_qmp_dp_pixel_clk_ops;
- init.name = name;
- dp_clks->dp_pixel_hw.init = &init;
- ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw);
- if (ret)
- return ret;
-
- ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks);
- if (ret)
- return ret;
-
- /*
- * Roll a devm action because the clock provider is the child node, but
- * the child node is not actually a device.
- */
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
-}
-
-static const struct phy_ops qcom_qmp_phy_usb_gen_ops = {
+static const struct phy_ops qcom_qmp_phy_usb_ops = {
.init = qcom_qmp_phy_usb_enable,
.exit = qcom_qmp_phy_usb_disable,
.set_mode = qcom_qmp_phy_usb_set_mode,
.owner = THIS_MODULE,
};
-static const struct phy_ops qcom_qmp_phy_usb_dp_ops = {
- .init = qcom_qmp_phy_usb_init,
- .configure = qcom_qmp_dp_phy_configure,
- .power_on = qcom_qmp_phy_usb_power_on,
- .calibrate = qcom_qmp_dp_phy_calibrate,
- .power_off = qcom_qmp_phy_usb_power_off,
- .exit = qcom_qmp_phy_usb_exit,
- .set_mode = qcom_qmp_phy_usb_set_mode,
- .owner = THIS_MODULE,
-};
-
-static const struct phy_ops qcom_qmp_pcie_ufs_ops = {
- .power_on = qcom_qmp_phy_usb_enable,
- .power_off = qcom_qmp_phy_usb_disable,
- .set_mode = qcom_qmp_phy_usb_set_mode,
- .owner = THIS_MODULE,
-};
-
static void qcom_qmp_reset_control_put(void *data)
{
reset_control_put(data);
@@ -2984,7 +2688,6 @@ int qcom_qmp_phy_usb_create(struct device *dev, struct device_node *np, int id,
struct qcom_qmp *qmp = dev_get_drvdata(dev);
struct phy *generic_phy;
struct qmp_phy *qphy;
- const struct phy_ops *ops;
char prop_name[MAX_PROP_NAME];
int ret;
@@ -3051,16 +2754,12 @@ int qcom_qmp_phy_usb_create(struct device *dev, struct device_node *np, int id,
snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name);
if (IS_ERR(qphy->pipe_clk)) {
- if (cfg->type == PHY_TYPE_PCIE ||
- cfg->type == PHY_TYPE_USB3) {
- ret = PTR_ERR(qphy->pipe_clk);
- if (ret != -EPROBE_DEFER)
- dev_err(dev,
- "failed to get lane%d pipe_clk, %d\n",
- id, ret);
- return ret;
- }
- qphy->pipe_clk = NULL;
+ ret = PTR_ERR(qphy->pipe_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev,
+ "failed to get lane%d pipe_clk, %d\n",
+ id, ret);
+ return ret;
}
/* Get lane reset, if any */
@@ -3077,14 +2776,7 @@ int qcom_qmp_phy_usb_create(struct device *dev, struct device_node *np, int id,
return ret;
}
- if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
- ops = &qcom_qmp_pcie_ufs_ops;
- else if (cfg->type == PHY_TYPE_DP)
- ops = &qcom_qmp_phy_usb_dp_ops;
- else
- ops = &qcom_qmp_phy_usb_gen_ops;
-
- generic_phy = devm_phy_create(dev, np, ops);
+ generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_usb_ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create qphy %d\n", ret);
@@ -3172,12 +2864,7 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
struct device_node *child;
struct phy_provider *phy_provider;
void __iomem *serdes;
- void __iomem *usb_serdes;
- void __iomem *dp_serdes = NULL;
- const struct qmp_phy_combo_cfg *combo_cfg = NULL;
const struct qmp_phy_cfg *cfg = NULL;
- const struct qmp_phy_cfg *usb_cfg = NULL;
- const struct qmp_phy_cfg *dp_cfg = NULL;
int num, id, expected_phys;
int ret;
@@ -3194,28 +2881,18 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
return -EINVAL;
/* per PHY serdes; usually located at base address */
- usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0);
+ serdes = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(serdes))
return PTR_ERR(serdes);
/* per PHY dp_com; if PHY has dp_com control block */
- if (combo_cfg || cfg->has_phy_dp_com_ctrl) {
+ if (cfg->has_phy_dp_com_ctrl) {
qmp->dp_com = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(qmp->dp_com))
return PTR_ERR(qmp->dp_com);
}
- if (combo_cfg) {
- /* Only two serdes for combo PHY */
- dp_serdes = devm_platform_ioremap_resource(pdev, 2);
- if (IS_ERR(dp_serdes))
- return PTR_ERR(dp_serdes);
-
- dp_cfg = combo_cfg->dp_cfg;
- expected_phys = 2;
- } else {
- expected_phys = cfg->nlanes;
- }
+ expected_phys = cfg->nlanes;
mutex_init(&qmp->phy_mutex);
@@ -3254,14 +2931,6 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
id = 0;
for_each_available_child_of_node(dev->of_node, child) {
- if (of_node_name_eq(child, "dp-phy")) {
- cfg = dp_cfg;
- serdes = dp_serdes;
- } else if (of_node_name_eq(child, "usb3-phy")) {
- cfg = usb_cfg;
- serdes = usb_serdes;
- }
-
/* Create per-lane phy */
ret = qcom_qmp_phy_usb_create(dev, child, id, serdes, cfg);
if (ret) {
@@ -3274,21 +2943,13 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
* Register the pipe clock provided by phy.
* See function description to see details of this pipe clock.
*/
- if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) {
- ret = phy_pipe_clk_register(qmp, child);
- if (ret) {
- dev_err(qmp->dev,
- "failed to register pipe clock source\n");
- goto err_node_put;
- }
- } else if (cfg->type == PHY_TYPE_DP) {
- ret = phy_dp_clks_register(qmp, qmp->phys[id], child);
- if (ret) {
- dev_err(qmp->dev,
- "failed to register DP clock source\n");
- goto err_node_put;
- }
+ ret = phy_pipe_clk_register(qmp, child);
+ if (ret) {
+ dev_err(qmp->dev,
+ "failed to register pipe clock source\n");
+ goto err_node_put;
}
+
id++;
}