/* * UniPHY sequencer core access example */ #include #include #include #include "core_debug_defines.h" #define DEBUG_MESSAGES 0 int send_command(volatile debug_data_t* debug_data_ptr, int command, int args[], int num_args) { volatile int i, response; // Wait until command_status is ready printf("Waiting for command status READY\n"); do { response = IORD_32DIRECT(&(debug_data_ptr->command_status), 0); } while(response != TCLDBG_TX_STATUS_CMD_READY); //TCLDBG_TX_STATUS_CMD_READY: RX interface ready to accept commands in debug mode // Load arguments if(num_args > COMMAND_PARAM_WORDS) { // Too many arguments return 0; } for(i = 0; i < num_args; i++) { IOWR_32DIRECT(&(debug_data_ptr->command_parameters[i]), 0, args[i]); } // Send command code printf("Sending command: %d\n", command); IOWR_32DIRECT(&(debug_data_ptr->requested_command), 0, command); // Wait for acknowledgment printf("Waiting for command acknowledgement\n"); do { response = IORD_32DIRECT(&(debug_data_ptr->command_status), 0); } while(response != TCLDBG_TX_STATUS_RESPOSE_READY && response != TCLDBG_TX_STATUS_ILLEGAL_CMD); //TX interface response ready // Acknowledge response IOWR_32DIRECT(&(debug_data_ptr->requested_command), 0, TCLDBG_CMD_RESPONSE_ACK); // Return 1 on success, 0 on illegal command return (response != TCLDBG_TX_STATUS_ILLEGAL_CMD); } int main() { volatile debug_data_t* my_debug_data_ptr; volatile debug_summary_report_t* my_summary_report_ptr; volatile debug_cal_report_t* my_cal_report_ptr; volatile debug_margin_report_t* my_margin_report_ptr; volatile debug_cal_observed_dq_margins_t* cal_observed_dq_margins_ptr; volatile debug_margin_min_max_margins_t* margin_min_max_margins_ptr; //Kumar volatile debug_cal_dqs_in_settings_t* cal_dqs_in_settings_ptr; volatile debug_cal_dq_settings_t* cal_dq_settings_ptr; volatile debug_printf_output_t* debug_printf_output_ptr; int i, j, size; int args[COMMAND_PARAM_WORDS]; unsigned int* tmp; unsigned int sr, num_sr, number_ranks; // Initialize pointers to the debug reports my_debug_data_ptr = (debug_data_t*)SEQ_CORE_DEBUG_BASE; my_summary_report_ptr = (debug_summary_report_t*)(IORD_32DIRECT(&(my_debug_data_ptr->summary_report_ptr), 0)); my_cal_report_ptr = (debug_cal_report_t*)(IORD_32DIRECT(&(my_debug_data_ptr->cal_report_ptr), 0)); my_margin_report_ptr = (debug_margin_report_t*)(IORD_32DIRECT(&(my_debug_data_ptr->margin_report_ptr), 0)); // Activate all groups and ranks, then calibrate send_command(my_debug_data_ptr, TCLDBG_MARK_ALL_DQS_GROUPS_AS_VALID, 0, 0); // Mark all groups as being valid for calibration send_command(my_debug_data_ptr, TCLDBG_MARK_ALL_RANKS_AS_VALID, 0, 0); // Mark all ranks as being valid for calibration send_command(my_debug_data_ptr, TCLDBG_RUN_MEM_CALIBRATE, 0, 0); // Run memory calibration // GENERAL INFO printf("data_size: %u\n", IORD_32DIRECT(&(my_debug_data_ptr->data_size), 0)); printf("status: %u\n", IORD_32DIRECT(&(my_debug_data_ptr->status), 0)); printf("requested_command: %u\n", IORD_32DIRECT(&(my_debug_data_ptr->requested_command), 0)); printf("command_status: %u\n", IORD_32DIRECT(&(my_debug_data_ptr->command_status), 0)); // etc... // SUMMARY printf("SUMMARY REPORT\n"); printf("mem_address_width: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->mem_address_width), 0)); printf("mem_bank_width: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->mem_bank_width), 0)); num_sr = IORD_32DIRECT(&(my_summary_report_ptr->num_shadow_regs), 0); printf("num_shadow_regs: %u\n", num_sr); // SUMMARY printf("CUSTOM SUMMARY REPORT \n"); printf("mem_cs_width: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->mem_cs_width), 0)); printf("mem_cke_width: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->mem_cke_width), 0)); number_ranks = IORD_32DIRECT(&(my_summary_report_ptr->mem_num_ranks), 0); printf("num_ranks: %u\n", number_ranks); //printf("num_ranks: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->mem_num_ranks), 0)); printf("mem_read_latency: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->cal_read_latency), 0)); printf("mem_write_latency: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->cal_write_latency), 0)); printf("dll_length: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->dll_length), 0)); printf("rate: %u\n", IORD_32DIRECT(&(my_summary_report_ptr->rate), 0)); // DQ delay chain settings printf("DQ delay chain settings REPORT \n"); for(sr = 0; sr < num_sr; sr++) { for(i = 0; i < RW_MGR_MEM_DATA_WIDTH; i++) { cal_dq_settings_ptr = &(my_cal_report_ptr->cal_dq_settings[sr][i]); printf("0x%x \n DQ %d \n DQ D5 delay (taps): %d\n", (unsigned int)cal_dq_settings_ptr, i, IORD_32DIRECT(&(cal_dq_settings_ptr->dq_out_delay1), 0)); printf("DQ D6 delay (taps): %d\n", IORD_32DIRECT(&(cal_dq_settings_ptr->dq_out_delay2), 0)); } } // DQS delay chain settings printf("DQS delay chain settings REPORT \n"); for(sr = 0; sr < num_sr; sr++) { for(i = 0; i < RW_MGR_MEM_IF_READ_DQS_WIDTH; i++) { cal_dqs_in_settings_ptr = &(my_cal_report_ptr->cal_dqs_in_settings[sr][i]); printf("0x %x \n DQ_%d \n DQS_en_delay: %d\n", (unsigned int)cal_dqs_in_settings_ptr, i, IORD_32DIRECT(&(cal_dqs_in_settings_ptr->dqs_en_delay), 0)); } } // MARGIN REPORT printf("MARGINING REPORT\n"); for(sr = 0; sr < num_sr; sr++) { for(i = 0; i < RW_MGR_MEM_DATA_WIDTH; i++) { margin_min_max_margins_ptr = &(my_margin_report_ptr->margin_dq_in_margins[sr][i]); printf("0x%x DQ %d Read Margin (taps): -%d : %d\n", (unsigned int)margin_min_max_margins_ptr, i, IORD_32DIRECT(&(margin_min_max_margins_ptr->min_working_setting), 0), IORD_32DIRECT(&(margin_min_max_margins_ptr->max_working_setting), 0)); } } // Change some settings and rerun calibration send_command(my_debug_data_ptr, TCLDBG_ENABLE_MARGIN_REPORT, 0, 0); // Enable the margining report as part of calibration args[0] = 1; // Mask group 1 send_command(my_debug_data_ptr, TCLDBG_MARK_GROUP_AS_SKIP, args, 1); // Mark a specific group to be skipped for calibration send_command(my_debug_data_ptr, TCLDBG_RUN_MEM_CALIBRATE, 0, 0); // Run memory calibration // MARGIN REPORT printf("MARGINING REPORT AFTER RECAL\n"); for(sr = 0; sr < num_sr; sr++) { for(i = 0; i < RW_MGR_MEM_DATA_WIDTH; i++) { margin_min_max_margins_ptr = &(my_margin_report_ptr->margin_dq_in_margins[sr][i]); printf("0x%x DQ %d Read Margin (taps): -%d : %d\n", (unsigned int)margin_min_max_margins_ptr, i, IORD_32DIRECT(&(margin_min_max_margins_ptr->min_working_setting), 0), IORD_32DIRECT(&(margin_min_max_margins_ptr->max_working_setting), 0)); } } // End of transmission putchar(4); return 0; }