Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb76c8d3 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "phy: qcom-ufs: don't error out if vddp-ref-clk-supply is absent"

parents fff4fc56 5935b509
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -66,11 +66,16 @@ struct ufs_qcom_phy {
	struct clk *ref_clk_src;
	struct clk *ref_clk_parent;
	struct clk *ref_clk;
	struct clk *ref_aux_clk;
	bool is_ref_clk_enabled;
	bool is_dev_ref_clk_enabled;
	struct ufs_qcom_phy_vreg vdda_pll;
	struct ufs_qcom_phy_vreg vdda_phy;
	struct ufs_qcom_phy_vreg vddp_ref_clk;

	/* Number of lanes available (1 or 2) for Rx/Tx */
	u32 lanes_per_direction;

	unsigned int quirks;

	/*
+98 −26
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2019, Linux Foundation. All rights reserved.
 */

#include "phy-qcom-ufs-i.h"
@@ -13,6 +13,8 @@
#define VDDP_REF_CLK_MIN_UV        1200000
#define VDDP_REF_CLK_MAX_UV        1200000

#define UFS_PHY_DEFAULT_LANES_PER_DIRECTION	1

int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
			   struct ufs_qcom_phy_calibration *tbl_A,
			   int tbl_size_A,
@@ -89,13 +91,6 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev,
		return err;
	}

	/* "dev_ref_clk_ctrl_mem" is optional resource */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
					   "dev_ref_clk_ctrl_mem");
	phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res);
	if (IS_ERR((void const *)phy_common->dev_ref_clk_ctrl_mmio))
		phy_common->dev_ref_clk_ctrl_mmio = NULL;

	return 0;
}

@@ -130,6 +125,19 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
		goto out;
	}

	if (of_property_read_u32(dev->of_node, "lanes-per-direction",
				 &common_cfg->lanes_per_direction))
		common_cfg->lanes_per_direction =
			UFS_PHY_DEFAULT_LANES_PER_DIRECTION;

	/*
	 * UFS PHY power management is managed by its parent (UFS host
	 * controller) hence set the no runtime PM callbacks flag
	 * on UFS PHY device to avoid any accidental attempt to call the
	 * PM callbacks for PHY device.
	 */
	pm_runtime_no_callbacks(&generic_phy->dev);

	common_cfg->phy_spec_ops = phy_spec_ops;
	common_cfg->dev = dev;

@@ -184,16 +192,19 @@ int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common)
	if (of_device_is_compatible(phy_common->dev->of_node,
				"qcom,msm8996-ufs-phy-qmp-14nm"))
		goto skip_txrx_clk;
	/*
	 * tx_iface_clk does not exist in newer version of ufs-phy HW,
	 * so don't return error if it is not found
	 */
	__ufs_qcom_phy_clk_get(phy_common->dev, "tx_iface_clk",
				   &phy_common->tx_iface_clk, false);

	err = ufs_qcom_phy_clk_get(phy_common->dev, "tx_iface_clk",
				   &phy_common->tx_iface_clk);
	if (err)
		goto out;

	err = ufs_qcom_phy_clk_get(phy_common->dev, "rx_iface_clk",
				   &phy_common->rx_iface_clk);
	if (err)
		goto out;
	/*
	 * rx_iface_clk does not exist in newer version of ufs-phy HW,
	 * so don't return error if it is not found
	 */
	__ufs_qcom_phy_clk_get(phy_common->dev, "rx_iface_clk",
				   &phy_common->rx_iface_clk, false);

skip_txrx_clk:
	err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk_src",
@@ -208,9 +219,19 @@ int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common)
	__ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk_parent",
				   &phy_common->ref_clk_parent, false);

	err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk",
				   &phy_common->ref_clk);
	/*
	 * Some platforms may not have the ON/OFF control for reference clock,
	 * hence this clock may be optional.
	 */
	__ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk",
				   &phy_common->ref_clk, false);

	/*
	 * "ref_aux_clk" is optional and only supported by certain
	 * phy versions, don't abort init if it's not found.
	 */
	 __ufs_qcom_phy_clk_get(phy_common->dev, "ref_aux_clk",
				   &phy_common->ref_aux_clk, false);
out:
	return err;
}
@@ -224,6 +245,14 @@ static int ufs_qcom_phy_init_vreg(struct device *dev,

	char prop_name[MAX_PROP_NAME];

	if (dev->of_node) {
		snprintf(prop_name, MAX_PROP_NAME, "%s-supply", name);
		if (!of_parse_phandle(dev->of_node, prop_name, 0)) {
			dev_dbg(dev, "No vreg data found for %s\n", prop_name);
			return -ENODATA;
		}
	}

	vreg->name = name;
	vreg->reg = devm_regulator_get(dev, name);
	if (IS_ERR(vreg->reg)) {
@@ -280,7 +309,7 @@ int ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common)
	if (err)
		goto out;

	err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
	ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
				     "vddp-ref-clk");

out:
@@ -381,16 +410,39 @@ static int ufs_qcom_phy_enable_ref_clk(struct ufs_qcom_phy *phy)
		}
	}

	/*
	 * "ref_clk" is optional clock hence make sure that clk reference
	 * is available before trying to enable the clock.
	 */
	if (phy->ref_clk) {
		ret = clk_prepare_enable(phy->ref_clk);
		if (ret) {
			dev_err(phy->dev, "%s: ref_clk enable failed %d\n",
					__func__, ret);
			goto out_disable_parent;
		}
	}

	/*
	 * "ref_aux_clk" is optional clock and only supported by certain
	 * phy versions, hence make sure that clk reference is available
	 * before trying to enable the clock.
	 */
	if (phy->ref_aux_clk) {
		ret = clk_prepare_enable(phy->ref_aux_clk);
		if (ret) {
			dev_err(phy->dev, "%s: ref_aux_clk enable failed %d\n",
					__func__, ret);
			goto out_disable_ref;
		}
	}

	phy->is_ref_clk_enabled = true;
	goto out;

out_disable_ref:
	if (phy->ref_clk)
		clk_disable_unprepare(phy->ref_clk);
out_disable_parent:
	if (phy->ref_clk_parent)
		clk_disable_unprepare(phy->ref_clk_parent);
@@ -425,7 +477,21 @@ static int ufs_qcom_phy_disable_vreg(struct device *dev,
static void ufs_qcom_phy_disable_ref_clk(struct ufs_qcom_phy *phy)
{
	if (phy->is_ref_clk_enabled) {
		/*
		 * "ref_aux_clk" is optional clock and only supported by
		 * certain phy versions, hence make sure that clk reference
		 * is available before trying to disable the clock.
		 */
		if (phy->ref_aux_clk)
			clk_disable_unprepare(phy->ref_aux_clk);

		/*
		 * "ref_clk" is optional clock hence make sure that clk
		 * reference is available before trying to disable the clock.
		 */
		if (phy->ref_clk)
			clk_disable_unprepare(phy->ref_clk);

		/*
		 * "ref_clk_parent" is optional clock hence make sure that clk
		 * reference is available before trying to disable the clock.
@@ -445,6 +511,9 @@ static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy)
	if (phy->is_iface_clk_enabled)
		goto out;

	if (!phy->tx_iface_clk)
		goto out;

	ret = clk_prepare_enable(phy->tx_iface_clk);
	if (ret) {
		dev_err(phy->dev, "%s: tx_iface_clk enable failed %d\n",
@@ -467,6 +536,9 @@ static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy)
/* Turn OFF M-PHY RMMI interface clocks */
static void ufs_qcom_phy_disable_iface_clk(struct ufs_qcom_phy *phy)
{
	if (!phy->tx_iface_clk)
		return;

	if (phy->is_iface_clk_enabled) {
		clk_disable_unprepare(phy->tx_iface_clk);
		clk_disable_unprepare(phy->rx_iface_clk);