1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) Marvell International Ltd. and its affiliates
9 #include <asm/arch/cpu.h>
10 #include <asm/arch/soc.h>
13 #include "high_speed_env_spec.h"
15 #include "../../../drivers/ddr/marvell/a38x/ddr3_init.h"
17 #if defined(MV_DEBUG_INIT_FULL) || defined(MV_DEBUG)
23 /* Array for mapping the operation (write, poll or delay) functions */
24 op_execute_func_ptr op_execute_func_arr[] = {
30 int write_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx)
32 u32 unit_base_reg, unit_offset, data, mask, reg_data, reg_addr;
34 /* Getting write op params from the input parameter */
35 data = params->data[data_arr_idx];
38 /* an empty operation */
42 /* get updated base address since it can be different between Serdes */
43 CHECK_STATUS(hws_get_ext_base_addr(serdes_num, params->unit_base_reg,
45 &unit_base_reg, &unit_offset));
47 /* Address calculation */
48 reg_addr = unit_base_reg + unit_offset * serdes_num;
51 printf("Write: 0x%x: 0x%x (mask 0x%x) - ", reg_addr, data, mask);
53 /* Reading old value */
54 reg_data = reg_read(reg_addr);
57 /* Writing new data */
60 reg_write(reg_addr, reg_data);
63 printf(" - 0x%x\n", reg_data);
69 int delay_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx)
73 /* Getting delay op params from the input parameter */
74 delay = params->wait_time;
76 printf("Delay: %d\n", delay);
83 int poll_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx)
85 u32 unit_base_reg, unit_offset, data, mask, num_of_loops, wait_time;
87 u32 reg_addr, reg_data;
89 /* Getting poll op params from the input parameter */
90 data = params->data[data_arr_idx];
92 num_of_loops = params->num_of_loops;
93 wait_time = params->wait_time;
95 /* an empty operation */
99 /* get updated base address since it can be different between Serdes */
100 CHECK_STATUS(hws_get_ext_base_addr(serdes_num, params->unit_base_reg,
102 &unit_base_reg, &unit_offset));
104 /* Address calculation */
105 reg_addr = unit_base_reg + unit_offset * serdes_num;
109 printf("Poll: 0x%x: 0x%x (mask 0x%x)\n", reg_addr, data, mask);
113 reg_data = reg_read(reg_addr) & mask;
116 } while ((reg_data != data) && (poll_counter < num_of_loops));
118 if ((poll_counter >= num_of_loops) && (reg_data != data)) {
119 DEBUG_INIT_S("poll_op_execute: TIMEOUT\n");
126 enum mv_op get_cfg_seq_op(struct op_params *params)
128 if (params->wait_time == 0)
130 else if (params->num_of_loops == 0)
136 int mv_seq_exec(u32 serdes_num, u32 seq_id)
139 struct op_params *seq_arr;
144 DB(printf("\n### mv_seq_exec ###\n"));
145 DB(printf("seq id: %d\n", seq_id));
147 if (hws_is_serdes_active(serdes_num) != 1) {
148 printf("mv_seq_exec_ext:Error: SerDes lane %d is not valid\n",
153 seq_arr = serdes_seq_db[seq_id].op_params_ptr;
154 seq_size = serdes_seq_db[seq_id].cfg_seq_size;
155 data_arr_idx = serdes_seq_db[seq_id].data_arr_idx;
157 DB(printf("seq_size: %d\n", seq_size));
158 DB(printf("data_arr_idx: %d\n", data_arr_idx));
160 /* Executing the sequence operations */
161 for (seq_idx = 0; seq_idx < seq_size; seq_idx++) {
162 curr_op = get_cfg_seq_op(&seq_arr[seq_idx]);
163 op_execute_func_arr[curr_op](serdes_num, &seq_arr[seq_idx],