Skip to content

Commit 930c681

Browse files
digetxthierryreding
authored andcommitted
memory: tegra30-emc: Poll EMC-CaR handshake instead of waiting for interrupt
The memory clock-rate change could be running on a non-boot CPU, while the boot CPU handles the EMC interrupt. This introduces an unnecessary latency since boot CPU should handle the interrupt and then notify the sibling CPU about clock-rate change completion. In some rare cases boot CPU could be in uninterruptible state for a significant time (like in a case of KASAN + NFS root), it could get to the point that completion timeouts before boot CPU gets a chance to handle interrupt. The solution is to get rid of the completion and replace it with interrupt-status polling. Signed-off-by: Dmitry Osipenko <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent adbcec8 commit 930c681

File tree

1 file changed

+44
-72
lines changed

1 file changed

+44
-72
lines changed

drivers/memory/tegra/tegra30-emc.c

Lines changed: 44 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include <linux/clk.h>
1313
#include <linux/clk/tegra.h>
14-
#include <linux/completion.h>
1514
#include <linux/debugfs.h>
1615
#include <linux/delay.h>
1716
#include <linux/err.h>
@@ -327,7 +326,6 @@ struct emc_timing {
327326
struct tegra_emc {
328327
struct device *dev;
329328
struct tegra_mc *mc;
330-
struct completion clk_handshake_complete;
331329
struct notifier_block clk_nb;
332330
struct clk *clk;
333331
void __iomem *regs;
@@ -374,52 +372,10 @@ static int emc_seq_update_timing(struct tegra_emc *emc)
374372
return 0;
375373
}
376374

377-
static void emc_complete_clk_change(struct tegra_emc *emc)
378-
{
379-
struct emc_timing *timing = emc->new_timing;
380-
unsigned int dram_num;
381-
bool failed = false;
382-
int err;
383-
384-
/* re-enable auto-refresh */
385-
dram_num = tegra_mc_get_emem_device_count(emc->mc);
386-
writel_relaxed(EMC_REFCTRL_ENABLE_ALL(dram_num),
387-
emc->regs + EMC_REFCTRL);
388-
389-
/* restore auto-calibration */
390-
if (emc->vref_cal_toggle)
391-
writel_relaxed(timing->emc_auto_cal_interval,
392-
emc->regs + EMC_AUTO_CAL_INTERVAL);
393-
394-
/* restore dynamic self-refresh */
395-
if (timing->emc_cfg_dyn_self_ref) {
396-
emc->emc_cfg |= EMC_CFG_DYN_SREF_ENABLE;
397-
writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG);
398-
}
399-
400-
/* set number of clocks to wait after each ZQ command */
401-
if (emc->zcal_long)
402-
writel_relaxed(timing->emc_zcal_cnt_long,
403-
emc->regs + EMC_ZCAL_WAIT_CNT);
404-
405-
/* wait for writes to settle */
406-
udelay(2);
407-
408-
/* update restored timing */
409-
err = emc_seq_update_timing(emc);
410-
if (err)
411-
failed = true;
412-
413-
/* restore early ACK */
414-
mc_writel(emc->mc, emc->mc_override, MC_EMEM_ARB_OVERRIDE);
415-
416-
WRITE_ONCE(emc->bad_state, failed);
417-
}
418-
419375
static irqreturn_t tegra_emc_isr(int irq, void *data)
420376
{
421377
struct tegra_emc *emc = data;
422-
u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
378+
u32 intmask = EMC_REFRESH_OVERFLOW_INT;
423379
u32 status;
424380

425381
status = readl_relaxed(emc->regs + EMC_INTSTATUS) & intmask;
@@ -434,18 +390,6 @@ static irqreturn_t tegra_emc_isr(int irq, void *data)
434390
/* clear interrupts */
435391
writel_relaxed(status, emc->regs + EMC_INTSTATUS);
436392

437-
/* notify about EMC-CAR handshake completion */
438-
if (status & EMC_CLKCHANGE_COMPLETE_INT) {
439-
if (completion_done(&emc->clk_handshake_complete)) {
440-
dev_err_ratelimited(emc->dev,
441-
"bogus handshake interrupt\n");
442-
return IRQ_NONE;
443-
}
444-
445-
emc_complete_clk_change(emc);
446-
complete(&emc->clk_handshake_complete);
447-
}
448-
449393
return IRQ_HANDLED;
450394
}
451395

@@ -801,29 +745,58 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
801745
*/
802746
mc_readl(emc->mc, MC_EMEM_ARB_OVERRIDE);
803747

804-
reinit_completion(&emc->clk_handshake_complete);
805-
806-
emc->new_timing = timing;
807-
808748
return 0;
809749
}
810750

811751
static int emc_complete_timing_change(struct tegra_emc *emc,
812752
unsigned long rate)
813753
{
814-
unsigned long timeout;
754+
struct emc_timing *timing = emc_find_timing(emc, rate);
755+
unsigned int dram_num;
756+
int err;
757+
u32 v;
815758

816-
timeout = wait_for_completion_timeout(&emc->clk_handshake_complete,
817-
msecs_to_jiffies(100));
818-
if (timeout == 0) {
819-
dev_err(emc->dev, "emc-car handshake failed\n");
820-
return -EIO;
759+
err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_INTSTATUS, v,
760+
v & EMC_CLKCHANGE_COMPLETE_INT,
761+
1, 100);
762+
if (err) {
763+
dev_err(emc->dev, "emc-car handshake timeout: %d\n", err);
764+
return err;
821765
}
822766

823-
if (READ_ONCE(emc->bad_state))
824-
return -EIO;
767+
/* re-enable auto-refresh */
768+
dram_num = tegra_mc_get_emem_device_count(emc->mc);
769+
writel_relaxed(EMC_REFCTRL_ENABLE_ALL(dram_num),
770+
emc->regs + EMC_REFCTRL);
771+
772+
/* restore auto-calibration */
773+
if (emc->vref_cal_toggle)
774+
writel_relaxed(timing->emc_auto_cal_interval,
775+
emc->regs + EMC_AUTO_CAL_INTERVAL);
825776

826-
return 0;
777+
/* restore dynamic self-refresh */
778+
if (timing->emc_cfg_dyn_self_ref) {
779+
emc->emc_cfg |= EMC_CFG_DYN_SREF_ENABLE;
780+
writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG);
781+
}
782+
783+
/* set number of clocks to wait after each ZQ command */
784+
if (emc->zcal_long)
785+
writel_relaxed(timing->emc_zcal_cnt_long,
786+
emc->regs + EMC_ZCAL_WAIT_CNT);
787+
788+
/* wait for writes to settle */
789+
udelay(2);
790+
791+
/* update restored timing */
792+
err = emc_seq_update_timing(emc);
793+
if (!err)
794+
emc->bad_state = false;
795+
796+
/* restore early ACK */
797+
mc_writel(emc->mc, emc->mc_override, MC_EMEM_ARB_OVERRIDE);
798+
799+
return err;
827800
}
828801

829802
static int emc_unprepare_timing_change(struct tegra_emc *emc,
@@ -1033,7 +1006,7 @@ static struct device_node *emc_find_node_by_ram_code(struct device *dev)
10331006

10341007
static int emc_setup_hw(struct tegra_emc *emc)
10351008
{
1036-
u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
1009+
u32 intmask = EMC_REFRESH_OVERFLOW_INT;
10371010
u32 fbio_cfg5, emc_cfg, emc_dbg;
10381011
enum emc_dram_type dram_type;
10391012

@@ -1321,7 +1294,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
13211294
if (!emc->mc)
13221295
return -EPROBE_DEFER;
13231296

1324-
init_completion(&emc->clk_handshake_complete);
13251297
emc->clk_nb.notifier_call = emc_clk_change_notify;
13261298
emc->dev = &pdev->dev;
13271299

0 commit comments

Comments
 (0)