Skip to content

Commit 443a124

Browse files
committed
scsi: ufs: core: Store min and max clk freq from OPP table
JIRA: https://issues.redhat.com/browse/RHEL-79078 commit 77a6725 Author: Nitin Rawat <quic_nitirawa@quicinc.com> Date: Fri Dec 8 18:43:31 2023 +0530 scsi: ufs: core: Store min and max clk freq from OPP table 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> Signed-off-by: Radu Rendec <rrendec@redhat.com>
1 parent e80627d commit 443a124

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

drivers/ufs/host/ufshcd-pltfrm.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Vinayak Holikatti <h.vinayak@samsung.com>
99
*/
1010

11+
#include <linux/clk.h>
1112
#include <linux/module.h>
1213
#include <linux/platform_device.h>
1314
#include <linux/pm_opp.h>
@@ -208,6 +209,55 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
208209
}
209210
}
210211

212+
/**
213+
* ufshcd_parse_clock_min_max_freq - Parse MIN and MAX clocks freq
214+
* @hba: per adapter instance
215+
*
216+
* This function parses MIN and MAX frequencies of all clocks required
217+
* by the host drivers.
218+
*
219+
* Returns 0 for success and non-zero for failure
220+
*/
221+
static int ufshcd_parse_clock_min_max_freq(struct ufs_hba *hba)
222+
{
223+
struct list_head *head = &hba->clk_list_head;
224+
struct ufs_clk_info *clki;
225+
struct dev_pm_opp *opp;
226+
unsigned long freq;
227+
u8 idx = 0;
228+
229+
list_for_each_entry(clki, head, list) {
230+
if (!clki->name)
231+
continue;
232+
233+
clki->clk = devm_clk_get(hba->dev, clki->name);
234+
if (IS_ERR(clki->clk))
235+
continue;
236+
237+
/* Find Max Freq */
238+
freq = ULONG_MAX;
239+
opp = dev_pm_opp_find_freq_floor_indexed(hba->dev, &freq, idx);
240+
if (IS_ERR(opp)) {
241+
dev_err(hba->dev, "Failed to find OPP for MAX frequency\n");
242+
return PTR_ERR(opp);
243+
}
244+
clki->max_freq = dev_pm_opp_get_freq_indexed(opp, idx);
245+
dev_pm_opp_put(opp);
246+
247+
/* Find Min Freq */
248+
freq = 0;
249+
opp = dev_pm_opp_find_freq_ceil_indexed(hba->dev, &freq, idx);
250+
if (IS_ERR(opp)) {
251+
dev_err(hba->dev, "Failed to find OPP for MIN frequency\n");
252+
return PTR_ERR(opp);
253+
}
254+
clki->min_freq = dev_pm_opp_get_freq_indexed(opp, idx++);
255+
dev_pm_opp_put(opp);
256+
}
257+
258+
return 0;
259+
}
260+
211261
static int ufshcd_parse_operating_points(struct ufs_hba *hba)
212262
{
213263
struct device *dev = hba->dev;
@@ -274,6 +324,10 @@ static int ufshcd_parse_operating_points(struct ufs_hba *hba)
274324
return ret;
275325
}
276326

327+
ret = ufshcd_parse_clock_min_max_freq(hba);
328+
if (ret)
329+
return ret;
330+
277331
hba->use_pm_opp = true;
278332

279333
return 0;

0 commit comments

Comments
 (0)