xref: /arm-trusted-firmware/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (C) 2018 Marvell International Ltd.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier:	BSD-3-Clause
5*91f16700Schasinglulu  * https://spdx.org/licenses
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <arch_helpers.h>
9*91f16700Schasinglulu #include <common/debug.h>
10*91f16700Schasinglulu #include <drivers/mentor/mi2cv.h>
11*91f16700Schasinglulu #include <lib/mmio.h>
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include <mv_ddr_if.h>
14*91f16700Schasinglulu #include <mvebu_def.h>
15*91f16700Schasinglulu #include <plat_marvell.h>
16*91f16700Schasinglulu 
17*91f16700Schasinglulu #define MVEBU_CP_MPP_CTRL37_OFFS		20
18*91f16700Schasinglulu #define MVEBU_CP_MPP_CTRL38_OFFS		24
19*91f16700Schasinglulu #define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA	0x2
20*91f16700Schasinglulu #define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA	0x2
21*91f16700Schasinglulu 
22*91f16700Schasinglulu #define MVEBU_MPP_CTRL_MASK			0xf
23*91f16700Schasinglulu 
24*91f16700Schasinglulu /*
25*91f16700Schasinglulu  * This struct provides the DRAM training code with
26*91f16700Schasinglulu  * the appropriate board DRAM configuration
27*91f16700Schasinglulu  */
28*91f16700Schasinglulu struct mv_ddr_iface dram_iface_ap0 = {
29*91f16700Schasinglulu 	.ap_base = MVEBU_REGS_BASE_AP(0),
30*91f16700Schasinglulu 	.state = MV_DDR_IFACE_NRDY,
31*91f16700Schasinglulu 	.validation = MV_DDR_MEMORY_CHECK,
32*91f16700Schasinglulu 	.sscg = SSCG_EN,
33*91f16700Schasinglulu 	.id = 0,
34*91f16700Schasinglulu 	.iface_base_addr = 0,
35*91f16700Schasinglulu 	.tm = {
36*91f16700Schasinglulu 		DEBUG_LEVEL_ERROR,
37*91f16700Schasinglulu 		0x1, /* active interfaces */
38*91f16700Schasinglulu 		/* cs_mask, mirror, dqs_swap, ck_swap X subphys */
39*91f16700Schasinglulu 		{ { { {0x1, 0x0, 0, 0},
40*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
41*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
42*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
43*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
44*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
45*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
46*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0},
47*91f16700Schasinglulu 		      {0x1, 0x0, 0, 0} },
48*91f16700Schasinglulu 		   SPEED_BIN_DDR_2400T,		/* speed_bin */
49*91f16700Schasinglulu 		   MV_DDR_DEV_WIDTH_8BIT,	/* sdram device width */
50*91f16700Schasinglulu 		   MV_DDR_DIE_CAP_8GBIT,	/* die capacity */
51*91f16700Schasinglulu 		   MV_DDR_FREQ_SAR,		/* frequency */
52*91f16700Schasinglulu 		   0, 0,			/* cas_l, cas_wl */
53*91f16700Schasinglulu 		   MV_DDR_TEMP_LOW} },		/* temperature */
54*91f16700Schasinglulu #if DDR32
55*91f16700Schasinglulu 		MV_DDR_32BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
56*91f16700Schasinglulu #else
57*91f16700Schasinglulu 		MV_DDR_64BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
58*91f16700Schasinglulu #endif
59*91f16700Schasinglulu 		MV_DDR_CFG_SPD,			/* ddr configuration data src */
60*91f16700Schasinglulu 		NOT_COMBINED,			/* ddr twin-die combined*/
61*91f16700Schasinglulu 		{ {0} },			/* raw spd data */
62*91f16700Schasinglulu 		{0},				/* timing parameters */
63*91f16700Schasinglulu 		{	/* electrical configuration */
64*91f16700Schasinglulu 			{	/* memory electrical configuration */
65*91f16700Schasinglulu 				MV_DDR_RTT_NOM_PARK_RZQ_DISABLE,  /* rtt_nom */
66*91f16700Schasinglulu 				{	/* rtt_park 1cs */
67*91f16700Schasinglulu 					MV_DDR_RTT_NOM_PARK_RZQ_DIV4,
68*91f16700Schasinglulu 					/* rtt_park 2cs */
69*91f16700Schasinglulu 					MV_DDR_RTT_NOM_PARK_RZQ_DIV1
70*91f16700Schasinglulu 				},
71*91f16700Schasinglulu 				{	/* rtt_wr 1cs */
72*91f16700Schasinglulu 					MV_DDR_RTT_WR_DYN_ODT_OFF,
73*91f16700Schasinglulu 					/* rtt_wr 2cs */
74*91f16700Schasinglulu 					MV_DDR_RTT_WR_RZQ_DIV2
75*91f16700Schasinglulu 				},
76*91f16700Schasinglulu 				MV_DDR_DIC_RZQ_DIV7	/* dic */
77*91f16700Schasinglulu 			},
78*91f16700Schasinglulu 			{	/* phy electrical configuration */
79*91f16700Schasinglulu 				MV_DDR_OHM_30,	/* data_drv_p */
80*91f16700Schasinglulu 				MV_DDR_OHM_30,	/* data_drv_n */
81*91f16700Schasinglulu 				MV_DDR_OHM_30,	/* ctrl_drv_p */
82*91f16700Schasinglulu 				MV_DDR_OHM_30,	/* ctrl_drv_n */
83*91f16700Schasinglulu 				{
84*91f16700Schasinglulu 					MV_DDR_OHM_60,	/* odt_p 1cs */
85*91f16700Schasinglulu 					MV_DDR_OHM_120	/* odt_p 2cs */
86*91f16700Schasinglulu 				},
87*91f16700Schasinglulu 				{
88*91f16700Schasinglulu 					MV_DDR_OHM_60,	/* odt_n 1cs */
89*91f16700Schasinglulu 					MV_DDR_OHM_120	/* odt_n 2cs */
90*91f16700Schasinglulu 				},
91*91f16700Schasinglulu 			},
92*91f16700Schasinglulu 			{	/* mac electrical configuration */
93*91f16700Schasinglulu 				MV_DDR_ODT_CFG_NORMAL,	/* odtcfg_pattern */
94*91f16700Schasinglulu 				MV_DDR_ODT_CFG_ALWAYS_ON,/* odtcfg_write */
95*91f16700Schasinglulu 				MV_DDR_ODT_CFG_NORMAL	/* odtcfg_read */
96*91f16700Schasinglulu 			},
97*91f16700Schasinglulu 		},
98*91f16700Schasinglulu 	},
99*91f16700Schasinglulu };
100*91f16700Schasinglulu 
101*91f16700Schasinglulu /* Pointer to the first DRAM interface in the system */
102*91f16700Schasinglulu struct mv_ddr_iface *ptr_iface = &dram_iface_ap0;
103*91f16700Schasinglulu 
104*91f16700Schasinglulu struct mv_ddr_iface *mv_ddr_iface_get(void)
105*91f16700Schasinglulu {
106*91f16700Schasinglulu 	/* Return current ddr interface */
107*91f16700Schasinglulu 	return ptr_iface;
108*91f16700Schasinglulu }
109*91f16700Schasinglulu 
110*91f16700Schasinglulu struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
111*91f16700Schasinglulu {
112*91f16700Schasinglulu 	/* Return the board topology as defined in the board code */
113*91f16700Schasinglulu 	return &ptr_iface->tm;
114*91f16700Schasinglulu }
115*91f16700Schasinglulu 
116*91f16700Schasinglulu static void mpp_config(void)
117*91f16700Schasinglulu {
118*91f16700Schasinglulu 	uintptr_t reg;
119*91f16700Schasinglulu 	uint32_t val;
120*91f16700Schasinglulu 
121*91f16700Schasinglulu 	reg = MVEBU_CP_MPP_REGS(0, 4);
122*91f16700Schasinglulu 	/* configure CP0 MPP 37 and 38 to i2c */
123*91f16700Schasinglulu 	val = mmio_read_32(reg);
124*91f16700Schasinglulu 	val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
125*91f16700Schasinglulu 		(MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
126*91f16700Schasinglulu 	val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA <<
127*91f16700Schasinglulu 			MVEBU_CP_MPP_CTRL37_OFFS) |
128*91f16700Schasinglulu 		(MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA <<
129*91f16700Schasinglulu 			MVEBU_CP_MPP_CTRL38_OFFS);
130*91f16700Schasinglulu 	mmio_write_32(reg, val);
131*91f16700Schasinglulu }
132*91f16700Schasinglulu 
133*91f16700Schasinglulu /*
134*91f16700Schasinglulu  * This function may modify the default DRAM parameters
135*91f16700Schasinglulu  * based on information received from SPD or bootloader
136*91f16700Schasinglulu  * configuration located on non volatile storage
137*91f16700Schasinglulu  */
138*91f16700Schasinglulu void plat_marvell_dram_update_topology(void)
139*91f16700Schasinglulu {
140*91f16700Schasinglulu 	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
141*91f16700Schasinglulu 
142*91f16700Schasinglulu 	INFO("Gathering DRAM information\n");
143*91f16700Schasinglulu 
144*91f16700Schasinglulu 	if (tm->cfg_src == MV_DDR_CFG_SPD) {
145*91f16700Schasinglulu 		/* configure MPPs to enable i2c */
146*91f16700Schasinglulu 		mpp_config();
147*91f16700Schasinglulu 
148*91f16700Schasinglulu 		/* initialize i2c */
149*91f16700Schasinglulu 		i2c_init((void *)MVEBU_CP0_I2C_BASE);
150*91f16700Schasinglulu 
151*91f16700Schasinglulu 		/* select SPD memory page 0 to access DRAM configuration */
152*91f16700Schasinglulu 		i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 0);
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 		/* read data from spd */
155*91f16700Schasinglulu 		i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
156*91f16700Schasinglulu 			 sizeof(tm->spd_data.all_bytes));
157*91f16700Schasinglulu 	}
158*91f16700Schasinglulu }
159