aboutsummaryrefslogtreecommitdiff
path: root/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
blob: 0befadfc63e5ebc249f2f226245998486f992a5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * Copyright (C) 2018 Marvell International Ltd.
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 * https://spdx.org/licenses
 */

#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/mentor/mi2cv.h>
#include <lib/mmio.h>

#include <mv_ddr_if.h>
#include <mvebu_def.h>
#include <plat_marvell.h>

#define MVEBU_CP_MPP_CTRL37_OFFS		20
#define MVEBU_CP_MPP_CTRL38_OFFS		24
#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA	0x2
#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA	0x2

#define MVEBU_MPP_CTRL_MASK			0xf

/*
 * This struct provides the DRAM training code with
 * the appropriate board DRAM configuration
 */
struct mv_ddr_iface dram_iface_ap0 = {
	.ap_base = MVEBU_REGS_BASE_AP(0),
	.state = MV_DDR_IFACE_NRDY,
	.validation = MV_DDR_MEMORY_CHECK,
	.sscg = SSCG_EN,
	.id = 0,
	.iface_base_addr = 0,
	.tm = {
		DEBUG_LEVEL_ERROR,
		0x1, /* active interfaces */
		/* cs_mask, mirror, dqs_swap, ck_swap X subphys */
		{ { { {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0},
		      {0x1, 0x0, 0, 0} },
		   SPEED_BIN_DDR_2400T,		/* speed_bin */
		   MV_DDR_DEV_WIDTH_8BIT,	/* sdram device width */
		   MV_DDR_DIE_CAP_8GBIT,	/* die capacity */
		   MV_DDR_FREQ_SAR,		/* frequency */
		   0, 0,			/* cas_l, cas_wl */
		   MV_DDR_TEMP_LOW} },		/* temperature */
#if DDR32
		MV_DDR_32BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
#else
		MV_DDR_64BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
#endif
		MV_DDR_CFG_SPD,			/* ddr configuration data src */
		NOT_COMBINED,			/* ddr twin-die combined*/
		{ {0} },			/* raw spd data */
		{0},				/* timing parameters */
		{	/* electrical configuration */
			{	/* memory electrical configuration */
				MV_DDR_RTT_NOM_PARK_RZQ_DISABLE,  /* rtt_nom */
				{	/* rtt_park 1cs */
					MV_DDR_RTT_NOM_PARK_RZQ_DIV4,
					/* rtt_park 2cs */
					MV_DDR_RTT_NOM_PARK_RZQ_DIV1
				},
				{	/* rtt_wr 1cs */
					MV_DDR_RTT_WR_DYN_ODT_OFF,
					/* rtt_wr 2cs */
					MV_DDR_RTT_WR_RZQ_DIV2
				},
				MV_DDR_DIC_RZQ_DIV7	/* dic */
			},
			{	/* phy electrical configuration */
				MV_DDR_OHM_30,	/* data_drv_p */
				MV_DDR_OHM_30,	/* data_drv_n */
				MV_DDR_OHM_30,	/* ctrl_drv_p */
				MV_DDR_OHM_30,	/* ctrl_drv_n */
				{
					MV_DDR_OHM_60,	/* odt_p 1cs */
					MV_DDR_OHM_120	/* odt_p 2cs */
				},
				{
					MV_DDR_OHM_60,	/* odt_n 1cs */
					MV_DDR_OHM_120	/* odt_n 2cs */
				},
			},
			{	/* mac electrical configuration */
				MV_DDR_ODT_CFG_NORMAL,	/* odtcfg_pattern */
				MV_DDR_ODT_CFG_ALWAYS_ON,/* odtcfg_write */
				MV_DDR_ODT_CFG_NORMAL	/* odtcfg_read */
			},
		},
	},
};

/* Pointer to the first DRAM interface in the system */
struct mv_ddr_iface *ptr_iface = &dram_iface_ap0;

struct mv_ddr_iface *mv_ddr_iface_get(void)
{
	/* Return current ddr interface */
	return ptr_iface;
}

struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
{
	/* Return the board topology as defined in the board code */
	return &ptr_iface->tm;
}

static void mpp_config(void)
{
	uintptr_t reg;
	uint32_t val;

	reg = MVEBU_CP_MPP_REGS(0, 4);
	/* configure CP0 MPP 37 and 38 to i2c */
	val = mmio_read_32(reg);
	val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
		(MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
	val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA <<
			MVEBU_CP_MPP_CTRL37_OFFS) |
		(MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA <<
			MVEBU_CP_MPP_CTRL38_OFFS);
	mmio_write_32(reg, val);
}

/*
 * This function may modify the default DRAM parameters
 * based on information received from SPD or bootloader
 * configuration located on non volatile storage
 */
void plat_marvell_dram_update_topology(void)
{
	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();

	INFO("Gathering DRAM information\n");

	if (tm->cfg_src == MV_DDR_CFG_SPD) {
		/* configure MPPs to enable i2c */
		mpp_config();

		/* initialize i2c */
		i2c_init((void *)MVEBU_CP0_I2C_BASE);

		/* select SPD memory page 0 to access DRAM configuration */
		i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1);

		/* read data from spd */
		i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
			 sizeof(tm->spd_data.all_bytes));
	}
}