Loading Documentation/devicetree/bindings/ufs/ufs-msm.txt +6 −2 Original line number Diff line number Diff line Loading @@ -10,7 +10,10 @@ Required properties: - compatible : compatible list, contains "qcom,ufs-phy-qmp-28nm" or "qcom,ufs-phy-qmp-20nm" according to the relevant phy in use - reg : <registers mapping> - reg : should contain PHY register address space (mandatory), device PHY control register map (optional). - reg-names : indicates various resources passed to driver (via reg proptery) by name. Required "reg-names" is "phy_mem" and "dev_ref_clk_ctrl_mem" is optional. - #phy-cells : This property shall be set to 0 - vdda-phy-supply : phandle to main PHY supply for analog domain - vdda-pll-supply : phandle to PHY PLL and Power-Gen block power supply Loading @@ -28,7 +31,8 @@ Example: ufsphy1: ufsphy@0xfc597000 { compatible = "qcom,ufs-phy-qmp-28nm"; reg = <0xfc597000 0x800>; reg = <0xfc597000 0x800>, <0xfd512074 0x4>; reg-names = "phy_mem", "dev_ref_clk_ctrl_mem"; #phy-cells = <0>; vdda-phy-supply = <&pma8084_l4>; vdda-pll-supply = <&pma8084_l12>; Loading arch/arm/boot/dts/qcom/msm8994.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -1048,6 +1048,7 @@ ufsphy1: ufsphy@fc597000 { compatible = "qcom,ufs-phy-qmp-20nm"; reg = <0xfc597000 0xda8>; reg-names = "phy_mem"; #phy-cells = <0>; vdda-phy-supply = <&pm8994_l28>; vdda-pll-supply = <&pm8994_l12>; Loading drivers/phy/phy-qcom-ufs.c +55 −4 Original line number Diff line number Diff line Loading @@ -124,10 +124,9 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev, struct resource *res; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem"); if (!res) { dev_err(dev, "%s: platform_get_resource() failed. returned NULL\n", __func__); dev_err(dev, "%s: phy_mem resource not found\n", __func__); err = -ENOMEM; goto out; } Loading @@ -135,7 +134,27 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev, phy_common->mmio = devm_ioremap_resource(dev, res); if (IS_ERR(phy_common->mmio)) { err = PTR_ERR(phy_common->mmio); dev_err(dev, "ioremap resource failed %d\n", err); phy_common->mmio = NULL; dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n", __func__, err); goto out; } /* "dev_ref_clk_ctrl_mem" is optional resource */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dev_ref_clk_ctrl_mem"); if (!res) { dev_dbg(dev, "%s: dev_ref_clk_ctrl_mem resource not found\n", __func__); goto out; } phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res); if (IS_ERR(phy_common->dev_ref_clk_ctrl_mmio)) { err = PTR_ERR(phy_common->dev_ref_clk_ctrl_mmio); phy_common->dev_ref_clk_ctrl_mmio = NULL; dev_err(dev, "%s: ioremap for dev_ref_clk_ctrl_mem resource failed %d\n", __func__, err); } out: Loading Loading @@ -434,6 +453,38 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy) } } #define UFS_REF_CLK_EN (1 << 5) static void ufs_qcom_phy_dev_ref_clk_ctrl(struct phy *generic_phy, bool enable) { struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy); if (phy->dev_ref_clk_ctrl_mmio && (enable ^ phy->is_dev_ref_clk_enabled)) { u32 temp = readl_relaxed(phy->dev_ref_clk_ctrl_mmio); if (enable) temp |= UFS_REF_CLK_EN; else temp &= ~UFS_REF_CLK_EN; writel_relaxed(temp, phy->dev_ref_clk_ctrl_mmio); /* ensure that ref_clk is enabled/disabled before we return */ wmb(); phy->is_dev_ref_clk_enabled = enable; } } void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy) { ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true); } void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy) { ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false); } void ufs_qcom_phy_restore_swi_regs(struct phy *generic_phy) { int i; Loading drivers/scsi/ufs/ufs-qcom.c +7 −3 Original line number Diff line number Diff line Loading @@ -871,16 +871,20 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on) ufs_qcom_phy_disable_iface_clk(host->generic_phy); goto out; } /* enable the device ref clock */ ufs_qcom_phy_enable_dev_ref_clk(host->generic_phy); vote = host->bus_vote.saved_vote; if (vote == host->bus_vote.min_bw_vote) ufs_qcom_update_bus_bw_vote(host); } else { /* M-PHY RMMI interface clocks can be turned off */ ufs_qcom_phy_disable_iface_clk(host->generic_phy); /* If link is not active, turn off UFS local PHY ref_clk */ if (!ufs_qcom_is_link_active(hba)) if (!ufs_qcom_is_link_active(hba)) { /* turn off UFS local PHY ref_clk */ ufs_qcom_phy_disable_ref_clk(host->generic_phy); /* disable device ref_clk */ ufs_qcom_phy_disable_dev_ref_clk(host->generic_phy); } vote = host->bus_vote.min_bw_vote; } Loading include/linux/phy/phy-qcom-ufs.h +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ struct ufs_qcom_phy { struct list_head list; struct device *dev; void __iomem *mmio; void __iomem *dev_ref_clk_ctrl_mmio; struct clk *tx_iface_clk; struct clk *rx_iface_clk; bool is_iface_clk_enabled; Loading @@ -68,6 +69,7 @@ struct ufs_qcom_phy { struct clk *ref_clk_parent; struct clk *ref_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; unsigned int quirks; Loading Loading @@ -167,6 +169,8 @@ int ufs_qcom_phy_disable_vreg(struct phy *phy, struct ufs_qcom_phy_vreg *vreg); int ufs_qcom_phy_enable_ref_clk(struct phy *phy); void ufs_qcom_phy_disable_ref_clk(struct phy *phy); void ufs_qcom_phy_enable_dev_ref_clk(struct phy *); void ufs_qcom_phy_disable_dev_ref_clk(struct phy *); int ufs_qcom_phy_enable_iface_clk(struct phy *phy); void ufs_qcom_phy_disable_iface_clk(struct phy *phy); void ufs_qcom_phy_restore_swi_regs(struct phy *phy); Loading Loading
Documentation/devicetree/bindings/ufs/ufs-msm.txt +6 −2 Original line number Diff line number Diff line Loading @@ -10,7 +10,10 @@ Required properties: - compatible : compatible list, contains "qcom,ufs-phy-qmp-28nm" or "qcom,ufs-phy-qmp-20nm" according to the relevant phy in use - reg : <registers mapping> - reg : should contain PHY register address space (mandatory), device PHY control register map (optional). - reg-names : indicates various resources passed to driver (via reg proptery) by name. Required "reg-names" is "phy_mem" and "dev_ref_clk_ctrl_mem" is optional. - #phy-cells : This property shall be set to 0 - vdda-phy-supply : phandle to main PHY supply for analog domain - vdda-pll-supply : phandle to PHY PLL and Power-Gen block power supply Loading @@ -28,7 +31,8 @@ Example: ufsphy1: ufsphy@0xfc597000 { compatible = "qcom,ufs-phy-qmp-28nm"; reg = <0xfc597000 0x800>; reg = <0xfc597000 0x800>, <0xfd512074 0x4>; reg-names = "phy_mem", "dev_ref_clk_ctrl_mem"; #phy-cells = <0>; vdda-phy-supply = <&pma8084_l4>; vdda-pll-supply = <&pma8084_l12>; Loading
arch/arm/boot/dts/qcom/msm8994.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -1048,6 +1048,7 @@ ufsphy1: ufsphy@fc597000 { compatible = "qcom,ufs-phy-qmp-20nm"; reg = <0xfc597000 0xda8>; reg-names = "phy_mem"; #phy-cells = <0>; vdda-phy-supply = <&pm8994_l28>; vdda-pll-supply = <&pm8994_l12>; Loading
drivers/phy/phy-qcom-ufs.c +55 −4 Original line number Diff line number Diff line Loading @@ -124,10 +124,9 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev, struct resource *res; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem"); if (!res) { dev_err(dev, "%s: platform_get_resource() failed. returned NULL\n", __func__); dev_err(dev, "%s: phy_mem resource not found\n", __func__); err = -ENOMEM; goto out; } Loading @@ -135,7 +134,27 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev, phy_common->mmio = devm_ioremap_resource(dev, res); if (IS_ERR(phy_common->mmio)) { err = PTR_ERR(phy_common->mmio); dev_err(dev, "ioremap resource failed %d\n", err); phy_common->mmio = NULL; dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n", __func__, err); goto out; } /* "dev_ref_clk_ctrl_mem" is optional resource */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dev_ref_clk_ctrl_mem"); if (!res) { dev_dbg(dev, "%s: dev_ref_clk_ctrl_mem resource not found\n", __func__); goto out; } phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res); if (IS_ERR(phy_common->dev_ref_clk_ctrl_mmio)) { err = PTR_ERR(phy_common->dev_ref_clk_ctrl_mmio); phy_common->dev_ref_clk_ctrl_mmio = NULL; dev_err(dev, "%s: ioremap for dev_ref_clk_ctrl_mem resource failed %d\n", __func__, err); } out: Loading Loading @@ -434,6 +453,38 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy) } } #define UFS_REF_CLK_EN (1 << 5) static void ufs_qcom_phy_dev_ref_clk_ctrl(struct phy *generic_phy, bool enable) { struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy); if (phy->dev_ref_clk_ctrl_mmio && (enable ^ phy->is_dev_ref_clk_enabled)) { u32 temp = readl_relaxed(phy->dev_ref_clk_ctrl_mmio); if (enable) temp |= UFS_REF_CLK_EN; else temp &= ~UFS_REF_CLK_EN; writel_relaxed(temp, phy->dev_ref_clk_ctrl_mmio); /* ensure that ref_clk is enabled/disabled before we return */ wmb(); phy->is_dev_ref_clk_enabled = enable; } } void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy) { ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true); } void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy) { ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false); } void ufs_qcom_phy_restore_swi_regs(struct phy *generic_phy) { int i; Loading
drivers/scsi/ufs/ufs-qcom.c +7 −3 Original line number Diff line number Diff line Loading @@ -871,16 +871,20 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on) ufs_qcom_phy_disable_iface_clk(host->generic_phy); goto out; } /* enable the device ref clock */ ufs_qcom_phy_enable_dev_ref_clk(host->generic_phy); vote = host->bus_vote.saved_vote; if (vote == host->bus_vote.min_bw_vote) ufs_qcom_update_bus_bw_vote(host); } else { /* M-PHY RMMI interface clocks can be turned off */ ufs_qcom_phy_disable_iface_clk(host->generic_phy); /* If link is not active, turn off UFS local PHY ref_clk */ if (!ufs_qcom_is_link_active(hba)) if (!ufs_qcom_is_link_active(hba)) { /* turn off UFS local PHY ref_clk */ ufs_qcom_phy_disable_ref_clk(host->generic_phy); /* disable device ref_clk */ ufs_qcom_phy_disable_dev_ref_clk(host->generic_phy); } vote = host->bus_vote.min_bw_vote; } Loading
include/linux/phy/phy-qcom-ufs.h +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ struct ufs_qcom_phy { struct list_head list; struct device *dev; void __iomem *mmio; void __iomem *dev_ref_clk_ctrl_mmio; struct clk *tx_iface_clk; struct clk *rx_iface_clk; bool is_iface_clk_enabled; Loading @@ -68,6 +69,7 @@ struct ufs_qcom_phy { struct clk *ref_clk_parent; struct clk *ref_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; unsigned int quirks; Loading Loading @@ -167,6 +169,8 @@ int ufs_qcom_phy_disable_vreg(struct phy *phy, struct ufs_qcom_phy_vreg *vreg); int ufs_qcom_phy_enable_ref_clk(struct phy *phy); void ufs_qcom_phy_disable_ref_clk(struct phy *phy); void ufs_qcom_phy_enable_dev_ref_clk(struct phy *); void ufs_qcom_phy_disable_dev_ref_clk(struct phy *); int ufs_qcom_phy_enable_iface_clk(struct phy *phy); void ufs_qcom_phy_disable_iface_clk(struct phy *phy); void ufs_qcom_phy_restore_swi_regs(struct phy *phy); Loading