Skip to content

Commit 0a7e457

Browse files
Sumit Guptakrzk
authored andcommitted
memory: tegra: add check if MRQ_EMC_DVFS_LATENCY is supported
Add check to ensure that "MRQ_EMC_DVFS_LATENCY" is supported by the BPMP-FW before making the MRQ request. Currently, if the BPMP-FW doesn't support this MRQ, then the "tegra186_emc_probe" fails. Due to this the Memory Interconnect initialization also doesn't happen. Memory Interconnect is not dependent on this MRQ and can initialize even when this MRQ is not supported in any platform. The check ensures that the MRQ is called only when it is supported by the BPMP-FW and Interconnect initializes independent of this MRQ. Also, moved the code to new function for better readability. Signed-off-by: Sumit Gupta <[email protected]> Acked-by: Thierry Reding <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Krzysztof Kozlowski <[email protected]>
1 parent b18e525 commit 0a7e457

File tree

1 file changed

+71
-65
lines changed

1 file changed

+71
-65
lines changed

drivers/memory/tegra/tegra186-emc.c

Lines changed: 71 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,73 @@ DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_max_rate_fops,
155155
tegra186_emc_debug_max_rate_get,
156156
tegra186_emc_debug_max_rate_set, "%llu\n");
157157

158+
static int tegra186_emc_get_emc_dvfs_latency(struct tegra186_emc *emc)
159+
{
160+
struct mrq_emc_dvfs_latency_response response;
161+
struct tegra_bpmp_message msg;
162+
unsigned int i;
163+
int err;
164+
165+
memset(&msg, 0, sizeof(msg));
166+
msg.mrq = MRQ_EMC_DVFS_LATENCY;
167+
msg.tx.data = NULL;
168+
msg.tx.size = 0;
169+
msg.rx.data = &response;
170+
msg.rx.size = sizeof(response);
171+
172+
err = tegra_bpmp_transfer(emc->bpmp, &msg);
173+
if (err < 0) {
174+
dev_err(emc->dev, "failed to EMC DVFS pairs: %d\n", err);
175+
return err;
176+
}
177+
if (msg.rx.ret < 0) {
178+
dev_err(emc->dev, "EMC DVFS MRQ failed: %d (BPMP error code)\n", msg.rx.ret);
179+
return -EINVAL;
180+
}
181+
182+
emc->debugfs.min_rate = ULONG_MAX;
183+
emc->debugfs.max_rate = 0;
184+
185+
emc->num_dvfs = response.num_pairs;
186+
187+
emc->dvfs = devm_kmalloc_array(emc->dev, emc->num_dvfs, sizeof(*emc->dvfs), GFP_KERNEL);
188+
if (!emc->dvfs)
189+
return -ENOMEM;
190+
191+
dev_dbg(emc->dev, "%u DVFS pairs:\n", emc->num_dvfs);
192+
193+
for (i = 0; i < emc->num_dvfs; i++) {
194+
emc->dvfs[i].rate = response.pairs[i].freq * 1000;
195+
emc->dvfs[i].latency = response.pairs[i].latency;
196+
197+
if (emc->dvfs[i].rate < emc->debugfs.min_rate)
198+
emc->debugfs.min_rate = emc->dvfs[i].rate;
199+
200+
if (emc->dvfs[i].rate > emc->debugfs.max_rate)
201+
emc->debugfs.max_rate = emc->dvfs[i].rate;
202+
203+
dev_dbg(emc->dev, " %2u: %lu Hz -> %lu us\n", i,
204+
emc->dvfs[i].rate, emc->dvfs[i].latency);
205+
}
206+
207+
err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate, emc->debugfs.max_rate);
208+
if (err < 0) {
209+
dev_err(emc->dev, "failed to set rate range [%lu-%lu] for %pC\n",
210+
emc->debugfs.min_rate, emc->debugfs.max_rate, emc->clk);
211+
return err;
212+
}
213+
214+
emc->debugfs.root = debugfs_create_dir("emc", NULL);
215+
debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
216+
emc, &tegra186_emc_debug_available_rates_fops);
217+
debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
218+
emc, &tegra186_emc_debug_min_rate_fops);
219+
debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
220+
emc, &tegra186_emc_debug_max_rate_fops);
221+
222+
return 0;
223+
}
224+
158225
/*
159226
* tegra_emc_icc_set_bw() - Set BW api for EMC provider
160227
* @src: ICC node for External Memory Controller (EMC)
@@ -251,10 +318,7 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc)
251318
static int tegra186_emc_probe(struct platform_device *pdev)
252319
{
253320
struct tegra_mc *mc = dev_get_drvdata(pdev->dev.parent);
254-
struct mrq_emc_dvfs_latency_response response;
255-
struct tegra_bpmp_message msg;
256321
struct tegra186_emc *emc;
257-
unsigned int i;
258322
int err;
259323

260324
emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
@@ -275,70 +339,12 @@ static int tegra186_emc_probe(struct platform_device *pdev)
275339
platform_set_drvdata(pdev, emc);
276340
emc->dev = &pdev->dev;
277341

278-
memset(&msg, 0, sizeof(msg));
279-
msg.mrq = MRQ_EMC_DVFS_LATENCY;
280-
msg.tx.data = NULL;
281-
msg.tx.size = 0;
282-
msg.rx.data = &response;
283-
msg.rx.size = sizeof(response);
284-
285-
err = tegra_bpmp_transfer(emc->bpmp, &msg);
286-
if (err < 0) {
287-
dev_err(&pdev->dev, "failed to EMC DVFS pairs: %d\n", err);
288-
goto put_bpmp;
289-
}
290-
if (msg.rx.ret < 0) {
291-
err = -EINVAL;
292-
dev_err(&pdev->dev, "EMC DVFS MRQ failed: %d (BPMP error code)\n", msg.rx.ret);
293-
goto put_bpmp;
294-
}
295-
296-
emc->debugfs.min_rate = ULONG_MAX;
297-
emc->debugfs.max_rate = 0;
298-
299-
emc->num_dvfs = response.num_pairs;
300-
301-
emc->dvfs = devm_kmalloc_array(&pdev->dev, emc->num_dvfs,
302-
sizeof(*emc->dvfs), GFP_KERNEL);
303-
if (!emc->dvfs) {
304-
err = -ENOMEM;
305-
goto put_bpmp;
306-
}
307-
308-
dev_dbg(&pdev->dev, "%u DVFS pairs:\n", emc->num_dvfs);
309-
310-
for (i = 0; i < emc->num_dvfs; i++) {
311-
emc->dvfs[i].rate = response.pairs[i].freq * 1000;
312-
emc->dvfs[i].latency = response.pairs[i].latency;
313-
314-
if (emc->dvfs[i].rate < emc->debugfs.min_rate)
315-
emc->debugfs.min_rate = emc->dvfs[i].rate;
316-
317-
if (emc->dvfs[i].rate > emc->debugfs.max_rate)
318-
emc->debugfs.max_rate = emc->dvfs[i].rate;
319-
320-
dev_dbg(&pdev->dev, " %2u: %lu Hz -> %lu us\n", i,
321-
emc->dvfs[i].rate, emc->dvfs[i].latency);
322-
}
323-
324-
err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
325-
emc->debugfs.max_rate);
326-
if (err < 0) {
327-
dev_err(&pdev->dev,
328-
"failed to set rate range [%lu-%lu] for %pC\n",
329-
emc->debugfs.min_rate, emc->debugfs.max_rate,
330-
emc->clk);
331-
goto put_bpmp;
342+
if (tegra_bpmp_mrq_is_supported(emc->bpmp, MRQ_EMC_DVFS_LATENCY)) {
343+
err = tegra186_emc_get_emc_dvfs_latency(emc);
344+
if (err)
345+
goto put_bpmp;
332346
}
333347

334-
emc->debugfs.root = debugfs_create_dir("emc", NULL);
335-
debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
336-
emc, &tegra186_emc_debug_available_rates_fops);
337-
debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
338-
emc, &tegra186_emc_debug_min_rate_fops);
339-
debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
340-
emc, &tegra186_emc_debug_max_rate_fops);
341-
342348
if (mc && mc->soc->icc_ops) {
343349
if (tegra_bpmp_mrq_is_supported(emc->bpmp, MRQ_BWMGR_INT)) {
344350
mc->bwmgr_mrq_supported = true;

0 commit comments

Comments
 (0)