drivers/memory/tegra/tegra30-emc.c

Source file repositories/reference/linux-study-clean/drivers/memory/tegra/tegra30-emc.c

File Facts

System
Linux kernel
Corpus path
drivers/memory/tegra/tegra30-emc.c
Extension
.c
Size
41952 bytes
Lines
1645
Domain
Driver Families
Bucket
drivers/memory
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct emc_timing {
	unsigned long rate;

	u32 data[ARRAY_SIZE(emc_timing_registers)];

	u32 emc_auto_cal_interval;
	u32 emc_mode_1;
	u32 emc_mode_2;
	u32 emc_mode_reset;
	u32 emc_zcal_cnt_long;
	bool emc_cfg_periodic_qrst;
	bool emc_cfg_dyn_self_ref;
};

struct tegra_emc {
	struct device *dev;
	struct tegra_mc *mc;
	struct icc_provider provider;
	struct notifier_block clk_nb;
	struct clk *clk;
	void __iomem *regs;
	unsigned int irq;
	bool bad_state;

	struct emc_timing *new_timing;
	struct emc_timing *timings;
	unsigned int num_timings;

	u32 mc_override;
	u32 emc_cfg;

	u32 emc_mode_1;
	u32 emc_mode_2;
	u32 emc_mode_reset;

	bool vref_cal_toggle : 1;
	bool zcal_long : 1;
	bool dll_on : 1;

	struct {
		struct dentry *root;
		unsigned long min_rate;
		unsigned long max_rate;
	} debugfs;

	struct tegra_emc_rate_requests reqs;

	bool mrr_error;
};

static int emc_seq_update_timing(struct tegra_emc *emc)
{
	u32 val;
	int err;

	writel_relaxed(EMC_TIMING_UPDATE, emc->regs + EMC_TIMING_CONTROL);

	err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_STATUS, val,
				!(val & EMC_STATUS_TIMING_UPDATE_STALLED),
				1, 200);
	if (err) {
		dev_err(emc->dev, "failed to update timing: %d\n", err);
		return err;
	}

	return 0;
}

static irqreturn_t tegra30_emc_isr(int irq, void *data)
{
	struct tegra_emc *emc = data;
	u32 intmask = EMC_REFRESH_OVERFLOW_INT;
	u32 status;

	status = readl_relaxed(emc->regs + EMC_INTSTATUS) & intmask;
	if (!status)
		return IRQ_NONE;

	/* notify about HW problem */
	if (status & EMC_REFRESH_OVERFLOW_INT)
		dev_err_ratelimited(emc->dev,
				    "refresh request overflow timeout\n");

	/* clear interrupts */
	writel_relaxed(status, emc->regs + EMC_INTSTATUS);

	return IRQ_HANDLED;
}

static struct emc_timing *emc_find_timing(struct tegra_emc *emc,

Annotation

Implementation Notes