Loading Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +14 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,20 @@ Note: The instantaneous bandwidth (IB) value in the vectors-KBps field should - qcom,bus-vector-names: specifies string IDs for the corresponding bus vectors in the same order as qcom,msm-bus,vectors-KBps property. * The following parameters are optional, but required in order for PM QoS to be enabled and functional in the driver: - qcom,pm-qos-cpu-groups: arrays of unsigned integers representing the cpu groups. The number of values in the array defines the number of cpu-groups. Each value is a bit-mask defining the cpus that take part in that cpu group. i.e. if bit N is set, then cpuN is a part of the cpu group. So basically, a cpu group corelated to a cpu cluster. A PM QoS request object is maintained for each cpu-group. - qcom,pm-qos-cpu-group-latency-us: array of values used for PM QoS voting, one for each cpu-group defined. the number of values must match the number of values defined in qcom,pm-qos-cpu-mask property. - qcom,pm-qos-default-cpu: PM QoS voting is based on the cpu associated with each IO request by the block layer. This defined the default cpu used for PM QoS voting in case a specific cpu value is not available. - qcom,vddp-ref-clk-supply : reference clock to ufs device. Controlled by the host driver. - qcom,vddp-ref-clk-max-microamp : specifies max. load that can be drawn for ref-clk supply. Loading drivers/phy/qualcomm/phy-qcom-ufs-i.h +1 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ struct ufs_qcom_phy_vreg { int min_uV; int max_uV; bool enabled; bool is_always_on; }; struct ufs_qcom_phy { Loading drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c +31 −18 Original line number Diff line number Diff line Loading @@ -81,7 +81,35 @@ void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common) static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) { return 0; struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy); struct ufs_qcom_phy *phy_common = &phy->common_cfg; int err; err = ufs_qcom_phy_init_clks(phy_common); if (err) { dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n", __func__, err); goto out; } err = ufs_qcom_phy_init_vregulators(phy_common); if (err) { dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n", __func__, err); goto out; } ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common); if (phy_common->quirks & UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING) { phy_common->vco_tune1_mode1 = readl_relaxed(phy_common->mmio + QSERDES_COM_VCO_TUNE1_MODE1); dev_info(phy_common->dev, "%s: vco_tune1_mode1 0x%x\n", __func__, phy_common->vco_tune1_mode1); } out: return err; } static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy) Loading Loading @@ -239,27 +267,12 @@ static int ufs_qcom_phy_qmp_14nm_probe(struct platform_device *pdev) &ufs_qcom_phy_qmp_14nm_phy_ops, &phy_14nm_ops); if (!generic_phy) { dev_err(dev, "%s: ufs_qcom_phy_generic_probe() failed\n", __func__); err = -EIO; goto out; } err = ufs_qcom_phy_init_clks(phy_common); if (err) goto out; err = ufs_qcom_phy_init_vregulators(phy_common); if (err) goto out; ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common); if (phy_common->quirks & UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING) { phy_common->vco_tune1_mode1 = readl_relaxed(phy_common->mmio + QSERDES_COM_VCO_TUNE1_MODE1); dev_info(phy_common->dev, "%s: vco_tune1_mode1 0x%x\n", __func__, phy_common->vco_tune1_mode1); } phy_set_drvdata(generic_phy, phy); strlcpy(phy_common->name, UFS_PHY_NAME, sizeof(phy_common->name)); Loading drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3.h +1 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A[] = { UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_RESETSM_CNTRL, 0x20), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CLK_SELECT, 0x30), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_SYS_CLK_CTRL, 0x02), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x04), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_BG_TIMER, 0x0A), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_HSCLK_SEL, 0x00), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP_EN, 0x01), Loading drivers/phy/qualcomm/phy-qcom-ufs.c +21 −1 Original line number Diff line number Diff line Loading @@ -223,7 +223,15 @@ int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common) err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk", &phy_common->ref_clk); if (err) goto out; /* * "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; } Loading Loading @@ -269,6 +277,9 @@ static int ufs_qcom_phy_init_vreg(struct device *dev, } err = 0; } snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name); vreg->is_always_on = of_property_read_bool(dev->of_node, prop_name); } if (!strcmp(name, "vdda-pll")) { Loading Loading @@ -317,6 +328,8 @@ static int ufs_qcom_phy_cfg_vreg(struct device *dev, int min_uV; int uA_load; WARN_ON(!vreg); if (regulator_count_voltages(reg) > 0) { min_uV = on ? vreg->min_uV : 0; ret = regulator_set_voltage(reg, min_uV, vreg->max_uV); Loading Loading @@ -442,7 +455,7 @@ static int ufs_qcom_phy_disable_vreg(struct device *dev, { int ret = 0; if (!vreg || !vreg->enabled) if (!vreg || !vreg->enabled || vreg->is_always_on) goto out; ret = regulator_disable(vreg->reg); Loading @@ -462,6 +475,13 @@ 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); clk_disable_unprepare(phy->ref_clk); /* * "ref_clk_parent" is optional clock hence make sure that clk Loading Loading
Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +14 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,20 @@ Note: The instantaneous bandwidth (IB) value in the vectors-KBps field should - qcom,bus-vector-names: specifies string IDs for the corresponding bus vectors in the same order as qcom,msm-bus,vectors-KBps property. * The following parameters are optional, but required in order for PM QoS to be enabled and functional in the driver: - qcom,pm-qos-cpu-groups: arrays of unsigned integers representing the cpu groups. The number of values in the array defines the number of cpu-groups. Each value is a bit-mask defining the cpus that take part in that cpu group. i.e. if bit N is set, then cpuN is a part of the cpu group. So basically, a cpu group corelated to a cpu cluster. A PM QoS request object is maintained for each cpu-group. - qcom,pm-qos-cpu-group-latency-us: array of values used for PM QoS voting, one for each cpu-group defined. the number of values must match the number of values defined in qcom,pm-qos-cpu-mask property. - qcom,pm-qos-default-cpu: PM QoS voting is based on the cpu associated with each IO request by the block layer. This defined the default cpu used for PM QoS voting in case a specific cpu value is not available. - qcom,vddp-ref-clk-supply : reference clock to ufs device. Controlled by the host driver. - qcom,vddp-ref-clk-max-microamp : specifies max. load that can be drawn for ref-clk supply. Loading
drivers/phy/qualcomm/phy-qcom-ufs-i.h +1 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ struct ufs_qcom_phy_vreg { int min_uV; int max_uV; bool enabled; bool is_always_on; }; struct ufs_qcom_phy { Loading
drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c +31 −18 Original line number Diff line number Diff line Loading @@ -81,7 +81,35 @@ void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common) static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) { return 0; struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy); struct ufs_qcom_phy *phy_common = &phy->common_cfg; int err; err = ufs_qcom_phy_init_clks(phy_common); if (err) { dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n", __func__, err); goto out; } err = ufs_qcom_phy_init_vregulators(phy_common); if (err) { dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n", __func__, err); goto out; } ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common); if (phy_common->quirks & UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING) { phy_common->vco_tune1_mode1 = readl_relaxed(phy_common->mmio + QSERDES_COM_VCO_TUNE1_MODE1); dev_info(phy_common->dev, "%s: vco_tune1_mode1 0x%x\n", __func__, phy_common->vco_tune1_mode1); } out: return err; } static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy) Loading Loading @@ -239,27 +267,12 @@ static int ufs_qcom_phy_qmp_14nm_probe(struct platform_device *pdev) &ufs_qcom_phy_qmp_14nm_phy_ops, &phy_14nm_ops); if (!generic_phy) { dev_err(dev, "%s: ufs_qcom_phy_generic_probe() failed\n", __func__); err = -EIO; goto out; } err = ufs_qcom_phy_init_clks(phy_common); if (err) goto out; err = ufs_qcom_phy_init_vregulators(phy_common); if (err) goto out; ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common); if (phy_common->quirks & UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING) { phy_common->vco_tune1_mode1 = readl_relaxed(phy_common->mmio + QSERDES_COM_VCO_TUNE1_MODE1); dev_info(phy_common->dev, "%s: vco_tune1_mode1 0x%x\n", __func__, phy_common->vco_tune1_mode1); } phy_set_drvdata(generic_phy, phy); strlcpy(phy_common->name, UFS_PHY_NAME, sizeof(phy_common->name)); Loading
drivers/phy/qualcomm/phy-qcom-ufs-qmp-v3.h +1 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A[] = { UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_RESETSM_CNTRL, 0x20), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CLK_SELECT, 0x30), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_SYS_CLK_CTRL, 0x02), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x04), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_BG_TIMER, 0x0A), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_HSCLK_SEL, 0x00), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP_EN, 0x01), Loading
drivers/phy/qualcomm/phy-qcom-ufs.c +21 −1 Original line number Diff line number Diff line Loading @@ -223,7 +223,15 @@ int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common) err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk", &phy_common->ref_clk); if (err) goto out; /* * "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; } Loading Loading @@ -269,6 +277,9 @@ static int ufs_qcom_phy_init_vreg(struct device *dev, } err = 0; } snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name); vreg->is_always_on = of_property_read_bool(dev->of_node, prop_name); } if (!strcmp(name, "vdda-pll")) { Loading Loading @@ -317,6 +328,8 @@ static int ufs_qcom_phy_cfg_vreg(struct device *dev, int min_uV; int uA_load; WARN_ON(!vreg); if (regulator_count_voltages(reg) > 0) { min_uV = on ? vreg->min_uV : 0; ret = regulator_set_voltage(reg, min_uV, vreg->max_uV); Loading Loading @@ -442,7 +455,7 @@ static int ufs_qcom_phy_disable_vreg(struct device *dev, { int ret = 0; if (!vreg || !vreg->enabled) if (!vreg || !vreg->enabled || vreg->is_always_on) goto out; ret = regulator_disable(vreg->reg); Loading @@ -462,6 +475,13 @@ 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); clk_disable_unprepare(phy->ref_clk); /* * "ref_clk_parent" is optional clock hence make sure that clk Loading