drivers/memory/tegra/tegra210-emc-cc-r21021.c

Source file repositories/reference/linux-study-clean/drivers/memory/tegra/tegra210-emc-cc-r21021.c

File Facts

System
Linux kernel
Corpus path
drivers/memory/tegra/tegra210-emc-cc-r21021.c
Extension
.c
Size
45536 bytes
Lines
1518
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

if (last->burst_regs[EMC_RP_INDEX] < tRTM) {
			if (tRTM > (last->burst_regs[EMC_R2P_INDEX] +
				    last->burst_regs[EMC_RP_INDEX])) {
				R2P_war = tRTM - last->burst_regs[EMC_RP_INDEX];
				RP_war = last->burst_regs[EMC_RP_INDEX];
				TRPab_war = last->burst_regs[EMC_TRPAB_INDEX];

				if (R2P_war > 63) {
					RP_war = R2P_war +
						 last->burst_regs[EMC_RP_INDEX] - 63;

					if (TRPab_war < RP_war)
						TRPab_war = RP_war;

					R2P_war = 63;
				}
			} else {
				R2P_war = last->burst_regs[EMC_R2P_INDEX];
				RP_war = last->burst_regs[EMC_RP_INDEX];
				TRPab_war = last->burst_regs[EMC_TRPAB_INDEX];
			}

			if (RP_war < deltaTWATM) {
				W2P_war = last->burst_regs[EMC_W2P_INDEX]
					  + deltaTWATM - RP_war;
				if (W2P_war > 63) {
					RP_war = RP_war + W2P_war - 63;
					if (TRPab_war < RP_war)
						TRPab_war = RP_war;
					W2P_war = 63;
				}
			} else {
				W2P_war = last->burst_regs[
					  EMC_W2P_INDEX];
			}

			if ((last->burst_regs[EMC_W2P_INDEX] ^ W2P_war) ||
			    (last->burst_regs[EMC_R2P_INDEX] ^ R2P_war) ||
			    (last->burst_regs[EMC_RP_INDEX] ^ RP_war) ||
			    (last->burst_regs[EMC_TRPAB_INDEX] ^ TRPab_war)) {
				emc_writel(emc, RP_war, EMC_RP);
				emc_writel(emc, R2P_war, EMC_R2P);
				emc_writel(emc, W2P_war, EMC_W2P);
				emc_writel(emc, TRPab_war, EMC_TRPAB);
			}

			tegra210_emc_timing_update(emc);
		} else {
			emc_dbg(emc, INFO, "Skipped WAR\n");
		}
	}

	if (!fsp_for_next_freq) {
		mr13_flip_fspwr = (next->emc_mrw3 & 0xffffff3f) | 0x80;
		mr13_flip_fspop = (next->emc_mrw3 & 0xffffff3f) | 0x00;
	} else {
		mr13_flip_fspwr = (next->emc_mrw3 & 0xffffff3f) | 0x40;
		mr13_flip_fspop = (next->emc_mrw3 & 0xffffff3f) | 0xc0;
	}

	if (dram_type == DRAM_TYPE_LPDDR4) {
		emc_writel(emc, mr13_flip_fspwr, EMC_MRW3);
		emc_writel(emc, next->emc_mrw, EMC_MRW);
		emc_writel(emc, next->emc_mrw2, EMC_MRW2);
	}

	/*
	 * Step 8:
	 *   Program the shadow registers.
	 */
	emc_dbg(emc, STEPS, "Step 8\n");
	emc_dbg(emc, SUB_STEPS, "Writing burst_regs\n");

	for (i = 0; i < next->num_burst; i++) {
		const u16 *offsets = emc->offsets->burst;
		u16 offset;

		if (!offsets[i])
			continue;

		value = next->burst_regs[i];
		offset = offsets[i];

		if (dram_type != DRAM_TYPE_LPDDR4 &&
		    (offset == EMC_MRW6 || offset == EMC_MRW7 ||
		     offset == EMC_MRW8 || offset == EMC_MRW9 ||
		     offset == EMC_MRW10 || offset == EMC_MRW11 ||
		     offset == EMC_MRW12 || offset == EMC_MRW13 ||
		     offset == EMC_MRW14 || offset == EMC_MRW15 ||
		     offset == EMC_TRAINING_CTRL))

Annotation

Implementation Notes