Skip to content

Commit

Permalink
scsi: ufs: core: Store min and max clk freq from OPP table
Browse files Browse the repository at this point in the history
OPP support added by commit 72208eb ("scsi: ufs: core: Add support for
parsing OPP") doesn't update the min_freq and max_freq of each clock in
'struct ufs_clk_info'.

But these values are used by the host drivers internally for controller
configuration. When the OPP support is enabled in devicetree, these values
will be 0, causing boot issues on the respective platforms.

So add support to parse the min_freq and max_freq of all clocks while
parsing the OPP table.

Fixes: 72208eb ("scsi: ufs: core: Add support for parsing OPP")
Co-developed-by: Manish Pandey <quic_mapa@quicinc.com>
Signed-off-by: Manish Pandey <quic_mapa@quicinc.com>
Signed-off-by: Nitin Rawat <quic_nitirawa@quicinc.com>
Link: https://lore.kernel.org/r/20231208131331.12596-1-quic_nitirawa@quicinc.com
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Nitin Rawat authored and Martin K. Petersen committed Dec 14, 2023
1 parent c5becf5 commit 77a6725
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/ufs/host/ufshcd-pltfrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Vinayak Holikatti <h.vinayak@samsung.com>
*/

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
Expand Down Expand Up @@ -213,6 +214,55 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
}
}

/**
* ufshcd_parse_clock_min_max_freq - Parse MIN and MAX clocks freq
* @hba: per adapter instance
*
* This function parses MIN and MAX frequencies of all clocks required
* by the host drivers.
*
* Returns 0 for success and non-zero for failure
*/
static int ufshcd_parse_clock_min_max_freq(struct ufs_hba *hba)
{
struct list_head *head = &hba->clk_list_head;
struct ufs_clk_info *clki;
struct dev_pm_opp *opp;
unsigned long freq;
u8 idx = 0;

list_for_each_entry(clki, head, list) {
if (!clki->name)
continue;

clki->clk = devm_clk_get(hba->dev, clki->name);
if (IS_ERR(clki->clk))
continue;

/* Find Max Freq */
freq = ULONG_MAX;
opp = dev_pm_opp_find_freq_floor_indexed(hba->dev, &freq, idx);
if (IS_ERR(opp)) {
dev_err(hba->dev, "Failed to find OPP for MAX frequency\n");
return PTR_ERR(opp);
}
clki->max_freq = dev_pm_opp_get_freq_indexed(opp, idx);
dev_pm_opp_put(opp);

/* Find Min Freq */
freq = 0;
opp = dev_pm_opp_find_freq_ceil_indexed(hba->dev, &freq, idx);
if (IS_ERR(opp)) {
dev_err(hba->dev, "Failed to find OPP for MIN frequency\n");
return PTR_ERR(opp);
}
clki->min_freq = dev_pm_opp_get_freq_indexed(opp, idx++);
dev_pm_opp_put(opp);
}

return 0;
}

static int ufshcd_parse_operating_points(struct ufs_hba *hba)
{
struct device *dev = hba->dev;
Expand Down Expand Up @@ -279,6 +329,10 @@ static int ufshcd_parse_operating_points(struct ufs_hba *hba)
return ret;
}

ret = ufshcd_parse_clock_min_max_freq(hba);
if (ret)
return ret;

hba->use_pm_opp = true;

return 0;
Expand Down

0 comments on commit 77a6725

Please sign in to comment.