tegra124/nyan: memory and display updates
tegra124: use pll_c_out1 as sclk parent Reviewed-on: https://chromium-review.googlesource.com/180865 (cherry picked from commit 418337a5bde70df6a770222201c51bf3e8892d5f) tegra124: take LP cluster out of reset Reviewed-on: https://chromium-review.googlesource.com/180866 (cherry picked from commit 74cdc68ea9b29da9af313635787e82bacb9e23e3) tegra124: norrin: display code clean up Reviewed-on: https://chromium-review.googlesource.com/181003 (cherry picked from commit 63843ec61b3b47ffc985edcb589771591c5c9f17) tegra124: Change the display hack to use window A Reviewed-on: https://chromium-review.googlesource.com/182001 (cherry picked from commit ef245e42eb17b2eb0e8712f252353a95ee6fc01a) tegra124: norrin: Initialize frame buffer Reviewed-on: https://chromium-review.googlesource.com/182090 (cherry picked from commit b7c1d1b3c9519cbbe1615737aed4c4c0efed2167) nyan: do not enable pull-ups on SPI1 (EC) data pins Reviewed-on: https://chromium-review.googlesource.com/181063 (cherry picked from commit 2f55188501ebcae9e01b12831f152d4520c7047c) tegra124: Add source for the LP0 resume blob. Reviewed-on: https://chromium-review.googlesource.com/183152 (cherry picked from commit a00d099bf710c297320d7edff7f7c608283d1b0b) tegra124: Revise Memory Controller registers structure definition. Reviewed-on: https://chromium-review.googlesource.com/182992 (cherry picked from commit ae83564cdd1d46c8166df1a95703e8cb1060c0a1) tegra124: Add more PMC register details. Reviewed-on: https://chromium-review.googlesource.com/183231 (cherry picked from commit d62ed2c19693284f10c2a12f4295091de3ace829) tegra124: Add SDRAM configuration header file from cbootimage. Reviewed-on: https://chromium-review.googlesource.com/182613 (cherry picked from commit 193ed2a104af38f6c41a332a649ce06a3238e0a4) tegra124: Revise sdram_param.h for Coreboot. Reviewed-on: https://chromium-review.googlesource.com/182614 (cherry picked from commit 311b0568c5de627435a5b035a7a1e40ecc2672f8) tegra124: Fix EMC base address. Reviewed-on: https://chromium-review.googlesource.com/183602 (cherry picked from commit 587c8969292ccecfa29c7720bcf24c704ed4ac4e) tegra124: Add EMC registers definition. Reviewed-on: https://chromium-review.googlesource.com/183622 (cherry picked from commit 67a8e5c7e87a1cc6bf006ad806751b549ffd3d5a) tegra124: Never touch MEM(MC)/EMC clocks in ramstage. Reviewed-on: https://chromium-review.googlesource.com/183623 (cherry picked from commit 8e3bb34d4ae37feae89b4a39850b2988a334d023) tegra124: use RAM_CODE[3:2] for ram code Reviewed-on: https://chromium-review.googlesource.com/183833 (cherry picked from commit 0154239467064ffcbdb82fc4c6b629f5d0c3568d) tegra124: Allow setting PLLM (clock for SDRAM). Reviewed-on: https://chromium-review.googlesource.com/183621 (cherry picked from commit a534e5b7c61d655eedd409dbd7780a4f90d40683) tegra124: SDRAM Initialization. Reviewed-on: https://chromium-review.googlesource.com/182615 (cherry picked from commit 5a60ae93b0603ee0d4806132be0360f3b1612bce) tegra124: Get RAM_CODE for SDRAM initialization. Reviewed-on: https://chromium-review.googlesource.com/183781 (cherry picked from commit a5b7ce70525d7ffef3fac90b8eb14b3f3787f4d8) Squashed 18 nyan/tegra commits for memory and display. Change-Id: I59a781ee8dc2fd9c9085373f5a9bb7c8108b094c Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Reviewed-on: http://review.coreboot.org/6914 Reviewed-by: Ronald G. Minnich <rminnich@gmail.com> Tested-by: build bot (Jenkins)
This commit is contained in:
		
				
					committed by
					
						 Isaac Christensen
						Isaac Christensen
					
				
			
			
				
	
			
			
			
						parent
						
							d65e214d66
						
					
				
				
					commit
					24d4f7f8de
				
			| @@ -14,3 +14,20 @@ DeviceParam[0].SpiFlashParams.ClockDivider        = 0x16; | ||||
| DeviceParam[0].SpiFlashParams.ClockSource         = NvBootSpiClockSource_PllPOut0; | ||||
| DeviceParam[0].SpiFlashParams.PageSize2kor16k     = 0; | ||||
|  | ||||
| DevType[1] = NvBootDevType_Spi; | ||||
| DeviceParam[1].SpiFlashParams.ReadCommandTypeFast = NV_FALSE; | ||||
| DeviceParam[1].SpiFlashParams.ClockDivider        = 0x16; | ||||
| DeviceParam[1].SpiFlashParams.ClockSource         = NvBootSpiClockSource_PllPOut0; | ||||
| DeviceParam[1].SpiFlashParams.PageSize2kor16k     = 0; | ||||
|  | ||||
| DevType[2] = NvBootDevType_Spi; | ||||
| DeviceParam[2].SpiFlashParams.ReadCommandTypeFast = NV_FALSE; | ||||
| DeviceParam[2].SpiFlashParams.ClockDivider        = 0x16; | ||||
| DeviceParam[2].SpiFlashParams.ClockSource         = NvBootSpiClockSource_PllPOut0; | ||||
| DeviceParam[2].SpiFlashParams.PageSize2kor16k     = 0; | ||||
|  | ||||
| DevType[3] = NvBootDevType_Spi; | ||||
| DeviceParam[3].SpiFlashParams.ReadCommandTypeFast = NV_FALSE; | ||||
| DeviceParam[3].SpiFlashParams.ClockDivider        = 0x16; | ||||
| DeviceParam[3].SpiFlashParams.ClockSource         = NvBootSpiClockSource_PllPOut0; | ||||
| DeviceParam[3].SpiFlashParams.PageSize2kor16k     = 0; | ||||
|   | ||||
| @@ -89,11 +89,11 @@ static void setup_pinmux(void) | ||||
|  | ||||
| 	// SPI1 MOSI | ||||
| 	pinmux_set_config(PINMUX_ULPI_CLK_INDEX, PINMUX_ULPI_CLK_FUNC_SPI1 | | ||||
| 						 PINMUX_PULL_UP | | ||||
| 						 PINMUX_PULL_NONE | | ||||
| 						 PINMUX_INPUT_ENABLE); | ||||
| 	// SPI1 MISO | ||||
| 	pinmux_set_config(PINMUX_ULPI_DIR_INDEX, PINMUX_ULPI_DIR_FUNC_SPI1 | | ||||
| 						 PINMUX_PULL_UP | | ||||
| 						 PINMUX_PULL_NONE | | ||||
| 						 PINMUX_INPUT_ENABLE); | ||||
| 	// SPI1 SCLK | ||||
| 	pinmux_set_config(PINMUX_ULPI_NXT_INDEX, PINMUX_ULPI_NXT_FUNC_SPI1 | | ||||
| @@ -216,9 +216,9 @@ static void setup_kernel_info(void) | ||||
|  | ||||
| 	// Not strictly info, but kernel graphics driver needs this region locked down | ||||
| 	struct tegra_mc_regs *mc = (void *)TEGRA_MC_BASE; | ||||
| 	writel(0, &mc->mc_vpr_bom); | ||||
| 	writel(0, &mc->mc_vpr_size); | ||||
| 	writel(1, &mc->mc_vpr_ctrl); | ||||
| 	writel(0, &mc->video_protect_bom); | ||||
| 	writel(0, &mc->video_protect_size_mb); | ||||
| 	writel(1, &mc->video_protect_reg_ctrl); | ||||
| } | ||||
|  | ||||
| static void setup_ec_spi(void) | ||||
| @@ -243,14 +243,17 @@ static void mainboard_init(device_t dev) | ||||
| 	 * conntected to AHUB (AUDIO, APBIF, I2S, DAM, AMX, ADX, SPDIF, AFC) out | ||||
| 	 * of reset and clock-enabled, otherwise reading AHUB devices (In our | ||||
| 	 * case, I2S/APBIF/AUDIO<XBAR>) will hang. | ||||
| 	 * | ||||
| 	 * Note that CLK_H_MEM (MC) and CLK_H_EMC should be already either | ||||
| 	 * initialized by BootROM, or in romstage SDRAM initialization. | ||||
| 	 */ | ||||
| 	clock_enable_clear_reset(CLK_L_GPIO | CLK_L_I2C1 | CLK_L_SDMMC4 | | ||||
| 				 CLK_L_I2S0 | CLK_L_I2S1 | CLK_L_I2S2 | | ||||
| 				 CLK_L_SPDIF | CLK_L_USBD | CLK_L_DISP1 | | ||||
| 				 CLK_L_HOST1X, | ||||
|  | ||||
| 				 CLK_H_EMC | CLK_H_I2C2 | CLK_H_SBC1 | | ||||
| 				 CLK_H_PMC | CLK_H_MEM | CLK_H_USB3, | ||||
| 				 CLK_H_I2C2 | CLK_H_SBC1 | CLK_H_PMC | | ||||
| 				 CLK_H_USB3, | ||||
|  | ||||
| 				 CLK_U_I2C3 | CLK_U_CSITE | CLK_U_SDMMC3, | ||||
|  | ||||
|   | ||||
| @@ -20,10 +20,12 @@ endif | ||||
|  | ||||
| romstage-y += cbfs.c | ||||
| romstage-y += cbmem.c | ||||
| romstage-y += clock.c | ||||
| romstage-y += early_display.c | ||||
| romstage-y += dma.c | ||||
| romstage-y += i2c.c | ||||
| romstage-y += monotonic_timer.c | ||||
| romstage-y += sdram.c | ||||
| romstage-y += spi.c | ||||
| romstage-y += ../tegra/gpio.c | ||||
| romstage-y += ../tegra/i2c.c | ||||
|   | ||||
| @@ -352,10 +352,20 @@ check_member(clk_rst_ctlr, clk_src_soc_therm, 0x644); | ||||
| #define PLL_BASE_DIVM_MASK		(0x1f << PLL_BASE_DIVM_SHIFT) | ||||
|  | ||||
| /* SPECIAL CASE: PLLM, PLLC and PLLX use different-sized fields here */ | ||||
| #define PLLCMX_BASE_DIVP_MASK		(0xfU << PLL_BASE_DIVP_SHIFT) | ||||
| #define PLLCX_BASE_DIVP_MASK		(0xfU << PLL_BASE_DIVP_SHIFT) | ||||
| #define PLLM_BASE_DIVP_MASK		(0x1U << PLL_BASE_DIVP_SHIFT) | ||||
| #define PLLCMX_BASE_DIVN_MASK		(0xffU << PLL_BASE_DIVN_SHIFT) | ||||
| #define PLLCMX_BASE_DIVM_MASK		(0xffU << PLL_BASE_DIVM_SHIFT) | ||||
|  | ||||
| /* PLLM specific registers */ | ||||
| #define PLLM_MISC1_SETUP_SHIFT			0 | ||||
| #define PLLM_MISC1_PD_LSHIFT_PH45_SHIFT		28 | ||||
| #define PLLM_MISC1_PD_LSHIFT_PH90_SHIFT		29 | ||||
| #define PLLM_MISC1_PD_LSHIFT_PH135_SHIFT	30 | ||||
| #define PLLM_MISC2_KCP_SHIFT			1 | ||||
| #define PLLM_MISC2_KVCO_SHIFT			0 | ||||
| #define PLLM_OUT1_RSTN_RESET_DISABLE		(1 << 0) | ||||
|  | ||||
| /* Generic, indiscriminate divisor mask. May catch some innocent bystander bits | ||||
|  * on the side that we don't particularly care about. */ | ||||
| #define PLL_BASE_DIV_MASK		(0xffffff) | ||||
| @@ -414,6 +424,8 @@ check_member(clk_rst_ctlr, clk_src_soc_therm, 0x644); | ||||
| #define CLK_SOURCE_SHIFT		29 | ||||
| #define CLK_SOURCE_MASK			(0x7 << CLK_SOURCE_SHIFT) | ||||
|  | ||||
| #define CLK_SOURCE_EMC_MC_EMC_SAME_FREQ (1 << 16) | ||||
|  | ||||
| #define CLK_UART_DIV_OVERRIDE		(1 << 24) | ||||
|  | ||||
| /* CLK_RST_CONTROLLER_SCLK_BURST_POLICY */ | ||||
| @@ -525,4 +537,15 @@ enum { | ||||
| 	CRC_RST_CPUG_CLR_PDBG = 0x1 << 30, | ||||
| }; | ||||
|  | ||||
| // RST_CPULP_CMPLX_CLR | ||||
| enum { | ||||
| 	CRC_RST_CPULP_CLR_CPU0 = 0x1 << 0, | ||||
| 	CRC_RST_CPULP_CLR_DBG0 = 0x1 << 12, | ||||
| 	CRC_RST_CPULP_CLR_CORE0 = 0x1 << 16, | ||||
| 	CRC_RST_CPULP_CLR_CX0 = 0x1 << 20, | ||||
| 	CRC_RST_CPULP_CLR_L2 = 0x1 << 24, | ||||
| 	CRC_RST_CPULP_CLR_NONCPU = 0x1 << 29, | ||||
| 	CRC_RST_CPULP_CLR_PDBG = 0x1 << 30, | ||||
| }; | ||||
|  | ||||
| #endif	/* _TEGRA124_CLK_RST_H_ */ | ||||
|   | ||||
| @@ -327,6 +327,63 @@ void clock_external_output(int clk_id) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Start PLLM for SDRAM. */ | ||||
| void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90, | ||||
| 		 u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source, | ||||
| 		 u32 same_freq) | ||||
| { | ||||
| 	u32 misc1 = ((setup << PLLM_MISC1_SETUP_SHIFT) | | ||||
| 		     (ph45 << PLLM_MISC1_PD_LSHIFT_PH45_SHIFT) | | ||||
| 		     (ph90 << PLLM_MISC1_PD_LSHIFT_PH90_SHIFT) | | ||||
| 		     (ph135 << PLLM_MISC1_PD_LSHIFT_PH135_SHIFT)), | ||||
| 	    misc2 = ((kvco << PLLM_MISC2_KVCO_SHIFT) | | ||||
| 		     (kcp << PLLM_MISC2_KCP_SHIFT)), | ||||
| 	    base; | ||||
|  | ||||
| 	if (same_freq) | ||||
| 		emc_source |= CLK_SOURCE_EMC_MC_EMC_SAME_FREQ; | ||||
| 	else | ||||
| 		emc_source &= ~CLK_SOURCE_EMC_MC_EMC_SAME_FREQ; | ||||
|  | ||||
| 	/* | ||||
| 	 * Note PLLM_BASE.PLLM_OUT1_RSTN must be in RESET_ENABLE mode, and | ||||
| 	 * PLLM_BASE.ENABLE must be in DISABLE state (both are the default | ||||
| 	 * values after coldboot reset). | ||||
| 	 */ | ||||
|  | ||||
| 	writel(misc1, &clk_rst->pllm_misc1); | ||||
| 	writel(misc2, &clk_rst->pllm_misc2); | ||||
|  | ||||
| 	/* PLLM.BASE needs BYPASS=0, different from general init_pll */ | ||||
| 	base = readl(&clk_rst->pllm_base); | ||||
| 	base &= ~(PLLCMX_BASE_DIVN_MASK | PLLCMX_BASE_DIVM_MASK | | ||||
| 		  PLLM_BASE_DIVP_MASK | PLL_BASE_BYPASS); | ||||
| 	base |= ((m << PLL_BASE_DIVM_SHIFT) | (n << PLL_BASE_DIVN_SHIFT) | | ||||
| 		 (p << PLL_BASE_DIVP_SHIFT)); | ||||
| 	writel(base, &clk_rst->pllm_base); | ||||
|  | ||||
| 	setbits_le32(&clk_rst->pllm_base, PLL_BASE_ENABLE); | ||||
| 	/* stable_time is required, before we can start to check lock. */ | ||||
| 	udelay(stable_time); | ||||
|  | ||||
| 	while (!(readl(&clk_rst->pllm_base) & PLL_BASE_LOCK)) { | ||||
| 		udelay(1); | ||||
| 	} | ||||
| 	/* | ||||
| 	 * After PLLM reports being locked, we have to delay 10us before | ||||
| 	 * enabling PLLM_OUT. | ||||
| 	 */ | ||||
| 	udelay(10); | ||||
|  | ||||
| 	/* Put OUT1 out of reset state (start to output). */ | ||||
| 	setbits_le32(&clk_rst->pllm_out, PLLM_OUT1_RSTN_RESET_DISABLE); | ||||
|  | ||||
| 	/* Enable and start MEM(MC) and EMC. */ | ||||
| 	clock_enable_clear_reset(0, CLK_H_MEM | CLK_H_EMC, 0, 0, 0, 0); | ||||
| 	writel(emc_source, &clk_rst->clk_src_emc); | ||||
| 	udelay(IO_STABILIZATION_DELAY); | ||||
| } | ||||
|  | ||||
| void clock_cpu0_config_and_reset(void *entry) | ||||
| { | ||||
| 	void * const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100; | ||||
| @@ -357,6 +414,7 @@ void clock_cpu0_config_and_reset(void *entry) | ||||
| 	// Enable other CPU related clocks. | ||||
| 	setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_CPU); | ||||
| 	setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPUG); | ||||
| 	setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPULP); | ||||
|  | ||||
| 	// Disable the reset on the non-CPU parts of the fast cluster. | ||||
| 	write32(CRC_RST_CPUG_CLR_NONCPU, | ||||
| @@ -372,6 +430,15 @@ void clock_cpu0_config_and_reset(void *entry) | ||||
| 		CRC_RST_CPUG_CLR_CX2 | CRC_RST_CPUG_CLR_CX3 | | ||||
| 		CRC_RST_CPUG_CLR_L2 | CRC_RST_CPUG_CLR_PDBG, | ||||
| 		&clk_rst->rst_cpug_cmplx_clr); | ||||
|  | ||||
| 	// Disable the reset on the non-CPU parts of the slow cluster. | ||||
| 	write32(CRC_RST_CPULP_CLR_NONCPU, | ||||
| 		&clk_rst->rst_cpulp_cmplx_clr); | ||||
| 	// Disable the various resets on the LP CPU. | ||||
| 	write32(CRC_RST_CPULP_CLR_CPU0 | CRC_RST_CPULP_CLR_DBG0 | | ||||
| 		CRC_RST_CPULP_CLR_CORE0 | CRC_RST_CPULP_CLR_CX0 | | ||||
| 		CRC_RST_CPULP_CLR_L2 | CRC_RST_CPULP_CLR_PDBG, | ||||
| 		&clk_rst->rst_cpulp_cmplx_clr); | ||||
| } | ||||
|  | ||||
| void clock_halt_avp(void) | ||||
| @@ -401,11 +468,10 @@ void clock_init(void) | ||||
| 	 * features section in the TRM). */ | ||||
| 	write32(1 << HCLK_DIVISOR_SHIFT | 0 << PCLK_DIVISOR_SHIFT, | ||||
| 		&clk_rst->clk_sys_rate);	/* pclk = hclk = sclk/2 */ | ||||
| 	write32(0 << SCLK_DIVIDEND_SHIFT | | ||||
| 		(CEIL_DIV(TEGRA_PLLC_KHZ, 300000) - 1) << SCLK_DIVISOR_SHIFT | ||||
| 		| SCLK_DIV_ENB, &clk_rst->super_sclk_div); | ||||
| 	write32(CLK_DIVIDER(TEGRA_PLLC_KHZ, 300000) << PLL_OUT_RATIO_SHIFT | | ||||
| 		PLL_OUT_CLKEN | PLL_OUT_RSTN, &clk_rst->pllc_out); | ||||
| 	write32(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT | | ||||
| 		SCLK_SOURCE_PLLC_OUT0 << SCLK_RUN_SHIFT, | ||||
| 		SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT, | ||||
| 		&clk_rst->sclk_brst_pol);		/* sclk = 300 MHz */ | ||||
|  | ||||
| 	/* Change the oscillator drive strength (from U-Boot -- why?) */ | ||||
|   | ||||
| @@ -301,11 +301,6 @@ void display_startup(device_t dev) | ||||
|  | ||||
| 	/* init dc_a */ | ||||
| 	init_dca_regs(); | ||||
| 	/* init sor */ | ||||
| 	init_sor_regs(); | ||||
|  | ||||
| 	/* init dpaux */ | ||||
| 	init_dpaux_regs(); | ||||
|  | ||||
| 	/* power up perip */ | ||||
| 	dp_io_powerup(); | ||||
| @@ -313,13 +308,9 @@ void display_startup(device_t dev) | ||||
| 	/* bringup dp */ | ||||
| 	dp_bringup(framebuffer_base_mb*MiB); | ||||
|  | ||||
| 	{  u16 *cp = (void *)(framebuffer_base_mb*MiB); | ||||
| 		for(i = 0; i < 1048576*8; i++) | ||||
| 			if (i % (1376 / 2) < 688 / 2) | ||||
| 				cp[i] = 0x222; | ||||
| 			else | ||||
| 				cp[i] = 0x888; | ||||
| 	} | ||||
| 	/* init frame buffer */ | ||||
| 	memset((void *)(framebuffer_base_mb*MiB), 0x00, | ||||
| 			framebuffer_size_mb*MiB); | ||||
|  | ||||
| 	/* tell depthcharge ... | ||||
| 	 */ | ||||
|   | ||||
| @@ -46,11 +46,6 @@ void debug_dpaux_print(u32 addr, u32 size); | ||||
| int dpaux_write(u32 addr, u32 size, u32 data); | ||||
| int dpaux_read(u32 addr, u32 size, u8 * data); | ||||
|  | ||||
| void init_dca_regs(void) | ||||
| { | ||||
| 	printk(BIOS_SPEW, "%s: entry\n", __func__); | ||||
|  | ||||
| #if 1 | ||||
| #define DCA_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 		WRITEL(val, (void *)(TEGRA_ARM_DISPLAYA + (reg<<2)));	\ | ||||
| @@ -63,17 +58,31 @@ void init_dca_regs(void) | ||||
| 	_reg_val |= val; \ | ||||
| 	WRITEL(_reg_val,  (void *)(TEGRA_ARM_DISPLAYA + (reg<<2))); \ | ||||
| 	} | ||||
| #else // read back | ||||
| #define DCA_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	printk(BIOS_SPEW,"DCA_WRITE: addr %#x = %#x\n", | ||||
| 	(unsigned int) (TEGRA_ARM_DISPLAYA + (reg<<2)), val);  \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_DISPLAYA + (reg<<2))); \ | ||||
| 	printk(BIOS_SPEW,"reads as %#x\n",  \ | ||||
| 		(unsigned int)READL( (void *)(TEGRA_ARM_DISPLAYA + (reg<<2)))); \ | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| #define SOR_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	} | ||||
|  | ||||
| #define SOR_READ(reg) READL((void *)(TEGRA_ARM_SOR + (reg<<2))) | ||||
|  | ||||
| #define SOR_READ_M_WRITE(reg, mask, val) \ | ||||
| 	{	\ | ||||
| 	u32 _reg_val; \ | ||||
| 	_reg_val = READL((void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	_reg_val &= ~mask;	\ | ||||
| 	_reg_val |= val;		\ | ||||
| 	WRITEL(_reg_val,  (void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	} | ||||
|  | ||||
| #define DPAUX_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_DPAUX + (reg<<2))); \ | ||||
| 	} | ||||
| #define DPAUX_READ(reg) READL((void *)(TEGRA_ARM_DPAUX + (reg<<2))) | ||||
|  | ||||
| void init_dca_regs(void) | ||||
| { | ||||
| 	DCA_WRITE (DC_CMD_DISPLAY_WINDOW_HEADER_0, 0x000000F0); | ||||
| 	DCA_WRITE (DC_WIN_A_WIN_OPTIONS_0, 0x00000000); | ||||
| 	DCA_WRITE (DC_WIN_A_BYTE_SWAP_0, 0x00000000); | ||||
| @@ -105,86 +114,20 @@ void init_dca_regs(void) | ||||
| 	DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE1_0, 0x00000000); | ||||
| 	DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE2_0, 0x00510104); | ||||
| 	DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE3_0, 0x00000555); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "initial DCA done\n"); | ||||
| } | ||||
|  | ||||
| void init_sor_regs(void) | ||||
| { | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ: %s: entry\n", __func__); | ||||
|  | ||||
| #if 1 | ||||
| #define SOR_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	} | ||||
|  | ||||
| #define SOR_READ(reg) READL( (void *)(TEGRA_ARM_SOR + (reg<<2))) | ||||
|  | ||||
| #else // read back | ||||
| #define SOR_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	printk(BIOS_SPEW,"SOR_WRITE: addr %#x = %#x\n", | ||||
| 	(unsigned int) (TEGRA_ARM_SOR + (reg<<2)), val);  \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	printk(BIOS_SPEW,"= %#x\n",  \ | ||||
| 		(unsigned int)READL( (void *)(TEGRA_ARM_SOR + (reg<<2)))); \ | ||||
| 	} | ||||
| #endif | ||||
| #define SOR_READ_M_WRITE(reg, mask, val) \ | ||||
| 	{	\ | ||||
| 	u32 _reg_val; \ | ||||
| 	_reg_val = READL( (void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	_reg_val &= ~mask;	\ | ||||
| 	_reg_val |= val;		\ | ||||
| 	WRITEL(_reg_val,  (void *)(TEGRA_ARM_SOR + (reg<<2))); \ | ||||
| 	} | ||||
|  | ||||
| 	printk(BIOS_SPEW, "initial SOR done\n"); | ||||
| } | ||||
|  | ||||
| void init_dpaux_regs(void) | ||||
| { | ||||
|  | ||||
| 	printk(BIOS_SPEW, "%s: entry\n", __func__); | ||||
|  | ||||
| #if 1 | ||||
| #define DPAUX_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_DPAUX + (reg<<2))); \ | ||||
| 	} | ||||
| #define DPAUX_READ(reg) READL( (void *)(TEGRA_ARM_DPAUX + (reg<<2))) | ||||
|  | ||||
| #else // read back | ||||
| #define DPAUX_WRITE(reg, val) \ | ||||
| 	{ \ | ||||
| 	printk(BIOS_SPEW,"DPAUX_WRITE: addr %#x = %#x\n", (unsigned int) | ||||
| 	(TEGRA_ARM_DPAUX + (reg<<2)), val);		    \ | ||||
| 	WRITEL(val,  (void *)(TEGRA_ARM_DPAUX + (reg<<2))); \ | ||||
| 	printk(BIOS_SPEW,"= %#x\n",  \ | ||||
| 		(unsigned int)READL( (void *)(TEGRA_ARM_DPAUX + (reg<<2)))); \ | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	printk(BIOS_SPEW, "initial DPAUX done\n"); | ||||
| } | ||||
|  | ||||
| static int dp_poll_register(void *addr, u32 exp_val, u32 mask, u32 timeout_ms) | ||||
| { | ||||
|  | ||||
| 	u32 reg_val = 0; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ: %s: enter, addr %#x: exp_val: %#x, mask: %#x\n", | ||||
| 		   __func__, (unsigned int)addr, exp_val, mask); | ||||
| 	do { | ||||
| 		udelay(1); | ||||
| 		udelay(1000); | ||||
| 		reg_val = READL(addr); | ||||
| 	} while (((reg_val & mask) != exp_val) && (--timeout_ms > 0)); | ||||
|  | ||||
| 	if ((reg_val & mask) == exp_val) | ||||
| 		return 0;	/* success */ | ||||
| 	printk(BIOS_SPEW, "poll_register %p: timeout\n", addr); | ||||
| 	printk(BIOS_WARNING, "poll_register %p: timeout\n", addr); | ||||
| 	return timeout_ms; | ||||
| } | ||||
|  | ||||
| @@ -196,15 +139,10 @@ static void dp_io_set_dpd(u32 power_down) | ||||
| 	 *  1: into deep power down | ||||
| 	 */ | ||||
| 	u32 val_reg; | ||||
| #define DP_LVDS_SHIFT	25 | ||||
| #define DP_LVDS		(1 << DP_LVDS_SHIFT) | ||||
|  | ||||
| 	val_reg = READL((void *)(0x7000e400 + 0x1c4));	/* APBDEV_PMC_IO_DPD2_STATUS_0 */ | ||||
| 	printk(BIOS_SPEW, "JZ: %s: enter, into dpd %d, cur_status: %#x\n", | ||||
| 		   __func__, power_down, val_reg); | ||||
|  | ||||
| 	if ((((val_reg & DP_LVDS) >> DP_LVDS_SHIFT) & 1) == power_down) { | ||||
| 		printk(BIOS_SPEW, "PAD already POWER=%d\n", 1 - power_down); | ||||
| 		printk(BIOS_DEBUG, "PAD already POWER=%d\n", 1 - power_down); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -212,14 +150,11 @@ static void dp_io_set_dpd(u32 power_down) | ||||
| 	WRITEL((DP_LVDS | ((1 + power_down) << 30)), (void *)(0x7000e400 + 0x1c0)); | ||||
|  | ||||
| 	dp_poll_register((void *)(0x7000e400 + 0x1C4), 0, DP_LVDS, 1000); | ||||
| 	//APBDEV_PMC_IO_DPD2_STATUS_0 | ||||
| 	/* APBDEV_PMC_IO_DPD2_STATUS_0 */ | ||||
| } | ||||
|  | ||||
| void dp_io_powerup(void) | ||||
| { | ||||
|  | ||||
| 	printk(BIOS_SPEW, "%s: entry\n", __func__); | ||||
|  | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_CLK_CNTRL_0, (6 << 2) | 2);//select PLLDP,  lowest speed(6x) | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, 0x00800000);	//set PDCAL | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_PLL0_0, 0x050003D5);	//set PWR,VCOPD | ||||
| @@ -227,14 +162,21 @@ void dp_io_powerup(void) | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_PLL2_0, 0x01C20000);	//set AUX1,6,7,8; clr AUX2 | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_PLL3_0, 0x38002220); | ||||
|  | ||||
| 	/* Deassert E_DPD to enable core logic circuits, and wait for > 5us */ | ||||
| 	dp_io_set_dpd(0); | ||||
| 	udelay(1);	//Deassert E_DPD to enable core logic circuits, and wait for > 5us | ||||
| 	udelay(10); | ||||
|  | ||||
| 	/* Deassert PDBG to enable bandgap, and wait for > 20us. */ | ||||
| 	SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0, | ||||
| 					 SOR_NV_PDISP_SOR_PLL2_0_AUX6_FIELD, | ||||
| 					 (0 << SOR_NV_PDISP_SOR_PLL2_0_AUX6_SHIFT)); | ||||
| 	udelay(20);	//Deassert PDBG to enable bandgap, and wait for > 20us. | ||||
| 	udelay(25); | ||||
|  | ||||
| 	/* | ||||
| 	 * Enable the PLL/charge-pump/VCO, and wait for >200us for the PLL to | ||||
| 	 * lock. Input Clock must be running and stable before PDPLL | ||||
| 	 * de-assertion. | ||||
| 	 */ | ||||
| 	SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL0_0, | ||||
| 					 SOR_NV_PDISP_SOR_PLL0_0_PWR_FIELD, | ||||
| 					 (0 << SOR_NV_PDISP_SOR_PLL0_0_PWR_SHIFT)); | ||||
| @@ -244,10 +186,8 @@ void dp_io_powerup(void) | ||||
| 	SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0, | ||||
| 					 SOR_NV_PDISP_SOR_PLL2_0_AUX8_FIELD, | ||||
| 					 (0 << SOR_NV_PDISP_SOR_PLL2_0_AUX8_SHIFT)); | ||||
| 	udelay(200); | ||||
| 	//Enable the PLL/charge-pump/VCO, and wait for >200us for the PLL to | ||||
| 	//lock. Input Clock must be running and stable before PDPLL | ||||
| 	//de-assertion. | ||||
| 	udelay(210); | ||||
|  | ||||
| 	SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0, | ||||
| 					 SOR_NV_PDISP_SOR_PLL2_0_AUX7_FIELD, | ||||
| 					 (0 << SOR_NV_PDISP_SOR_PLL2_0_AUX7_SHIFT)); | ||||
| @@ -256,7 +196,6 @@ void dp_io_powerup(void) | ||||
| 					 (1 << SOR_NV_PDISP_SOR_PLL2_0_AUX9_SHIFT)); | ||||
| 	udelay(100); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "%s: exit\n", __func__); | ||||
| } | ||||
|  | ||||
| static int dpaux_check(u32 bytes, u32 data, u32 mask) | ||||
| @@ -268,18 +207,19 @@ static int dpaux_check(u32 bytes, u32 data, u32 mask) | ||||
| 	DPAUX_WRITE(DPAUX_DP_AUXDATA_READ_W0, 0); | ||||
| 	status = dpaux_read(0x202, bytes, buf); | ||||
| 	if (status != 0) | ||||
| 		printk(BIOS_SPEW, "******AuxRead Error:%04x: status %08x\n", 0x202, | ||||
| 			   status); | ||||
| 		printk(BIOS_ERR, "******AuxRead Error:%04x: status %08x\n", | ||||
| 				 0x202, status); | ||||
| 	else { | ||||
| 		temp = DPAUX_READ(DPAUX_DP_AUXDATA_READ_W0); | ||||
| 		if ((temp & mask) != (data & mask)) { | ||||
| 			printk(BIOS_SPEW, "AuxCheck ERROR:(r_data) %08x & (mask) %08x != " | ||||
| 				   "(data) %08x & (mask) %08x\n", temp, mask, data, mask); | ||||
| 			printk(BIOS_ERR, "AuxCheck ERROR:(r_data) %08x &" | ||||
| 				" (mask) %08x != (data) %08x & (mask) %08x\n", | ||||
| 				temp, mask, data, mask); | ||||
| 			return -1; | ||||
| 		} else { | ||||
| 			printk(BIOS_SPEW, | ||||
| 				   "AuxCheck PASS:(bytes=%d,data=%08x,mask=%08x):0x%08x\n", | ||||
| 				   bytes, data, mask, temp); | ||||
| 			printk(BIOS_DEBUG, "AuxCheck PASS:(bytes=%d, " | ||||
| 				"data=%08x, mask=%08x):0x%08x\n", | ||||
| 				bytes, data, mask, temp); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| @@ -304,8 +244,6 @@ static int dpaux_check(u32 bytes, u32 data, u32 mask) | ||||
|  */ | ||||
| static void pattern_level(u32 current, u32 preemph, u32 postcur) | ||||
| { | ||||
| 	printk(BIOS_SPEW, "set level:%d %d %d\n", current, preemph, postcur); | ||||
|  | ||||
| 	//calibrating required | ||||
| 	if (current == 0) | ||||
| 		SOR_WRITE(SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0, 0x20202020); | ||||
| @@ -355,7 +293,7 @@ static int dp_training(u32 level, u32 check, u32 speed) | ||||
| 			wcfg = wcfg | 0x20; | ||||
| 		wcfg = wcfg | (wcfg << 8) | (wcfg << 16) | (wcfg << 24); | ||||
| 		dpaux_write(0x103, 4, wcfg); | ||||
| 		udelay(50);	//100us | ||||
| 		udelay(100); | ||||
| 		DPAUX_WRITE(DPAUX_DP_AUXDATA_READ_W0, 0); | ||||
| 		if (!dpaux_check(2, check, check)) | ||||
| 			cnt = 100; | ||||
| @@ -366,7 +304,7 @@ static int dp_training(u32 level, u32 check, u32 speed) | ||||
| 			if (cfg == cfg_d) { | ||||
| 				++cnt; | ||||
| 				if (cnt > 5) | ||||
| 					printk(BIOS_SPEW, "link training FAILED\n"); | ||||
| 					printk(BIOS_ERR, "Error: link training FAILED\n"); | ||||
| 			} else { | ||||
| 				cnt = 0; | ||||
| 				cfg_d = cfg; | ||||
| @@ -396,10 +334,7 @@ void dp_link_training(u32 lanes, u32 speed) | ||||
| 	u32 mask, level; | ||||
| 	u32 reg_val; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "%s: entry, lanes: %d, speed: %d\n", __func__, lanes, | ||||
| 		   speed); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "\nLink training start\n"); | ||||
| 	printk(BIOS_DEBUG, "\nLink training start\n"); | ||||
|  | ||||
| 	switch (lanes) { | ||||
| 		case 1: | ||||
| @@ -412,21 +347,22 @@ void dp_link_training(u32 lanes, u32 speed) | ||||
| 			lane_on = 0x0f; | ||||
| 			break; | ||||
| 		default: | ||||
| 			printk(BIOS_SPEW, "dp: invalid lane count: %d\n", lanes); | ||||
| 			printk(BIOS_DEBUG, "dp: invalid lane count: %d\n", | ||||
| 				lanes); | ||||
| 			return; | ||||
| 	} | ||||
|  | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, (0x008000000 | lane_on)); | ||||
| 	SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, | ||||
| 			 SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_VALUE_FIELD, | ||||
| 			 (6 << SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_VALUE_SHIFT)); | ||||
| 		 SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_VALUE_FIELD, | ||||
| 		 (6 << SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_VALUE_SHIFT)); | ||||
| 	SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, | ||||
| 			 SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_FIELD, | ||||
| 			 (1 << SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_SHIFT)); | ||||
| 		 SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_FIELD, | ||||
| 		 (1 << SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_SHIFT)); | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_LVDS_0, 0); | ||||
|  | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_CLK_CNTRL_0, ((speed << 2) | 2)); | ||||
| 	udelay(100); | ||||
| 	udelay(100 * 1000); | ||||
|  | ||||
| 	sor_clock_start(); | ||||
|  | ||||
| @@ -434,34 +370,34 @@ void dp_link_training(u32 lanes, u32 speed) | ||||
| 			  (((0xF >> (4 - lanes)) << 16) | 1)); | ||||
|  | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_LANE_SEQ_CTL_0, 0x80100000); | ||||
| 	printk(BIOS_SPEW, "Polling SOR_NV_PDISP_SOR_LANE_SEQ_CTL_0.DONE\n"); | ||||
| 	printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_LANE_SEQ_CTL_0.DONE\n"); | ||||
|  | ||||
| 	dp_poll_register((void *)0x54540084, 0x00000000, 0x80000000, 1000); | ||||
|  | ||||
| 	debug_dpaux_print(0x202, 4); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "set link rate and lane number: %dMHz, %d lanes\n", | ||||
| 	printk(BIOS_DEBUG, "set link rate and lane number: %dMHz, %d lanes\n", | ||||
| 		   (speed * 27), lanes); | ||||
|  | ||||
| 	dpaux_write(0x100, 2, ((lanes << 8) | speed)); | ||||
| 	printk(BIOS_SPEW, "precharge lane 10us\n"); | ||||
| 	printk(BIOS_DEBUG, "precharge lane 10us\n"); | ||||
| 	reg_val = SOR_READ(SOR_NV_PDISP_SOR_DP_PADCTL0_0); | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, (0x000000f0 | reg_val)); | ||||
| 	udelay(100); | ||||
| 	udelay(100 * 1000); | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, reg_val); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "link training cr start\n"); | ||||
| 	printk(BIOS_DEBUG, "link training cr start\n"); | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_TPG_0, 0x41414141); | ||||
| 	dpaux_write(0x102, 1, 0x21); | ||||
|  | ||||
| 	mask = 0x0000ffff >> ((4 - lanes) * 4); | ||||
| 	level = 0; | ||||
| 	level = dp_training(level, 0x1111 & mask, speed); | ||||
| 	printk(BIOS_SPEW, "level:%x\n", level); | ||||
| 	printk(BIOS_DEBUG, "level:%x\n", level); | ||||
|  | ||||
| 	debug_dpaux_print(0x210, 16); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "link training eq start\n"); | ||||
| 	printk(BIOS_DEBUG, "link training eq start\n"); | ||||
| 	if (speed == 20) { | ||||
| 		SOR_WRITE(SOR_NV_PDISP_SOR_DP_TPG_0, 0x43434343); | ||||
| 		dpaux_write(0x102, 1, 0x23); | ||||
| @@ -471,7 +407,7 @@ void dp_link_training(u32 lanes, u32 speed) | ||||
| 	} | ||||
|  | ||||
| 	level = dp_training(level, (0x7777 & mask) | 0x10000, speed); | ||||
| 	printk(BIOS_SPEW, "level:%x\n", level); | ||||
| 	printk(BIOS_DEBUG, "level:%x\n", level); | ||||
|  | ||||
| 	debug_dpaux_print(0x210, 16); | ||||
|  | ||||
| @@ -482,8 +418,7 @@ void dp_link_training(u32 lanes, u32 speed) | ||||
| 	debug_dpaux_print(0x200, 16); | ||||
| 	debug_dpaux_print(0x210, 16); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "Link training done\n\n"); | ||||
| 	printk(BIOS_SPEW, "%s: exit\n", __func__); | ||||
| 	printk(BIOS_DEBUG, "Link training done\n\n"); | ||||
| } | ||||
|  | ||||
| static u32 div_f(u32 a, u32 b, u32 one) | ||||
| @@ -492,23 +427,10 @@ static u32 div_f(u32 a, u32 b, u32 one) | ||||
| 	return (d); | ||||
| } | ||||
|  | ||||
| u32 dp_setup_timing(u32 panel_id, u32 width, u32 height); | ||||
| u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) | ||||
| u32 dp_setup_timing(u32 width, u32 height) | ||||
| { | ||||
| 	u32 pclk_freq = 0; | ||||
|  | ||||
| 	/////////////////////////////////////////// | ||||
| 	// set up clocks, using PLLD2 | ||||
| 	// format: pclk  , PLL  ,  panel | ||||
| 	//2560x1440:  241.5  , 483/2,  dp   VESA.red. | ||||
| 	//1920x1080:  148.5  , 594/4,  dp   CEA | ||||
| 	//1600x1200:  161.0  , 483/3,  dp   VESA | ||||
| 	//1280x 720:   74.25 , 594/8,  dp   CEA | ||||
| 	// 1024x768:   63.5  , 508/8,  dp   VESA | ||||
| 	//  800x600:   38.25 , 459/12, dp   VESA | ||||
| 	//  720x480:   27.00 , 594/22, dp   CEA | ||||
| 	//  640x480:   23.75 , 475/20, dp   VESA | ||||
|  | ||||
| 	u32 PLL_FREQ = (12 / 12 * 283) / 1 / 2;	/* 141.5 */ | ||||
| 	u32 PLL_DIV = 2; | ||||
| 	u32 SYNC_WIDTH = (8 << 16) | 46; | ||||
| @@ -529,14 +451,6 @@ u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) | ||||
| 	u32 PCLK_FREQ_I, PCLK_FREQ_F; | ||||
| 	u32 FRATE_I, FRATE_F; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "%s: entry\n", __func__); | ||||
|  | ||||
| 	if (panel_id != 5) { | ||||
| 		printk(BIOS_SPEW, "%s: Unsupported panel_id: %d, format=%dx%d\n", | ||||
| 			   __func__, panel_id, width, height); | ||||
| 		return pclk_freq; | ||||
| 	} | ||||
|  | ||||
| 	PLL_FREQ = PLL_FREQ * 1000000; | ||||
| 	pclk_freq = PLL_FREQ / PLL_DIV; | ||||
| 	PLL_FREQ_I = PLL_FREQ / 1000000; | ||||
| @@ -545,19 +459,19 @@ u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) | ||||
| 	PCLK_FREQ_F = div_f(PLL_FREQ, PLL_DIV * 1000000, 100); | ||||
| 	FRATE_I = PLL_FREQ / (PLL_DIV * TOTAL_PIXELS); | ||||
| 	FRATE_F = div_f(PLL_FREQ, (PLL_DIV * TOTAL_PIXELS), 100); | ||||
| 	//bug 1021453 | ||||
| 	/* nv_bug 1021453 */ | ||||
| 	BACK_PORCH = BACK_PORCH - 0x10000; | ||||
| 	FRONT_PORCH = FRONT_PORCH + 0x10000; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "ACTIVE:            %dx%d\n", (DISP_ACTIVE & 0xFFFF), | ||||
| 	printk(BIOS_DEBUG, "ACTIVE:      %dx%d\n", (DISP_ACTIVE & 0xFFFF), | ||||
| 		   (DISP_ACTIVE >> 16)); | ||||
| 	printk(BIOS_SPEW, "TOTAL:             %dx%d\n", (DISP_TOTAL & 0xffff), | ||||
| 	printk(BIOS_DEBUG, "TOTAL:       %dx%d\n", (DISP_TOTAL & 0xffff), | ||||
| 		   (DISP_TOTAL >> 16)); | ||||
| 	printk(BIOS_SPEW, "PLL Freq:          %d.%d MHz\n", PLL_FREQ_I, PLL_FREQ_F); | ||||
| 	printk(BIOS_SPEW, "Pclk Freq:         %d.%d MHz\n", PCLK_FREQ_I, | ||||
| 	printk(BIOS_DEBUG, "PLL Freq:    %d.%d MHz\n", PLL_FREQ_I, PLL_FREQ_F); | ||||
| 	printk(BIOS_DEBUG, "Pclk Freq:   %d.%d MHz\n", PCLK_FREQ_I, | ||||
| 		   PCLK_FREQ_F); | ||||
| 	printk(BIOS_SPEW, "Frame Rate:        %d.%d Hz\n", FRATE_I, FRATE_F); | ||||
| 	printk(BIOS_SPEW, "\n"); | ||||
| 	printk(BIOS_DEBUG, "Frame Rate:  %d.%d Hz\n", FRATE_I, FRATE_F); | ||||
| 	printk(BIOS_DEBUG, "\n"); | ||||
|  | ||||
| 	DCA_WRITE(DC_CMD_STATE_ACCESS_0, 0x00000004); | ||||
| 	DCA_WRITE(DC_DISP_DISP_CLOCK_CONTROL_0, SHIFT_CLK_DIVIDER); | ||||
| @@ -569,9 +483,6 @@ u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) | ||||
| 	DCA_WRITE(DC_DISP_DISP_ACTIVE_0, DISP_ACTIVE); | ||||
| 	DCA_WRITE(DC_DISP_FRONT_PORCH_0, FRONT_PORCH); | ||||
|  | ||||
| 	printk(BIOS_SPEW, | ||||
| 		   "JZ: sync_width: %d, back_porch: %d, disp_active: %d, front_porch: %d\n", | ||||
| 		   SYNC_WIDTH, BACK_PORCH, DISP_ACTIVE, FRONT_PORCH); | ||||
| 	//REG(DC_DISP_DISP_WIN_OPTIONS_0, SOR_ENABLE , 1) | ||||
| 	DCA_READ_M_WRITE(DC_DISP_DISP_WIN_OPTIONS_0, | ||||
| 					 DC_DISP_DISP_WIN_OPTIONS_0_SOR_ENABLE_FIELD, | ||||
| @@ -611,7 +522,6 @@ u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) | ||||
| 					 SOR_NV_PDISP_SOR_STATE1_0_ASY_OWNER_FIELD, | ||||
| 					 (SOR_NV_PDISP_SOR_STATE1_0_ASY_OWNER_HEAD0 << | ||||
| 					  SOR_NV_PDISP_SOR_STATE1_0_ASY_OWNER_SHIFT)); | ||||
| 	printk(BIOS_SPEW, "%s: exit\n", __func__); | ||||
| 	return pclk_freq; | ||||
| } | ||||
|  | ||||
| @@ -623,7 +533,9 @@ static u32 calc_config(u32 ts, u32 a, u32 b, u32 bpp) | ||||
| 	u32 act_frac; | ||||
| 	u32 err; | ||||
| 	u32 water_mark; | ||||
| 	printk(BIOS_SPEW, "calc_config ts %d a %d b %d bpp %d\n", ts, a, b, bpp); | ||||
|  | ||||
| 	printk(BIOS_DEBUG, "calc_config ts %d a %d b %d bpp %d\n", | ||||
| 			ts, a, b, bpp); | ||||
| 	if (diff != 0) { | ||||
| 		if (diff > (b / 2)) { | ||||
| 			diff = b - diff; | ||||
| @@ -669,7 +581,7 @@ static u32 calc_config(u32 ts, u32 a, u32 b, u32 bpp) | ||||
| 				 (water_mark << | ||||
| 				  SOR_NV_PDISP_SOR_DP_CONFIG0_0_WATERMARK_SHIFT)); | ||||
|  | ||||
| 		printk(BIOS_SPEW, | ||||
| 		printk(BIOS_DEBUG, | ||||
| 		       "SOR_DP_CONFIG0:TU,CNT,POL,FRAC,WMK,ERR=%d,%d,%d,%d,%d,%d/%d\n", | ||||
| 		       ts, act_cnt, act_pol, act_frac, water_mark, err, b); | ||||
| 	} | ||||
| @@ -687,7 +599,8 @@ static u32 dp_buf_config(u32 pclkfreq, u32 linkfreq, u32 lanes, u32 bpp) | ||||
| 	u32 min_err = 1000000000; | ||||
| 	u32 ts = 64; | ||||
| 	u32 c_err; | ||||
| 	printk(BIOS_SPEW, "dp buf config pclkfreq %d linkfreq %d lanes %d bpp %d\n", | ||||
|  | ||||
| 	printk(BIOS_DEBUG, "dp buf config pclkfreq %d linkfreq %d lanes %d bpp %d\n", | ||||
| 		   pclkfreq, linkfreq, lanes, bpp); | ||||
| 	for (i = 2; i <= 7; ++i) { | ||||
| 		while (((pf / i * i) == pf) && ((lf / i * i) == lf)) { | ||||
| @@ -698,9 +611,9 @@ static u32 dp_buf_config(u32 pclkfreq, u32 linkfreq, u32 lanes, u32 bpp) | ||||
|  | ||||
| 	a = pf * bpp / 8; | ||||
| 	b = lf * lanes; | ||||
| 	printk(BIOS_SPEW, "ratio:%d/%d\n", a, b); | ||||
| 	printk(BIOS_DEBUG, "ratio:%d/%d\n", a, b); | ||||
| 	if (a > (b * 98 / 100)) | ||||
| 		printk(BIOS_SPEW, "Error:link speed not enough\n"); | ||||
| 		printk(BIOS_ERR, "Error:link speed not enough\n"); | ||||
|  | ||||
| 	//search best tusize | ||||
| 	//min_err = 1000000000; | ||||
| @@ -727,10 +640,11 @@ static u32 dp_buf_config(u32 pclkfreq, u32 linkfreq, u32 lanes, u32 bpp) | ||||
| 	return (tusize); | ||||
| } | ||||
|  | ||||
| /* | ||||
| void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 		     u32 lane_count, u32 enhanced_framing, u32 panel_edp, | ||||
| 		     u32 pclkfreq, u32 linkfreq); | ||||
|  | ||||
| */ | ||||
| void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 		     u32 lane_count, u32 enhanced_framing, u32 panel_edp, | ||||
| 		     u32 pclkfreq, u32 linkfreq) | ||||
| @@ -738,8 +652,8 @@ void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 	u32 tusize; | ||||
| 	u32 linkctl; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "%s: entry, winb: 0x%08x ", __func__, winb_addr); | ||||
| 	printk(BIOS_SPEW, " panel_bpp %d\n", panel_bpp); | ||||
| 	printk(BIOS_DEBUG, "%s: winb: 0x%08x, panel_bpp %d ", | ||||
| 			__func__, winb_addr, panel_bpp); | ||||
|  | ||||
| 	if (panel_bpp == 18) { | ||||
| 		//0x54540010 | ||||
| @@ -755,37 +669,25 @@ void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 				  SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_SHIFT)); | ||||
| 	} | ||||
|  | ||||
| #define SRC_BPP		16 | ||||
| #define COLORDEPTH	0x6 | ||||
|  | ||||
| #define BLUE	0xFF0000 | ||||
| #define GREEN	0x00FF00 | ||||
| #define RED	0x0000FF | ||||
| #define YELLOW	0x00FFFF | ||||
| #define BLACK	0x000000 | ||||
| #define WHITE	0xFFFFFF | ||||
| #define GREY	0x55aa00 | ||||
|  | ||||
| 	DCA_WRITE(DC_B_WIN_BD_SIZE_0, ((height << 16) | width)); | ||||
| 	DCA_WRITE(DC_B_WIN_BD_PRESCALED_SIZE_0, | ||||
| 	DCA_WRITE(DC_CMD_DISPLAY_WINDOW_HEADER_0, 0x00000010); | ||||
| 	DCA_WRITE(DC_WIN_A_SIZE_0, ((height << 16) | width)); | ||||
| 	DCA_WRITE(DC_WIN_A_PRESCALED_SIZE_0, | ||||
| 			  ((height << 16) | (width * SRC_BPP / 8))); | ||||
| 	DCA_WRITE(DC_B_WIN_BD_LINE_STRIDE_0, | ||||
| 	DCA_WRITE(DC_WIN_A_LINE_STRIDE_0, | ||||
| 			  ((width * SRC_BPP / 8 + 31) / 32 * 32)); | ||||
| 	DCA_WRITE(DC_B_WIN_BD_COLOR_DEPTH_0, COLORDEPTH); | ||||
| 	DCA_WRITE(DC_B_WINBUF_BD_START_ADDR_0, winb_addr); | ||||
| 	DCA_WRITE(DC_B_WIN_BD_DDA_INCREMENT_0, 0x10001000); | ||||
| 	DCA_WRITE(DC_WIN_A_COLOR_DEPTH_0, COLORDEPTH); | ||||
| 	DCA_WRITE(DC_WINBUF_A_START_ADDR_LO_0, winb_addr); | ||||
| 	DCA_WRITE(DC_WIN_A_DDA_INCREMENT_0, 0x10001000); | ||||
|  | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_CRC_CNTRL_0, 0x00000001); | ||||
| 	DCA_WRITE(DC_COM_CRC_CONTROL_0, 0x00000009);	//CRC_ALWAYS+CRC_ENABLE | ||||
| 	DCA_WRITE(DC_COM_PIN_OUTPUT_ENABLE2_0, 0x00000000); | ||||
| 	DCA_WRITE(DC_COM_PIN_OUTPUT_ENABLE3_0, 0x00000000); | ||||
| 	DCA_WRITE(DC_DISP_DISP_SIGNAL_OPTIONS0_0, 0x00000000); | ||||
| 	//  DCA_WRITE (DC_DISP_BLEND_BACKGROUND_COLOR_0                ,WHITE     ); | ||||
| 	DCA_WRITE(DC_DISP_BLEND_BACKGROUND_COLOR_0, YELLOW); | ||||
| 	DCA_WRITE(DC_DISP_BLEND_BACKGROUND_COLOR_0, COLOR_WHITE); | ||||
| 	DCA_WRITE(DC_CMD_DISPLAY_COMMAND_0, 0x00000020); | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_AUDIO_VBLANK_SYMBOLS_0, 0x00000e48); | ||||
|  | ||||
|  | ||||
| 	dpaux_write(0x101, 1, (enhanced_framing << 7) | lane_count); | ||||
| 	if (panel_edp) | ||||
| 		dpaux_write(0x10A, 1, 1); | ||||
| @@ -793,8 +695,6 @@ void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 	tusize = | ||||
| 		dp_buf_config(pclkfreq, (linkfreq * 1000000), lane_count, panel_bpp); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ, after dp_buf_config, tusize: 0x%08x\n", tusize); | ||||
|  | ||||
| 	linkctl = | ||||
| 		((0xF >> (4 - lane_count)) << 16) | (enhanced_framing << 14) | (tusize | ||||
| 										<< 2) | | ||||
| @@ -804,7 +704,7 @@ void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_DP_SPARE0_0, ((panel_edp << 1) | 0x05)); | ||||
|  | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_PWR_0, 0x80000001); | ||||
| 	printk(BIOS_SPEW, "Polling SOR_NV_PDISP_SOR_PWR_0.DONE\n"); | ||||
| 	printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_PWR_0.DONE\n"); | ||||
| 	dp_poll_register((void *)0x54540054, 0x00000000, 0x80000000, 1000); | ||||
| 	//SOR_NV_PDISP_SOR_PWR_0 | ||||
| 	//sor_update | ||||
| @@ -815,7 +715,7 @@ void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_SUPER_STATE1_0, 0x0000000e); | ||||
| 	//sor_super_update | ||||
| 	SOR_WRITE(SOR_NV_PDISP_SOR_SUPER_STATE0_0, 0x00000000); | ||||
| 	printk(BIOS_SPEW, "Polling SOR_NV_PDISP_SOR_TEST_0.ATTACHED\n"); | ||||
| 	printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_TEST_0.ATTACHED\n"); | ||||
| 	dp_poll_register((void *)0x54540058, 0x00000400, 0x00000400, 1000); | ||||
| 	//SOR_NV_PDISP_SOR_TEST_0 | ||||
|  | ||||
| @@ -823,21 +723,16 @@ void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 	DCA_WRITE(DC_CMD_STATE_CONTROL_0, 0x0000009f); | ||||
| 	DCA_WRITE(DC_CMD_DISPLAY_POWER_CONTROL_0, 0x00050155); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "Polling SOR_NV_PDISP_SOR_TEST_0.AWAKE\n"); | ||||
| 	printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_TEST_0.AWAKE\n"); | ||||
| 	dp_poll_register((void *)0x54540058, 0x00000200, 0x00000300, 1000); | ||||
| 	//SOR_NV_PDISP_SOR_TEST_0 | ||||
|  | ||||
| 	//  DCA_WRITE (DC_CMD_STATE_ACCESS_0   ,0); | ||||
| 	DCA_WRITE(DC_CMD_STATE_ACCESS_0, 4); | ||||
| 	DCA_WRITE(DC_CMD_STATE_CONTROL_0, 0x0000ffff); | ||||
| 	/* enable win_b */ | ||||
|  | ||||
| 	DCA_READ_M_WRITE(DC_B_WIN_BD_WIN_OPTIONS_0, | ||||
| 			 DC_B_WIN_BD_WIN_OPTIONS_0_BD_WIN_ENABLE_FIELD, | ||||
| 			 (DC_B_WIN_BD_WIN_OPTIONS_0_BD_WIN_ENABLE_ENABLE << | ||||
| 			  DC_B_WIN_BD_WIN_OPTIONS_0_BD_WIN_ENABLE_SHIFT)); | ||||
|  | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ: %s: f_ret @ line %d\n", __func__, __LINE__); | ||||
| 	DCA_READ_M_WRITE(DC_WIN_A_WIN_OPTIONS_0, | ||||
| 			 DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_FIELD, | ||||
| 			 (DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_ENABLE << | ||||
| 			  DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_SHIFT)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -39,33 +39,36 @@ static inline u32 tegra_dpaux_readl(struct tegra_dc_dp_data *dp, u32 reg) | ||||
| } | ||||
|  | ||||
| static inline void tegra_dpaux_writel(struct tegra_dc_dp_data *dp, | ||||
| 									  u32 reg, u32 val) | ||||
| 					  u32 reg, u32 val) | ||||
| { | ||||
| 	void *addr = dp->aux_base + (u32) (reg << 2); | ||||
| 	WRITEL(val, addr); | ||||
| } | ||||
|  | ||||
| static inline u32 tegra_dc_dpaux_poll_register(struct tegra_dc_dp_data *dp, | ||||
| 											   u32 reg, u32 mask, u32 exp_val, | ||||
| 											   u32 poll_interval_us, | ||||
| 											   u32 timeout_ms) | ||||
| 					   u32 reg, u32 mask, u32 exp_val, | ||||
| 					   u32 poll_interval_us, | ||||
| 					   u32 timeout_us) | ||||
| { | ||||
| 	u32 reg_val = 0; | ||||
| 	u32 temp = timeout_us; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ: %s: enter, poll_reg: %#x: timeout: 0x%x\n", | ||||
| 		   __func__, reg * 4, timeout_ms); | ||||
| 	do { | ||||
| 		udelay(1); | ||||
| 		udelay(poll_interval_us); | ||||
| 		reg_val = tegra_dpaux_readl(dp, reg); | ||||
| 	} while (((reg_val & mask) != exp_val) && (--timeout_ms > 0)); | ||||
| 		if (timeout_us > poll_interval_us) | ||||
| 			timeout_us -= poll_interval_us; | ||||
| 		else | ||||
| 			break; | ||||
| 	} while ((reg_val & mask) != exp_val); | ||||
|  | ||||
| 	if ((reg_val & mask) == exp_val) | ||||
| 		return 0;	/* success */ | ||||
| 	printk(BIOS_SPEW, | ||||
| 	printk(BIOS_ERR, | ||||
| 		   "dpaux_poll_register 0x%x: timeout: " | ||||
| 		   "(reg_val)0x%08x & (mask)0x%08x != (exp_val)0x%08x\n", | ||||
| 		   reg, reg_val, mask, exp_val); | ||||
| 	return timeout_ms; | ||||
| 	return temp; | ||||
| } | ||||
|  | ||||
| static inline int tegra_dpaux_wait_transaction(struct tegra_dc_dp_data *dp) | ||||
| @@ -73,18 +76,18 @@ static inline int tegra_dpaux_wait_transaction(struct tegra_dc_dp_data *dp) | ||||
| 	/* According to DP spec, each aux transaction needs to finish | ||||
| 	   within 40ms. */ | ||||
| 	if (tegra_dc_dpaux_poll_register(dp, DPAUX_DP_AUXCTL, | ||||
| 									 DPAUX_DP_AUXCTL_TRANSACTREQ_MASK, | ||||
| 									 DPAUX_DP_AUXCTL_TRANSACTREQ_DONE, | ||||
| 									 100, DP_AUX_TIMEOUT_MS * 1000) != 0) { | ||||
| 		printk(BIOS_SPEW, "dp: DPAUX transaction timeout\n"); | ||||
| 					 DPAUX_DP_AUXCTL_TRANSACTREQ_MASK, | ||||
| 					 DPAUX_DP_AUXCTL_TRANSACTREQ_DONE, | ||||
| 					 100, DP_AUX_TIMEOUT_MS * 1000) != 0) { | ||||
| 		printk(BIOS_INFO, "dp: DPAUX transaction timeout\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 									  u32 addr, u8 * data, u32 * size, | ||||
| 									  u32 * aux_stat) | ||||
| 					  u32 addr, u8 *data, u32 *size, | ||||
| 					  u32 *aux_stat) | ||||
| { | ||||
| 	int i; | ||||
| 	u32 reg_val; | ||||
| @@ -102,21 +105,11 @@ static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 		case DPAUX_DP_AUXCTL_CMD_AUXWR: | ||||
| 			break; | ||||
| 		default: | ||||
| 			printk(BIOS_SPEW, "dp: aux write cmd 0x%x is invalid\n", cmd); | ||||
| 			printk(BIOS_ERR, "dp: aux write cmd 0x%x is invalid\n", | ||||
| 				cmd); | ||||
| 			return -1; | ||||
| 	} | ||||
|  | ||||
| #if 0 | ||||
| /* interesting. */ | ||||
| 	if (tegra_platform_is_silicon()) { | ||||
| 		*aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT); | ||||
| 		if (!(*aux_stat & DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED)) { | ||||
| 			printk(BIOS_SPEW, "dp: HPD is not detected\n"); | ||||
| 			return -EFAULT; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	tegra_dpaux_writel(dp, DPAUX_DP_AUXADDR, addr); | ||||
| 	for (i = 0; i < DP_AUX_MAX_BYTES / 4; ++i) { | ||||
| 		memcpy(&temp_data, data, 4); | ||||
| @@ -139,7 +132,7 @@ static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 		tegra_dpaux_writel(dp, DPAUX_DP_AUXCTL, reg_val); | ||||
|  | ||||
| 		if (tegra_dpaux_wait_transaction(dp)) | ||||
| 			printk(BIOS_SPEW, "dp: aux write transaction timeout\n"); | ||||
| 			printk(BIOS_ERR, "dp: aux write transaction timeout\n"); | ||||
|  | ||||
| 		*aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT); | ||||
|  | ||||
| @@ -148,13 +141,13 @@ static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR_PENDING) || | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_NO_STOP_ERROR_PENDING)) { | ||||
| 			if (timeout_retries-- > 0) { | ||||
| 				printk(BIOS_SPEW, "dp: aux write retry (0x%x) -- %d\n", | ||||
| 				printk(BIOS_INFO, "dp: aux write retry (0x%x) -- %d\n", | ||||
| 					   *aux_stat, timeout_retries); | ||||
| 				/* clear the error bits */ | ||||
| 				tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT, *aux_stat); | ||||
| 				continue; | ||||
| 			} else { | ||||
| 				printk(BIOS_SPEW, "dp: aux write got error (0x%x)\n", | ||||
| 				printk(BIOS_ERR, "dp: aux write got error (0x%x)\n", | ||||
| 					   *aux_stat); | ||||
| 				return -1; | ||||
| 			} | ||||
| @@ -163,13 +156,13 @@ static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 		if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER) || | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER)) { | ||||
| 			if (defer_retries-- > 0) { | ||||
| 				printk(BIOS_SPEW, "dp: aux write defer (0x%x) -- %d\n", | ||||
| 				printk(BIOS_INFO, "dp: aux write defer (0x%x) -- %d\n", | ||||
| 					   *aux_stat, defer_retries); | ||||
| 				/* clear the error bits */ | ||||
| 				tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT, *aux_stat); | ||||
| 				continue; | ||||
| 			} else { | ||||
| 				printk(BIOS_SPEW, "dp: aux write defer exceeds max retries " | ||||
| 				printk(BIOS_ERR, "dp: aux write defer exceeds max retries " | ||||
| 					   "(0x%x)\n", *aux_stat); | ||||
| 				return -1; | ||||
| 			} | ||||
| @@ -180,7 +173,8 @@ static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 			*size = ((*aux_stat) & DPAUX_DP_AUXSTAT_REPLY_M_MASK); | ||||
| 			return 0; | ||||
| 		} else { | ||||
| 			printk(BIOS_SPEW, "dp: aux write failed (0x%x)\n", *aux_stat); | ||||
| 			printk(BIOS_ERR, "dp: aux write failed (0x%x)\n", | ||||
| 				*aux_stat); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| @@ -189,7 +183,7 @@ static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| } | ||||
|  | ||||
| static int tegra_dc_dpaux_write(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, | ||||
| 								u8 * data, u32 * size, u32 * aux_stat) | ||||
| 					u8 *data, u32 *size, u32 *aux_stat) | ||||
| { | ||||
| 	u32 cur_size = 0; | ||||
| 	u32 finished = 0; | ||||
| @@ -202,7 +196,7 @@ static int tegra_dc_dpaux_write(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, | ||||
| 			cur_size = DP_AUX_MAX_BYTES; | ||||
| 		cur_left = cur_size; | ||||
| 		ret = tegra_dc_dpaux_write_chunk(dp, cmd, addr, | ||||
| 										 data, &cur_left, aux_stat); | ||||
| 						 data, &cur_left, aux_stat); | ||||
|  | ||||
| 		cur_size -= cur_left; | ||||
| 		finished += cur_size; | ||||
| @@ -218,8 +212,8 @@ static int tegra_dc_dpaux_write(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, | ||||
| } | ||||
|  | ||||
| static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 									 u32 addr, u8 * data, u32 * size, | ||||
| 									 u32 * aux_stat) | ||||
| 					 u32 addr, u8 *data, u32 *size, | ||||
| 					 u32 *aux_stat) | ||||
| { | ||||
| 	u32 reg_val; | ||||
| 	u32 timeout_retries = DP_AUX_TIMEOUT_MAX_TRIES; | ||||
| @@ -236,7 +230,8 @@ static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 		case DPAUX_DP_AUXCTL_CMD_AUXRD: | ||||
| 			break; | ||||
| 		default: | ||||
| 			printk(BIOS_SPEW, "dp: aux read cmd 0x%x is invalid\n", cmd); | ||||
| 			printk(BIOS_ERR, "dp: aux read cmd 0x%x is invalid\n", | ||||
| 				cmd); | ||||
| 			return -1; | ||||
| 	} | ||||
|  | ||||
| @@ -253,37 +248,38 @@ static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 	reg_val = tegra_dpaux_readl(dp, DPAUX_DP_AUXCTL); | ||||
| 	reg_val &= ~DPAUX_DP_AUXCTL_CMD_MASK; | ||||
| 	reg_val |= cmd; | ||||
| 	printk(BIOS_SPEW, "cmd = %08x\n", reg_val); | ||||
| 	reg_val &= ~DPAUX_DP_AUXCTL_CMDLEN_FIELD; | ||||
| 	reg_val |= ((*size - 1) << DPAUX_DP_AUXCTL_CMDLEN_SHIFT); | ||||
| 	printk(BIOS_SPEW, "cmd = %08x\n", reg_val); | ||||
| 	while ((timeout_retries > 0) && (defer_retries > 0)) { | ||||
| 		if ((timeout_retries != DP_AUX_TIMEOUT_MAX_TRIES) || | ||||
| 			(defer_retries != DP_AUX_DEFER_MAX_TRIES)) | ||||
| 			udelay(DP_DPCP_RETRY_SLEEP_NS * 2); | ||||
|  | ||||
| 		reg_val |= DPAUX_DP_AUXCTL_TRANSACTREQ_PENDING; | ||||
| 		printk(BIOS_SPEW, "cmd = %08x\n", reg_val); | ||||
| 		tegra_dpaux_writel(dp, DPAUX_DP_AUXCTL, reg_val); | ||||
|  | ||||
| 		if (tegra_dpaux_wait_transaction(dp)) | ||||
| 			printk(BIOS_SPEW, "dp: aux read transaction timeout\n"); | ||||
| 			printk(BIOS_INFO, "dp: aux read transaction timeout\n"); | ||||
|  | ||||
| 		*aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT); | ||||
| 		printk(BIOS_SPEW, "dp: %s: aux stat: 0x%08x\n", __func__, *aux_stat); | ||||
| 		printk(BIOS_DEBUG, "dp: %s: aux stat: 0x%08x\n", __func__, | ||||
| 				*aux_stat); | ||||
|  | ||||
| 		if ((*aux_stat & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR_PENDING) || | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_RX_ERROR_PENDING) || | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR_PENDING) || | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_NO_STOP_ERROR_PENDING)) { | ||||
| 			if (timeout_retries-- > 0) { | ||||
| 				printk(BIOS_SPEW, "dp: aux read retry (0x%x) -- %d\n", | ||||
| 					   *aux_stat, timeout_retries); | ||||
| 				printk(BIOS_INFO, "dp: aux read retry (0x%x)" | ||||
| 						" -- %d\n", *aux_stat, | ||||
| 						timeout_retries); | ||||
| 				/* clear the error bits */ | ||||
| 				tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT, *aux_stat); | ||||
| 				tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT, | ||||
| 						*aux_stat); | ||||
| 				continue;	/* retry */ | ||||
| 			} else { | ||||
| 				printk(BIOS_SPEW, "dp: aux read got error (0x%x)\n", *aux_stat); | ||||
| 				printk(BIOS_ERR, "dp: aux read got error" | ||||
| 						" (0x%x)\n", *aux_stat); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| @@ -291,13 +287,13 @@ static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 		if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER) || | ||||
| 			(*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER)) { | ||||
| 			if (defer_retries-- > 0) { | ||||
| 				printk(BIOS_SPEW, "dp: aux read defer (0x%x) -- %d\n", | ||||
| 				printk(BIOS_INFO, "dp: aux read defer (0x%x) -- %d\n", | ||||
| 					   *aux_stat, defer_retries); | ||||
| 				/* clear the error bits */ | ||||
| 				tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT, *aux_stat); | ||||
| 				continue; | ||||
| 			} else { | ||||
| 				printk(BIOS_SPEW, "dp: aux read defer exceeds max retries " | ||||
| 				printk(BIOS_INFO, "dp: aux read defer exceeds max retries " | ||||
| 					   "(0x%x)\n", *aux_stat); | ||||
| 				return -1; | ||||
| 			} | ||||
| @@ -310,20 +306,22 @@ static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
|  | ||||
| 			for (i = 0; i < DP_AUX_MAX_BYTES / 4; ++i) | ||||
| 				temp_data[i] = tegra_dpaux_readl(dp, | ||||
| 												 DPAUX_DP_AUXDATA_READ_W(i)); | ||||
| 						DPAUX_DP_AUXDATA_READ_W(i)); | ||||
|  | ||||
| 			*size = ((*aux_stat) & DPAUX_DP_AUXSTAT_REPLY_M_MASK); | ||||
| 			printk(BIOS_SPEW, "dp: aux read data %d bytes\n", *size); | ||||
| 			printk(BIOS_INFO, "dp: aux read data %d bytes\n", | ||||
| 					*size); | ||||
| 			memcpy(data, temp_data, *size); | ||||
|  | ||||
| 			return 0; | ||||
| 		} else { | ||||
| 			printk(BIOS_SPEW, "dp: aux read failed (0x%x\n", *aux_stat); | ||||
| 			printk(BIOS_ERR, "dp: aux read failed (0x%x\n", | ||||
| 					*aux_stat); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 	/* Should never come to here */ | ||||
| 	printk(BIOS_SPEW, "%s: can't\n", __func__); | ||||
| 	printk(BIOS_ERR, "%s: can't\n", __func__); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| @@ -340,7 +338,7 @@ int tegra_dc_dpaux_read(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, | ||||
| 			cur_size = DP_AUX_MAX_BYTES; | ||||
|  | ||||
| 		ret = tegra_dc_dpaux_read_chunk(dp, cmd, addr, | ||||
| 										data, &cur_size, aux_stat); | ||||
| 						data, &cur_size, aux_stat); | ||||
|  | ||||
| 		/* cur_size should be the real size returned */ | ||||
| 		addr += cur_size; | ||||
| @@ -350,12 +348,6 @@ int tegra_dc_dpaux_read(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, | ||||
| 		if (ret) | ||||
| 			break; | ||||
|  | ||||
| #if 0 | ||||
| 		if (cur_size == 0) { | ||||
| 			printk(BIOS_SPEW, "JZ: no data found, ret\n"); | ||||
| 			break; | ||||
| 		} | ||||
| #endif | ||||
| 	} while (*size > finished); | ||||
|  | ||||
| 	*size = finished; | ||||
| @@ -372,7 +364,7 @@ static int tegra_dc_dp_dpcd_read(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| 	ret = tegra_dc_dpaux_read_chunk(dp, DPAUX_DP_AUXCTL_CMD_AUXRD, | ||||
| 									cmd, data_ptr, &size, &status); | ||||
| 	if (ret) | ||||
| 		printk(BIOS_SPEW, | ||||
| 		printk(BIOS_ERR, | ||||
| 			   "dp: Failed to read DPCD data. CMD 0x%x, Status 0x%x\n", cmd, | ||||
| 			   status); | ||||
|  | ||||
| @@ -380,7 +372,7 @@ static int tegra_dc_dp_dpcd_read(struct tegra_dc_dp_data *dp, u32 cmd, | ||||
| } | ||||
|  | ||||
| static int tegra_dc_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, | ||||
| 										 struct tegra_dc_dp_link_config *cfg) | ||||
| 					 struct tegra_dc_dp_link_config *cfg) | ||||
| { | ||||
| 	u8 dpcd_data; | ||||
| 	int ret; | ||||
| @@ -390,27 +382,26 @@ static int tegra_dc_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, | ||||
| 		return ret; | ||||
|  | ||||
| 	cfg->max_lane_count = dpcd_data & NV_DPCD_MAX_LANE_COUNT_MASK; | ||||
| 	printk(BIOS_SPEW, "JZ: %s: max_lane_count: %d\n", __func__, | ||||
| 	printk(BIOS_INFO, "%s: max_lane_count: %d\n", __func__, | ||||
| 		   cfg->max_lane_count); | ||||
|  | ||||
| 	cfg->support_enhanced_framing = | ||||
| 		(dpcd_data & NV_DPCD_MAX_LANE_COUNT_ENHANCED_FRAMING_YES) ? 1 : 0; | ||||
| 	printk(BIOS_SPEW, "JZ: %s: enh-framing: %d\n", __func__, | ||||
| 	printk(BIOS_INFO, "%s: enh-framing: %d\n", __func__, | ||||
| 		   cfg->support_enhanced_framing); | ||||
|  | ||||
| 	ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_MAX_DOWNSPREAD, &dpcd_data); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	cfg->downspread = (dpcd_data & NV_DPCD_MAX_DOWNSPREAD_VAL_0_5_PCT) ? 1 : 0; | ||||
| 	printk(BIOS_SPEW, "JZ: %s: downspread: %d\n", __func__, cfg->downspread); | ||||
| 	printk(BIOS_INFO, "%s: downspread: %d\n", __func__, cfg->downspread); | ||||
|  | ||||
| 	ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_MAX_LINK_BANDWIDTH, | ||||
| 								&cfg->max_link_bw); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	printk(BIOS_SPEW, "JZ: %s: max_link_bw: %d\n", __func__, cfg->max_link_bw); | ||||
| 	printk(BIOS_INFO, "%s: max_link_bw: %d\n", __func__, cfg->max_link_bw); | ||||
|  | ||||
| 	// jz, changed | ||||
| 	// cfg->bits_per_pixel = dp->dc->pdata->default_out->depth; | ||||
| 	cfg->bits_per_pixel = 18; | ||||
|  | ||||
| @@ -427,7 +418,7 @@ static int tegra_dc_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, | ||||
| 		(dpcd_data & NV_DPCD_EDP_CONFIG_CAP_ASC_RESET_YES) ? 1 : 0; | ||||
| 	cfg->only_enhanced_framing = | ||||
| 		(dpcd_data & NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES) ? 1 : 0; | ||||
| 	printk(BIOS_SPEW, "JZ: %s: alt_reset_cap: %d, only_enh_framing: %d\n", | ||||
| 	printk(BIOS_DEBUG, "%s: alt_reset_cap: %d, only_enh_framing: %d\n", | ||||
| 		   __func__, cfg->alt_scramber_reset_cap, cfg->only_enhanced_framing); | ||||
|  | ||||
| 	cfg->lane_count = cfg->max_lane_count; | ||||
| @@ -448,13 +439,13 @@ static int tegra_dc_dpcd_read_rev(struct tegra_dc_dp_data *dp, u8 * rev) | ||||
| 	ret = tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD, | ||||
| 							  NV_DPCD_REV, rev, &size, &status); | ||||
| 	if (ret) { | ||||
| 		printk(BIOS_SPEW, "dp: Failed to read NV_DPCD_REV\n"); | ||||
| 		printk(BIOS_WARNING, "dp: Failed to read NV_DPCD_REV\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| u32 dp_setup_timing(u32 panel_id, u32 width, u32 height); | ||||
| u32 dp_setup_timing(u32 width, u32 height); | ||||
| void dp_bringup(u32 winb_addr) | ||||
| { | ||||
| 	struct tegra_dc_dp_data *dp = &dp_data; | ||||
| @@ -465,40 +456,40 @@ void dp_bringup(u32 winb_addr) | ||||
| 	u32 xres = 1366;	/* norrin display */ | ||||
| 	u32 yres = 768; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ: %s: entry\n", __func__); | ||||
|  | ||||
| 	dp->sor.base = (void *)TEGRA_ARM_SOR; | ||||
| 	dp->sor.portnum = 0; | ||||
|  | ||||
| 	dp->aux_base = (void *)TEGRA_ARM_DPAUX; | ||||
|  | ||||
| 	/* read panel info */ | ||||
| 	if (!tegra_dc_dpcd_read_rev(dp, (u8 *) & dpcd_rev)) { | ||||
| 		printk(BIOS_SPEW, "PANEL info: \n"); | ||||
| 		printk(BIOS_SPEW, "--DPCP version(%#x): %d.%d\n", | ||||
| 			   dpcd_rev, (dpcd_rev >> 4) & 0x0f, (dpcd_rev & 0x0f)); | ||||
| 	if (!tegra_dc_dpcd_read_rev(dp, (u8 *)&dpcd_rev)) { | ||||
| 		printk(BIOS_INFO, "PANEL info:\n"); | ||||
| 		printk(BIOS_INFO, "--DPCP version(%#x): %d.%d\n", | ||||
| 				dpcd_rev, (dpcd_rev >> 4) & 0x0f, | ||||
| 				(dpcd_rev & 0x0f)); | ||||
| 	} | ||||
|  | ||||
| 	if (tegra_dc_dp_init_max_link_cfg(dp, &dp->link_cfg)) | ||||
| 		printk(BIOS_SPEW, "dp: failed to init link configuration\n"); | ||||
| 		printk(BIOS_ERR, "dp: failed to init link configuration\n"); | ||||
|  | ||||
| 	dp_link_training((u32) (dp->link_cfg.lane_count), | ||||
| 					 (u32) (dp->link_cfg.link_bw)); | ||||
|  | ||||
| 	pclk_freq = dp_setup_timing(5, xres, yres); | ||||
| 	printk(BIOS_SPEW, "JZ: %s: pclk_freq: %d\n", __func__, pclk_freq); | ||||
| 	pclk_freq = dp_setup_timing(xres, yres); | ||||
| 	printk(BIOS_DEBUG, "%s: pclk_freq: %d\n", __func__, pclk_freq); | ||||
|  | ||||
| 	void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 						 u32 lane_count, u32 enhanced_framing, u32 panel_edp, | ||||
| 						 u32 pclkfreq, u32 linkfreq); | ||||
|  | ||||
| 	void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, | ||||
| 				u32 winb_addr, u32 lane_count, | ||||
| 				u32 enhanced_framing, u32 panel_edp, | ||||
| 				u32 pclkfreq, u32 linkfreq); | ||||
|  | ||||
| 	dp_misc_setting(dp->link_cfg.bits_per_pixel, | ||||
| 					xres, yres, winb_addr, | ||||
| 					(u32) dp->link_cfg.lane_count, | ||||
| 					(u32) dp->link_cfg.enhanced_framing, | ||||
| 					(u32) dp->link_cfg.alt_scramber_reset_cap, | ||||
| 					pclk_freq, dp->link_cfg.link_bw * 27); | ||||
|  | ||||
| 				xres, yres, winb_addr, | ||||
| 				(u32) dp->link_cfg.lane_count, | ||||
| 				(u32) dp->link_cfg.enhanced_framing, | ||||
| 				(u32) dp->link_cfg.alt_scramber_reset_cap, | ||||
| 				pclk_freq, dp->link_cfg.link_bw * 27); | ||||
| } | ||||
|  | ||||
| void debug_dpaux_print(u32 addr, u32 size) | ||||
| @@ -509,21 +500,22 @@ void debug_dpaux_print(u32 addr, u32 size) | ||||
| 	int i; | ||||
|  | ||||
| 	if ((size == 0) || (size > 16)) { | ||||
| 		printk(BIOS_SPEW, "dp: %s: invalid size %d\n", __func__, size); | ||||
| 		printk(BIOS_ERR, "dp: %s: invalid size %d\n", __func__, size); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD, | ||||
| 							addr, buf, &size, &status)) { | ||||
| 		printk(BIOS_SPEW, "******AuxRead Error: 0x%04x: status 0x%08x\n", addr, | ||||
| 			   status); | ||||
| 				addr, buf, &size, &status)) { | ||||
| 		printk(BIOS_ERR, "******AuxRead Error: 0x%04x: status 0x%08x\n", | ||||
| 				addr, status); | ||||
| 		return; | ||||
| 	} | ||||
| 	printk(BIOS_SPEW, "%s: addr: 0x%04x, size: %d\n", __func__, addr, size); | ||||
| 	printk(BIOS_DEBUG, "%s: addr: 0x%04x, size: %d\n", __func__, | ||||
| 			addr, size); | ||||
| 	for (i = 0; i < size; ++i) | ||||
| 		printk(BIOS_SPEW, " %02x", buf[i]); | ||||
| 		printk(BIOS_DEBUG, " %02x", buf[i]); | ||||
|  | ||||
| 	printk(BIOS_SPEW, "\n"); | ||||
| 	printk(BIOS_DEBUG, "\n"); | ||||
| } | ||||
|  | ||||
| int dpaux_read(u32 addr, u32 size, u8 * data) | ||||
| @@ -533,14 +525,14 @@ int dpaux_read(u32 addr, u32 size, u8 * data) | ||||
| 	u32 status = 0; | ||||
|  | ||||
| 	if ((size == 0) || (size > 16)) { | ||||
| 		printk(BIOS_SPEW, "dp: %s: invalid size %d\n", __func__, size); | ||||
| 		printk(BIOS_ERR, "dp: %s: invalid size %d\n", __func__, size); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD, | ||||
| 							addr, data, &size, &status)) { | ||||
| 		printk(BIOS_SPEW, "dp: Failed to read reg %#x, status: %#x\n", addr, | ||||
| 			   status); | ||||
| 					addr, data, &size, &status)) { | ||||
| 		printk(BIOS_ERR, "dp: Failed to read reg %#x, status: %#x\n", | ||||
| 				addr, status); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @@ -553,13 +545,10 @@ int dpaux_write(u32 addr, u32 size, u32 data) | ||||
| 	u32 status = 0; | ||||
| 	int ret; | ||||
|  | ||||
| 	printk(BIOS_SPEW, "JZ: %s: entry, addr: 0x%08x, size: 0x%08x, data: %#x\n", | ||||
| 		   __func__, addr, size, data); | ||||
|  | ||||
| 	ret = tegra_dc_dpaux_write(dp, DPAUX_DP_AUXCTL_CMD_AUXWR, | ||||
| 							   addr, (u8 *) & data, &size, &status); | ||||
| 	if (ret) | ||||
| 		printk(BIOS_SPEW, "dp: Failed to write to reg %#x, status: 0x%x\n", | ||||
| 		printk(BIOS_ERR, "dp: Failed to write to reg %#x, status: 0x%x\n", | ||||
| 			   addr, status); | ||||
| 	return ret; | ||||
| } | ||||
|   | ||||
							
								
								
									
										323
									
								
								src/soc/nvidia/tegra124/emc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								src/soc/nvidia/tegra124/emc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,323 @@ | ||||
| /* | ||||
|  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved. | ||||
|  * Copyright (C) 2013 Google Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms and conditions of the GNU General Public License, | ||||
|  * version 2, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope it will be useful, but WITHOUT | ||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|  * more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef __SOC_NVIDIA_TEGRA124_EMC_H__ | ||||
| #define __SOC_NVIDIA_TEGRA124_EMC_H__ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| enum { | ||||
| 	EMC_PIN_RESET_MASK = 1 << 8, | ||||
| 	EMC_PIN_RESET_ACTIVE = 0 << 8, | ||||
| 	EMC_PIN_RESET_INACTIVE = 1 << 8, | ||||
| 	EMC_PIN_DQM_MASK = 1 << 4, | ||||
| 	EMC_PIN_DQM_NORMAL = 0 << 4, | ||||
| 	EMC_PIN_DQM_INACTIVE = 1 << 4, | ||||
| 	EMC_PIN_CKE_MASK = 1 << 0, | ||||
| 	EMC_PIN_CKE_POWERDOWN = 0 << 0, | ||||
| 	EMC_PIN_CKE_NORMAL = 1 << 0, | ||||
|  | ||||
| 	EMC_REF_CMD_MASK = 1 << 0, | ||||
| 	EMC_REF_CMD_REFRESH = 1 << 0, | ||||
| 	EMC_REF_NORMAL_MASK = 1 << 1, | ||||
| 	EMC_REF_NORMAL_INIT = 0 << 1, | ||||
| 	EMC_REF_NORMAL_ENABLED = 1 << 1, | ||||
| 	EMC_REF_NUM_SHIFT = 8, | ||||
| 	EMC_REF_NUM_MASK = 0xFF << EMC_REF_NUM_SHIFT, | ||||
| 	EMC_REF_DEV_SELECTN_SHIFT = 30, | ||||
| 	EMC_REF_DEV_SELECTN_MASK = 3 << EMC_REF_DEV_SELECTN_SHIFT, | ||||
|  | ||||
| 	EMC_REFCTRL_REF_VALID_MASK = 1 << 31, | ||||
| 	EMC_REFCTRL_REF_VALID_DISABLED = 0 << 31, | ||||
| 	EMC_REFCTRL_REF_VALID_ENABLED = 1 << 31, | ||||
|  | ||||
| 	EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE_MASK = 1 << 1, | ||||
| 	EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1_MASK = 1 << 2, | ||||
| 	EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2_MASK = 1 << 3, | ||||
|  | ||||
| 	EMC_NOP_NOP_CMD_SHIFT = 0, | ||||
| 	EMC_NOP_NOP_CMD_MASK = 1 << EMC_NOP_NOP_CMD_SHIFT, | ||||
| 	EMC_NOP_NOP_DEV_SELECTN_SHIFT = 30, | ||||
| 	EMC_NOP_NOP_DEV_SELECTN_MASK = 3 << EMC_NOP_NOP_DEV_SELECTN_SHIFT, | ||||
|  | ||||
| 	EMC_TIMING_CONTROL_TIMING_UPDATE = 1, | ||||
| }; | ||||
|  | ||||
| struct tegra_emc_regs { | ||||
| 	uint32_t intstatus;		/* 0x0 */ | ||||
| 	uint32_t intmask;		/* 0x4 */ | ||||
| 	uint32_t dbg;			/* 0x8 */ | ||||
| 	uint32_t cfg;			/* 0xc */ | ||||
| 	uint32_t adr_cfg;		/* 0x10 */ | ||||
| 	uint32_t rsvd_0x14[3];		/* 0x14 */ | ||||
|  | ||||
| 	uint32_t refctrl;		/* 0x20 */ | ||||
| 	uint32_t pin;			/* 0x24 */ | ||||
| 	uint32_t timing_control;	/* 0x28 */ | ||||
| 	uint32_t rc;			/* 0x2c */ | ||||
| 	uint32_t rfc;			/* 0x30 */ | ||||
| 	uint32_t ras;			/* 0x34 */ | ||||
| 	uint32_t rp;			/* 0x38 */ | ||||
| 	uint32_t r2w;			/* 0x3c */ | ||||
| 	uint32_t w2r;			/* 0x40 */ | ||||
| 	uint32_t r2p;			/* 0x44 */ | ||||
| 	uint32_t w2p;			/* 0x48 */ | ||||
| 	uint32_t rd_rcd;		/* 0x4c */ | ||||
| 	uint32_t wr_rcd;		/* 0x50 */ | ||||
| 	uint32_t rrd;			/* 0x54 */ | ||||
| 	uint32_t rext;			/* 0x58 */ | ||||
| 	uint32_t wdv;			/* 0x5c */ | ||||
| 	uint32_t quse;			/* 0x60 */ | ||||
| 	uint32_t qrst;			/* 0x64 */ | ||||
| 	uint32_t qsafe;			/* 0x68 */ | ||||
| 	uint32_t rdv;			/* 0x6c */ | ||||
| 	uint32_t refresh;		/* 0x70 */ | ||||
| 	uint32_t burst_refresh_num;	/* 0x74 */ | ||||
| 	uint32_t pdex2wr;		/* 0x78 */ | ||||
| 	uint32_t pdex2rd;		/* 0x7c */ | ||||
| 	uint32_t pchg2pden;		/* 0x80 */ | ||||
| 	uint32_t act2pden;		/* 0x84 */ | ||||
| 	uint32_t ar2pden;		/* 0x88 */ | ||||
| 	uint32_t rw2pden;		/* 0x8c */ | ||||
| 	uint32_t txsr;			/* 0x90 */ | ||||
| 	uint32_t tcke;			/* 0x94 */ | ||||
| 	uint32_t tfaw;			/* 0x98 */ | ||||
| 	uint32_t trpab;			/* 0x9c */ | ||||
| 	uint32_t tclkstable;		/* 0xa0 */ | ||||
| 	uint32_t tclkstop;		/* 0xa4 */ | ||||
| 	uint32_t trefbw;		/* 0xa8 */ | ||||
| 	uint32_t rsvd_0xac[1];		/* 0xac */ | ||||
| 	uint32_t odt_write;		/* 0xb0 */ | ||||
| 	uint32_t odt_read;		/* 0xb4 */ | ||||
| 	uint32_t wext;			/* 0xb8 */ | ||||
| 	uint32_t ctt;			/* 0xbc */ | ||||
| 	uint32_t rfc_slr;		/* 0xc0 */ | ||||
| 	uint32_t mrs_wait_cnt2;		/* 0xc4 */ | ||||
| 	uint32_t mrs_wait_cnt;		/* 0xc8 */ | ||||
| 	uint32_t mrs;			/* 0xcc */ | ||||
| 	uint32_t emrs;			/* 0xd0 */ | ||||
| 	uint32_t ref;			/* 0xd4 */ | ||||
| 	uint32_t pre;			/* 0xd8 */ | ||||
| 	uint32_t nop;			/* 0xdc */ | ||||
| 	uint32_t self_ref;		/* 0xe0 */ | ||||
| 	uint32_t dpd;			/* 0xe4 */ | ||||
| 	uint32_t mrw;			/* 0xe8 */ | ||||
| 	uint32_t mrr;			/* 0xec */ | ||||
| 	uint32_t cmdq;			/* 0xf0 */ | ||||
| 	uint32_t mc2emcq;		/* 0xf4 */ | ||||
| 	uint32_t xm2dqspadctrl3;	/* 0xf8 */ | ||||
| 	uint32_t rsvd_0xfc[1];		/* 0xfc */ | ||||
| 	uint32_t fbio_spare;		/* 0x100 */ | ||||
| 	uint32_t fbio_cfg5;		/* 0x104 */ | ||||
| 	uint32_t fbio_wrptr_eq_2;	/* 0x108 */ | ||||
| 	uint32_t rsvd_0x10c[2];		/* 0x10c */ | ||||
|  | ||||
| 	uint32_t fbio_cfg6;		/* 0x114 */ | ||||
| 	uint32_t rsvd_0x118[2];		/* 0x118 */ | ||||
|  | ||||
| 	uint32_t cfg_rsv;		/* 0x120 */ | ||||
| 	uint32_t acpd_control;		/* 0x124 */ | ||||
| 	uint32_t rsvd_0x128[1];		/* 0x128 */ | ||||
| 	uint32_t emrs2;			/* 0x12c */ | ||||
| 	uint32_t emrs3;			/* 0x130 */ | ||||
| 	uint32_t mrw2;			/* 0x134 */ | ||||
| 	uint32_t mrw3;			/* 0x138 */ | ||||
| 	uint32_t mrw4;			/* 0x13c */ | ||||
| 	uint32_t clken_override;	/* 0x140 */ | ||||
| 	uint32_t r2r;			/* 0x144 */ | ||||
| 	uint32_t w2w;			/* 0x148 */ | ||||
| 	uint32_t einput;		/* 0x14c */ | ||||
| 	uint32_t einput_duration;	/* 0x150 */ | ||||
| 	uint32_t puterm_extra;		/* 0x154 */ | ||||
| 	uint32_t tckesr;		/* 0x158 */ | ||||
| 	uint32_t tpd;			/* 0x15c */ | ||||
| 	uint32_t rsvd_0x160[81];		/* 0x160 */ | ||||
|  | ||||
| 	uint32_t auto_cal_config;	/* 0x2a4 */ | ||||
| 	uint32_t auto_cal_interval;	/* 0x2a8 */ | ||||
| 	uint32_t auto_cal_status;	/* 0x2ac */ | ||||
| 	uint32_t req_ctrl;		/* 0x2b0 */ | ||||
| 	uint32_t status;		/* 0x2b4 */ | ||||
| 	uint32_t cfg_2;			/* 0x2b8 */ | ||||
| 	uint32_t cfg_dig_dll;		/* 0x2bc */ | ||||
| 	uint32_t cfg_dig_dll_period;	/* 0x2c0 */ | ||||
| 	uint32_t rsvd_0x2c4[1];		/* 0x2c4 */ | ||||
| 	uint32_t dig_dll_status;	/* 0x2c8 */ | ||||
| 	uint32_t rdv_mask;		/* 0x2cc */ | ||||
| 	uint32_t wdv_mask;		/* 0x2d0 */ | ||||
| 	uint32_t rsvd_0x2d4[1];		/* 0x2d4 */ | ||||
| 	uint32_t ctt_duration;		/* 0x2d8 */ | ||||
| 	uint32_t ctt_term_ctrl;		/* 0x2dc */ | ||||
| 	uint32_t zcal_interval;		/* 0x2e0 */ | ||||
| 	uint32_t zcal_wait_cnt;		/* 0x2e4 */ | ||||
| 	uint32_t zcal_mrw_cmd;		/* 0x2e8 */ | ||||
| 	uint32_t zq_cal;		/* 0x2ec */ | ||||
| 	uint32_t xm2cmdpadctrl;		/* 0x2f0 */ | ||||
| 	uint32_t xm2cmdpadctrl2;	/* 0x2f4 */ | ||||
| 	uint32_t xm2dqspadctrl;		/* 0x2f8 */ | ||||
| 	uint32_t xm2dqspadctrl2;	/* 0x2fc */ | ||||
| 	uint32_t xm2dqpadctrl;		/* 0x300 */ | ||||
| 	uint32_t xm2dqpadctrl2;		/* 0x304 */ | ||||
| 	uint32_t xm2clkpadctrl;		/* 0x308 */ | ||||
| 	uint32_t xm2comppadctrl;	/* 0x30c */ | ||||
| 	uint32_t xm2vttgenpadctrl;	/* 0x310 */ | ||||
| 	uint32_t xm2vttgenpadctrl2;	/* 0x314 */ | ||||
| 	uint32_t xm2vttgenpadctrl3;	/* 0x318 */ | ||||
| 	uint32_t emcpaden;		/* 0x31c */ | ||||
| 	uint32_t xm2dqspadctrl4;	/* 0x320 */ | ||||
| 	uint32_t scratch0;		/* 0x324 */ | ||||
| 	uint32_t dll_xform_dqs0;	/* 0x328 */ | ||||
| 	uint32_t dll_xform_dqs1;	/* 0x32c */ | ||||
| 	uint32_t dll_xform_dqs2;	/* 0x330 */ | ||||
| 	uint32_t dll_xform_dqs3;	/* 0x334 */ | ||||
| 	uint32_t dll_xform_dqs4;	/* 0x338 */ | ||||
| 	uint32_t dll_xform_dqs5;	/* 0x33c */ | ||||
| 	uint32_t dll_xform_dqs6;	/* 0x340 */ | ||||
| 	uint32_t dll_xform_dqs7;	/* 0x344 */ | ||||
| 	uint32_t dll_xform_quse0;	/* 0x348 */ | ||||
| 	uint32_t dll_xform_quse1;	/* 0x34c */ | ||||
| 	uint32_t dll_xform_quse2;	/* 0x350 */ | ||||
| 	uint32_t dll_xform_quse3;	/* 0x354 */ | ||||
| 	uint32_t dll_xform_quse4;	/* 0x358 */ | ||||
| 	uint32_t dll_xform_quse5;	/* 0x35c */ | ||||
| 	uint32_t dll_xform_quse6;	/* 0x360 */ | ||||
| 	uint32_t dll_xform_quse7;	/* 0x364 */ | ||||
| 	uint32_t dll_xform_dq0;		/* 0x368 */ | ||||
| 	uint32_t dll_xform_dq1;		/* 0x36c */ | ||||
| 	uint32_t dll_xform_dq2;		/* 0x370 */ | ||||
| 	uint32_t dll_xform_dq3;		/* 0x374 */ | ||||
| 	uint32_t dli_rx_trim0;		/* 0x378 */ | ||||
| 	uint32_t dli_rx_trim1;		/* 0x37c */ | ||||
| 	uint32_t dli_rx_trim2;		/* 0x380 */ | ||||
| 	uint32_t dli_rx_trim3;		/* 0x384 */ | ||||
| 	uint32_t dli_rx_trim4;		/* 0x388 */ | ||||
| 	uint32_t dli_rx_trim5;		/* 0x38c */ | ||||
| 	uint32_t dli_rx_trim6;		/* 0x390 */ | ||||
| 	uint32_t dli_rx_trim7;		/* 0x394 */ | ||||
| 	uint32_t dli_tx_trim0;		/* 0x398 */ | ||||
| 	uint32_t dli_tx_trim1;		/* 0x39c */ | ||||
| 	uint32_t dli_tx_trim2;		/* 0x3a0 */ | ||||
| 	uint32_t dli_tx_trim3;		/* 0x3a4 */ | ||||
| 	uint32_t dli_trim_txdqs0;	/* 0x3a8 */ | ||||
| 	uint32_t dli_trim_txdqs1;	/* 0x3ac */ | ||||
| 	uint32_t dli_trim_txdqs2;	/* 0x3b0 */ | ||||
| 	uint32_t dli_trim_txdqs3;	/* 0x3b4 */ | ||||
| 	uint32_t dli_trim_txdqs4;	/* 0x3b8 */ | ||||
| 	uint32_t dli_trim_txdqs5;	/* 0x3bc */ | ||||
| 	uint32_t dli_trim_txdqs6;	/* 0x3c0 */ | ||||
| 	uint32_t dli_trim_txdqs7;	/* 0x3c4 */ | ||||
| 	uint32_t rsvd_0x3c8[1];		/* 0x3c8 */ | ||||
| 	uint32_t stall_then_exe_after_clkchange;	/* 0x3cc */ | ||||
| 	uint32_t rsvd_0x3d0[1];		/* 0x3d0 */ | ||||
| 	uint32_t auto_cal_clk_status;	/* 0x3d4 */ | ||||
| 	uint32_t sel_dpd_ctrl;		/* 0x3d8 */ | ||||
| 	uint32_t pre_refresh_req_cnt;	/* 0x3dc */ | ||||
| 	uint32_t dyn_self_ref_control;	/* 0x3e0 */ | ||||
| 	uint32_t txsrdll;		/* 0x3e4 */ | ||||
| 	uint32_t ccfifo_addr;		/* 0x3e8 */ | ||||
| 	uint32_t ccfifo_data;		/* 0x3ec */ | ||||
| 	uint32_t ccfifo_status;		/* 0x3f0 */ | ||||
| 	uint32_t cdb_cntl_1;		/* 0x3f4 */ | ||||
| 	uint32_t cdb_cntl_2;		/* 0x3f8 */ | ||||
| 	uint32_t xm2clkpadctrl2;	/* 0x3fc */ | ||||
| 	uint32_t swizzle_rank0_byte_cfg;	/* 0x400 */ | ||||
| 	uint32_t swizzle_rank0_byte0;	/* 0x404 */ | ||||
| 	uint32_t swizzle_rank0_byte1;	/* 0x408 */ | ||||
| 	uint32_t swizzle_rank0_byte2;	/* 0x40c */ | ||||
| 	uint32_t swizzle_rank0_byte3;	/* 0x410 */ | ||||
| 	uint32_t swizzle_rank1_byte_cfg;	/* 0x414 */ | ||||
| 	uint32_t swizzle_rank1_byte0;	/* 0x418 */ | ||||
| 	uint32_t swizzle_rank1_byte1;	/* 0x41c */ | ||||
| 	uint32_t swizzle_rank1_byte2;	/* 0x420 */ | ||||
| 	uint32_t swizzle_rank1_byte3;	/* 0x424 */ | ||||
| 	uint32_t ca_training_start;	/* 0x428 */ | ||||
| 	uint32_t ca_training_busy;	/* 0x42c */ | ||||
| 	uint32_t ca_training_cfg;	/* 0x430 */ | ||||
| 	uint32_t ca_training_timing_cntl1;	/* 0x434 */ | ||||
| 	uint32_t ca_training_timing_cntl2;	/* 0x438 */ | ||||
| 	uint32_t ca_training_ca_lead_in;	/* 0x43c */ | ||||
| 	uint32_t ca_training_ca;	/* 0x440 */ | ||||
| 	uint32_t ca_training_ca_lead_out;	/* 0x444 */ | ||||
| 	uint32_t ca_training_result1;	/* 0x448 */ | ||||
| 	uint32_t ca_training_result2;	/* 0x44c */ | ||||
| 	uint32_t ca_training_result3;	/* 0x450 */ | ||||
| 	uint32_t ca_training_result4;	/* 0x454 */ | ||||
| 	uint32_t auto_cal_config2;	/* 0x458 */ | ||||
| 	uint32_t auto_cal_config3;	/* 0x45c */ | ||||
| 	uint32_t auto_cal_status2;	/* 0x460 */ | ||||
| 	uint32_t xm2cmdpadctrl3;	/* 0x464 */ | ||||
| 	uint32_t ibdly;			/* 0x468 */ | ||||
| 	uint32_t dll_xform_addr0;	/* 0x46c */ | ||||
| 	uint32_t dll_xform_addr1;	/* 0x470 */ | ||||
| 	uint32_t dll_xform_addr2;	/* 0x474 */ | ||||
| 	uint32_t dli_addr_trim;		/* 0x478 */ | ||||
| 	uint32_t dsr_vttgen_drv;	/* 0x47c */ | ||||
| 	uint32_t txdsrvttgen;		/* 0x480 */ | ||||
| 	uint32_t xm2cmdpadctrl4;	/* 0x484 */ | ||||
| 	uint32_t xm2cmdpadctrl5;	/* 0x488 */ | ||||
| 	uint32_t rsvd_0x48c[5];		/* 0x48c */ | ||||
|  | ||||
| 	uint32_t dll_xform_dqs8;	/* 0x4a0 */ | ||||
| 	uint32_t dll_xform_dqs9;	/* 0x4a4 */ | ||||
| 	uint32_t dll_xform_dqs10;	/* 0x4a8 */ | ||||
| 	uint32_t dll_xform_dqs11;	/* 0x4ac */ | ||||
| 	uint32_t dll_xform_dqs12;	/* 0x4b0 */ | ||||
| 	uint32_t dll_xform_dqs13;	/* 0x4b4 */ | ||||
| 	uint32_t dll_xform_dqs14;	/* 0x4b8 */ | ||||
| 	uint32_t dll_xform_dqs15;	/* 0x4bc */ | ||||
| 	uint32_t dll_xform_quse8;	/* 0x4c0 */ | ||||
| 	uint32_t dll_xform_quse9;	/* 0x4c4 */ | ||||
| 	uint32_t dll_xform_quse10;	/* 0x4c8 */ | ||||
| 	uint32_t dll_xform_quse11;	/* 0x4cc */ | ||||
| 	uint32_t dll_xform_quse12;	/* 0x4d0 */ | ||||
| 	uint32_t dll_xform_quse13;	/* 0x4d4 */ | ||||
| 	uint32_t dll_xform_quse14;	/* 0x4d8 */ | ||||
| 	uint32_t dll_xform_quse15;	/* 0x4dc */ | ||||
| 	uint32_t dll_xform_dq4;		/* 0x4e0 */ | ||||
| 	uint32_t dll_xform_dq5;		/* 0x4e4 */ | ||||
| 	uint32_t dll_xform_dq6;		/* 0x4e8 */ | ||||
| 	uint32_t dll_xform_dq7;		/* 0x4ec */ | ||||
| 	uint32_t rsvd_0x4f0[12];		/* 0x4f0 */ | ||||
|  | ||||
| 	uint32_t dli_trim_txdqs8;	/* 0x520 */ | ||||
| 	uint32_t dli_trim_txdqs9;	/* 0x524 */ | ||||
| 	uint32_t dli_trim_txdqs10;	/* 0x528 */ | ||||
| 	uint32_t dli_trim_txdqs11;	/* 0x52c */ | ||||
| 	uint32_t dli_trim_txdqs12;	/* 0x530 */ | ||||
| 	uint32_t dli_trim_txdqs13;	/* 0x534 */ | ||||
| 	uint32_t dli_trim_txdqs14;	/* 0x538 */ | ||||
| 	uint32_t dli_trim_txdqs15;	/* 0x53c */ | ||||
| 	uint32_t cdb_cntl_3;		/* 0x540 */ | ||||
| 	uint32_t xm2dqspadctrl5;	/* 0x544 */ | ||||
| 	uint32_t xm2dqspadctrl6;	/* 0x548 */ | ||||
| 	uint32_t xm2dqpadctrl3;		/* 0x54c */ | ||||
| 	uint32_t dll_xform_addr3;	/* 0x550 */ | ||||
| 	uint32_t dll_xform_addr4;	/* 0x554 */ | ||||
| 	uint32_t dll_xform_addr5;	/* 0x558 */ | ||||
| 	uint32_t rsvd_0x55c[1];		/* 0x55c */ | ||||
| 	uint32_t cfg_pipe;		/* 0x560 */ | ||||
| 	uint32_t qpop;			/* 0x564 */ | ||||
| 	uint32_t quse_width;		/* 0x568 */ | ||||
| 	uint32_t puterm_width;		/* 0x56c */ | ||||
| 	uint32_t bgbias_ctl0;		/* 0x570 */ | ||||
| 	uint32_t puterm_adj;		/* 0x574 */ | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| check_member(tegra_emc_regs, puterm_adj, 0x574); | ||||
|  | ||||
| #endif /* __SOC_NVIDIA_TEGRA124_EMC_H__ */ | ||||
| @@ -66,9 +66,9 @@ enum { | ||||
| 	TEGRA_SPI6_BASE =		TEGRA_APB_MISC_BASE + 0xDE00, | ||||
| 	TEGRA_DVC_BASE =		TEGRA_APB_MISC_BASE + 0xD000, | ||||
| 	TEGRA_PMC_BASE =		TEGRA_APB_MISC_BASE + 0xE400, | ||||
| 	TEGRA_EMC_BASE =		TEGRA_APB_MISC_BASE + 0xF400, | ||||
| 	TEGRA_FUSE_BASE =		TEGRA_APB_MISC_BASE + 0xF800, | ||||
| 	TEGRA_MC_BASE =			0x70019000, | ||||
| 	TEGRA_EMC_BASE =		0x7001B000, | ||||
| 	TEGRA_CSITE_BASE =		0x70040000, | ||||
| 	TEGRA_SYSCTR0_BASE =		0x700F0000, | ||||
| 	TEGRA_USBD_BASE =		0x7D000000, | ||||
|   | ||||
| @@ -247,6 +247,9 @@ enum clock_source {  /* Careful: Not true for all sources, always check TRM! */ | ||||
| int clock_get_osc_khz(void); | ||||
| void clock_early_uart(void); | ||||
| void clock_external_output(int clk_id); | ||||
| void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90, | ||||
| 		 u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source, | ||||
| 		 u32 same_freq); | ||||
| void clock_cpu0_config_and_reset(void * entry); | ||||
| void clock_halt_avp(void); | ||||
| void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x); | ||||
|   | ||||
| @@ -44,6 +44,9 @@ | ||||
|  | ||||
| /* ardisplay_a.h */ | ||||
| #define DC_WIN_A_WIN_OPTIONS_0			0x700 | ||||
| #define DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_SHIFT	30 | ||||
| #define DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_FIELD	(0x1 << DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_SHIFT) | ||||
| #define DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_ENABLE	(1) | ||||
| #define DC_WIN_A_BYTE_SWAP_0			0x701 | ||||
| #define DC_WIN_A_BUFFER_CONTROL_0		0x702 | ||||
| #define DC_WIN_A_COLOR_DEPTH_0			0x703 | ||||
| @@ -59,6 +62,7 @@ | ||||
| #define DC_WIN_A_BLEND_MATCH_SELECT_0		0x717 | ||||
| #define DC_WIN_A_BLEND_NOMATCH_SELECT_0		0x718 | ||||
| #define DC_WIN_A_BLEND_ALPHA_1BIT_0		0x719 | ||||
| #define DC_WINBUF_A_START_ADDR_LO_0		0x800 | ||||
| #define DC_WINBUF_A_START_ADDR_HI_0		0x80d | ||||
| #define DC_WINBUF_A_ADDR_H_OFFSET_0		0x806 | ||||
| #define DC_WINBUF_A_ADDR_V_OFFSET_0		0x808 | ||||
| @@ -177,9 +181,18 @@ | ||||
| /* ardpaux.h */ | ||||
| #define DPAUX_DP_AUXDATA_READ_W0				0x19 | ||||
|  | ||||
| #define DP_LVDS_SHIFT	25 | ||||
| #define DP_LVDS		(1 << DP_LVDS_SHIFT) | ||||
|  | ||||
| #define SRC_BPP		16 | ||||
| #define COLORDEPTH	0x6 | ||||
| #define COLOR_WHITE	0xFFFFFF | ||||
|  | ||||
| void setup_display(struct soc_nvidia_tegra124_config *config); | ||||
| void init_dca_regs(void); | ||||
| void init_dpaux_regs(void); | ||||
| void init_sor_regs(void); | ||||
| void dp_io_powerup(void); | ||||
| u32 dp_setup_timing(u32 width, u32 height); | ||||
| void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr, | ||||
| 		     u32 lane_count, u32 enhanced_framing, u32 panel_edp, | ||||
| 		     u32 pclkfreq, u32 linkfreq); | ||||
| #endif /* __SOC_NVIDIA_TEGRA124_INCLUDE_SOC_DISPLAY_H__ */ | ||||
|   | ||||
							
								
								
									
										58
									
								
								src/soc/nvidia/tegra124/lp0/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/soc/nvidia/tegra124/lp0/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| ################################################################################ | ||||
| ## | ||||
| ## Copyright 2014 Google Inc. | ||||
| ## | ||||
| ## This program is free software; you can redistribute it and/or modify | ||||
| ## it under the terms of the GNU General Public License as published by | ||||
| ## the Free Software Foundation; version 2 of the License. | ||||
| ## | ||||
| ## This program is distributed in the hope that it will be useful, | ||||
| ## but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| ## GNU General Public License for more details. | ||||
| ## | ||||
| ## You should have received a copy of the GNU General Public License | ||||
| ## along with this program; if not, write to the Free Software | ||||
| ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||||
| ## | ||||
| ################################################################################ | ||||
|  | ||||
| CC = $(GCC_PREFIX)gcc | ||||
| NM = $(GCC_PREFIX)nm | ||||
| OBJCOPY = $(GCC_PREFIX)objcopy | ||||
|  | ||||
| OPENSSL = openssl | ||||
| DD = dd | ||||
| CP = cp | ||||
| MV = mv | ||||
| RM = rm | ||||
|  | ||||
| SIGKEY = 00000000000000000000000000000000 | ||||
|  | ||||
| .PHONY: all | ||||
| all: tegra_lp0_resume.fw | ||||
|  | ||||
| tegra_lp0_resume.elf: tegra_lp0_resume.ld tegra_lp0_resume.c | ||||
| 	$(CC) -marm -march=armv4t -mno-unaligned-access -nostdlib -static \ | ||||
| 		-Os -fpie -Wl,--build-id=none -ggdb3 -T tegra_lp0_resume.ld \ | ||||
| 		-o $@ $(filter %.c,$+) | ||||
|  | ||||
| tegra_lp0_resume.fw: tegra_lp0_resume.elf | ||||
| 	@# Get rid of any files we're about to create. | ||||
| 	$(RM) -f $@.nosig $@.sig $@.tosig | ||||
| 	@# Convert the ELF image into a binary image. | ||||
| 	$(OBJCOPY) -O binary $< $@.nosig | ||||
| 	@# Extract the part of the binary which needs to be signed. | ||||
| 	$(DD) bs=1 skip=544 if=$@.nosig of=$@.tosig | ||||
| 	@# Calculate a signature for that part. | ||||
| 	$(OPENSSL) dgst -mac cmac -macopt cipher:aes-128-cbc \ | ||||
| 		-macopt hexkey:$(SIGKEY) -md5 -binary \ | ||||
| 		$@.tosig > $@.sig | ||||
| 	@# Inject the signature into the binary image's header. | ||||
| 	$(DD) conv=notrunc bs=1 seek=272 count=16 if=$@.sig of=$@.nosig | ||||
| 	@# Copy the signed binary to the target file name. | ||||
| 	$(MV) $@.nosig $@ | ||||
|  | ||||
| clean: | ||||
| 	$(RM) -f tegra_lp0_resume.fw tegra_lp0_resume.fw.sig | ||||
| 	$(RM) -f tegra_lp0_resume.fw.tosig tegra_lp0_resume.elf | ||||
							
								
								
									
										627
									
								
								src/soc/nvidia/tegra124/lp0/tegra_lp0_resume.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										627
									
								
								src/soc/nvidia/tegra124/lp0/tegra_lp0_resume.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,627 @@ | ||||
| /* | ||||
|  * Copyright 2014 Google Inc. | ||||
|  * Copyright 2013, NVIDIA CORPORATION.  All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms and conditions of the GNU General Public License, | ||||
|  * version 2, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope it will be useful, but WITHOUT | ||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|  * more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| /* Function unit addresses. */ | ||||
| enum { | ||||
| 	UP_TAG_BASE = 0X60000000, | ||||
| 	TIMER_BASE = 0X60005000, | ||||
| 	CLK_RST_BASE = 0X60006000, | ||||
| 	FLOW_CTLR_BASE = 0X60007000, | ||||
| 	TEGRA_EVP_BASE = 0x6000f000, | ||||
| 	PMC_CTLR_BASE = 0X7000e400, | ||||
| 	MC_CTLR_BASE = 0X70019000, | ||||
| 	SYSCTR_CTLR_BASE = 0X700f0000 | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* UP tag registers. */ | ||||
| static uint32_t *up_tag_ptr = (void *)(UP_TAG_BASE + 0x0); | ||||
| enum { | ||||
| 	UP_TAG_AVP = 0xaaaaaaaa | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Timer registers. */ | ||||
| static uint32_t *timer_us_ptr = (void *)(TIMER_BASE + 0x10); | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Clock and reset controller registers. */ | ||||
| static uint32_t *clk_rst_rst_devices_l_ptr = (void *)(CLK_RST_BASE + 0x4); | ||||
| enum { | ||||
| 	SWR_TRIG_SYS_RST = 0x1 << 2 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_cclk_burst_policy_ptr = (void *)(CLK_RST_BASE + 0x20); | ||||
| enum { | ||||
| 	CCLK_PLLP_BURST_POLICY = 0x20004444 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_super_cclk_div_ptr = (void *)(CLK_RST_BASE + 0x24); | ||||
| enum { | ||||
| 	SUPER_CDIV_ENB = 0x1 << 31 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_osc_ctrl_ptr = (void *)(CLK_RST_BASE + 0x50); | ||||
| enum { | ||||
| 	OSC_XOE = 0x1 << 0, | ||||
| 	OSC_XOFS_SHIFT = 4, | ||||
| 	OSC_XOFS_MASK = 0x3f << OSC_XOFS_SHIFT, | ||||
| 	OSC_FREQ_SHIFT = 28, | ||||
| 	OSC_FREQ_MASK = 0xf << OSC_FREQ_SHIFT | ||||
| }; | ||||
| enum { | ||||
| 	OSC_FREQ_13 = 0, | ||||
| 	OSC_FREQ_16P8 = 1, | ||||
| 	OSC_FREQ_19P2 = 4, | ||||
| 	OSC_FREQ_38P4 = 5, | ||||
| 	OSC_FREQ_12 = 8, | ||||
| 	OSC_FREQ_48 = 9, | ||||
| 	OSC_FREQ_26 = 12 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_pllu_base_ptr = (void *)(CLK_RST_BASE + 0xc0); | ||||
| enum { | ||||
| 	PLLU_DIVM_SHIFT = 0, | ||||
| 	PLLU_DIVN_SHIFT = 8, | ||||
| 	PLLU_OVERRIDE = 0x1 << 24, | ||||
| 	PLLU_ENABLE = 0x1 << 30, | ||||
| 	PLLU_BYPASS = 0x1 << 31 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_pllu_misc_ptr = (void *)(CLK_RST_BASE + 0xcc); | ||||
| enum { | ||||
| 	PLLU_LFCON_SHIFT = 4, | ||||
| 	PLLU_CPCON_SHIFT = 8, | ||||
| 	PLLU_LOCK_ENABLE = 22 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_pllx_base_ptr = (void *)(CLK_RST_BASE + 0xe0); | ||||
| enum { | ||||
| 	PLLX_ENABLE = 0x1 << 30 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_rst_dev_u_clr_ptr = (void *)(CLK_RST_BASE + 0x314); | ||||
| enum { | ||||
| 	SWR_CSITE_RST = 0x1 << 9 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_clk_enb_l_set_ptr = (void *)(CLK_RST_BASE + 0x320); | ||||
| enum { | ||||
| 	CLK_ENB_CPU = 0x1 << 0 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_clk_out_enb_u_set_ptr = | ||||
| 	(void *)(CLK_RST_BASE + 0x330); | ||||
| enum { | ||||
| 	CLK_ENB_CSITE = 0x1 << 9 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_cpu_softrst_ctrl2_ptr = | ||||
| 	(void *)(CLK_RST_BASE + 0x388); | ||||
| enum { | ||||
| 	CAR2PMC_CPU_ACK_WIDTH_SHIFT = 0, | ||||
| 	CAR2PMC_CPU_ACK_WIDTH_MASK = 0xfff << CAR2PMC_CPU_ACK_WIDTH_SHIFT | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_clk_src_mselect_ptr = | ||||
| 	(void *)(CLK_RST_BASE + 0x3b4); | ||||
| enum { | ||||
| 	MSELECT_CLK_DIV_SHIFT = 0, | ||||
| 	MSELECT_CLK_SRC_SHIFT = 29, | ||||
| 	MSELECT_CLK_SRC_PLLP_OUT0 = 0x0 << MSELECT_CLK_SRC_SHIFT, | ||||
| 	MSELECT_CLK_SRC_PLLC2_OUT0 = 0x1 << MSELECT_CLK_SRC_SHIFT, | ||||
| 	MSELECT_CLK_SRC_PLLC_OUT0 = 0x2 << MSELECT_CLK_SRC_SHIFT, | ||||
| 	MSELECT_CLK_SRC_PLLC3_OUT0 = 0x3 << MSELECT_CLK_SRC_SHIFT | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_rst_dev_v_clr_ptr = (void *)(CLK_RST_BASE + 0x434); | ||||
| enum { | ||||
| 	SWR_MSELECT_RST = 0x1 << 3 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_clk_enb_v_set_ptr = (void *)(CLK_RST_BASE + 0x440); | ||||
| enum { | ||||
| 	CLK_ENB_CPUG = 0x1 << 0, | ||||
| 	CLK_ENB_CPULP = 0x1 << 1, | ||||
| 	CLK_ENB_MSELECT = 0x1 << 3 | ||||
| }; | ||||
|  | ||||
| static uint32_t *clk_rst_rst_cpulp_cmplx_clr_ptr = | ||||
| 	(void *)(CLK_RST_BASE + 0x45c); | ||||
| static uint32_t *clk_rst_rst_cpug_cmplx_clr_ptr = | ||||
| 	(void *)(CLK_RST_BASE + 0x454); | ||||
| enum { | ||||
| 	CLR_CPURESET0 = 0x1 << 0, | ||||
| 	CLR_CPURESET1 = 0x1 << 1, | ||||
| 	CLR_CPURESET2 = 0x1 << 2, | ||||
| 	CLR_CPURESET3 = 0x1 << 3, | ||||
| 	CLR_DBGRESET0 = 0x1 << 12, | ||||
| 	CLR_DBGRESET1 = 0x1 << 13, | ||||
| 	CLR_DBGRESET2 = 0x1 << 14, | ||||
| 	CLR_DBGRESET3 = 0x1 << 15, | ||||
| 	CLR_CORERESET0 = 0x1 << 16, | ||||
| 	CLR_CORERESET1 = 0x1 << 17, | ||||
| 	CLR_CORERESET2 = 0x1 << 18, | ||||
| 	CLR_CORERESET3 = 0x1 << 19, | ||||
| 	CLR_CXRESET0 = 0x1 << 20, | ||||
| 	CLR_CXRESET1 = 0x1 << 21, | ||||
| 	CLR_CXRESET2 = 0x1 << 22, | ||||
| 	CLR_CXRESET3 = 0x1 << 23, | ||||
| 	CLR_NONCPURESET = 0x1 << 29 | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Reset vector. */ | ||||
|  | ||||
| static uint32_t *evp_cpu_reset_ptr = (void *)(TEGRA_EVP_BASE + 0x100); | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Flow controller registers. */ | ||||
| static uint32_t *flow_ctlr_halt_cop_events_ptr = | ||||
| 	(void *)(FLOW_CTLR_BASE + 0x4); | ||||
| enum { | ||||
| 	EVENT_MSEC = 0x1 << 24, | ||||
| 	EVENT_JTAG = 0x1 << 28, | ||||
| 	FLOW_MODE_SHIFT = 29, | ||||
| 	FLOW_MODE_STOP = 2 << FLOW_MODE_SHIFT, | ||||
| }; | ||||
|  | ||||
| static uint32_t *flow_ctlr_cluster_control_ptr = | ||||
| 	(void *)(FLOW_CTLR_BASE + 0x2c); | ||||
| enum { | ||||
| 	FLOW_CLUSTER_ACTIVE_LP = 0x1 << 0 | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Power management controller registers. */ | ||||
| enum { | ||||
| 	PARTID_CRAIL = 0, | ||||
| 	PARTID_CELP = 12, | ||||
| 	PARTID_CE0 = 14, | ||||
| 	PARTID_C0NC = 15, | ||||
| 	PARTID_C1NC = 16 | ||||
| }; | ||||
|  | ||||
| static uint32_t *pmc_ctlr_clamp_status_ptr = (void *)(PMC_CTLR_BASE + 0x2c); | ||||
|  | ||||
| static uint32_t *pmc_ctlr_pwrgate_toggle_ptr = (void *)(PMC_CTLR_BASE + 0x30); | ||||
| enum { | ||||
| 	PWRGATE_TOGGLE_START = 0x1 << 8 | ||||
| }; | ||||
|  | ||||
| static uint32_t *pmc_ctlr_pwrgate_status_ptr = (void *)(PMC_CTLR_BASE + 0x38); | ||||
|  | ||||
| static uint32_t *pmc_ctlr_scratch4_ptr = (void *)(PMC_CTLR_BASE + 0x60); | ||||
| enum { | ||||
| 	PMC_SCRATCH4_LP = 0x1 << 31 | ||||
| }; | ||||
|  | ||||
| static uint32_t *pmc_ctlr_cpupwrgood_timer_ptr = | ||||
| 	(void *)(PMC_CTLR_BASE + 0xc8); | ||||
|  | ||||
| static uint32_t *pmc_ctlr_scratch41_ptr = (void *)(PMC_CTLR_BASE + 0x140); | ||||
|  | ||||
| static uint32_t *pmc_ctlr_osc_edpd_over_ptr = (void *)(PMC_CTLR_BASE + 0x1a4); | ||||
| enum { | ||||
| 	PMC_XOFS_SHIFT = 1, | ||||
| 	PMC_XOFS_MASK = 0x3f << PMC_XOFS_SHIFT | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Memory controller registers. */ | ||||
| static uint32_t *mc_video_protect_size_mb_ptr = (void *)(MC_CTLR_BASE + 0x64c); | ||||
|  | ||||
| static uint32_t *mc_video_protect_reg_ctrl_ptr = | ||||
| 	(void *)(MC_CTLR_BASE + 0x650); | ||||
| enum { | ||||
| 	VIDEO_PROTECT_WRITE_ACCESS_DISABLE = 0x1 << 0, | ||||
| 	VIDEO_PROTECT_ALLOW_TZ_WRITE_ACCESS = 0x1 << 1 | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* System counter registers. */ | ||||
| static uint32_t *sysctr_cntcr_ptr = (void *)(SYSCTR_CTLR_BASE + 0x0); | ||||
| enum { | ||||
| 	TSC_CNTCR_ENABLE = 0x1 << 0, | ||||
| 	TSC_CNTCR_HDBG = 0x1 << 1 | ||||
| }; | ||||
|  | ||||
| static uint32_t *sysctr_cntfid0_ptr = (void *)(SYSCTR_CTLR_BASE + 0x20); | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Utility functions. */ | ||||
|  | ||||
| static inline void __attribute__((always_inline)) | ||||
| 		   __attribute__((noreturn)) halt(void) | ||||
| { | ||||
| 	for (;;); | ||||
| } | ||||
|  | ||||
| inline static uint32_t read32(const void *addr) | ||||
| { | ||||
| 	return *(volatile uint32_t *)addr; | ||||
| } | ||||
|  | ||||
| inline static void write32(uint32_t val, void *addr) | ||||
| { | ||||
| 	*(volatile uint32_t *)addr = val; | ||||
| } | ||||
|  | ||||
| inline static void setbits32(uint32_t bits, void *addr) | ||||
| { | ||||
| 	write32(read32(addr) | bits, addr); | ||||
| } | ||||
|  | ||||
| inline static void clrbits32(uint32_t bits, void *addr) | ||||
| { | ||||
| 	write32(read32(addr) & ~bits, addr); | ||||
| } | ||||
|  | ||||
| static void __attribute__((noreturn)) reset(void) | ||||
| { | ||||
| 	write32(SWR_TRIG_SYS_RST, clk_rst_rst_devices_l_ptr); | ||||
| 	halt(); | ||||
| } | ||||
|  | ||||
| static void udelay(unsigned usecs) | ||||
| { | ||||
| 	uint32_t start = read32(timer_us_ptr); | ||||
| 	while (read32(timer_us_ptr) - start < usecs) | ||||
| 		; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Accessors. */ | ||||
|  | ||||
| static int wakeup_on_lp(void) | ||||
| { | ||||
| 	return !!(read32(pmc_ctlr_scratch4_ptr) & PMC_SCRATCH4_LP); | ||||
| } | ||||
|  | ||||
| static uint32_t get_wakeup_vector(void) | ||||
| { | ||||
| 	return read32(pmc_ctlr_scratch41_ptr); | ||||
| } | ||||
|  | ||||
| static unsigned get_osc_freq(void) | ||||
| { | ||||
| 	return (read32(clk_rst_osc_ctrl_ptr) & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Clock configuration. */ | ||||
|  | ||||
| static void config_oscillator(void) | ||||
| { | ||||
| 	// Read oscillator drive strength from OSC_EDPD_OVER.XOFS and copy | ||||
| 	// to OSC_CTRL.XOFS and set XOE. | ||||
| 	uint32_t xofs = (read32(pmc_ctlr_osc_edpd_over_ptr) & | ||||
| 		    PMC_XOFS_MASK) >> PMC_XOFS_SHIFT; | ||||
|  | ||||
| 	uint32_t osc_ctrl = read32(clk_rst_osc_ctrl_ptr); | ||||
| 	osc_ctrl &= OSC_XOFS_MASK; | ||||
| 	osc_ctrl |= (xofs << OSC_XOFS_SHIFT); | ||||
| 	osc_ctrl |= OSC_XOE; | ||||
| 	write32(osc_ctrl, clk_rst_osc_ctrl_ptr); | ||||
| } | ||||
|  | ||||
| static void config_pllu(void) | ||||
| { | ||||
| 	// Figure out what parameters to use for PLLU. | ||||
| 	uint32_t divm, divn, cpcon, lfcon; | ||||
| 	switch (get_osc_freq()) { | ||||
| 	case OSC_FREQ_12: | ||||
| 	case OSC_FREQ_48: | ||||
| 		divm = 0x0c; | ||||
| 		divn = 0x3c0; | ||||
| 		cpcon = 0x0c; | ||||
| 		lfcon = 0x02; | ||||
| 		break; | ||||
| 	case OSC_FREQ_16P8: | ||||
| 		divm = 0x07; | ||||
| 		divn = 0x190; | ||||
| 		cpcon = 0x05; | ||||
| 		lfcon = 0x02; | ||||
| 		break; | ||||
| 	case OSC_FREQ_19P2: | ||||
| 	case OSC_FREQ_38P4: | ||||
| 		divm = 0x04; | ||||
| 		divn = 0xc8; | ||||
| 		cpcon = 0x03; | ||||
| 		lfcon = 0x02; | ||||
| 		break; | ||||
| 	case OSC_FREQ_26: | ||||
| 		divm = 0x1a; | ||||
| 		divn = 0x3c0; | ||||
| 		cpcon = 0x0c; | ||||
| 		lfcon = 0x02; | ||||
| 		break; | ||||
| 	default: | ||||
| 		// Map anything that's not recognized to 13MHz. | ||||
| 		divm = 0x0d; | ||||
| 		divn = 0x3c0; | ||||
| 		cpcon = 0x0c; | ||||
| 		lfcon = 0x02; | ||||
| 	} | ||||
|  | ||||
| 	// Configure PLLU. | ||||
| 	uint32_t base = PLLU_BYPASS | PLLU_OVERRIDE | | ||||
| 			(divn << PLLU_DIVN_SHIFT) | (divm << PLLU_DIVM_SHIFT); | ||||
| 	write32(base, clk_rst_pllu_base_ptr); | ||||
| 	uint32_t misc = (cpcon << PLLU_CPCON_SHIFT) | | ||||
| 			(lfcon << PLLU_LFCON_SHIFT); | ||||
| 	write32(misc, clk_rst_pllu_misc_ptr); | ||||
|  | ||||
| 	// Enable PLLU. | ||||
| 	base &= ~PLLU_BYPASS; | ||||
| 	base |= PLLU_ENABLE; | ||||
| 	write32(base, clk_rst_pllu_base_ptr); | ||||
| 	misc |= PLLU_LOCK_ENABLE; | ||||
| 	write32(misc, clk_rst_pllu_misc_ptr); | ||||
| } | ||||
|  | ||||
| static void config_tsc(void) | ||||
| { | ||||
| 	// Tell the TSC the oscillator frequency. | ||||
| 	switch (get_osc_freq()) { | ||||
| 	case OSC_FREQ_12: | ||||
| 		write32(12000000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	case OSC_FREQ_48: | ||||
| 		write32(48000000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	case OSC_FREQ_16P8: | ||||
| 		write32(16800000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	case OSC_FREQ_19P2: | ||||
| 		write32(19200000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	case OSC_FREQ_38P4: | ||||
| 		write32(38400000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	case OSC_FREQ_26: | ||||
| 		write32(26000000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	default: | ||||
| 		// Default to 13MHz. | ||||
| 		write32(13000000, sysctr_cntfid0_ptr); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	// Enable the TSC. | ||||
| 	setbits32(TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG, sysctr_cntcr_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Function unit configuration. */ | ||||
|  | ||||
| static void config_core_sight(void) | ||||
| { | ||||
| 	// Enable the CoreSight clock. | ||||
| 	write32(CLK_ENB_CSITE, clk_rst_clk_out_enb_u_set_ptr); | ||||
|  | ||||
| 	/* | ||||
| 	 * De-assert CoreSight reset. | ||||
| 	 * NOTE: We're leaving the CoreSight clock on the oscillator for | ||||
| 	 *       now. It will be restored to its original clock source | ||||
| 	 *       when the CPU-side restoration code runs. | ||||
| 	 */ | ||||
| 	write32(SWR_CSITE_RST, clk_rst_rst_dev_u_clr_ptr); | ||||
| } | ||||
|  | ||||
| static void config_mselect(void) | ||||
| { | ||||
| 	// Set MSELECT clock source to PLLP with 1:4 divider. | ||||
| 	write32((6 << MSELECT_CLK_DIV_SHIFT) | MSELECT_CLK_SRC_PLLP_OUT0, | ||||
| 		clk_rst_clk_src_mselect_ptr); | ||||
|  | ||||
| 	// Enable clock to MSELECT. | ||||
| 	write32(CLK_ENB_MSELECT, clk_rst_clk_enb_v_set_ptr); | ||||
|  | ||||
| 	udelay(2); | ||||
|  | ||||
| 	// Bring MSELECT out of reset. | ||||
| 	write32(SWR_MSELECT_RST, clk_rst_rst_dev_v_clr_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Resets. */ | ||||
|  | ||||
| static void clear_cpu_resets(void) | ||||
| { | ||||
| 	// Take the non-cpu of the G and LP clusters out of reset. | ||||
| 	write32(CLR_NONCPURESET, clk_rst_rst_cpulp_cmplx_clr_ptr); | ||||
| 	write32(CLR_NONCPURESET, clk_rst_rst_cpug_cmplx_clr_ptr); | ||||
|  | ||||
| 	// Clear software controlled reset of the slow cluster. | ||||
| 	write32(CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0, | ||||
| 		clk_rst_rst_cpulp_cmplx_clr_ptr); | ||||
|  | ||||
| 	// Clear software controlled reset of the fast cluster. | ||||
| 	write32(CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | | ||||
| 		CLR_CPURESET1 | CLR_DBGRESET1 | CLR_CORERESET1 | CLR_CXRESET1 | | ||||
| 		CLR_CPURESET2 | CLR_DBGRESET2 | CLR_CORERESET2 | CLR_CXRESET2 | | ||||
| 		CLR_CPURESET3 | CLR_DBGRESET3 | CLR_CORERESET3 | CLR_CXRESET3, | ||||
| 		clk_rst_rst_cpug_cmplx_clr_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Power. */ | ||||
|  | ||||
| static void power_on_partition(unsigned id) | ||||
| { | ||||
| 	uint32_t bit = 0x1 << id; | ||||
| 	if (!(read32(pmc_ctlr_pwrgate_status_ptr) & bit)) { | ||||
| 		// Partition is not on. Turn it on. | ||||
| 		write32(id | PWRGATE_TOGGLE_START, pmc_ctlr_pwrgate_toggle_ptr); | ||||
|  | ||||
| 		// Wait until the partition is powerd on. | ||||
| 		while (!(read32(pmc_ctlr_pwrgate_status_ptr) & bit)) | ||||
| 			; | ||||
|  | ||||
| 		// Wait until clamp is off. | ||||
| 		while (read32(pmc_ctlr_clamp_status_ptr) & bit) | ||||
| 			; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void power_on_main_cpu(void) | ||||
| { | ||||
| 	/* | ||||
| 	 * Reprogram PMC_CPUPWRGOOD_TIMER register: | ||||
| 	 * | ||||
| 	 * XXX This is a fragile assumption. XXX | ||||
| 	 * The kernel prepares PMC_CPUPWRGOOD_TIMER based on a 32768Hz clock. | ||||
| 	 * Note that PMC_CPUPWRGOOD_TIMER is running at pclk. | ||||
| 	 * | ||||
| 	 * We need to reprogram PMC_CPUPWRGOOD_TIMER based on the current pclk | ||||
| 	 * which is at 408Mhz (pclk = sclk = pllp_out0) after reset. Multiply | ||||
| 	 * PMC_CPUPWRGOOD_TIMER by 408M / 32K. | ||||
| 	 * | ||||
| 	 * Save the original PMC_CPUPWRGOOD_TIMER register which we need to | ||||
| 	 * restore after the CPU is powered up. | ||||
| 	 */ | ||||
| 	uint32_t orig_timer = read32(pmc_ctlr_cpupwrgood_timer_ptr); | ||||
|  | ||||
| 	write32(orig_timer * (408000000 / 32768), | ||||
| 		pmc_ctlr_cpupwrgood_timer_ptr); | ||||
|  | ||||
| 	if (wakeup_on_lp()) { | ||||
| 		power_on_partition(PARTID_C1NC); | ||||
| 		power_on_partition(PARTID_CELP); | ||||
| 	} else { | ||||
| 		power_on_partition(PARTID_CRAIL); | ||||
| 		power_on_partition(PARTID_C0NC); | ||||
| 		power_on_partition(PARTID_CE0); | ||||
| 	} | ||||
|  | ||||
| 	// Give I/O signals time to stablize. | ||||
| 	write32(20 | EVENT_MSEC | FLOW_MODE_STOP, | ||||
| 		flow_ctlr_halt_cop_events_ptr); | ||||
|  | ||||
| 	// Restore the original PMC_CPUPWRGOOD_TIMER. | ||||
| 	write32(orig_timer, pmc_ctlr_cpupwrgood_timer_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Entry point. */ | ||||
|  | ||||
| void lp0_resume(void) | ||||
| { | ||||
| 	// If not on the AVP, reset. | ||||
| 	if (read32(up_tag_ptr) != UP_TAG_AVP) | ||||
| 		reset(); | ||||
|  | ||||
| 	config_oscillator(); | ||||
|  | ||||
| 	// Tell the flow controller which cluster to wake up. The default is | ||||
| 	// the fast cluster. | ||||
| 	if (wakeup_on_lp()) | ||||
| 		setbits32(FLOW_CLUSTER_ACTIVE_LP, | ||||
| 			  flow_ctlr_cluster_control_ptr); | ||||
|  | ||||
| 	// Program SUPER_CCLK_DIVIDER. | ||||
| 	write32(SUPER_CDIV_ENB, clk_rst_super_cclk_div_ptr); | ||||
|  | ||||
| 	config_core_sight(); | ||||
|  | ||||
| 	config_pllu(); | ||||
|  | ||||
| 	// Set the CPU reset vector. | ||||
| 	write32(get_wakeup_vector(), evp_cpu_reset_ptr); | ||||
|  | ||||
| 	// Select CPU complex clock source. | ||||
| 	write32(CCLK_PLLP_BURST_POLICY, clk_rst_cclk_burst_policy_ptr); | ||||
|  | ||||
| 	config_mselect(); | ||||
|  | ||||
| 	// Disable PLLX since it isn't used as CPU clock source. | ||||
| 	clrbits32(PLLX_ENABLE, clk_rst_pllx_base_ptr); | ||||
|  | ||||
| 	// Set CAR2PMC_CPU_ACK_WIDTH to 408. | ||||
| 	uint32_t ack_width = read32(clk_rst_cpu_softrst_ctrl2_ptr); | ||||
| 	ack_width &= ~CAR2PMC_CPU_ACK_WIDTH_MASK; | ||||
| 	ack_width |= 408 << CAR2PMC_CPU_ACK_WIDTH_SHIFT; | ||||
| 	write32(ack_width, clk_rst_cpu_softrst_ctrl2_ptr); | ||||
|  | ||||
| 	// Enable the CPU complex clock. | ||||
| 	write32(CLK_ENB_CPU, clk_rst_clk_enb_l_set_ptr); | ||||
| 	write32(CLK_ENB_CPUG | CLK_ENB_CPULP, clk_rst_clk_enb_v_set_ptr); | ||||
|  | ||||
| 	clear_cpu_resets(); | ||||
|  | ||||
| 	config_tsc(); | ||||
|  | ||||
| 	power_on_main_cpu(); | ||||
|  | ||||
| 	// Disable VPR. | ||||
| 	write32(0, mc_video_protect_size_mb_ptr); | ||||
| 	write32(VIDEO_PROTECT_WRITE_ACCESS_DISABLE, | ||||
| 		mc_video_protect_reg_ctrl_ptr); | ||||
|  | ||||
| 	// Halt the AVP. | ||||
| 	while (1) | ||||
| 		write32(FLOW_MODE_STOP | EVENT_JTAG, | ||||
| 			flow_ctlr_halt_cop_events_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Header. */ | ||||
|  | ||||
| extern uint8_t blob_data; | ||||
| extern uint8_t blob_data_size; | ||||
| extern uint8_t blob_total_size; | ||||
|  | ||||
| struct lp0_header { | ||||
| 	uint32_t length_insecure;	// Insecure total length. | ||||
| 	uint32_t reserved[3]; | ||||
| 	uint8_t rsa_modulus[256];	// RSA key modulus. | ||||
| 	uint8_t aes_signature[16];	// AES signature. | ||||
| 	uint8_t rsa_signature[256];	// RSA-PSS signature. | ||||
| 	uint8_t random_aes_block[16];	// Random data, may be zero. | ||||
| 	uint32_t length_secure;		// Secure total length. | ||||
| 	uint32_t destination;		// Where to load the blob in iRAM. | ||||
| 	uint32_t entry_point;		// Entry point for the blob. | ||||
| 	uint32_t code_length;		// Length of just the data. | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| struct lp0_header header __attribute__((section(".header"))) = | ||||
| { | ||||
| 	.length_insecure = (uintptr_t)&blob_total_size, | ||||
| 	.length_secure = (uintptr_t)&blob_total_size, | ||||
| 	.destination = (uintptr_t)&blob_data, | ||||
| 	.entry_point = (uintptr_t)&lp0_resume, | ||||
| 	.code_length = (uintptr_t)&blob_data_size | ||||
| }; | ||||
							
								
								
									
										73
									
								
								src/soc/nvidia/tegra124/lp0/tegra_lp0_resume.ld
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/soc/nvidia/tegra124/lp0/tegra_lp0_resume.ld
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* | ||||
|  * Copyright 2014 Google Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; version 2 of the License. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| /* We use ELF as output format. So that we can debug the code in some form. */ | ||||
| OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") | ||||
| OUTPUT_ARCH(arm) | ||||
|  | ||||
| PHDRS | ||||
| { | ||||
| 	to_load PT_LOAD; | ||||
| } | ||||
|  | ||||
| ENTRY(lp0_resume) | ||||
| SECTIONS | ||||
| { | ||||
| 	. = 0x40020000 - 0x240; | ||||
|  | ||||
| 	/* | ||||
| 	 * The lp0 blob header is built as a static data structure and put | ||||
| 	 * in the .header section. | ||||
| 	 */ | ||||
| 	.header_start = .; | ||||
| 	.header . : { | ||||
| 		*(.header); | ||||
| 	} : to_load = 0xff | ||||
| 	.header_end = .; | ||||
|  | ||||
| 	. = 0x40020000; | ||||
|  | ||||
| 	/* The actual lp0 blob code. */ | ||||
| 	.data_start = .; | ||||
| 	.data . : { | ||||
| 		*(.text); | ||||
| 		*(.text.*); | ||||
| 		*(.rodata); | ||||
| 		*(.rodata.*); | ||||
| 		*(.data); | ||||
| 		*(.data.*); | ||||
| 		*(.bss); | ||||
| 		*(.bss.*); | ||||
| 		*(.sbss); | ||||
| 		*(.sbss.*); | ||||
| 		. = ALIGN(16); | ||||
| 	} | ||||
| 	.data_end = .; | ||||
|  | ||||
| 	/* Some values we need in the header. */ | ||||
| 	blob_data = .data_start; | ||||
| 	blob_data_size = .data_end - .data_start; | ||||
| 	blob_total_size = .data_end - .header_start; | ||||
|  | ||||
| 	/DISCARD/ : { | ||||
| 		*(.comment) | ||||
| 		*(.note) | ||||
| 		*(.comment.*) | ||||
| 		*(.note.*) | ||||
| 		*(.ARM.*) | ||||
| 	} | ||||
| } | ||||
| @@ -1,5 +1,6 @@ | ||||
| /* | ||||
|  * Copyright (c) 2010 - 2013, NVIDIA CORPORATION.  All rights reserved. | ||||
|  * Copyright (C) 2013 Google Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms and conditions of the GNU General Public License, | ||||
| @@ -14,34 +15,114 @@ | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef _TEGRA124_MC_H_ | ||||
| #define _TEGRA124_MC_H_ | ||||
| #ifndef __SOC_NVIDIA_TEGRA124_MC_H__ | ||||
| #define __SOC_NVIDIA_TEGRA124_MC_H__ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| // Memory Controller registers we need/care about | ||||
|  | ||||
| struct tegra_mc_regs { | ||||
| 	u32 reserved0[4]; | ||||
| 	u32 mc_smmu_config; | ||||
| 	u32 mc_smmu_tlb_config; | ||||
| 	u32 mc_smmu_ptc_config; | ||||
| 	u32 mc_smmu_ptb_asid; | ||||
| 	u32 mc_smmu_ptb_data; | ||||
| 	u32 reserved1[3]; | ||||
| 	u32 mc_smmu_tlb_flush; | ||||
| 	u32 mc_smmu_ptc_flush; | ||||
| 	u32 reserved2[6]; | ||||
| 	u32 mc_emem_cfg; | ||||
| 	u32 mc_emem_adr_cfg; | ||||
| 	u32 mc_emem_adr_cfg_dev0; | ||||
| 	u32 mc_emem_adr_cfg_dev1; | ||||
| 	u32 reserved3[12]; | ||||
| 	u32 mc_emem_arb_reserved[28]; | ||||
| 	u32 reserved4[338]; | ||||
| 	u32 mc_vpr_bom; | ||||
| 	u32 mc_vpr_size; | ||||
| 	u32 mc_vpr_ctrl; | ||||
| 	uint32_t rsvd_0x0[4];			/* 0x00 */ | ||||
| 	uint32_t smmu_config;			/* 0x10 */ | ||||
| 	uint32_t smmu_tlb_config;		/* 0x14 */ | ||||
| 	uint32_t smmu_ptc_config;		/* 0x18 */ | ||||
| 	uint32_t smmu_ptb_asid;			/* 0x1c */ | ||||
| 	uint32_t smmu_ptb_data;			/* 0x20 */ | ||||
| 	uint32_t rsvd_0x24[3];			/* 0x24 */ | ||||
| 	uint32_t smmu_tlb_flush;		/* 0x30 */ | ||||
| 	uint32_t smmu_ptc_flush;		/* 0x34 */ | ||||
| 	uint32_t rsvd_0x38[6];			/* 0x38 */ | ||||
| 	uint32_t emem_cfg;			/* 0x50 */ | ||||
| 	uint32_t emem_adr_cfg;			/* 0x54 */ | ||||
| 	uint32_t emem_adr_cfg_dev0;		/* 0x58 */ | ||||
| 	uint32_t emem_adr_cfg_dev1;		/* 0x5c */ | ||||
| 	uint32_t rsvd_0x60[1];			/* 0x60 */ | ||||
| 	uint32_t emem_adr_cfg_bank_mask_0;	/* 0x64 */ | ||||
| 	uint32_t emem_adr_cfg_bank_mask_1;	/* 0x68 */ | ||||
| 	uint32_t emem_adr_cfg_bank_mask_2;	/* 0x6c */ | ||||
| 	uint32_t rsvd_0x70[8];			/* 0x70 */ | ||||
| 	uint32_t emem_arb_cfg;			/* 0x90 */ | ||||
| 	uint32_t emem_arb_outstanding_req;	/* 0x94 */ | ||||
| 	uint32_t emem_arb_timing_rcd;		/* 0x98 */ | ||||
| 	uint32_t emem_arb_timing_rp;		/* 0x9c */ | ||||
| 	uint32_t emem_arb_timing_rc;		/* 0xa0 */ | ||||
| 	uint32_t emem_arb_timing_ras;		/* 0xa4 */ | ||||
| 	uint32_t emem_arb_timing_faw;		/* 0xa8 */ | ||||
| 	uint32_t emem_arb_timing_rrd;		/* 0xac */ | ||||
| 	uint32_t emem_arb_timing_rap2pre;	/* 0xb0 */ | ||||
| 	uint32_t emem_arb_timing_wap2pre;	/* 0xb4 */ | ||||
| 	uint32_t emem_arb_timing_r2r;		/* 0xb8 */ | ||||
| 	uint32_t emem_arb_timing_w2w;		/* 0xbc */ | ||||
| 	uint32_t emem_arb_timing_r2w;		/* 0xc0 */ | ||||
| 	uint32_t emem_arb_timing_w2r;		/* 0xc4 */ | ||||
| 	uint32_t rsvd_0xc8[2];			/* 0xc8 */ | ||||
| 	uint32_t emem_arb_da_turns;		/* 0xd0 */ | ||||
| 	uint32_t emem_arb_da_covers;		/* 0xd4 */ | ||||
| 	uint32_t emem_arb_misc0;		/* 0xd8 */ | ||||
| 	uint32_t emem_arb_misc1;		/* 0xdc */ | ||||
| 	uint32_t emem_arb_ring1_throttle;	/* 0xe0 */ | ||||
| 	uint32_t emem_arb_ring3_throttle;	/* 0xe4 */ | ||||
| 	uint32_t emem_arb_override;		/* 0xe8 */ | ||||
| 	uint32_t emem_arb_rsv;			/* 0xec */ | ||||
| 	uint32_t rsvd_0xf0[1];			/* 0xf0 */ | ||||
| 	uint32_t clken_override;		/* 0xf4 */ | ||||
| 	uint32_t timing_control_dbg;		/* 0xf8 */ | ||||
| 	uint32_t timing_control;		/* 0xfc */ | ||||
| 	uint32_t stat_control;			/* 0x100 */ | ||||
| 	uint32_t rsvd_0x104[65];		/* 0x104 */ | ||||
| 	uint32_t emem_arb_isochronous_0;	/* 0x208 */ | ||||
| 	uint32_t emem_arb_isochronous_1;	/* 0x20c */ | ||||
| 	uint32_t emem_arb_isochronous_2;	/* 0x210 */ | ||||
| 	uint32_t rsvd_0x214[38];		/* 0x214 */ | ||||
| 	uint32_t dis_extra_snap_levels;		/* 0x2ac */ | ||||
| 	uint32_t rsvd_0x2b0[90];		/* 0x2b0 */ | ||||
| 	uint32_t video_protect_vpr_override;	/* 0x418 */ | ||||
| 	uint32_t rsvd_0x41c[93];		/* 0x41c */ | ||||
| 	uint32_t video_protect_vpr_override1;	/* 0x590 */ | ||||
| 	uint32_t rsvd_0x594[29];		/* 0x594 */ | ||||
| 	uint32_t display_snap_ring;		/* 0x608 */ | ||||
| 	uint32_t rsvd_0x60c[15];		/* 0x60c */ | ||||
| 	uint32_t video_protect_bom;		/* 0x648 */ | ||||
| 	uint32_t video_protect_size_mb;		/* 0x64c */ | ||||
| 	uint32_t video_protect_reg_ctrl;	/* 0x650 */ | ||||
| 	uint32_t rsvd_0x654[4];			/* 0x654 */ | ||||
| 	uint32_t emem_cfg_access_ctrl;		/* 0x664 */ | ||||
| 	uint32_t rsvd_0x668[2];			/* 0x668 */ | ||||
| 	uint32_t sec_carveout_bom;		/* 0x670 */ | ||||
| 	uint32_t sec_carveout_size_mb;		/* 0x674 */ | ||||
| 	uint32_t sec_carveout_reg_ctrl;		/* 0x678 */ | ||||
| 	uint32_t rsvd_0x67c[187];		/* 0x67c */ | ||||
| 	uint32_t emem_arb_override_1;		/* 0x968 */ | ||||
| 	uint32_t rsvd_0x96c[3];			/* 0x96c */ | ||||
| 	uint32_t video_protect_bom_adr_hi;	/* 0x978 */ | ||||
| 	uint32_t rsvd_0x97c[2];			/* 0x97c */ | ||||
| 	uint32_t video_protect_gpu_override_0;	/* 0x984 */ | ||||
| 	uint32_t video_protect_gpu_override_1;	/* 0x988 */ | ||||
| 	uint32_t rsvd_0x98c[5];			/* 0x98c */ | ||||
| 	uint32_t mts_carveout_bom;		/* 0x9a0 */ | ||||
| 	uint32_t mts_carveout_size_mb;		/* 0x9a4 */ | ||||
| 	uint32_t mts_carveout_adr_hi;		/* 0x9a8 */ | ||||
| 	uint32_t mts_carveout_reg_ctrl;		/* 0x9ac */ | ||||
| 	uint32_t rsvd_0x9b0[4];			/* 0x9b0 */ | ||||
| 	uint32_t emem_bank_swizzle_cfg0;	/* 0x9c0 */ | ||||
| 	uint32_t emem_bank_swizzle_cfg1;	/* 0x9c4 */ | ||||
| 	uint32_t emem_bank_swizzle_cfg2;	/* 0x9c8 */ | ||||
| 	uint32_t emem_bank_swizzle_cfg3;	/* 0x9cc */ | ||||
| 	uint32_t rsvd_0x9d0[1];			/* 0x9d0 */ | ||||
| 	uint32_t sec_carveout_adr_hi;		/* 0x9d4 */ | ||||
| }; | ||||
|  | ||||
| #endif	/* _TEGRA124_MC_H_ */ | ||||
| enum { | ||||
| 	MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_SHIFT = 27, | ||||
| 	MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_MASK = 1 << 27, | ||||
|  | ||||
| 	MC_EMEM_CFG_ACCESS_CTRL_WRITE_ACCESS_DISABLED = 1, | ||||
|  | ||||
| 	MC_TIMING_CONTROL_TIMING_UPDATE = 1, | ||||
| }; | ||||
|  | ||||
| check_member(tegra_mc_regs, sec_carveout_adr_hi, 0x9d4); | ||||
|  | ||||
| #endif	/* __SOC_NVIDIA_TEGRA124_MC_H__ */ | ||||
|   | ||||
| @@ -62,10 +62,36 @@ struct tegra_pmc_regs { | ||||
| 	u32 no_iopower; | ||||
| 	u32 pwr_det; | ||||
| 	u32 pwr_det_latch; | ||||
| 	u32 scratch[20]; | ||||
| 	u32 scratch0; | ||||
| 	u32 scratch1; | ||||
| 	u32 scratch2; | ||||
| 	u32 scratch3; | ||||
| 	u32 scratch4; | ||||
| 	u32 scratch5; | ||||
| 	u32 scratch6; | ||||
| 	u32 scratch7; | ||||
| 	u32 scratch8; | ||||
| 	u32 scratch9; | ||||
| 	u32 scratch10; | ||||
| 	u32 scratch11; | ||||
| 	u32 scratch12; | ||||
| 	u32 scratch13; | ||||
| 	u32 scratch14; | ||||
| 	u32 scratch15; | ||||
| 	u32 scratch16; | ||||
| 	u32 scratch17; | ||||
| 	u32 scratch18; | ||||
| 	u32 scratch19; | ||||
| 	u32 odmdata; | ||||
| 	u32 scratch21[24 - 21]; | ||||
| 	u32 secure_scratch[6]; | ||||
| 	u32 scratch21; | ||||
| 	u32 scratch22; | ||||
| 	u32 scratch23; | ||||
| 	u32 secure_scratch0; | ||||
| 	u32 secure_scratch1; | ||||
| 	u32 secure_scratch2; | ||||
| 	u32 secure_scratch3; | ||||
| 	u32 secure_scratch4; | ||||
| 	u32 secure_scratch5; | ||||
| 	u32 cpupwrgood_timer; | ||||
| 	u32 cpupwroff_timer; | ||||
| 	u32 pg_mask; | ||||
| @@ -79,7 +105,25 @@ struct tegra_pmc_regs { | ||||
| 	u32 usb_a0; | ||||
| 	u32 crypto_op; | ||||
| 	u32 pllp_wb0_override; | ||||
| 	u32 scratch24[43 - 24]; | ||||
| 	u32 scratch24; | ||||
| 	u32 scratch25; | ||||
| 	u32 scratch26; | ||||
| 	u32 scratch27; | ||||
| 	u32 scratch28; | ||||
| 	u32 scratch29; | ||||
| 	u32 scratch30; | ||||
| 	u32 scratch31; | ||||
| 	u32 scratch32; | ||||
| 	u32 scratch33; | ||||
| 	u32 scratch34; | ||||
| 	u32 scratch35; | ||||
| 	u32 scratch36; | ||||
| 	u32 scratch37; | ||||
| 	u32 scratch38; | ||||
| 	u32 scratch39; | ||||
| 	u32 scratch40; | ||||
| 	u32 scratch41; | ||||
| 	u32 scratch42; | ||||
| 	u32 bondout_mirror[3]; | ||||
| 	u32 sys_33v_en; | ||||
| 	u32 bondout_mirror_access; | ||||
| @@ -124,9 +168,24 @@ struct tegra_pmc_regs { | ||||
| 	u32 utmip_uhsic_status; | ||||
| 	u32 utmip_uhsic_fake; | ||||
| 	u32 bondout_mirror3[5 - 3]; | ||||
| 	u32 secure_scratch6[8 - 6]; | ||||
| 	u32 scratch43[56 - 43]; | ||||
| 	u32 scratch_eco[3]; | ||||
| 	u32 secure_scratch6; | ||||
| 	u32 secure_scratch7; | ||||
| 	u32 scratch43; | ||||
| 	u32 scratch44; | ||||
| 	u32 scratch45; | ||||
| 	u32 scratch46; | ||||
| 	u32 scratch47; | ||||
| 	u32 scratch48; | ||||
| 	u32 scratch49; | ||||
| 	u32 scratch50; | ||||
| 	u32 scratch51; | ||||
| 	u32 scratch52; | ||||
| 	u32 scratch53; | ||||
| 	u32 scratch54; | ||||
| 	u32 scratch55; | ||||
| 	u32 scratch0_eco; | ||||
| 	u32 por_dpd_ctrl; | ||||
| 	u32 scratch2_eco; | ||||
| 	u32 utmip_uhsic_line_wakeup; | ||||
| 	u32 utmip_bias_master_cntrl; | ||||
| 	u32 utmip_master_config; | ||||
| @@ -153,10 +212,108 @@ struct tegra_pmc_regs { | ||||
| 	u32 reg_short; | ||||
| 	u32 pg_mask_andor; | ||||
| 	u8 _rsv1[0x2c]; | ||||
| 	u32 secure_scratch8[24 - 8]; | ||||
| 	u32 scratch56[120 - 56]; | ||||
| 	u32 secure_scratch8; | ||||
| 	u32 secure_scratch9; | ||||
| 	u32 secure_scratch10; | ||||
| 	u32 secure_scratch11; | ||||
| 	u32 secure_scratch12; | ||||
| 	u32 secure_scratch13; | ||||
| 	u32 secure_scratch14; | ||||
| 	u32 secure_scratch15; | ||||
| 	u32 secure_scratch16; | ||||
| 	u32 secure_scratch17; | ||||
| 	u32 secure_scratch18; | ||||
| 	u32 secure_scratch19; | ||||
| 	u32 secure_scratch20; | ||||
| 	u32 secure_scratch21; | ||||
| 	u32 secure_scratch22; | ||||
| 	u32 secure_scratch23; | ||||
| 	u32 secure_scratch24; | ||||
| 	u32 secure_scratch25; | ||||
| 	u32 secure_scratch26; | ||||
| 	u32 secure_scratch27; | ||||
| 	u32 secure_scratch28; | ||||
| 	u32 secure_scratch29; | ||||
| 	u32 secure_scratch30; | ||||
| 	u32 secure_scratch31; | ||||
| 	u32 secure_scratch32; | ||||
| 	u32 secure_scratch33; | ||||
| 	u32 secure_scratch34; | ||||
| 	u32 secure_scratch35; | ||||
| 	u8 _rsv2[0xd0]; | ||||
| 	u32 cntrl2; | ||||
| 	u8 _rsv3[0x18]; | ||||
| 	u32 io_dpd3_req; | ||||
| 	u32 io_dqd3_status; | ||||
| 	u32 strapping_opt_a; | ||||
| 	u8 _rsv4[0x198]; | ||||
| 	u32 scratch56; | ||||
| 	u32 scratch57; | ||||
| 	u32 scratch58; | ||||
| 	u32 scratch59; | ||||
| 	u32 scratch60; | ||||
| 	u32 scratch61; | ||||
| 	u32 scratch62; | ||||
| 	u32 scratch63; | ||||
| 	u32 scratch64; | ||||
| 	u32 scratch65; | ||||
| 	u32 scratch66; | ||||
| 	u32 scratch67; | ||||
| 	u32 scratch68; | ||||
| 	u32 scratch69; | ||||
| 	u32 scratch70; | ||||
| 	u32 scratch71; | ||||
| 	u32 scratch72; | ||||
| 	u32 scratch73; | ||||
| 	u32 scratch74; | ||||
| 	u32 scratch75; | ||||
| 	u32 scratch76; | ||||
| 	u32 scratch77; | ||||
| 	u32 scratch78; | ||||
| 	u32 scratch79; | ||||
| 	u32 scratch80; | ||||
| 	u32 scratch81; | ||||
| 	u32 scratch82; | ||||
| 	u32 scratch83; | ||||
| 	u32 scratch84; | ||||
| 	u32 scratch85; | ||||
| 	u32 scratch86; | ||||
| 	u32 scratch87; | ||||
| 	u32 scratch88; | ||||
| 	u32 scratch89; | ||||
| 	u32 scratch90; | ||||
| 	u32 scratch91; | ||||
| 	u32 scratch92; | ||||
| 	u32 scratch93; | ||||
| 	u32 scratch94; | ||||
| 	u32 scratch95; | ||||
| 	u32 scratch96; | ||||
| 	u32 scratch97; | ||||
| 	u32 scratch98; | ||||
| 	u32 scratch99; | ||||
| 	u32 scratch100; | ||||
| 	u32 scratch101; | ||||
| 	u32 scratch102; | ||||
| 	u32 scratch103; | ||||
| 	u32 scratch104; | ||||
| 	u32 scratch105; | ||||
| 	u32 scratch106; | ||||
| 	u32 scratch107; | ||||
| 	u32 scratch108; | ||||
| 	u32 scratch109; | ||||
| 	u32 scratch110; | ||||
| 	u32 scratch111; | ||||
| 	u32 scratch112; | ||||
| 	u32 scratch113; | ||||
| 	u32 scratch114; | ||||
| 	u32 scratch115; | ||||
| 	u32 scratch116; | ||||
| 	u32 scratch117; | ||||
| 	u32 scratch118; | ||||
| 	u32 scratch119; | ||||
| }; | ||||
| check_member(tegra_pmc_regs, scratch56, 0x340); | ||||
|  | ||||
| check_member(tegra_pmc_regs, scratch119, 0x6fc); | ||||
|  | ||||
| enum { | ||||
| 	PMC_PWRGATE_TOGGLE_PARTID_MASK = 0x1f, | ||||
| @@ -190,6 +347,29 @@ enum { | ||||
| 		0x3 << PMC_CNTRL_CPUPWRGOOD_SEL_SHIFT | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	PMC_DDR_PWR_EMMC_MASK = 1 << 1, | ||||
| 	PMC_DDR_PWR_VAL_MASK = 1 << 0, | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	PMC_DDR_CFG_PKG_MASK = 1 << 0, | ||||
| 	PMC_DDR_CFG_IF_MASK = 1 << 1, | ||||
| 	PMC_DDR_CFG_XM0_RESET_TRI_MASK = 1 << 12, | ||||
| 	PMC_DDR_CFG_XM0_RESET_DPDIO_MASK = 1 << 13, | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	PMC_NO_IOPOWER_MEM_MASK = 1 << 7, | ||||
| 	PMC_NO_IOPOWER_MEM_COMP_MASK = 1 << 16, | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	PMC_POR_DPD_CTRL_MEM0_ADDR0_CLK_SEL_DPD_MASK = 1 << 0, | ||||
| 	PMC_POR_DPD_CTRL_MEM0_ADDR1_CLK_SEL_DPD_MASK = 1 << 1, | ||||
| 	PMC_POR_DPD_CTRL_MEM0_HOLD_CKE_LOW_OVR_MASK = 1 << 31, | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	PMC_CNTRL2_HOLD_CKE_LOW_EN = 0x1 << 12 | ||||
| }; | ||||
| @@ -200,4 +380,10 @@ enum { | ||||
| 		0x3f << PMC_OSC_EDPD_OVER_XOFS_SHIFT | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT = 4, | ||||
| 	PMC_STRAPPING_OPT_A_RAM_CODE_MASK = | ||||
| 		0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT, | ||||
| }; | ||||
|  | ||||
| #endif	/* _TEGRA124_PMC_H_ */ | ||||
|   | ||||
							
								
								
									
										611
									
								
								src/soc/nvidia/tegra124/sdram.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										611
									
								
								src/soc/nvidia/tegra124/sdram.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,611 @@ | ||||
| /* | ||||
|  * This file is part of the coreboot project. | ||||
|  * | ||||
|  * Copyright 2013 Google Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; version 2 of the License. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #include <arch/io.h> | ||||
| #include <console/console.h> | ||||
| #include <delay.h> | ||||
| #include <soc/addressmap.h> | ||||
| #include <soc/clock.h> | ||||
|  | ||||
| #include "emc.h" | ||||
| #include "mc.h" | ||||
| #include "pmc.h" | ||||
| #include "sdram.h" | ||||
|  | ||||
| static void sdram_patch(uintptr_t addr, uint32_t value) | ||||
| { | ||||
| 	if (addr) | ||||
| 		writel(value, (uint32_t*)addr); | ||||
| } | ||||
|  | ||||
| static void writebits(uint32_t value, uint32_t *addr, uint32_t mask) | ||||
| { | ||||
| 	clrsetbits_le32(addr, mask, (value & mask)); | ||||
| } | ||||
|  | ||||
| /* PMC must be configured before clock-enable and de-reset of MC/EMC. */ | ||||
| static void sdram_configure_pmc(const struct sdram_params *param, | ||||
| 				struct tegra_pmc_regs *regs) | ||||
| { | ||||
| 	/* VDDP Select */ | ||||
| 	writel(param->PmcVddpSel, ®s->vddp_sel); | ||||
| 	udelay(param->PmcVddpSelWait); | ||||
|  | ||||
| 	/* Set DDR pad voltage */ | ||||
| 	writebits(param->PmcDdrPwr, ®s->ddr_pwr, PMC_DDR_PWR_VAL_MASK); | ||||
|  | ||||
| 	/* Set package and DPD pad control */ | ||||
| 	writebits(param->PmcDdrCfg, ®s->ddr_cfg, | ||||
| 		  (PMC_DDR_CFG_PKG_MASK | PMC_DDR_CFG_IF_MASK | | ||||
| 		   PMC_DDR_CFG_XM0_RESET_TRI_MASK | | ||||
| 		   PMC_DDR_CFG_XM0_RESET_DPDIO_MASK)); | ||||
|  | ||||
| 	/* Turn on MEM IO Power */ | ||||
| 	writebits(param->PmcNoIoPower, ®s->no_iopower, | ||||
| 		  (PMC_NO_IOPOWER_MEM_MASK | PMC_NO_IOPOWER_MEM_COMP_MASK)); | ||||
|  | ||||
| 	writel(param->PmcRegShort, ®s->reg_short); | ||||
| } | ||||
|  | ||||
| static void sdram_start_clocks(const struct sdram_params *param) | ||||
| { | ||||
| 	u32 is_same_freq = (param->McEmemArbMisc0 & | ||||
| 			    MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_MASK) ? 1 : 0; | ||||
|  | ||||
| 	clock_sdram(param->PllMInputDivider, param->PllMFeedbackDivider, | ||||
| 		    param->PllMSelectDiv2, param->PllMSetupControl, | ||||
| 		    param->PllMPDLshiftPh45, param->PllMPDLshiftPh90, | ||||
| 		    param->PllMPDLshiftPh135, param->PllMKVCO, | ||||
| 		    param->PllMKCP, param->PllMStableTime, | ||||
| 		    param->EmcClockSource, is_same_freq); | ||||
| } | ||||
|  | ||||
| static void sdram_deassert_clock_enable_signal(const struct sdram_params *param, | ||||
| 					       struct tegra_pmc_regs *regs) | ||||
| { | ||||
| 	clrbits_le32(®s->por_dpd_ctrl, | ||||
| 		     PMC_POR_DPD_CTRL_MEM0_HOLD_CKE_LOW_OVR_MASK); | ||||
| 	udelay(param->PmcPorDpdCtrlWait); | ||||
| } | ||||
|  | ||||
| static void sdram_deassert_sel_dpd(const struct sdram_params *param, | ||||
| 				   struct tegra_pmc_regs *regs) | ||||
| { | ||||
| 	clrbits_le32(®s->por_dpd_ctrl, | ||||
| 		     (PMC_POR_DPD_CTRL_MEM0_ADDR0_CLK_SEL_DPD_MASK | | ||||
| 		      PMC_POR_DPD_CTRL_MEM0_ADDR1_CLK_SEL_DPD_MASK)); | ||||
| 	/* | ||||
| 	 * Note NVIDIA recommended to always do 10us delay here and ignore | ||||
| 	 * BCT.PmcPorDpdCtrlWait. | ||||
| 	 * */ | ||||
| 	udelay(10); | ||||
| } | ||||
|  | ||||
| static void sdram_set_swizzle(const struct sdram_params *param, | ||||
| 			      struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	writel(param->EmcSwizzleRank0ByteCfg, ®s->swizzle_rank0_byte_cfg); | ||||
| 	writel(param->EmcSwizzleRank0Byte0, ®s->swizzle_rank0_byte0); | ||||
| 	writel(param->EmcSwizzleRank0Byte1, ®s->swizzle_rank0_byte1); | ||||
| 	writel(param->EmcSwizzleRank0Byte2, ®s->swizzle_rank0_byte2); | ||||
| 	writel(param->EmcSwizzleRank0Byte3, ®s->swizzle_rank0_byte3); | ||||
| 	writel(param->EmcSwizzleRank1ByteCfg, ®s->swizzle_rank1_byte_cfg); | ||||
| 	writel(param->EmcSwizzleRank1Byte0, ®s->swizzle_rank1_byte0); | ||||
| 	writel(param->EmcSwizzleRank1Byte1, ®s->swizzle_rank1_byte1); | ||||
| 	writel(param->EmcSwizzleRank1Byte2, ®s->swizzle_rank1_byte2); | ||||
| 	writel(param->EmcSwizzleRank1Byte3, ®s->swizzle_rank1_byte3); | ||||
| } | ||||
|  | ||||
| static void sdram_set_pad_controls(const struct sdram_params *param, | ||||
| 				   struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	/* Program the pad controls */ | ||||
| 	writel(param->EmcXm2CmdPadCtrl, ®s->xm2cmdpadctrl); | ||||
| 	writel(param->EmcXm2CmdPadCtrl2, ®s->xm2cmdpadctrl2); | ||||
| 	writel(param->EmcXm2CmdPadCtrl3, ®s->xm2cmdpadctrl3); | ||||
| 	writel(param->EmcXm2CmdPadCtrl4, ®s->xm2cmdpadctrl4); | ||||
| 	writel(param->EmcXm2CmdPadCtrl5, ®s->xm2cmdpadctrl5); | ||||
|  | ||||
| 	writel(param->EmcXm2DqsPadCtrl, ®s->xm2dqspadctrl); | ||||
| 	writel(param->EmcXm2DqsPadCtrl2, ®s->xm2dqspadctrl2); | ||||
| 	writel(param->EmcXm2DqsPadCtrl3, ®s->xm2dqspadctrl3); | ||||
| 	writel(param->EmcXm2DqsPadCtrl4, ®s->xm2dqspadctrl4); | ||||
| 	writel(param->EmcXm2DqsPadCtrl5, ®s->xm2dqspadctrl5); | ||||
| 	writel(param->EmcXm2DqsPadCtrl6, ®s->xm2dqspadctrl6); | ||||
|  | ||||
| 	writel(param->EmcXm2DqPadCtrl, ®s->xm2dqpadctrl); | ||||
| 	writel(param->EmcXm2DqPadCtrl2, ®s->xm2dqpadctrl2); | ||||
| 	writel(param->EmcXm2DqPadCtrl3, ®s->xm2dqpadctrl3); | ||||
|  | ||||
| 	writel(param->EmcXm2ClkPadCtrl, ®s->xm2clkpadctrl); | ||||
| 	writel(param->EmcXm2ClkPadCtrl2, ®s->xm2clkpadctrl2); | ||||
|  | ||||
| 	writel(param->EmcXm2CompPadCtrl, ®s->xm2comppadctrl); | ||||
|  | ||||
| 	writel(param->EmcXm2VttGenPadCtrl, ®s->xm2vttgenpadctrl); | ||||
| 	writel(param->EmcXm2VttGenPadCtrl2, ®s->xm2vttgenpadctrl2); | ||||
| 	writel(param->EmcXm2VttGenPadCtrl3, ®s->xm2vttgenpadctrl3); | ||||
|  | ||||
| 	writel(param->EmcCttTermCtrl, ®s->ctt_term_ctrl); | ||||
| } | ||||
|  | ||||
| static void sdram_trigger_emc_timing_update(struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	writel(EMC_TIMING_CONTROL_TIMING_UPDATE, ®s->timing_control); | ||||
| } | ||||
|  | ||||
| static void sdram_init_mc(const struct sdram_params *param, | ||||
| 			  struct tegra_mc_regs *regs) | ||||
| { | ||||
| 	/* Initialize MC VPR settings */ | ||||
| 	writel(param->McDisplaySnapRing, ®s->display_snap_ring); | ||||
| 	writel(param->McVideoProtectBom, ®s->video_protect_bom); | ||||
| 	writel(param->McVideoProtectBomAdrHi, ®s->video_protect_bom_adr_hi); | ||||
| 	writel(param->McVideoProtectSizeMb, ®s->video_protect_size_mb); | ||||
| 	writel(param->McVideoProtectVprOverride, | ||||
| 	       ®s->video_protect_vpr_override); | ||||
| 	writel(param->McVideoProtectVprOverride1, | ||||
| 	       ®s->video_protect_vpr_override1); | ||||
| 	writel(param->McVideoProtectGpuOverride0, | ||||
| 	       ®s->video_protect_gpu_override_0); | ||||
| 	writel(param->McVideoProtectGpuOverride1, | ||||
| 	       ®s->video_protect_gpu_override_1); | ||||
|  | ||||
| 	/* Program SDRAM geometry paarameters */ | ||||
| 	writel(param->McEmemAdrCfg, ®s->emem_adr_cfg); | ||||
| 	writel(param->McEmemAdrCfgDev0, ®s->emem_adr_cfg_dev0); | ||||
| 	writel(param->McEmemAdrCfgDev1, ®s->emem_adr_cfg_dev1); | ||||
|  | ||||
| 	/* Program bank swizzling */ | ||||
| 	writel(param->McEmemAdrCfgBankMask0, ®s->emem_bank_swizzle_cfg0); | ||||
| 	writel(param->McEmemAdrCfgBankMask1, ®s->emem_bank_swizzle_cfg1); | ||||
| 	writel(param->McEmemAdrCfgBankMask2, ®s->emem_bank_swizzle_cfg2); | ||||
| 	writel(param->McEmemAdrCfgBankSwizzle3, ®s->emem_bank_swizzle_cfg3); | ||||
|  | ||||
| 	/* Program external memory aperature (base and size) */ | ||||
| 	writel(param->McEmemCfg, ®s->emem_cfg); | ||||
|  | ||||
| 	/* Program SEC carveout (base and size) */ | ||||
| 	writel(param->McSecCarveoutBom, ®s->sec_carveout_bom); | ||||
| 	writel(param->McSecCarveoutAdrHi, ®s->sec_carveout_adr_hi); | ||||
| 	writel(param->McSecCarveoutSizeMb, ®s->sec_carveout_size_mb); | ||||
|  | ||||
| 	/* Program MTS carveout (base and size) */ | ||||
| 	writel(param->McMtsCarveoutBom, ®s->mts_carveout_bom); | ||||
| 	writel(param->McMtsCarveoutAdrHi, ®s->mts_carveout_adr_hi); | ||||
| 	writel(param->McMtsCarveoutSizeMb, ®s->mts_carveout_size_mb); | ||||
|  | ||||
| 	/* Program the memory arbiter */ | ||||
| 	writel(param->McEmemArbCfg, ®s->emem_arb_cfg); | ||||
| 	writel(param->McEmemArbOutstandingReq, ®s->emem_arb_outstanding_req); | ||||
| 	writel(param->McEmemArbTimingRcd, ®s->emem_arb_timing_rcd); | ||||
| 	writel(param->McEmemArbTimingRp, ®s->emem_arb_timing_rp); | ||||
| 	writel(param->McEmemArbTimingRc, ®s->emem_arb_timing_rc); | ||||
| 	writel(param->McEmemArbTimingRas, ®s->emem_arb_timing_ras); | ||||
| 	writel(param->McEmemArbTimingFaw, ®s->emem_arb_timing_faw); | ||||
| 	writel(param->McEmemArbTimingRrd, ®s->emem_arb_timing_rrd); | ||||
| 	writel(param->McEmemArbTimingRap2Pre, ®s->emem_arb_timing_rap2pre); | ||||
| 	writel(param->McEmemArbTimingWap2Pre, ®s->emem_arb_timing_wap2pre); | ||||
| 	writel(param->McEmemArbTimingR2R, ®s->emem_arb_timing_r2r); | ||||
| 	writel(param->McEmemArbTimingW2W, ®s->emem_arb_timing_w2w); | ||||
| 	writel(param->McEmemArbTimingR2W, ®s->emem_arb_timing_r2w); | ||||
| 	writel(param->McEmemArbTimingW2R, ®s->emem_arb_timing_w2r); | ||||
| 	writel(param->McEmemArbDaTurns, ®s->emem_arb_da_turns); | ||||
| 	writel(param->McEmemArbDaCovers, ®s->emem_arb_da_covers); | ||||
| 	writel(param->McEmemArbMisc0, ®s->emem_arb_misc0); | ||||
| 	writel(param->McEmemArbMisc1, ®s->emem_arb_misc1); | ||||
| 	writel(param->McEmemArbRing1Throttle, ®s->emem_arb_ring1_throttle); | ||||
| 	writel(param->McEmemArbOverride, ®s->emem_arb_override); | ||||
| 	writel(param->McEmemArbOverride1, ®s->emem_arb_override_1); | ||||
| 	writel(param->McEmemArbRsv, ®s->emem_arb_rsv); | ||||
|  | ||||
| 	/* Program extra snap levels for display client */ | ||||
| 	writel(param->McDisExtraSnapLevels, ®s->dis_extra_snap_levels); | ||||
|  | ||||
| 	/* Trigger MC timing update */ | ||||
| 	writel(MC_TIMING_CONTROL_TIMING_UPDATE, ®s->timing_control); | ||||
|  | ||||
| 	/* Program second-level clock enable overrides */ | ||||
| 	writel(param->McClkenOverride, ®s->clken_override); | ||||
|  | ||||
| 	/* Program statistics gathering */ | ||||
| 	writel(param->McStatControl, ®s->stat_control); | ||||
| } | ||||
|  | ||||
| static void sdram_init_emc(const struct sdram_params *param, | ||||
| 			   struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	/* Program SDRAM geometry parameters */ | ||||
| 	writel(param->EmcAdrCfg, ®s->adr_cfg); | ||||
|  | ||||
| 	/* Program second-level clock enable overrides */ | ||||
| 	writel(param->EmcClkenOverride, ®s->clken_override); | ||||
|  | ||||
| 	/* Program EMC pad auto calibration */ | ||||
| 	writel(param->EmcAutoCalInterval, ®s->auto_cal_interval); | ||||
| 	writel(param->EmcAutoCalConfig2, ®s->auto_cal_config2); | ||||
| 	writel(param->EmcAutoCalConfig3, ®s->auto_cal_config3); | ||||
| 	writel(param->EmcAutoCalConfig, ®s->auto_cal_config); | ||||
| 	udelay(param->EmcAutoCalWait); | ||||
| } | ||||
|  | ||||
| static void sdram_set_emc_timing(const struct sdram_params *param, | ||||
| 				 struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	/* Program EMC timing configuration */ | ||||
| 	writel(param->EmcCfg2, ®s->cfg_2); | ||||
| 	writel(param->EmcCfgPipe, ®s->cfg_pipe); | ||||
| 	writel(param->EmcDbg, ®s->dbg); | ||||
| 	writel(param->EmcCmdQ, ®s->cmdq); | ||||
| 	writel(param->EmcMc2EmcQ, ®s->mc2emcq); | ||||
| 	writel(param->EmcMrsWaitCnt, ®s->mrs_wait_cnt); | ||||
| 	writel(param->EmcMrsWaitCnt2, ®s->mrs_wait_cnt2); | ||||
| 	writel(param->EmcFbioCfg5, ®s->fbio_cfg5); | ||||
| 	writel(param->EmcRc, ®s->rc); | ||||
| 	writel(param->EmcRfc, ®s->rfc); | ||||
| 	writel(param->EmcRfcSlr, ®s->rfc_slr); | ||||
| 	writel(param->EmcRas, ®s->ras); | ||||
| 	writel(param->EmcRp, ®s->rp); | ||||
| 	writel(param->EmcR2r, ®s->r2r); | ||||
| 	writel(param->EmcW2w, ®s->w2w); | ||||
| 	writel(param->EmcR2w, ®s->r2w); | ||||
| 	writel(param->EmcW2r, ®s->w2r); | ||||
| 	writel(param->EmcR2p, ®s->r2p); | ||||
| 	writel(param->EmcW2p, ®s->w2p); | ||||
| 	writel(param->EmcRdRcd, ®s->rd_rcd); | ||||
| 	writel(param->EmcWrRcd, ®s->wr_rcd); | ||||
| 	writel(param->EmcRrd, ®s->rrd); | ||||
| 	writel(param->EmcRext, ®s->rext); | ||||
| 	writel(param->EmcWext, ®s->wext); | ||||
| 	writel(param->EmcWdv, ®s->wdv); | ||||
| 	writel(param->EmcWdvMask, ®s->wdv_mask); | ||||
| 	writel(param->EmcQUse, ®s->quse); | ||||
| 	writel(param->EmcQuseWidth, ®s->quse_width); | ||||
| 	writel(param->EmcIbdly, ®s->ibdly); | ||||
| 	writel(param->EmcEInput, ®s->einput); | ||||
| 	writel(param->EmcEInputDuration, ®s->einput_duration); | ||||
| 	writel(param->EmcPutermExtra, ®s->puterm_extra); | ||||
| 	writel(param->EmcPutermWidth, ®s->puterm_width); | ||||
| 	writel(param->EmcPutermAdj, ®s->puterm_adj); | ||||
| 	writel(param->EmcCdbCntl1, ®s->cdb_cntl_1); | ||||
| 	writel(param->EmcCdbCntl2, ®s->cdb_cntl_2); | ||||
| 	writel(param->EmcCdbCntl3, ®s->cdb_cntl_3); | ||||
| 	writel(param->EmcQRst, ®s->qrst); | ||||
| 	writel(param->EmcQSafe, ®s->qsafe); | ||||
| 	writel(param->EmcRdv, ®s->rdv); | ||||
| 	writel(param->EmcRdvMask, ®s->rdv_mask); | ||||
| 	writel(param->EmcQpop, ®s->qpop); | ||||
| 	writel(param->EmcCtt, ®s->ctt); | ||||
| 	writel(param->EmcCttDuration, ®s->ctt_duration); | ||||
| 	writel(param->EmcRefresh, ®s->refresh); | ||||
| 	writel(param->EmcBurstRefreshNum, ®s->burst_refresh_num); | ||||
| 	writel(param->EmcPreRefreshReqCnt, ®s->pre_refresh_req_cnt); | ||||
| 	writel(param->EmcPdEx2Wr, ®s->pdex2wr); | ||||
| 	writel(param->EmcPdEx2Rd, ®s->pdex2rd); | ||||
| 	writel(param->EmcPChg2Pden, ®s->pchg2pden); | ||||
| 	writel(param->EmcAct2Pden, ®s->act2pden); | ||||
| 	writel(param->EmcAr2Pden, ®s->ar2pden); | ||||
| 	writel(param->EmcRw2Pden, ®s->rw2pden); | ||||
| 	writel(param->EmcTxsr, ®s->txsr); | ||||
| 	writel(param->EmcTxsrDll, ®s->txsrdll); | ||||
| 	writel(param->EmcTcke, ®s->tcke); | ||||
| 	writel(param->EmcTckesr, ®s->tckesr); | ||||
| 	writel(param->EmcTpd, ®s->tpd); | ||||
| 	writel(param->EmcTfaw, ®s->tfaw); | ||||
| 	writel(param->EmcTrpab, ®s->trpab); | ||||
| 	writel(param->EmcTClkStable, ®s->tclkstable); | ||||
| 	writel(param->EmcTClkStop, ®s->tclkstop); | ||||
| 	writel(param->EmcTRefBw, ®s->trefbw); | ||||
| 	writel(param->EmcOdtWrite, ®s->odt_write); | ||||
| 	writel(param->EmcOdtRead, ®s->odt_read); | ||||
| 	writel(param->EmcFbioCfg6, ®s->fbio_cfg6); | ||||
| 	writel(param->EmcCfgDigDll, ®s->cfg_dig_dll); | ||||
| 	writel(param->EmcCfgDigDllPeriod, ®s->cfg_dig_dll_period); | ||||
|  | ||||
| 	/* Don't write bit 1: addr swizzle lock bit. Written at end of sequence. */ | ||||
| 	writel(param->EmcFbioSpare & 0xfffffffd, ®s->fbio_spare); | ||||
|  | ||||
| 	writel(param->EmcCfgRsv, ®s->cfg_rsv); | ||||
| 	writel(param->EmcDllXformDqs0, ®s->dll_xform_dqs0); | ||||
| 	writel(param->EmcDllXformDqs1, ®s->dll_xform_dqs1); | ||||
| 	writel(param->EmcDllXformDqs2, ®s->dll_xform_dqs2); | ||||
| 	writel(param->EmcDllXformDqs3, ®s->dll_xform_dqs3); | ||||
| 	writel(param->EmcDllXformDqs4, ®s->dll_xform_dqs4); | ||||
| 	writel(param->EmcDllXformDqs5, ®s->dll_xform_dqs5); | ||||
| 	writel(param->EmcDllXformDqs6, ®s->dll_xform_dqs6); | ||||
| 	writel(param->EmcDllXformDqs7, ®s->dll_xform_dqs7); | ||||
| 	writel(param->EmcDllXformDqs8, ®s->dll_xform_dqs8); | ||||
| 	writel(param->EmcDllXformDqs9, ®s->dll_xform_dqs9); | ||||
| 	writel(param->EmcDllXformDqs10, ®s->dll_xform_dqs10); | ||||
| 	writel(param->EmcDllXformDqs11, ®s->dll_xform_dqs11); | ||||
| 	writel(param->EmcDllXformDqs12, ®s->dll_xform_dqs12); | ||||
| 	writel(param->EmcDllXformDqs13, ®s->dll_xform_dqs13); | ||||
| 	writel(param->EmcDllXformDqs14, ®s->dll_xform_dqs14); | ||||
| 	writel(param->EmcDllXformDqs15, ®s->dll_xform_dqs15); | ||||
| 	writel(param->EmcDllXformQUse0, ®s->dll_xform_quse0); | ||||
| 	writel(param->EmcDllXformQUse1, ®s->dll_xform_quse1); | ||||
| 	writel(param->EmcDllXformQUse2, ®s->dll_xform_quse2); | ||||
| 	writel(param->EmcDllXformQUse3, ®s->dll_xform_quse3); | ||||
| 	writel(param->EmcDllXformQUse4, ®s->dll_xform_quse4); | ||||
| 	writel(param->EmcDllXformQUse5, ®s->dll_xform_quse5); | ||||
| 	writel(param->EmcDllXformQUse6, ®s->dll_xform_quse6); | ||||
| 	writel(param->EmcDllXformQUse7, ®s->dll_xform_quse7); | ||||
| 	writel(param->EmcDllXformQUse8, ®s->dll_xform_quse8); | ||||
| 	writel(param->EmcDllXformQUse9, ®s->dll_xform_quse9); | ||||
| 	writel(param->EmcDllXformQUse10, ®s->dll_xform_quse10); | ||||
| 	writel(param->EmcDllXformQUse11, ®s->dll_xform_quse11); | ||||
| 	writel(param->EmcDllXformQUse12, ®s->dll_xform_quse12); | ||||
| 	writel(param->EmcDllXformQUse13, ®s->dll_xform_quse13); | ||||
| 	writel(param->EmcDllXformQUse14, ®s->dll_xform_quse14); | ||||
| 	writel(param->EmcDllXformQUse15, ®s->dll_xform_quse15); | ||||
| 	writel(param->EmcDllXformDq0, ®s->dll_xform_dq0); | ||||
| 	writel(param->EmcDllXformDq1, ®s->dll_xform_dq1); | ||||
| 	writel(param->EmcDllXformDq2, ®s->dll_xform_dq2); | ||||
| 	writel(param->EmcDllXformDq3, ®s->dll_xform_dq3); | ||||
| 	writel(param->EmcDllXformDq4, ®s->dll_xform_dq4); | ||||
| 	writel(param->EmcDllXformDq5, ®s->dll_xform_dq5); | ||||
| 	writel(param->EmcDllXformDq6, ®s->dll_xform_dq6); | ||||
| 	writel(param->EmcDllXformDq7, ®s->dll_xform_dq7); | ||||
| 	writel(param->EmcDllXformAddr0, ®s->dll_xform_addr0); | ||||
| 	writel(param->EmcDllXformAddr1, ®s->dll_xform_addr1); | ||||
| 	writel(param->EmcDllXformAddr2, ®s->dll_xform_addr2); | ||||
| 	writel(param->EmcDllXformAddr3, ®s->dll_xform_addr3); | ||||
| 	writel(param->EmcDllXformAddr4, ®s->dll_xform_addr4); | ||||
| 	writel(param->EmcDllXformAddr5, ®s->dll_xform_addr5); | ||||
| 	writel(param->EmcAcpdControl, ®s->acpd_control); | ||||
| 	writel(param->EmcDsrVttgenDrv, ®s->dsr_vttgen_drv); | ||||
| 	writel(param->EmcTxdsrvttgen, ®s->txdsrvttgen); | ||||
| 	writel(param->EmcBgbiasCtl0, ®s->bgbias_ctl0); | ||||
|  | ||||
| 	/* | ||||
| 	 * Set pipe bypass enable bits before sending any DRAM commands. | ||||
| 	 * Note other bits in EMC_CFG must be set AFTER REFCTRL is configured. | ||||
| 	 */ | ||||
| 	writebits(param->EmcCfg, ®s->cfg, | ||||
| 		  (EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE_MASK | | ||||
| 		   EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1_MASK | | ||||
| 		   EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2_MASK)); | ||||
| } | ||||
|  | ||||
| static void sdram_patch_bootrom(const struct sdram_params *param, | ||||
| 				struct tegra_mc_regs *regs) | ||||
| { | ||||
| 	if (param->BootRomPatchControl & BOOT_ROM_PATCH_CONTROL_ENABLE_MASK) { | ||||
| 		uintptr_t addr = ((param->BootRomPatchControl & | ||||
| 				  BOOT_ROM_PATCH_CONTROL_OFFSET_MASK) >> | ||||
| 				  BOOT_ROM_PATCH_CONTROL_OFFSET_SHIFT); | ||||
| 		addr = BOOT_ROM_PATCH_CONTROL_BASE_ADDRESS + (addr << 2); | ||||
| 		writel(param->BootRomPatchData, (uint32_t *)addr); | ||||
| 		writel(1, ®s->timing_control); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void sdram_set_dpd3(const struct sdram_params *param, | ||||
| 			   struct tegra_pmc_regs *regs) | ||||
| { | ||||
| 	/* Program DPD request */ | ||||
| 	writel(param->PmcIoDpd3Req, ®s->io_dpd3_req); | ||||
| 	udelay(param->PmcIoDpd3ReqWait); | ||||
| } | ||||
|  | ||||
| static void sdram_set_dli_trims(const struct sdram_params *param, | ||||
| 				struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	/* Program DLI trims */ | ||||
| 	writel(param->EmcDliTrimTxDqs0, ®s->dli_trim_txdqs0); | ||||
| 	writel(param->EmcDliTrimTxDqs1, ®s->dli_trim_txdqs1); | ||||
| 	writel(param->EmcDliTrimTxDqs2, ®s->dli_trim_txdqs2); | ||||
| 	writel(param->EmcDliTrimTxDqs3, ®s->dli_trim_txdqs3); | ||||
| 	writel(param->EmcDliTrimTxDqs4, ®s->dli_trim_txdqs4); | ||||
| 	writel(param->EmcDliTrimTxDqs5, ®s->dli_trim_txdqs5); | ||||
| 	writel(param->EmcDliTrimTxDqs6, ®s->dli_trim_txdqs6); | ||||
| 	writel(param->EmcDliTrimTxDqs7, ®s->dli_trim_txdqs7); | ||||
| 	writel(param->EmcDliTrimTxDqs8, ®s->dli_trim_txdqs8); | ||||
| 	writel(param->EmcDliTrimTxDqs9, ®s->dli_trim_txdqs9); | ||||
| 	writel(param->EmcDliTrimTxDqs10, ®s->dli_trim_txdqs10); | ||||
| 	writel(param->EmcDliTrimTxDqs11, ®s->dli_trim_txdqs11); | ||||
| 	writel(param->EmcDliTrimTxDqs12, ®s->dli_trim_txdqs12); | ||||
| 	writel(param->EmcDliTrimTxDqs13, ®s->dli_trim_txdqs13); | ||||
| 	writel(param->EmcDliTrimTxDqs14, ®s->dli_trim_txdqs14); | ||||
| 	writel(param->EmcDliTrimTxDqs15, ®s->dli_trim_txdqs15); | ||||
|  | ||||
| 	writel(param->EmcCaTrainingTimingCntl1, | ||||
| 	       ®s->ca_training_timing_cntl1); | ||||
| 	writel(param->EmcCaTrainingTimingCntl2, | ||||
| 	       ®s->ca_training_timing_cntl2); | ||||
|  | ||||
| 	sdram_trigger_emc_timing_update(regs); | ||||
| 	udelay(param->EmcTimingControlWait); | ||||
| } | ||||
|  | ||||
| static void sdram_set_clock_enable_signal(const struct sdram_params *param, | ||||
| 					  struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	volatile uint32_t dummy = 0; | ||||
| 	clrbits_le32(®s->pin, (EMC_PIN_RESET_MASK | EMC_PIN_DQM_MASK | | ||||
| 				  EMC_PIN_CKE_MASK)); | ||||
| 	/* | ||||
| 	 * Assert dummy read of PIN register to ensure above write to PIN | ||||
| 	 * register went through. 200 is the recommended value by NVIDIA. | ||||
| 	 */ | ||||
| 	dummy |= readl(®s->pin); | ||||
| 	udelay(200 + param->EmcPinExtraWait); | ||||
|  | ||||
| 	/* Deassert reset */ | ||||
| 	setbits_le32(®s->pin, EMC_PIN_RESET_INACTIVE); | ||||
| 	/* | ||||
| 	 * Assert dummy read of PIN register to ensure above write to PIN | ||||
| 	 * register went through. 200 is the recommended value by NVIDIA. | ||||
| 	 */ | ||||
| 	dummy |= readl(®s->pin); | ||||
| 	udelay(500 + param->EmcPinExtraWait); | ||||
|  | ||||
| 	/* Enable clock enable signal */ | ||||
| 	setbits_le32(®s->pin, EMC_PIN_CKE_NORMAL); | ||||
| 	/* | ||||
| 	 * Assert dummy read of PIN register to ensure above write to PIN | ||||
| 	 * register went through. 200 is the recommended value by NVIDIA. | ||||
| 	 */ | ||||
| 	dummy |= readl(®s->pin); | ||||
| 	udelay(param->EmcPinProgramWait); | ||||
|  | ||||
| 	if (!dummy) { | ||||
| 		die("Failed to program EMC pin."); | ||||
| 	} | ||||
|  | ||||
| 	/* Send NOP (trigger) */ | ||||
| 	writebits(((1 << EMC_NOP_NOP_CMD_SHIFT) | | ||||
| 		   (param->EmcDevSelect << EMC_NOP_NOP_DEV_SELECTN_SHIFT)), | ||||
| 		  ®s->nop, | ||||
| 		  EMC_NOP_NOP_CMD_MASK | EMC_NOP_NOP_DEV_SELECTN_MASK); | ||||
|  | ||||
| 	/* Write mode registers */ | ||||
| 	writel(param->EmcEmrs2, ®s->emrs2); | ||||
| 	writel(param->EmcEmrs3, ®s->emrs3); | ||||
| 	writel(param->EmcEmrs, ®s->emrs); | ||||
| 	writel(param->EmcMrs, ®s->mrs); | ||||
|  | ||||
| 	if (param->EmcExtraModeRegWriteEnable) { | ||||
| 		writel(param->EmcMrwExtra, ®s->mrs); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void sdram_init_zq_calibration(const struct sdram_params *param, | ||||
| 				      struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	if ((param->EmcZcalWarmColdBootEnables & | ||||
| 	     EMC_ZCAL_WARM_COLD_BOOT_ENABLES_COLDBOOT_MASK) == 1) { | ||||
| 		/* Need to initialize ZCAL on coldboot. */ | ||||
| 		writel(param->EmcZcalInitDev0, ®s->zq_cal); | ||||
| 		udelay(param->EmcZcalInitWait); | ||||
|  | ||||
| 		if ((param->EmcDevSelect & 2) == 0) { | ||||
| 			writel(param->EmcZcalInitDev1, ®s->zq_cal); | ||||
| 			udelay(param->EmcZcalInitWait); | ||||
| 		} | ||||
| 	} else { | ||||
| 		udelay(param->EmcZcalInitWait); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void sdram_set_zq_calibration(const struct sdram_params *param, | ||||
| 				     struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	/* Start periodic ZQ calibration */ | ||||
| 	writel(param->EmcZcalInterval, ®s->zcal_interval); | ||||
| 	writel(param->EmcZcalWaitCnt, ®s->zcal_wait_cnt); | ||||
| 	writel(param->EmcZcalMrwCmd, ®s->zcal_mrw_cmd); | ||||
| } | ||||
|  | ||||
| static void sdram_set_refresh(const struct sdram_params *param, | ||||
| 			      struct tegra_emc_regs *regs) | ||||
| { | ||||
| 	/* Insert burst refresh */ | ||||
| 	if (param->EmcExtraRefreshNum > 0) { | ||||
| 		uint32_t refresh_num = (1 << param->EmcExtraRefreshNum) - 1; | ||||
| 		writebits((EMC_REF_CMD_REFRESH | EMC_REF_NORMAL_ENABLED | | ||||
| 			   (refresh_num << EMC_REF_NUM_SHIFT) | | ||||
| 			   (param->EmcDevSelect << EMC_REF_DEV_SELECTN_SHIFT)), | ||||
| 			  ®s->ref, (EMC_REF_CMD_MASK | EMC_REF_NORMAL_MASK | | ||||
| 				       EMC_REF_NUM_MASK | | ||||
| 				       EMC_REF_DEV_SELECTN_MASK)); | ||||
| 	} | ||||
|  | ||||
| 	/* Enable refresh */ | ||||
| 	writel((param->EmcDevSelect | EMC_REFCTRL_REF_VALID_ENABLED), | ||||
| 	       ®s->refctrl); | ||||
|  | ||||
| 	writel(param->EmcDynSelfRefControl, ®s->dyn_self_ref_control); | ||||
| 	writel(param->EmcCfg, ®s->cfg); | ||||
| 	writel(param->EmcSelDpdCtrl, ®s->sel_dpd_ctrl); | ||||
|  | ||||
| 	/* Write addr swizzle lock bit */ | ||||
| 	writel(param->EmcFbioSpare, ®s->fbio_spare); | ||||
|  | ||||
| 	/* Re-trigger timing to latch power saving functions */ | ||||
| 	sdram_trigger_emc_timing_update(regs); | ||||
| } | ||||
|  | ||||
| static void sdram_enable_arbiter(const struct sdram_params *param) | ||||
| { | ||||
| 	/* TODO(hungte) Move values here to standalone header file. */ | ||||
| 	uint32_t *AHB_ARBITRATION_XBAR_CTRL = (uint32_t*)(0x6000c000 + 0xe0); | ||||
| 	setbits_le32(AHB_ARBITRATION_XBAR_CTRL, | ||||
| 		     param->AhbArbitrationXbarCtrlMemInitDone << 16); | ||||
| } | ||||
|  | ||||
| static void sdram_lock_carveouts(const struct sdram_params *param, | ||||
| 				 struct tegra_mc_regs *regs) | ||||
| { | ||||
| 	/* Lock carveouts, and emem_cfg registers */ | ||||
| 	writel(param->McVideoProtectWriteAccess, ®s->video_protect_reg_ctrl); | ||||
| 	writel(MC_EMEM_CFG_ACCESS_CTRL_WRITE_ACCESS_DISABLED, | ||||
| 	       ®s->emem_cfg_access_ctrl); | ||||
| 	writel(param->McSecCarveoutProtectWriteAccess, | ||||
| 	       ®s->sec_carveout_reg_ctrl); | ||||
| 	writel(param->McMtsCarveoutRegCtrl, ®s->mts_carveout_reg_ctrl); | ||||
| } | ||||
|  | ||||
| void sdram_init(const struct sdram_params *param) | ||||
| { | ||||
| 	struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs*)TEGRA_PMC_BASE; | ||||
| 	struct tegra_mc_regs *mc = (struct tegra_mc_regs*)TEGRA_MC_BASE; | ||||
| 	struct tegra_emc_regs *emc = (struct tegra_emc_regs*)TEGRA_EMC_BASE; | ||||
|  | ||||
| 	sdram_configure_pmc(param, pmc); | ||||
| 	sdram_patch(param->EmcBctSpare0, param->EmcBctSpare1); | ||||
|  | ||||
| 	sdram_start_clocks(param); | ||||
| 	sdram_patch(param->EmcBctSpare2, param->EmcBctSpare3); | ||||
|  | ||||
| 	sdram_deassert_sel_dpd(param, pmc); | ||||
| 	sdram_set_swizzle(param, emc); | ||||
| 	sdram_set_pad_controls(param, emc); | ||||
| 	sdram_patch(param->EmcBctSpare4, param->EmcBctSpare5); | ||||
|  | ||||
| 	sdram_trigger_emc_timing_update(emc); | ||||
| 	sdram_init_mc(param, mc); | ||||
| 	sdram_init_emc(param, emc); | ||||
| 	sdram_patch(param->EmcBctSpare6, param->EmcBctSpare7); | ||||
|  | ||||
| 	sdram_set_emc_timing(param, emc); | ||||
| 	sdram_patch_bootrom(param, mc); | ||||
| 	sdram_set_dpd3(param, pmc); | ||||
| 	sdram_set_dli_trims(param, emc); | ||||
| 	sdram_deassert_clock_enable_signal(param, pmc); | ||||
| 	sdram_set_clock_enable_signal(param, emc); | ||||
| 	sdram_init_zq_calibration(param, emc); | ||||
| 	sdram_patch(param->EmcBctSpare8, param->EmcBctSpare9); | ||||
|  | ||||
| 	sdram_set_zq_calibration(param, emc); | ||||
| 	sdram_patch(param->EmcBctSpare10, param->EmcBctSpare11); | ||||
|  | ||||
| 	sdram_trigger_emc_timing_update(emc); | ||||
| 	sdram_set_refresh(param, emc); | ||||
| 	sdram_enable_arbiter(param); | ||||
| 	sdram_lock_carveouts(param, mc); | ||||
| } | ||||
|  | ||||
| uint32_t sdram_get_ram_code(void) | ||||
| { | ||||
| 	struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs*)TEGRA_PMC_BASE; | ||||
| 	return ((readl(&pmc->strapping_opt_a) & | ||||
| 		 PMC_STRAPPING_OPT_A_RAM_CODE_MASK) >> | ||||
| 		PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT); | ||||
| } | ||||
							
								
								
									
										28
									
								
								src/soc/nvidia/tegra124/sdram.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/soc/nvidia/tegra124/sdram.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  * This file is part of the coreboot project. | ||||
|  * | ||||
|  * Copyright 2013 Google Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; version 2 of the License. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #ifndef __SOC_NVIDIA_TEGRA124_SDRAM_H__ | ||||
| #define __SOC_NVIDIA_TEGRA124_SDRAM_H__ | ||||
|  | ||||
| #include "sdram_param.h" | ||||
|  | ||||
| uint32_t sdram_get_ram_code(void); | ||||
| void sdram_init(const struct sdram_params *param); | ||||
|  | ||||
| #endif /* __SOC_NVIDIA_TEGRA124_SDRAM_H__ */ | ||||
							
								
								
									
										816
									
								
								src/soc/nvidia/tegra124/sdram_param.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										816
									
								
								src/soc/nvidia/tegra124/sdram_param.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,816 @@ | ||||
| /* | ||||
|  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved. | ||||
|  * Copyright 2013 Google Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms and conditions of the GNU General Public License, | ||||
|  * version 2, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope it will be useful, but WITHOUT | ||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|  * more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * See file CREDITS for list of people who contributed to this | ||||
|  * project. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Defines the SDRAM parameter structure. | ||||
|  * | ||||
|  * Note that PLLM is used by EMC. The field names are in camel case to ease | ||||
|  * directly converting BCT config files (*.cfg) into C structure. | ||||
|  */ | ||||
|  | ||||
| #ifndef __SOC_NVIDIA_TEGRA124_SDRAM_PARAM_H__ | ||||
| #define __SOC_NVIDIA_TEGRA124_SDRAM_PARAM_H__ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| enum { | ||||
| 	/* Specifies the memory type to be undefined */ | ||||
| 	MEMORY_TYPE_NONE = 0, | ||||
|  | ||||
| 	/* Specifies the memory type to be DDR SDRAM */ | ||||
| 	MEMORY_TYPE_DDR = 0, | ||||
|  | ||||
| 	/* Specifies the memory type to be LPDDR SDRAM */ | ||||
| 	MEMORY_TYPE_LPDDR = 0, | ||||
|  | ||||
| 	/* Specifies the memory type to be DDR2 SDRAM */ | ||||
| 	MEMORY_TYPE_DDR2 = 0, | ||||
|  | ||||
| 	/* Specifies the memory type to be LPDDR2 SDRAM */ | ||||
| 	MEMORY_TYPE_LPDDR2, | ||||
|  | ||||
| 	/* Specifies the memory type to be DDR3 SDRAM */ | ||||
| 	MEMORY_TYPE_DDR3, | ||||
|  | ||||
| 	MEMORY_TYPE_NUM, | ||||
| 	MEMORY_TYPE_FORCE32 = 0X7FFFFFF | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	BOOT_ROM_PATCH_CONTROL_ENABLE_MASK = 0x1 << 31, | ||||
| 	BOOT_ROM_PATCH_CONTROL_OFFSET_SHIFT = 0, | ||||
| 	BOOT_ROM_PATCH_CONTROL_OFFSET_MASK = 0x7FFFFFFF << 0, | ||||
| 	BOOT_ROM_PATCH_CONTROL_BASE_ADDRESS = 0x70000000, | ||||
|  | ||||
| 	EMC_ZCAL_WARM_COLD_BOOT_ENABLES_COLDBOOT_MASK = 1 << 0, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Defines the SDRAM parameter structure | ||||
|  */ | ||||
| struct sdram_params { | ||||
|  | ||||
| 	/* Specifies the type of memory device */ | ||||
| 	uint32_t memory_type; | ||||
|  | ||||
| 	/* MC/EMC clock source configuration */ | ||||
|  | ||||
| 	/* Specifies the M value for PllM */ | ||||
| 	uint32_t PllMInputDivider; | ||||
| 	/* Specifies the N value for PllM */ | ||||
| 	uint32_t PllMFeedbackDivider; | ||||
| 	/* Specifies the time to wait for PLLM to lock (in microseconds) */ | ||||
| 	uint32_t PllMStableTime; | ||||
| 	/* Specifies misc. control bits */ | ||||
| 	uint32_t PllMSetupControl; | ||||
| 	/* Enables the Div by 2 */ | ||||
| 	uint32_t PllMSelectDiv2; | ||||
| 	/* Powers down VCO output Level shifter */ | ||||
| 	uint32_t PllMPDLshiftPh45; | ||||
| 	/* Powers down VCO output Level shifter */ | ||||
| 	uint32_t PllMPDLshiftPh90; | ||||
| 	/* Powers down VCO output Level shifter */ | ||||
| 	uint32_t PllMPDLshiftPh135; | ||||
| 	/* Specifies value for Charge Pump Gain Control */ | ||||
| 	uint32_t PllMKCP; | ||||
| 	/* Specifies VCO gain */ | ||||
| 	uint32_t PllMKVCO; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare0; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare1; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare2; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare3; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare4; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare5; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare6; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare7; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare8; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare9; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare10; | ||||
| 	/* Spare BCT param */ | ||||
| 	uint32_t EmcBctSpare11; | ||||
| 	/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */ | ||||
| 	uint32_t EmcClockSource; | ||||
|  | ||||
| 	/* Auto-calibration of EMC pads */ | ||||
|  | ||||
| 	/* Specifies the value for EMC_AUTO_CAL_INTERVAL */ | ||||
| 	uint32_t EmcAutoCalInterval; | ||||
| 	/* | ||||
| 	 * Specifies the value for EMC_AUTO_CAL_CONFIG | ||||
| 	 * Note: Trigger bits are set by the SDRAM code. | ||||
| 	 */ | ||||
| 	uint32_t EmcAutoCalConfig; | ||||
|  | ||||
| 	/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */ | ||||
| 	uint32_t EmcAutoCalConfig2; | ||||
|  | ||||
| 	/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */ | ||||
| 	uint32_t EmcAutoCalConfig3; | ||||
|  | ||||
| 	/* | ||||
| 	 * Specifies the time for the calibration | ||||
| 	 * to stabilize (in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t EmcAutoCalWait; | ||||
|  | ||||
| 	/* | ||||
| 	 * DRAM size information | ||||
| 	 * Specifies the value for EMC_ADR_CFG | ||||
| 	 */ | ||||
| 	uint32_t EmcAdrCfg; | ||||
|  | ||||
| 	/* | ||||
| 	 * Specifies the time to wait after asserting pin | ||||
| 	 * CKE (in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t EmcPinProgramWait; | ||||
| 	/* Specifies the extra delay before/after pin RESET/CKE command */ | ||||
| 	uint32_t EmcPinExtraWait; | ||||
| 	/* | ||||
| 	 * Specifies the extra delay after the first writing | ||||
| 	 * of EMC_TIMING_CONTROL | ||||
| 	 */ | ||||
| 	uint32_t EmcTimingControlWait; | ||||
|  | ||||
| 	/* Timing parameters required for the SDRAM */ | ||||
|  | ||||
| 	/* Specifies the value for EMC_RC */ | ||||
| 	uint32_t EmcRc; | ||||
| 	/* Specifies the value for EMC_RFC */ | ||||
| 	uint32_t EmcRfc; | ||||
| 	/* Specifies the value for EMC_RFC_SLR */ | ||||
| 	uint32_t EmcRfcSlr; | ||||
| 	/* Specifies the value for EMC_RAS */ | ||||
| 	uint32_t EmcRas; | ||||
| 	/* Specifies the value for EMC_RP */ | ||||
| 	uint32_t EmcRp; | ||||
| 	/* Specifies the value for EMC_R2R */ | ||||
| 	uint32_t EmcR2r; | ||||
| 	/* Specifies the value for EMC_W2W */ | ||||
| 	uint32_t EmcW2w; | ||||
| 	/* Specifies the value for EMC_R2W */ | ||||
| 	uint32_t EmcR2w; | ||||
| 	/* Specifies the value for EMC_W2R */ | ||||
| 	uint32_t EmcW2r; | ||||
| 	/* Specifies the value for EMC_R2P */ | ||||
| 	uint32_t EmcR2p; | ||||
| 	/* Specifies the value for EMC_W2P */ | ||||
| 	uint32_t EmcW2p; | ||||
| 	/* Specifies the value for EMC_RD_RCD */ | ||||
| 	uint32_t EmcRdRcd; | ||||
| 	/* Specifies the value for EMC_WR_RCD */ | ||||
| 	uint32_t EmcWrRcd; | ||||
| 	/* Specifies the value for EMC_RRD */ | ||||
| 	uint32_t EmcRrd; | ||||
| 	/* Specifies the value for EMC_REXT */ | ||||
| 	uint32_t EmcRext; | ||||
| 	/* Specifies the value for EMC_WEXT */ | ||||
| 	uint32_t EmcWext; | ||||
| 	/* Specifies the value for EMC_WDV */ | ||||
| 	uint32_t EmcWdv; | ||||
| 	/* Specifies the value for EMC_WDV_MASK */ | ||||
| 	uint32_t EmcWdvMask; | ||||
| 	/* Specifies the value for EMC_QUSE */ | ||||
| 	uint32_t EmcQUse; | ||||
| 	/* Specifies the value for EMC_QUSE_WIDTH */ | ||||
| 	uint32_t EmcQuseWidth; | ||||
| 	/* Specifies the value for EMC_IBDLY */ | ||||
| 	uint32_t EmcIbdly; | ||||
| 	/* Specifies the value for EMC_EINPUT */ | ||||
| 	uint32_t EmcEInput; | ||||
| 	/* Specifies the value for EMC_EINPUT_DURATION */ | ||||
| 	uint32_t EmcEInputDuration; | ||||
| 	/* Specifies the value for EMC_PUTERM_EXTRA */ | ||||
| 	uint32_t EmcPutermExtra; | ||||
| 	/* Specifies the value for EMC_PUTERM_WIDTH */ | ||||
| 	uint32_t EmcPutermWidth; | ||||
| 	/* Specifies the value for EMC_PUTERM_ADJ */ | ||||
| 	uint32_t EmcPutermAdj; | ||||
| 	/* Specifies the value for EMC_CDB_CNTL_1 */ | ||||
| 	uint32_t EmcCdbCntl1; | ||||
| 	/* Specifies the value for EMC_CDB_CNTL_2 */ | ||||
| 	uint32_t EmcCdbCntl2; | ||||
| 	/* Specifies the value for EMC_CDB_CNTL_3 */ | ||||
| 	uint32_t EmcCdbCntl3; | ||||
| 	/* Specifies the value for EMC_QRST */ | ||||
| 	uint32_t EmcQRst; | ||||
| 	/* Specifies the value for EMC_QSAFE */ | ||||
| 	uint32_t EmcQSafe; | ||||
| 	/* Specifies the value for EMC_RDV */ | ||||
| 	uint32_t EmcRdv; | ||||
| 	/* Specifies the value for EMC_RDV_MASK */ | ||||
| 	uint32_t EmcRdvMask; | ||||
| 	/* Specifies the value for EMC_QPOP */ | ||||
| 	uint32_t EmcQpop; | ||||
| 	/* Specifies the value for EMC_CTT */ | ||||
| 	uint32_t EmcCtt; | ||||
| 	/* Specifies the value for EMC_CTT_DURATION */ | ||||
| 	uint32_t EmcCttDuration; | ||||
| 	/* Specifies the value for EMC_REFRESH */ | ||||
| 	uint32_t EmcRefresh; | ||||
| 	/* Specifies the value for EMC_BURST_REFRESH_NUM */ | ||||
| 	uint32_t EmcBurstRefreshNum; | ||||
| 	/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */ | ||||
| 	uint32_t EmcPreRefreshReqCnt; | ||||
| 	/* Specifies the value for EMC_PDEX2WR */ | ||||
| 	uint32_t EmcPdEx2Wr; | ||||
| 	/* Specifies the value for EMC_PDEX2RD */ | ||||
| 	uint32_t EmcPdEx2Rd; | ||||
| 	/* Specifies the value for EMC_PCHG2PDEN */ | ||||
| 	uint32_t EmcPChg2Pden; | ||||
| 	/* Specifies the value for EMC_ACT2PDEN */ | ||||
| 	uint32_t EmcAct2Pden; | ||||
| 	/* Specifies the value for EMC_AR2PDEN */ | ||||
| 	uint32_t EmcAr2Pden; | ||||
| 	/* Specifies the value for EMC_RW2PDEN */ | ||||
| 	uint32_t EmcRw2Pden; | ||||
| 	/* Specifies the value for EMC_TXSR */ | ||||
| 	uint32_t EmcTxsr; | ||||
| 	/* Specifies the value for EMC_TXSRDLL */ | ||||
| 	uint32_t EmcTxsrDll; | ||||
| 	/* Specifies the value for EMC_TCKE */ | ||||
| 	uint32_t EmcTcke; | ||||
| 	/* Specifies the value for EMC_TCKESR */ | ||||
| 	uint32_t EmcTckesr; | ||||
| 	/* Specifies the value for EMC_TPD */ | ||||
| 	uint32_t EmcTpd; | ||||
| 	/* Specifies the value for EMC_TFAW */ | ||||
| 	uint32_t EmcTfaw; | ||||
| 	/* Specifies the value for EMC_TRPAB */ | ||||
| 	uint32_t EmcTrpab; | ||||
| 	/* Specifies the value for EMC_TCLKSTABLE */ | ||||
| 	uint32_t EmcTClkStable; | ||||
| 	/* Specifies the value for EMC_TCLKSTOP */ | ||||
| 	uint32_t EmcTClkStop; | ||||
| 	/* Specifies the value for EMC_TREFBW */ | ||||
| 	uint32_t EmcTRefBw; | ||||
|  | ||||
| 	/* FBIO configuration values */ | ||||
|  | ||||
| 	/* Specifies the value for EMC_FBIO_CFG5 */ | ||||
| 	uint32_t EmcFbioCfg5; | ||||
| 	/* Specifies the value for EMC_FBIO_CFG6 */ | ||||
| 	uint32_t EmcFbioCfg6; | ||||
| 	/* Specifies the value for EMC_FBIO_SPARE */ | ||||
| 	uint32_t EmcFbioSpare; | ||||
|  | ||||
| 	/* Specifies the value for EMC_CFG_RSV */ | ||||
| 	uint32_t EmcCfgRsv; | ||||
|  | ||||
| 	/* MRS command values */ | ||||
|  | ||||
| 	/* Specifies the value for EMC_MRS */ | ||||
| 	uint32_t EmcMrs; | ||||
| 	/* Specifies the MP0 command to initialize mode registers */ | ||||
| 	uint32_t EmcEmrs; | ||||
| 	/* Specifies the MP2 command to initialize mode registers */ | ||||
| 	uint32_t EmcEmrs2; | ||||
| 	/* Specifies the MP3 command to initialize mode registers */ | ||||
| 	uint32_t EmcEmrs3; | ||||
| 	/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */ | ||||
| 	uint32_t EmcMrw1; | ||||
| 	/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */ | ||||
| 	uint32_t EmcMrw2; | ||||
| 	/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */ | ||||
| 	uint32_t EmcMrw3; | ||||
| 	/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */ | ||||
| 	uint32_t EmcMrw4; | ||||
| 	/* | ||||
| 	 * Specifies the programming to extra LPDDR2 Mode Register | ||||
| 	 * at cold boot | ||||
| 	 */ | ||||
| 	uint32_t EmcMrwExtra; | ||||
| 	/* | ||||
| 	 * Specifies the programming to extra LPDDR2 Mode Register | ||||
| 	 * at warm boot | ||||
| 	 */ | ||||
| 	uint32_t EmcWarmBootMrwExtra; | ||||
| 	/* | ||||
| 	 * Specify the enable of extra Mode Register programming at | ||||
| 	 * warm boot | ||||
| 	 */ | ||||
| 	uint32_t EmcWarmBootExtraModeRegWriteEnable; | ||||
| 	/* | ||||
| 	 * Specify the enable of extra Mode Register programming at | ||||
| 	 * cold boot | ||||
| 	 */ | ||||
| 	uint32_t EmcExtraModeRegWriteEnable; | ||||
|  | ||||
| 	/* Specifies the EMC_MRW reset command value */ | ||||
| 	uint32_t EmcMrwResetCommand; | ||||
| 	/* Specifies the EMC Reset wait time (in microseconds) */ | ||||
| 	uint32_t EmcMrwResetNInitWait; | ||||
| 	/* Specifies the value for EMC_MRS_WAIT_CNT */ | ||||
| 	uint32_t EmcMrsWaitCnt; | ||||
| 	/* Specifies the value for EMC_MRS_WAIT_CNT2 */ | ||||
| 	uint32_t EmcMrsWaitCnt2; | ||||
|  | ||||
| 	/* EMC miscellaneous configurations */ | ||||
|  | ||||
| 	/* Specifies the value for EMC_CFG */ | ||||
| 	uint32_t EmcCfg; | ||||
| 	/* Specifies the value for EMC_CFG_2 */ | ||||
| 	uint32_t EmcCfg2; | ||||
| 	/* Specifies the pipe bypass controls */ | ||||
| 	uint32_t EmcCfgPipe; | ||||
| 	/* Specifies the value for EMC_DBG */ | ||||
| 	uint32_t EmcDbg; | ||||
| 	/* Specifies the value for EMC_CMDQ */ | ||||
| 	uint32_t EmcCmdQ; | ||||
| 	/* Specifies the value for EMC_MC2EMCQ */ | ||||
| 	uint32_t EmcMc2EmcQ; | ||||
| 	/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */ | ||||
| 	uint32_t EmcDynSelfRefControl; | ||||
|  | ||||
| 	/* Specifies the value for MEM_INIT_DONE */ | ||||
| 	uint32_t AhbArbitrationXbarCtrlMemInitDone; | ||||
|  | ||||
| 	/* Specifies the value for EMC_CFG_DIG_DLL */ | ||||
| 	uint32_t EmcCfgDigDll; | ||||
| 	/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */ | ||||
| 	uint32_t EmcCfgDigDllPeriod; | ||||
| 	/* Specifies the value of *DEV_SELECTN of various EMC registers */ | ||||
| 	uint32_t EmcDevSelect; | ||||
|  | ||||
| 	/* Specifies the value for EMC_SEL_DPD_CTRL */ | ||||
| 	uint32_t EmcSelDpdCtrl; | ||||
|  | ||||
| 	/* Pads trimmer delays */ | ||||
|  | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS0 */ | ||||
| 	uint32_t EmcDllXformDqs0; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS1 */ | ||||
| 	uint32_t EmcDllXformDqs1; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS2 */ | ||||
| 	uint32_t EmcDllXformDqs2; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS3 */ | ||||
| 	uint32_t EmcDllXformDqs3; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS4 */ | ||||
| 	uint32_t EmcDllXformDqs4; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS5 */ | ||||
| 	uint32_t EmcDllXformDqs5; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS6 */ | ||||
| 	uint32_t EmcDllXformDqs6; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS7 */ | ||||
| 	uint32_t EmcDllXformDqs7; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS8 */ | ||||
| 	uint32_t EmcDllXformDqs8; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS9 */ | ||||
| 	uint32_t EmcDllXformDqs9; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS10 */ | ||||
| 	uint32_t EmcDllXformDqs10; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS11 */ | ||||
| 	uint32_t EmcDllXformDqs11; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS12 */ | ||||
| 	uint32_t EmcDllXformDqs12; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS13 */ | ||||
| 	uint32_t EmcDllXformDqs13; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS14 */ | ||||
| 	uint32_t EmcDllXformDqs14; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQS15 */ | ||||
| 	uint32_t EmcDllXformDqs15; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE0 */ | ||||
| 	uint32_t EmcDllXformQUse0; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE1 */ | ||||
| 	uint32_t EmcDllXformQUse1; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE2 */ | ||||
| 	uint32_t EmcDllXformQUse2; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE3 */ | ||||
| 	uint32_t EmcDllXformQUse3; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE4 */ | ||||
| 	uint32_t EmcDllXformQUse4; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE5 */ | ||||
| 	uint32_t EmcDllXformQUse5; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE6 */ | ||||
| 	uint32_t EmcDllXformQUse6; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE7 */ | ||||
| 	uint32_t EmcDllXformQUse7; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_ADDR0 */ | ||||
| 	uint32_t EmcDllXformAddr0; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_ADDR1 */ | ||||
| 	uint32_t EmcDllXformAddr1; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_ADDR2 */ | ||||
| 	uint32_t EmcDllXformAddr2; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_ADDR3 */ | ||||
| 	uint32_t EmcDllXformAddr3; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_ADDR4 */ | ||||
| 	uint32_t EmcDllXformAddr4; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_ADDR5 */ | ||||
| 	uint32_t EmcDllXformAddr5; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE8 */ | ||||
| 	uint32_t EmcDllXformQUse8; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE9 */ | ||||
| 	uint32_t EmcDllXformQUse9; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE10 */ | ||||
| 	uint32_t EmcDllXformQUse10; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE11 */ | ||||
| 	uint32_t EmcDllXformQUse11; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE12 */ | ||||
| 	uint32_t EmcDllXformQUse12; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE13 */ | ||||
| 	uint32_t EmcDllXformQUse13; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE14 */ | ||||
| 	uint32_t EmcDllXformQUse14; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_QUSE15 */ | ||||
| 	uint32_t EmcDllXformQUse15; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS0 */ | ||||
| 	uint32_t EmcDliTrimTxDqs0; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS1 */ | ||||
| 	uint32_t EmcDliTrimTxDqs1; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS2 */ | ||||
| 	uint32_t EmcDliTrimTxDqs2; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS3 */ | ||||
| 	uint32_t EmcDliTrimTxDqs3; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS4 */ | ||||
| 	uint32_t EmcDliTrimTxDqs4; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS5 */ | ||||
| 	uint32_t EmcDliTrimTxDqs5; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS6 */ | ||||
| 	uint32_t EmcDliTrimTxDqs6; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS7 */ | ||||
| 	uint32_t EmcDliTrimTxDqs7; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS8 */ | ||||
| 	uint32_t EmcDliTrimTxDqs8; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS9 */ | ||||
| 	uint32_t EmcDliTrimTxDqs9; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS10 */ | ||||
| 	uint32_t EmcDliTrimTxDqs10; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS11 */ | ||||
| 	uint32_t EmcDliTrimTxDqs11; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS12 */ | ||||
| 	uint32_t EmcDliTrimTxDqs12; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS13 */ | ||||
| 	uint32_t EmcDliTrimTxDqs13; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS14 */ | ||||
| 	uint32_t EmcDliTrimTxDqs14; | ||||
| 	/* Specifies the value for EMC_DLI_TRIM_TXDQS15 */ | ||||
| 	uint32_t EmcDliTrimTxDqs15; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ0 */ | ||||
| 	uint32_t EmcDllXformDq0; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ1 */ | ||||
| 	uint32_t EmcDllXformDq1; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ2 */ | ||||
| 	uint32_t EmcDllXformDq2; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ3 */ | ||||
| 	uint32_t EmcDllXformDq3; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ4 */ | ||||
| 	uint32_t EmcDllXformDq4; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ5 */ | ||||
| 	uint32_t EmcDllXformDq5; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ6 */ | ||||
| 	uint32_t EmcDllXformDq6; | ||||
| 	/* Specifies the value for EMC_DLL_XFORM_DQ7 */ | ||||
| 	uint32_t EmcDllXformDq7; | ||||
|  | ||||
| 	/* | ||||
| 	 * Specifies the delay after asserting CKE pin during a WarmBoot0 | ||||
| 	 * sequence (in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t WarmBootWait; | ||||
|  | ||||
| 	/* Specifies the value for EMC_CTT_TERM_CTRL */ | ||||
| 	uint32_t EmcCttTermCtrl; | ||||
|  | ||||
| 	/* Specifies the value for EMC_ODT_WRITE */ | ||||
| 	uint32_t EmcOdtWrite; | ||||
| 	/* Specifies the value for EMC_ODT_WRITE */ | ||||
| 	uint32_t EmcOdtRead; | ||||
|  | ||||
| 	/* Periodic ZQ calibration */ | ||||
|  | ||||
| 	/* | ||||
| 	 * Specifies the value for EMC_ZCAL_INTERVAL | ||||
| 	 * Value 0 disables ZQ calibration | ||||
| 	 */ | ||||
| 	uint32_t EmcZcalInterval; | ||||
| 	/* Specifies the value for EMC_ZCAL_WAIT_CNT */ | ||||
| 	uint32_t EmcZcalWaitCnt; | ||||
| 	/* Specifies the value for EMC_ZCAL_MRW_CMD */ | ||||
| 	uint32_t EmcZcalMrwCmd; | ||||
|  | ||||
| 	/* DRAM initialization sequence flow control */ | ||||
|  | ||||
| 	/* Specifies the MRS command value for resetting DLL */ | ||||
| 	uint32_t EmcMrsResetDll; | ||||
| 	/* Specifies the command for ZQ initialization of device 0 */ | ||||
| 	uint32_t EmcZcalInitDev0; | ||||
| 	/* Specifies the command for ZQ initialization of device 1 */ | ||||
| 	uint32_t EmcZcalInitDev1; | ||||
| 	/* | ||||
| 	 * Specifies the wait time after programming a ZQ initialization | ||||
| 	 * command (in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t EmcZcalInitWait; | ||||
| 	/* | ||||
| 	 * Specifies the enable for ZQ calibration at cold boot [bit 0] | ||||
| 	 * and warm boot [bit 1] | ||||
| 	 */ | ||||
| 	uint32_t EmcZcalWarmColdBootEnables; | ||||
|  | ||||
| 	/* | ||||
| 	 * Specifies the MRW command to LPDDR2 for ZQ calibration | ||||
| 	 * on warmboot | ||||
| 	 */ | ||||
| 	/* Is issued to both devices separately */ | ||||
| 	uint32_t EmcMrwLpddr2ZcalWarmBoot; | ||||
| 	/* | ||||
| 	 * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot | ||||
| 	 * Is issued to both devices separately | ||||
| 	 */ | ||||
| 	uint32_t EmcZqCalDdr3WarmBoot; | ||||
| 	/* | ||||
| 	 * Specifies the wait time for ZQ calibration on warmboot | ||||
| 	 * (in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t EmcZcalWarmBootWait; | ||||
| 	/* | ||||
| 	 * Specifies the enable for DRAM Mode Register programming | ||||
| 	 * at warm boot | ||||
| 	 */ | ||||
| 	uint32_t EmcMrsWarmBootEnable; | ||||
| 	/* | ||||
| 	 * Specifies the wait time after sending an MRS DLL reset command | ||||
| 	 * in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t EmcMrsResetDllWait; | ||||
| 	/* Specifies the extra MRS command to initialize mode registers */ | ||||
| 	uint32_t EmcMrsExtra; | ||||
| 	/* Specifies the extra MRS command at warm boot */ | ||||
| 	uint32_t EmcWarmBootMrsExtra; | ||||
| 	/* Specifies the EMRS command to enable the DDR2 DLL */ | ||||
| 	uint32_t EmcEmrsDdr2DllEnable; | ||||
| 	/* Specifies the MRS command to reset the DDR2 DLL */ | ||||
| 	uint32_t EmcMrsDdr2DllReset; | ||||
| 	/* Specifies the EMRS command to set OCD calibration */ | ||||
| 	uint32_t EmcEmrsDdr2OcdCalib; | ||||
| 	/* | ||||
| 	 * Specifies the wait between initializing DDR and setting OCD | ||||
| 	 * calibration (in microseconds) | ||||
| 	 */ | ||||
| 	uint32_t EmcDdr2Wait; | ||||
| 	/* Specifies the value for EMC_CLKEN_OVERRIDE */ | ||||
| 	uint32_t EmcClkenOverride; | ||||
| 	/* Specifies the value for MC_DIS_EXTRA_SNAP_LEVELS */ | ||||
| 	uint32_t McDisExtraSnapLevels; | ||||
| 	/* | ||||
| 	 * Specifies LOG2 of the extra refresh numbers after booting | ||||
| 	 * Program 0 to disable | ||||
| 	 */ | ||||
| 	uint32_t EmcExtraRefreshNum; | ||||
| 	/* Specifies the master override for all EMC clocks */ | ||||
| 	uint32_t EmcClkenOverrideAllWarmBoot; | ||||
| 	/* Specifies the master override for all MC clocks */ | ||||
| 	uint32_t McClkenOverrideAllWarmBoot; | ||||
| 	/* Specifies digital dll period, choosing between 4 to 64 ms */ | ||||
| 	uint32_t EmcCfgDigDllPeriodWarmBoot; | ||||
|  | ||||
| 	/* Pad controls */ | ||||
|  | ||||
| 	/* Specifies the value for PMC_VDDP_SEL */ | ||||
| 	uint32_t PmcVddpSel; | ||||
| 	/* Specifies the wait time after programming PMC_VDDP_SEL */ | ||||
| 	uint32_t PmcVddpSelWait; | ||||
| 	/* Specifies the value for PMC_DDR_PWR */ | ||||
| 	uint32_t PmcDdrPwr; | ||||
| 	/* Specifies the value for PMC_DDR_CFG */ | ||||
| 	uint32_t PmcDdrCfg; | ||||
| 	/* Specifies the value for PMC_IO_DPD3_REQ */ | ||||
| 	uint32_t PmcIoDpd3Req; | ||||
| 	/* Specifies the wait time after programming PMC_IO_DPD3_REQ */ | ||||
| 	uint32_t PmcIoDpd3ReqWait; | ||||
| 	/* Specifies the value for PMC_REG_SHORT */ | ||||
| 	uint32_t PmcRegShort; | ||||
| 	/* Specifies the value for PMC_NO_IOPOWER */ | ||||
| 	uint32_t PmcNoIoPower; | ||||
| 	/* Specifies the wait time after programming PMC_POR_DPD_CTRL */ | ||||
| 	uint32_t PmcPorDpdCtrlWait; | ||||
| 	/* Specifies the value for EMC_XM2CMDPADCTRL */ | ||||
| 	uint32_t EmcXm2CmdPadCtrl; | ||||
| 	/* Specifies the value for EMC_XM2CMDPADCTRL2 */ | ||||
| 	uint32_t EmcXm2CmdPadCtrl2; | ||||
| 	/* Specifies the value for EMC_XM2CMDPADCTRL3 */ | ||||
| 	uint32_t EmcXm2CmdPadCtrl3; | ||||
| 	/* Specifies the value for EMC_XM2CMDPADCTRL4 */ | ||||
| 	uint32_t EmcXm2CmdPadCtrl4; | ||||
| 	/* Specifies the value for EMC_XM2CMDPADCTRL5 */ | ||||
| 	uint32_t EmcXm2CmdPadCtrl5; | ||||
| 	/* Specifies the value for EMC_XM2DQSPADCTRL */ | ||||
| 	uint32_t EmcXm2DqsPadCtrl; | ||||
| 	/* Specifies the value for EMC_XM2DQSPADCTRL2 */ | ||||
| 	uint32_t EmcXm2DqsPadCtrl2; | ||||
| 	/* Specifies the value for EMC_XM2DQSPADCTRL3 */ | ||||
| 	uint32_t EmcXm2DqsPadCtrl3; | ||||
| 	/* Specifies the value for EMC_XM2DQSPADCTRL4 */ | ||||
| 	uint32_t EmcXm2DqsPadCtrl4; | ||||
| 	/* Specifies the value for EMC_XM2DQSPADCTRL5 */ | ||||
| 	uint32_t EmcXm2DqsPadCtrl5; | ||||
| 	/* Specifies the value for EMC_XM2DQSPADCTRL6 */ | ||||
| 	uint32_t EmcXm2DqsPadCtrl6; | ||||
| 	/* Specifies the value for EMC_XM2DQPADCTRL */ | ||||
| 	uint32_t EmcXm2DqPadCtrl; | ||||
| 	/* Specifies the value for EMC_XM2DQPADCTRL2 */ | ||||
| 	uint32_t EmcXm2DqPadCtrl2; | ||||
| 	/* Specifies the value for EMC_XM2DQPADCTRL3 */ | ||||
| 	uint32_t EmcXm2DqPadCtrl3; | ||||
| 	/* Specifies the value for EMC_XM2CLKPADCTRL */ | ||||
| 	uint32_t EmcXm2ClkPadCtrl; | ||||
| 	/* Specifies the value for EMC_XM2CLKPADCTRL2 */ | ||||
| 	uint32_t EmcXm2ClkPadCtrl2; | ||||
| 	/* Specifies the value for EMC_XM2COMPPADCTRL */ | ||||
| 	uint32_t EmcXm2CompPadCtrl; | ||||
| 	/* Specifies the value for EMC_XM2VTTGENPADCTRL */ | ||||
| 	uint32_t EmcXm2VttGenPadCtrl; | ||||
| 	/* Specifies the value for EMC_XM2VTTGENPADCTRL2 */ | ||||
| 	uint32_t EmcXm2VttGenPadCtrl2; | ||||
| 	/* Specifies the value for EMC_XM2VTTGENPADCTRL3 */ | ||||
| 	uint32_t EmcXm2VttGenPadCtrl3; | ||||
| 	/* Specifies the value for EMC_ACPD_CONTROL */ | ||||
| 	uint32_t EmcAcpdControl; | ||||
|  | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */ | ||||
| 	uint32_t EmcSwizzleRank0ByteCfg; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */ | ||||
| 	uint32_t EmcSwizzleRank0Byte0; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */ | ||||
| 	uint32_t EmcSwizzleRank0Byte1; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */ | ||||
| 	uint32_t EmcSwizzleRank0Byte2; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */ | ||||
| 	uint32_t EmcSwizzleRank0Byte3; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */ | ||||
| 	uint32_t EmcSwizzleRank1ByteCfg; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */ | ||||
| 	uint32_t EmcSwizzleRank1Byte0; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */ | ||||
| 	uint32_t EmcSwizzleRank1Byte1; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */ | ||||
| 	uint32_t EmcSwizzleRank1Byte2; | ||||
| 	/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */ | ||||
| 	uint32_t EmcSwizzleRank1Byte3; | ||||
|  | ||||
| 	/* Specifies the value for EMC_DSR_VTTGEN_DRV */ | ||||
| 	uint32_t EmcDsrVttgenDrv; | ||||
|  | ||||
| 	/* Specifies the value for EMC_TXDSRVTTGEN */ | ||||
| 	uint32_t EmcTxdsrvttgen; | ||||
| 	/* Specifies the value for EMC_BGBIAS_CTL */ | ||||
| 	uint32_t EmcBgbiasCtl0; | ||||
|  | ||||
| 	/* DRAM size information */ | ||||
|  | ||||
| 	/* Specifies the value for MC_EMEM_ADR_CFG */ | ||||
| 	uint32_t McEmemAdrCfg; | ||||
| 	/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */ | ||||
| 	uint32_t McEmemAdrCfgDev0; | ||||
| 	/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */ | ||||
| 	uint32_t McEmemAdrCfgDev1; | ||||
| 	/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */ | ||||
| 	uint32_t McEmemAdrCfgBankMask0; | ||||
| 	/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */ | ||||
| 	uint32_t McEmemAdrCfgBankMask1; | ||||
| 	/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */ | ||||
| 	uint32_t McEmemAdrCfgBankMask2; | ||||
| 	/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG3 */ | ||||
| 	uint32_t McEmemAdrCfgBankSwizzle3; | ||||
|  | ||||
| 	/* | ||||
| 	 * Specifies the value for MC_EMEM_CFG which holds the external memory | ||||
| 	 * size (in KBytes) | ||||
| 	 */ | ||||
| 	uint32_t McEmemCfg; | ||||
|  | ||||
| 	/* MC arbitration configuration */ | ||||
|  | ||||
| 	/* Specifies the value for MC_EMEM_ARB_CFG */ | ||||
| 	uint32_t McEmemArbCfg; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */ | ||||
| 	uint32_t McEmemArbOutstandingReq; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */ | ||||
| 	uint32_t McEmemArbTimingRcd; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_RP */ | ||||
| 	uint32_t McEmemArbTimingRp; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_RC */ | ||||
| 	uint32_t McEmemArbTimingRc; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */ | ||||
| 	uint32_t McEmemArbTimingRas; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */ | ||||
| 	uint32_t McEmemArbTimingFaw; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */ | ||||
| 	uint32_t McEmemArbTimingRrd; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */ | ||||
| 	uint32_t McEmemArbTimingRap2Pre; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */ | ||||
| 	uint32_t McEmemArbTimingWap2Pre; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */ | ||||
| 	uint32_t McEmemArbTimingR2R; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */ | ||||
| 	uint32_t McEmemArbTimingW2W; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */ | ||||
| 	uint32_t McEmemArbTimingR2W; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */ | ||||
| 	uint32_t McEmemArbTimingW2R; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_DA_TURNS */ | ||||
| 	uint32_t McEmemArbDaTurns; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_DA_COVERS */ | ||||
| 	uint32_t McEmemArbDaCovers; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_MISC0 */ | ||||
| 	uint32_t McEmemArbMisc0; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_MISC1 */ | ||||
| 	uint32_t McEmemArbMisc1; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */ | ||||
| 	uint32_t McEmemArbRing1Throttle; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_OVERRIDE */ | ||||
| 	uint32_t McEmemArbOverride; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */ | ||||
| 	uint32_t McEmemArbOverride1; | ||||
| 	/* Specifies the value for MC_EMEM_ARB_RSV */ | ||||
| 	uint32_t McEmemArbRsv; | ||||
|  | ||||
| 	/* Specifies the value for MC_CLKEN_OVERRIDE */ | ||||
| 	uint32_t McClkenOverride; | ||||
|  | ||||
| 	/* Specifies the value for MC_STAT_CONTROL */ | ||||
| 	uint32_t McStatControl; | ||||
| 	/* Specifies the value for MC_DISPLAY_SNAP_RING */ | ||||
| 	uint32_t McDisplaySnapRing; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_BOM */ | ||||
| 	uint32_t McVideoProtectBom; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */ | ||||
| 	uint32_t McVideoProtectBomAdrHi; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */ | ||||
| 	uint32_t McVideoProtectSizeMb; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */ | ||||
| 	uint32_t McVideoProtectVprOverride; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */ | ||||
| 	uint32_t McVideoProtectVprOverride1; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */ | ||||
| 	uint32_t McVideoProtectGpuOverride0; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */ | ||||
| 	uint32_t McVideoProtectGpuOverride1; | ||||
| 	/* Specifies the value for MC_SEC_CARVEOUT_BOM */ | ||||
| 	uint32_t McSecCarveoutBom; | ||||
| 	/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */ | ||||
| 	uint32_t McSecCarveoutAdrHi; | ||||
| 	/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */ | ||||
| 	uint32_t McSecCarveoutSizeMb; | ||||
| 	/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */ | ||||
| 	uint32_t McVideoProtectWriteAccess; | ||||
| 	/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */ | ||||
| 	uint32_t McSecCarveoutProtectWriteAccess; | ||||
|  | ||||
| 	/* Specifies enable for CA training */ | ||||
| 	uint32_t EmcCaTrainingEnable; | ||||
| 	/* Specifies the value for EMC_CA_TRAINING_TIMING_CNTRL1 */ | ||||
| 	uint32_t EmcCaTrainingTimingCntl1; | ||||
| 	/* Specifies the value for EMC_CA_TRAINING_TIMING_CNTRL2 */ | ||||
| 	uint32_t EmcCaTrainingTimingCntl2; | ||||
| 	/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */ | ||||
| 	uint32_t SwizzleRankByteEncode; | ||||
| 	/* Specifies enable and offset for patched boot rom write */ | ||||
| 	uint32_t BootRomPatchControl; | ||||
| 	/* Specifies data for patched boot rom write */ | ||||
| 	uint32_t BootRomPatchData; | ||||
| 	/* Specifies the value for MC_MTS_CARVEOUT_BOM */ | ||||
| 	uint32_t McMtsCarveoutBom; | ||||
| 	/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */ | ||||
| 	uint32_t McMtsCarveoutAdrHi; | ||||
| 	/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */ | ||||
| 	uint32_t McMtsCarveoutSizeMb; | ||||
| 	/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */ | ||||
| 	uint32_t McMtsCarveoutRegCtrl; | ||||
|  | ||||
| 	/* End of generated code by warmboot_code_gen */ | ||||
| }; | ||||
|  | ||||
| check_member(sdram_params, McMtsCarveoutRegCtrl, 0x4d0); | ||||
|  | ||||
| #endif /* __SOC_NVIDIA_TEGRA124_SDRAM_PARAM_H__ */ | ||||
		Reference in New Issue
	
	Block a user