Errors in dealing with the mode register write on Tegra K1


I am trying to apply a PASR(Partial Array Self Refresh) framework, which can stop the refresh of some specified memory banks to reduce energy, on Nexus 9. Nexus 9 is with 64-bit Tegra K1 chipset. The kernel version is android-tegra-flounder-3.10.

To apply the PASR framework, what I need to do is to tell the memory controller through a memory register MR16, i.e. send command to EMC_MRW, that which memory bank should stop being refreshed.

The following shows the main steps to send the command.

static void tegra132_pasr_apply_mask(u16 *mem_reg, void *cookie)
	u32 val = 0;
	int device = (int)cookie; /*shows which device to choose: 0x2 for dev0; 0x1 for dev1*/
	val = TEGRA_EMC_MODE_REG_16 | *mem_reg;
	val |= device << TEGRA_EMC_MRW_DEV_SHIFT;
	emc_writel(val, EMC_MRW);
	pr_debug("%s: cookie = %d mem_reg = 0x%04x val = 0x%08x\n", __func__,
			(int)cookie, *mem_reg, val);

The value of 32-bit “val” is set based on the parameters given in the Nvidia Tegra K1 technical reference manual (page 806). Bit 31:30 indicates the device selection (dev0 or dev1); bit 23:16 is 0X10, showing the MR16 register address; and bit 7:0 is set to 0xff, showing the data written to MR16, where 0xff indicates the refresh of all memory banks have been stopped.

By registering the above driver module, it is expected to see the device crashed, as all memory have been stopped refreshing. However, the device is still alive! Besides, no matter bit 7:0 are set to what value, there is no energy difference on Nexus 9.

Does anyone have any idea about the bug reason? Or maybe someone can suggest where to start debugging?