xref: /rk3399_ARM-atf/plat/intel/soc/common/drivers/ddr/ddr.c (revision 29461e4c880235532385c01f202e638fb5ba11de)
1*29461e4cSJit Loon Lim /*
2*29461e4cSJit Loon Lim  * Copyright (c) 2022, Intel Corporation. All rights reserved.
3*29461e4cSJit Loon Lim  *
4*29461e4cSJit Loon Lim  * SPDX-License-Identifier: BSD-3-Clause
5*29461e4cSJit Loon Lim  */
6*29461e4cSJit Loon Lim 
7*29461e4cSJit Loon Lim #include <assert.h>
8*29461e4cSJit Loon Lim #include <errno.h>
9*29461e4cSJit Loon Lim #include <common/debug.h>
10*29461e4cSJit Loon Lim #include "ddr.h"
11*29461e4cSJit Loon Lim #include <lib/mmio.h>
12*29461e4cSJit Loon Lim #include "socfpga_handoff.h"
13*29461e4cSJit Loon Lim 
14*29461e4cSJit Loon Lim int ddr_calibration_check(void)
15*29461e4cSJit Loon Lim {
16*29461e4cSJit Loon Lim 	// DDR calibration check
17*29461e4cSJit Loon Lim 	int status = 0;
18*29461e4cSJit Loon Lim 	uint32_t u32data_read = 0;
19*29461e4cSJit Loon Lim 
20*29461e4cSJit Loon Lim 	NOTICE("DDR: Access address 0x%x:...\n", IO96B_0_REG_BASE);
21*29461e4cSJit Loon Lim 	u32data_read = mmio_read_32(IO96B_0_REG_BASE);
22*29461e4cSJit Loon Lim 	NOTICE("DDR: Access address 0x%x: read 0x%04x\n", IO96B_0_REG_BASE, u32data_read);
23*29461e4cSJit Loon Lim 
24*29461e4cSJit Loon Lim 	if (u32data_read == -EPERM) {
25*29461e4cSJit Loon Lim 		status = -EPERM;
26*29461e4cSJit Loon Lim 		assert(u32data_read);
27*29461e4cSJit Loon Lim 	}
28*29461e4cSJit Loon Lim 
29*29461e4cSJit Loon Lim 	u32data_read = 0x0;
30*29461e4cSJit Loon Lim 	NOTICE("DDR: Access address 0x%x: ...\n", IO96B_1_REG_BASE);
31*29461e4cSJit Loon Lim 	u32data_read = mmio_read_32(IO96B_1_REG_BASE);
32*29461e4cSJit Loon Lim 	NOTICE("DDR: Access address 0x%x: read 0x%04x\n", IO96B_1_REG_BASE, u32data_read);
33*29461e4cSJit Loon Lim 
34*29461e4cSJit Loon Lim 	if (u32data_read == -EPERM) {
35*29461e4cSJit Loon Lim 		status = -EPERM;
36*29461e4cSJit Loon Lim 		assert(u32data_read);
37*29461e4cSJit Loon Lim 	}
38*29461e4cSJit Loon Lim 
39*29461e4cSJit Loon Lim 	return status;
40*29461e4cSJit Loon Lim }
41*29461e4cSJit Loon Lim 
42*29461e4cSJit Loon Lim int iossm_mb_init(void)
43*29461e4cSJit Loon Lim {
44*29461e4cSJit Loon Lim 	// int status;
45*29461e4cSJit Loon Lim 
46*29461e4cSJit Loon Lim 	// Update according to IOSSM mailbox spec
47*29461e4cSJit Loon Lim 
48*29461e4cSJit Loon Lim 	// if (status) {
49*29461e4cSJit Loon Lim 		// return status;
50*29461e4cSJit Loon Lim 	// }
51*29461e4cSJit Loon Lim 
52*29461e4cSJit Loon Lim 	return 0;
53*29461e4cSJit Loon Lim }
54*29461e4cSJit Loon Lim 
55*29461e4cSJit Loon Lim int wait_respond(uint16_t timeout)
56*29461e4cSJit Loon Lim {
57*29461e4cSJit Loon Lim 	uint32_t status = 0;
58*29461e4cSJit Loon Lim 	uint32_t count = 0;
59*29461e4cSJit Loon Lim 	uint32_t data = 0;
60*29461e4cSJit Loon Lim 
61*29461e4cSJit Loon Lim 	/* Wait status command response ready */
62*29461e4cSJit Loon Lim 	do {
63*29461e4cSJit Loon Lim 		data = mmio_read_32(IO96B_CSR_REG(CMD_RESPONSE_STATUS));
64*29461e4cSJit Loon Lim 		count++;
65*29461e4cSJit Loon Lim 		if (count >= timeout) {
66*29461e4cSJit Loon Lim 			return -ETIMEDOUT;
67*29461e4cSJit Loon Lim 		}
68*29461e4cSJit Loon Lim 
69*29461e4cSJit Loon Lim 	} while (STATUS_COMMAND_RESPONSE(data) != STATUS_COMMAND_RESPONSE_READY);
70*29461e4cSJit Loon Lim 
71*29461e4cSJit Loon Lim 	status = (data & STATUS_GENERAL_ERROR_MASK) >> STATUS_GENERAL_ERROR_OFFSET;
72*29461e4cSJit Loon Lim 	if (status != 0) {
73*29461e4cSJit Loon Lim 		return status;
74*29461e4cSJit Loon Lim 	}
75*29461e4cSJit Loon Lim 
76*29461e4cSJit Loon Lim 	status = (data & STATUS_CMD_RESPONSE_ERROR_MASK) >> STATUS_CMD_RESPONSE_ERROR_OFFSET;
77*29461e4cSJit Loon Lim 	if (status != 0) {
78*29461e4cSJit Loon Lim 		return status;
79*29461e4cSJit Loon Lim 	}
80*29461e4cSJit Loon Lim 
81*29461e4cSJit Loon Lim 	return status;
82*29461e4cSJit Loon Lim }
83*29461e4cSJit Loon Lim 
84*29461e4cSJit Loon Lim int iossm_mb_read_response(void)
85*29461e4cSJit Loon Lim {
86*29461e4cSJit Loon Lim 	uint32_t status = 0;
87*29461e4cSJit Loon Lim 	unsigned int i;
88*29461e4cSJit Loon Lim 	uint32_t resp_data[IOSSM_RESP_MAX_WORD_SIZE];
89*29461e4cSJit Loon Lim 	uint32_t resp_param_reg;
90*29461e4cSJit Loon Lim 
91*29461e4cSJit Loon Lim 	// Check STATUS_CMD_RESPONSE_DATA_PTR_VALID in
92*29461e4cSJit Loon Lim 	// STATUS_COMMAND_RESPONSE to ensure data pointer response
93*29461e4cSJit Loon Lim 
94*29461e4cSJit Loon Lim 	/* Read CMD_RESPONSE_STATUS and CMD_RESPONSE_DATA_* */
95*29461e4cSJit Loon Lim 	resp_data[0] = mmio_read_32(IO96B_CSR_REG(CMD_RESPONSE_STATUS));
96*29461e4cSJit Loon Lim 	resp_data[0] = (resp_data[0] & CMD_RESPONSE_DATA_SHORT_MASK) >>
97*29461e4cSJit Loon Lim 			CMD_RESPONSE_DATA_SHORT_OFFSET;
98*29461e4cSJit Loon Lim 	resp_param_reg = CMD_RESPONSE_STATUS;
99*29461e4cSJit Loon Lim 	for (i = 1; i < IOSSM_RESP_MAX_WORD_SIZE; i++) {
100*29461e4cSJit Loon Lim 		resp_param_reg = resp_param_reg - CMD_RESPONSE_OFFSET;
101*29461e4cSJit Loon Lim 		resp_data[i] = mmio_read_32(IO96B_CSR_REG(resp_param_reg));
102*29461e4cSJit Loon Lim 	}
103*29461e4cSJit Loon Lim 
104*29461e4cSJit Loon Lim 	/* Wait for STATUS_COMMAND_RESPONSE_READY*/
105*29461e4cSJit Loon Lim 	status = wait_respond(1000);
106*29461e4cSJit Loon Lim 
107*29461e4cSJit Loon Lim 	/* Read CMD_RESPONSE_STATUS and CMD_RESPONSE_DATA_* */
108*29461e4cSJit Loon Lim 	mmio_setbits_32(STATUS_COMMAND_RESPONSE(IO96B_CSR_REG(
109*29461e4cSJit Loon Lim 			CMD_RESPONSE_STATUS)),
110*29461e4cSJit Loon Lim 			STATUS_COMMAND_RESPONSE_READY_CLEAR);
111*29461e4cSJit Loon Lim 
112*29461e4cSJit Loon Lim 	return status;
113*29461e4cSJit Loon Lim }
114*29461e4cSJit Loon Lim 
115*29461e4cSJit Loon Lim int iossm_mb_send(uint32_t cmd_target_ip_type, uint32_t cmd_target_ip_instance_id,
116*29461e4cSJit Loon Lim 			uint32_t cmd_type, uint32_t cmd_opcode, uint32_t *args,
117*29461e4cSJit Loon Lim 			unsigned int len)
118*29461e4cSJit Loon Lim {
119*29461e4cSJit Loon Lim 	unsigned int i;
120*29461e4cSJit Loon Lim 	uint32_t status = 0;
121*29461e4cSJit Loon Lim 	uint32_t cmd_req;
122*29461e4cSJit Loon Lim 	uint32_t cmd_param_reg;
123*29461e4cSJit Loon Lim 
124*29461e4cSJit Loon Lim 	cmd_target_ip_type = (cmd_target_ip_type & CMD_TARGET_IP_TYPE_MASK) <<
125*29461e4cSJit Loon Lim 				CMD_TARGET_IP_TYPE_OFFSET;
126*29461e4cSJit Loon Lim 	cmd_target_ip_instance_id = (cmd_target_ip_instance_id &
127*29461e4cSJit Loon Lim 				CMD_TARGET_IP_INSTANCE_ID_MASK) <<
128*29461e4cSJit Loon Lim 				CMD_TARGET_IP_INSTANCE_ID_OFFSET;
129*29461e4cSJit Loon Lim 	cmd_type = (cmd_type & CMD_TYPE_MASK) << CMD_TYPE_OFFSET;
130*29461e4cSJit Loon Lim 	cmd_opcode = (cmd_opcode & CMD_OPCODE_MASK) << CMD_OPCODE_OFFSET;
131*29461e4cSJit Loon Lim 	cmd_req = cmd_target_ip_type | cmd_target_ip_instance_id | cmd_type |
132*29461e4cSJit Loon Lim 			cmd_opcode;
133*29461e4cSJit Loon Lim 
134*29461e4cSJit Loon Lim 	/* send mailbox request */
135*29461e4cSJit Loon Lim 	IOSSM_MB_WRITE(IO96B_CSR_REG(CMD_REQ), cmd_req);
136*29461e4cSJit Loon Lim 	if (len != 0) {
137*29461e4cSJit Loon Lim 		cmd_param_reg = CMD_REQ;
138*29461e4cSJit Loon Lim 		for (i = 0; i < len; i++) {
139*29461e4cSJit Loon Lim 			cmd_param_reg = cmd_param_reg - CMD_PARAM_OFFSET;
140*29461e4cSJit Loon Lim 			IOSSM_MB_WRITE(IO96B_CSR_REG(cmd_param_reg), args[i]);
141*29461e4cSJit Loon Lim 		}
142*29461e4cSJit Loon Lim 	}
143*29461e4cSJit Loon Lim 
144*29461e4cSJit Loon Lim 	status = iossm_mb_read_response();
145*29461e4cSJit Loon Lim 	if (status != 0) {
146*29461e4cSJit Loon Lim 		return status;
147*29461e4cSJit Loon Lim 	}
148*29461e4cSJit Loon Lim 
149*29461e4cSJit Loon Lim 	return status;
150*29461e4cSJit Loon Lim }
151*29461e4cSJit Loon Lim 
152*29461e4cSJit Loon Lim int ddr_iossm_mailbox_cmd(uint32_t cmd_opcode)
153*29461e4cSJit Loon Lim {
154*29461e4cSJit Loon Lim 	// IOSSM
155*29461e4cSJit Loon Lim 	uint32_t status = 0;
156*29461e4cSJit Loon Lim 	unsigned int i = 0;
157*29461e4cSJit Loon Lim 	uint32_t payload[IOSSM_CMD_MAX_WORD_SIZE] = {0U};
158*29461e4cSJit Loon Lim 
159*29461e4cSJit Loon Lim 	switch (cmd_opcode) {
160*29461e4cSJit Loon Lim 	case CMD_INIT:
161*29461e4cSJit Loon Lim 		status = iossm_mb_init();
162*29461e4cSJit Loon Lim 		break;
163*29461e4cSJit Loon Lim 
164*29461e4cSJit Loon Lim 	case OPCODE_GET_MEM_INTF_INFO:
165*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0, MBOX_CMD_GET_SYS_INFO,
166*29461e4cSJit Loon Lim 		OPCODE_GET_MEM_INTF_INFO, payload, i);
167*29461e4cSJit Loon Lim 		break;
168*29461e4cSJit Loon Lim 
169*29461e4cSJit Loon Lim 	case OPCODE_GET_MEM_TECHNOLOGY:
170*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0, MBOX_CMD_GET_MEM_INFO,
171*29461e4cSJit Loon Lim 		OPCODE_GET_MEM_TECHNOLOGY, payload, i);
172*29461e4cSJit Loon Lim 		break;
173*29461e4cSJit Loon Lim 
174*29461e4cSJit Loon Lim 	case OPCODE_GET_MEM_WIDTH_INFO:
175*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0, MBOX_CMD_GET_MEM_INFO,
176*29461e4cSJit Loon Lim 		OPCODE_GET_MEM_WIDTH_INFO, payload, i);
177*29461e4cSJit Loon Lim 		break;
178*29461e4cSJit Loon Lim 
179*29461e4cSJit Loon Lim 	case OPCODE_ECC_ENABLE_STATUS:
180*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0,
181*29461e4cSJit Loon Lim 		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_ENABLE_STATUS,
182*29461e4cSJit Loon Lim 		payload, i);
183*29461e4cSJit Loon Lim 		break;
184*29461e4cSJit Loon Lim 
185*29461e4cSJit Loon Lim 	case OPCODE_ECC_INTERRUPT_MASK:
186*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_0 [16:0]: ECC_INTERRUPT_MASK
187*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0,
188*29461e4cSJit Loon Lim 		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_INTERRUPT_MASK,
189*29461e4cSJit Loon Lim 		payload, i);
190*29461e4cSJit Loon Lim 		break;
191*29461e4cSJit Loon Lim 
192*29461e4cSJit Loon Lim 	case OPCODE_ECC_SCRUB_MODE_0_START:
193*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_0 [15:0]: ECC_SCRUB_INTERVAL
194*29461e4cSJit Loon Lim 		//i++;
195*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_1 [11:0]: ECC_SCRUB_LEN
196*29461e4cSJit Loon Lim 		//i++;
197*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_2 [0:0]: ECC_SCRUB_FULL_MEM
198*29461e4cSJit Loon Lim 		//i++;
199*29461e4cSJit Loon Lim 		// payload[i]= CMD_PARAM_3 [31:0]: ECC_SCRUB_START_ADDR [31:0]
200*29461e4cSJit Loon Lim 		//i++;
201*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_4 [5:0]: ECC_SCRUB_START_ADDR [36:32]
202*29461e4cSJit Loon Lim 		//i++;
203*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_5 [31:0]: ECC_SCRUB_END_ADDR [31:0]
204*29461e4cSJit Loon Lim 		//i++;
205*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_6 [5:0]: ECC_SCRUB_END_ADDR [36:32]
206*29461e4cSJit Loon Lim 		//i++;
207*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0,
208*29461e4cSJit Loon Lim 		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_SCRUB_MODE_0_START,
209*29461e4cSJit Loon Lim 		payload, i);
210*29461e4cSJit Loon Lim 		break;
211*29461e4cSJit Loon Lim 
212*29461e4cSJit Loon Lim 	case OPCODE_ECC_SCRUB_MODE_1_START:
213*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_0 [15:0]: ECC_SCRUB_IDLE_CNT
214*29461e4cSJit Loon Lim 		//i++;
215*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_1 [11:0]: ECC_SCRUB_LEN
216*29461e4cSJit Loon Lim 		//i++;
217*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_2 [0:0]: ECC_SCRUB_FULL_MEM
218*29461e4cSJit Loon Lim 		//i++;
219*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_3 [31:0]: ECC_SCRUB_START_ADDR [31:0]
220*29461e4cSJit Loon Lim 		//i++;
221*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_4 [5:0]: ECC_SCRUB_START_ADDR [36:32]
222*29461e4cSJit Loon Lim 		//i++;
223*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_5 [31:0]: ECC_SCRUB_END_ADDR [31:0]
224*29461e4cSJit Loon Lim 		//i++;
225*29461e4cSJit Loon Lim 		// payload[i] = CMD_PARAM_6 [5:0]: ECC_SCRUB_END_ADDR [36:32]
226*29461e4cSJit Loon Lim 		//i++;
227*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0,
228*29461e4cSJit Loon Lim 		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_ECC_SCRUB_MODE_1_START,
229*29461e4cSJit Loon Lim 		payload, i);
230*29461e4cSJit Loon Lim 		break;
231*29461e4cSJit Loon Lim 
232*29461e4cSJit Loon Lim 	case OPCODE_BIST_RESULTS_STATUS:
233*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0,
234*29461e4cSJit Loon Lim 		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_BIST_RESULTS_STATUS,
235*29461e4cSJit Loon Lim 		payload, i);
236*29461e4cSJit Loon Lim 		break;
237*29461e4cSJit Loon Lim 
238*29461e4cSJit Loon Lim 	case OPCODE_BIST_MEM_INIT_START:
239*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0,
240*29461e4cSJit Loon Lim 		MBOX_CMD_TRIG_CONTROLLER_OP, OPCODE_BIST_MEM_INIT_START,
241*29461e4cSJit Loon Lim 		payload, i);
242*29461e4cSJit Loon Lim 		break;
243*29461e4cSJit Loon Lim 
244*29461e4cSJit Loon Lim 	case OPCODE_TRIG_MEM_CAL:
245*29461e4cSJit Loon Lim 		status = iossm_mb_send(0, 0, MBOX_CMD_TRIG_MEM_CAL_OP,
246*29461e4cSJit Loon Lim 		OPCODE_TRIG_MEM_CAL, payload, i);
247*29461e4cSJit Loon Lim 		break;
248*29461e4cSJit Loon Lim 
249*29461e4cSJit Loon Lim 	default:
250*29461e4cSJit Loon Lim 		break;
251*29461e4cSJit Loon Lim 	}
252*29461e4cSJit Loon Lim 
253*29461e4cSJit Loon Lim 	if (status == -EPERM) {
254*29461e4cSJit Loon Lim 		assert(status);
255*29461e4cSJit Loon Lim 	}
256*29461e4cSJit Loon Lim 
257*29461e4cSJit Loon Lim 	return status;
258*29461e4cSJit Loon Lim }
259*29461e4cSJit Loon Lim 
260*29461e4cSJit Loon Lim int ddr_config_handoff(handoff *hoff_ptr)
261*29461e4cSJit Loon Lim {
262*29461e4cSJit Loon Lim 	/* Populate DDR handoff data */
263*29461e4cSJit Loon Lim 	/* TODO: To add in DDR handoff configuration once available */
264*29461e4cSJit Loon Lim 	return 0;
265*29461e4cSJit Loon Lim }
266*29461e4cSJit Loon Lim 
267*29461e4cSJit Loon Lim // DDR firewall and non secure access
268*29461e4cSJit Loon Lim void ddr_enable_ns_access(void)
269*29461e4cSJit Loon Lim {
270*29461e4cSJit Loon Lim 	/* Please set the ddr non secure registers accordingly */
271*29461e4cSJit Loon Lim 
272*29461e4cSJit Loon Lim 	mmio_setbits_32(CCU_REG(DMI0_DMIUSMCTCR),
273*29461e4cSJit Loon Lim 			CCU_DMI_ALLOCEN | CCU_DMI_LOOKUPEN);
274*29461e4cSJit Loon Lim 	mmio_setbits_32(CCU_REG(DMI1_DMIUSMCTCR),
275*29461e4cSJit Loon Lim 			CCU_DMI_ALLOCEN | CCU_DMI_LOOKUPEN);
276*29461e4cSJit Loon Lim 
277*29461e4cSJit Loon Lim 	/* TODO: To add in CCU NCORE OCRAM bypass mask for non secure registers */
278*29461e4cSJit Loon Lim 	NOTICE("DDR non secure configured\n");
279*29461e4cSJit Loon Lim }
280*29461e4cSJit Loon Lim 
281*29461e4cSJit Loon Lim void ddr_enable_firewall(void)
282*29461e4cSJit Loon Lim {
283*29461e4cSJit Loon Lim 	/* Please set the ddr firewall registers accordingly */
284*29461e4cSJit Loon Lim 	/* TODO: To add in CCU NCORE OCRAM bypass mask for firewall registers */
285*29461e4cSJit Loon Lim 	NOTICE("DDR firewall enabled\n");
286*29461e4cSJit Loon Lim }
287*29461e4cSJit Loon Lim 
288*29461e4cSJit Loon Lim bool is_ddr_init_in_progress(void)
289*29461e4cSJit Loon Lim {
290*29461e4cSJit Loon Lim 	uint32_t reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
291*29461e4cSJit Loon Lim 
292*29461e4cSJit Loon Lim 	if (reg & SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_0_MASK) {
293*29461e4cSJit Loon Lim 		return true;
294*29461e4cSJit Loon Lim 	}
295*29461e4cSJit Loon Lim 	return false;
296*29461e4cSJit Loon Lim }
297*29461e4cSJit Loon Lim 
298*29461e4cSJit Loon Lim int ddr_init(void)
299*29461e4cSJit Loon Lim {
300*29461e4cSJit Loon Lim 	// DDR driver initialization
301*29461e4cSJit Loon Lim 	int status = -EPERM;
302*29461e4cSJit Loon Lim 	uint32_t cmd_opcode = 0;
303*29461e4cSJit Loon Lim 
304*29461e4cSJit Loon Lim 	// Check and set Boot Scratch Register
305*29461e4cSJit Loon Lim 	if (is_ddr_init_in_progress()) {
306*29461e4cSJit Loon Lim 		return status;
307*29461e4cSJit Loon Lim 	}
308*29461e4cSJit Loon Lim 	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0), 0x01);
309*29461e4cSJit Loon Lim 
310*29461e4cSJit Loon Lim 	// Populate DDR handoff data
311*29461e4cSJit Loon Lim 	handoff reverse_handoff_ptr;
312*29461e4cSJit Loon Lim 
313*29461e4cSJit Loon Lim 	if (!socfpga_get_handoff(&reverse_handoff_ptr)) {
314*29461e4cSJit Loon Lim 		assert(status);
315*29461e4cSJit Loon Lim 	}
316*29461e4cSJit Loon Lim 	status = ddr_config_handoff(&reverse_handoff_ptr);
317*29461e4cSJit Loon Lim 	if (status == -EPERM) {
318*29461e4cSJit Loon Lim 		assert(status);
319*29461e4cSJit Loon Lim 	}
320*29461e4cSJit Loon Lim 
321*29461e4cSJit Loon Lim 	// CCU and firewall setup
322*29461e4cSJit Loon Lim 	ddr_enable_ns_access();
323*29461e4cSJit Loon Lim 	ddr_enable_firewall();
324*29461e4cSJit Loon Lim 
325*29461e4cSJit Loon Lim 	// DDR calibration check
326*29461e4cSJit Loon Lim 	status = ddr_calibration_check();
327*29461e4cSJit Loon Lim 	if (status == -EPERM) {
328*29461e4cSJit Loon Lim 		assert(status);
329*29461e4cSJit Loon Lim 	}
330*29461e4cSJit Loon Lim 
331*29461e4cSJit Loon Lim 	// DDR mailbox command
332*29461e4cSJit Loon Lim 	status = ddr_iossm_mailbox_cmd(cmd_opcode);
333*29461e4cSJit Loon Lim 	if (status != 0) {
334*29461e4cSJit Loon Lim 		assert(status);
335*29461e4cSJit Loon Lim 	}
336*29461e4cSJit Loon Lim 
337*29461e4cSJit Loon Lim 	// Check and set Boot Scratch Register
338*29461e4cSJit Loon Lim 	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0), 0x00);
339*29461e4cSJit Loon Lim 
340*29461e4cSJit Loon Lim 	NOTICE("DDR init successfully\n");
341*29461e4cSJit Loon Lim 	return status;
342*29461e4cSJit Loon Lim }
343