void tclrpt_loop(void)
{
	alt_u32 rank;

	// Set up the interface to be ready for access. The initial state is user mode.
	tclrpt_mark_interface_as_ready();

	// Forever just respond to commands
	for (;;)
	{
	    // KALEN: Do we need this in debug?
	    // AIDIL: Yes since debug is turned on by default, not having this means deep
	    // powerdown would stall controller
		user_init_cal_req();
	    
		if (debug_data->command_status == TCLDBG_TX_STATUS_RESPOSE_READY
				|| debug_data->command_status == TCLDBG_TX_STATUS_ILLEGAL_CMD)
			switch (debug_data->requested_command)
			{
				case TCLDBG_CMD_RESPONSE_ACK :
					// The TCL interface has read the response
					// Since the TCL interface has read the response we can mark the interface
					// As being ready to accept another command
					tclrpt_mark_interface_as_ready();
					break;
			}
		else if (debug_data->command_status == TCLDBG_TX_STATUS_CMD_READY)
		{
			switch (debug_data->requested_command)
			{
				case TCLDBG_CMD_WAIT_CMD :
					//wait for commands
					break;
				case TCLDBG_CMD_NOP : //NOOP command
					// Perform no operation
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_RUN_MEM_CALIBRATE :
					// Run the full memory calibration
					run_mem_calibrate();
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_RUN_EYE_DIAGRAM_PATTERN :
					// Generate the pattern to view eye diagrams
					// This function never returns
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_MARK_ALL_DQS_GROUPS_AS_VALID :
					// Mark all groups as being valid for calibration
					param->skip_groups = 0;
					tclrpt_update_rank_group_mask();
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_MARK_GROUP_AS_SKIP :
					// Mark the specified group as being skipped for calibration

					// Make sure it is a legal group
					if (debug_data->command_parameters[0] < RW_MGR_MEM_IF_WRITE_DQS_WIDTH) {
						param->skip_groups |= 1 << debug_data->command_parameters[0];

						tclrpt_update_rank_group_mask();
						tclrpt_mark_interface_as_response_ready();
					}
					else {
						// Illegal payload detected
						tclrpt_mark_interface_as_illegal_command();
					}

					break;
				case TCLDBG_MARK_ALL_RANKS_AS_VALID :
					// Mark all ranks as being valid for calibration
					for (rank = 0; rank < RW_MGR_MEM_NUMBER_OF_RANKS; rank++)
					{
						param->skip_ranks[rank] = 0;
					}
					tclrpt_update_rank_group_mask();
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_MARK_RANK_AS_SKIP :
					// Make sure it is a legal group
					if (debug_data->command_parameters[0] < RW_MGR_MEM_NUMBER_OF_RANKS) {
						param->skip_ranks[debug_data->command_parameters[0]] = 1;

						tclrpt_update_rank_group_mask();
						tclrpt_mark_interface_as_response_ready();
					}
					else {
						// Illegal payload detected
						tclrpt_mark_interface_as_illegal_command();
					}

					break;
				case TCLDBG_ENABLE_MARGIN_REPORT :
					gbl->phy_debug_mode_flags |= PHY_DEBUG_ENABLE_MARGIN_RPT;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_ENABLE_SWEEP_ALL_GROUPS :
					gbl->phy_debug_mode_flags |= PHY_DEBUG_SWEEP_ALL_GROUPS;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_DISABLE_GUARANTEED_READ :
					gbl->phy_debug_mode_flags |= PHY_DEBUG_DISABLE_GUARANTEED_READ;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_SET_NON_DESTRUCTIVE_CALIBRATION:
				  if (debug_data->command_parameters[0]) {
					gbl->phy_debug_mode_flags |= PHY_DEBUG_ENABLE_NON_DESTRUCTIVE_CALIBRATION;
				  } else {
					gbl->phy_debug_mode_flags &= ~(PHY_DEBUG_ENABLE_NON_DESTRUCTIVE_CALIBRATION);
				  }
				  tclrpt_mark_interface_as_response_ready();
				  break;
				default :
					// Illegal command
					tclrpt_mark_interface_as_illegal_command();
					break;
			}
		}
	}
}
void tclrpt_loop(void)
{
	alt_u32 rank, group, pin, pin_in_group, value;
	alt_u32 rdimm_control_word_updated;
	rdimm_control_word_updated = 0;	
	// Set up the interface to be ready for access. The initial state is user mode.
	tclrpt_mark_interface_as_ready();

	// Forever just respond to commands
	for (;;)
	{
		// This is to check if RDIMM Control Word has been updated
		if ( rdimm_control_word_updated == 1 ) 
		{
			break;
		}		
		
	    // KALEN: Do we need this in debug?
	    // AIDIL: Yes since debug is turned on by default, not having this means deep
	    // powerdown would stall controller
		user_init_cal_req();
	    
		if (debug_data->command_status == TCLDBG_TX_STATUS_RESPONSE_READY
				|| debug_data->command_status == TCLDBG_TX_STATUS_ILLEGAL_CMD)
			switch (debug_data->requested_command)
			{
				case TCLDBG_CMD_RESPONSE_ACK :
					// The TCL interface has read the response
					// Since the TCL interface has read the response we can mark the interface
					// As being ready to accept another command
					tclrpt_mark_interface_as_ready();
					break;
			}
		else if (debug_data->command_status == TCLDBG_TX_STATUS_CMD_READY)
		{
			switch (debug_data->requested_command)
			{
				case TCLDBG_SET_UPDATE_PARAMETERS :
					rdimm_control_word_updated = 1;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_CMD_WAIT_CMD :
					//wait for commands
					break;
				case TCLDBG_CMD_NOP : //NOOP command
					// Perform no operation
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_RUN_MEM_CALIBRATE :
					// Run the full memory calibration
#if ENABLE_NON_DES_CAL					
					run_mem_calibrate(0);
#else
					run_mem_calibrate();
#endif
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_RUN_NON_DES_MEM_CALIBRATE :
					// Run the full memory calibration
#if ENABLE_NON_DES_CAL					
					run_mem_calibrate(1);
#else
					run_mem_calibrate();
#endif
					tclrpt_mark_interface_as_response_ready();
					break;

				case TCLDBG_RUN_EYE_DIAGRAM_PATTERN :
					// Generate the pattern to view eye diagrams
					// This function never returns
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_MARK_ALL_DQS_GROUPS_AS_VALID :
					// Mark all groups as being valid for calibration
					param->skip_groups = 0;
					tclrpt_update_rank_group_mask();
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_MARK_GROUP_AS_SKIP :
					// Mark the specified group as being skipped for calibration

					// Make sure it is a legal group
					if (debug_data->command_parameters[0] < RW_MGR_MEM_IF_WRITE_DQS_WIDTH) {
						param->skip_groups |= 1 << debug_data->command_parameters[0];

						tclrpt_update_rank_group_mask();
						tclrpt_mark_interface_as_response_ready();
					}
					else {
						// Illegal payload detected
						tclrpt_mark_interface_as_illegal_command();
					}

					break;
				case TCLDBG_MARK_ALL_RANKS_AS_VALID :
					// Mark all ranks as being valid for calibration
					for (rank = 0; rank < RW_MGR_MEM_NUMBER_OF_RANKS; rank++)
					{
						param->skip_ranks[rank] = 0;
					}
					tclrpt_update_rank_group_mask();
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_MARK_RANK_AS_SKIP :
					// Make sure it is a legal group
					if (debug_data->command_parameters[0] < RW_MGR_MEM_NUMBER_OF_RANKS) {
						param->skip_ranks[debug_data->command_parameters[0]] = 1;

						tclrpt_update_rank_group_mask();
						tclrpt_mark_interface_as_response_ready();
					}
					else {
						// Illegal payload detected
						tclrpt_mark_interface_as_illegal_command();
					}

					break;
				case TCLDBG_ENABLE_MARGIN_REPORT :
					gbl->phy_debug_mode_flags |= PHY_DEBUG_ENABLE_MARGIN_RPT;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_ENABLE_SWEEP_ALL_GROUPS :
					gbl->phy_debug_mode_flags |= PHY_DEBUG_SWEEP_ALL_GROUPS;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_DISABLE_GUARANTEED_READ :
					gbl->phy_debug_mode_flags |= PHY_DEBUG_DISABLE_GUARANTEED_READ;
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_SET_NON_DESTRUCTIVE_CALIBRATION:
				  if (debug_data->command_parameters[0]) {
					gbl->phy_debug_mode_flags |= PHY_DEBUG_ENABLE_NON_DESTRUCTIVE_CALIBRATION;
				  } else {
					gbl->phy_debug_mode_flags &= ~(PHY_DEBUG_ENABLE_NON_DESTRUCTIVE_CALIBRATION);
				  }
				  tclrpt_mark_interface_as_response_ready();
				  break;
				#if ENABLE_DELAY_CHAIN_WRITE
				case TCLDBG_SET_DQ_D1_DELAY :
					// DQ D1 Delay (I/O buffer to input register)
					pin = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];
					group = pin/RW_MGR_MEM_DQ_PER_READ_DQS;
					pin_in_group = pin%RW_MGR_MEM_DQ_PER_READ_DQS;

					// Make sure parameter values are legal
					if (pin < RW_MGR_MEM_DATA_WIDTH && value <= IO_IO_IN_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dq_in_delay(group, pin_in_group, value);
						scc_mgr_load_dq (pin_in_group);
						IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQ_D5_DELAY :
					// DQ D5 Delay (output register to I/O buffer)
					pin = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];
					group = pin/RW_MGR_MEM_DQ_PER_WRITE_DQS;
					pin_in_group = pin%RW_MGR_MEM_DQ_PER_WRITE_DQS;

					// Make sure parameter values are legal
					if (pin < RW_MGR_MEM_DATA_WIDTH && value <= IO_IO_OUT1_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dq_out1_delay(group, pin_in_group, value);
						scc_mgr_load_dq (pin_in_group);
						IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQ_D6_DELAY :
					// DQ D6 Delay (output register to I/O buffer)
					pin = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];
					group = pin/RW_MGR_MEM_DQ_PER_WRITE_DQS;
					pin_in_group = pin%RW_MGR_MEM_DQ_PER_WRITE_DQS;

					// Make sure parameter values are legal
					if (pin < RW_MGR_MEM_DATA_WIDTH && value <= IO_IO_OUT2_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dq_out2_delay(group, pin_in_group, value);
						scc_mgr_load_dq (pin_in_group);
						IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQS_D4_DELAY :
					// DQS D4 Delay (DQS delay chain)
					group = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH && value <= IO_DQS_IN_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dqs_bus_in_delay(group, value);
						scc_mgr_load_dqs (group);
						IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQDQS_OUTPUT_PHASE :
					// DQS DQ Output Phase (deg) = DQS Output Phase (deg) - 90
					group = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH && value <= IO_DQDQS_OUT_PHASE_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dqdqs_output_phase_all_ranks (group, value);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQS_D5_DELAY :
					// DQS D5 Delay (output register to I/O buffer) = D5 OCT Delay (OCT to I/O buffer)
					group = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH && value <= IO_IO_OUT1_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_group_dqs_io_and_oct_out1_gradual (group, value);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQS_D6_DELAY :
					// DQS D6 Delay (output register to I/O buffer) = D6 OCT Delay (OCT to I/O buffer)
					group = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH && value <= IO_IO_OUT2_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_group_dqs_io_and_oct_out2_gradual (group, value);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQS_EN_PHASE :
					// DQS Enable Phase (deg)
					group = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH && value <= IO_DQS_EN_PHASE_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dqs_en_phase_all_ranks (group, value);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DQS_T11_DELAY :
					// DQS T11 Delay (DQS post-amble delay)
					group = debug_data->command_parameters[0];
					value = debug_data->command_parameters[1];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH && value <= IO_DQS_EN_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dqs_en_delay_all_ranks (group, value);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DM_D5_DELAY :
					// DM D5 OCT Delay (OCT to I/O buffer)
					group = debug_data->command_parameters[0];
					pin_in_group = debug_data->command_parameters[1];
					value = debug_data->command_parameters[2];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH && pin_in_group < RW_MGR_NUM_DM_PER_WRITE_GROUP && value <= IO_IO_OUT1_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dm_out1_delay(group, pin_in_group, value);
						scc_mgr_load_dm (pin_in_group);
						IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SET_DM_D6_DELAY :
					// DM D6 OCT Delay (OCT to I/O buffer)
					group = debug_data->command_parameters[0];
					pin_in_group = debug_data->command_parameters[1];
					value = debug_data->command_parameters[2];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH && pin_in_group < RW_MGR_NUM_DM_PER_WRITE_GROUP && value <= IO_IO_OUT2_DELAY_MAX) {
						IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
						scc_mgr_set_dm_out2_delay(group, pin_in_group, value);
						scc_mgr_load_dm (pin_in_group);
						IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_REMARGIN_DQ :
					rank = debug_data->command_parameters[0];
					group = debug_data->command_parameters[1];
					// Pre-margining process
					initialize();
					rw_mgr_mem_initialize ();
					mem_config ();
					
					IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
					run_dq_margining(rank, group);
					
					// Post-margining process
					rw_mgr_mem_handoff ();
					IOWR_32DIRECT (PHY_MGR_MUX_SEL, 0, 0); // Give control back to user logic.
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_REMARGIN_DM :
					rank = debug_data->command_parameters[0];
					group = debug_data->command_parameters[1];
					// Pre-margining process
					initialize();
					rw_mgr_mem_initialize ();
					mem_config ();
					
					IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
					run_dm_margining(rank, group);
					
					// Post-margining process
					rw_mgr_mem_handoff ();
					IOWR_32DIRECT (PHY_MGR_MUX_SEL, 0, 0); // Give control back to user logic.
					tclrpt_mark_interface_as_response_ready();
					break;
				case TCLDBG_INCR_VFIFO :
					// Increment the VFIFO by 1 step
					group = debug_data->command_parameters[0];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH) {
						rw_mgr_incr_vfifo_auto(group);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_DECR_VFIFO :
					// Decrement the VFIFO by 1 step
					group = debug_data->command_parameters[0];

					// Make sure parameter values are legal
					if (group < RW_MGR_MEM_IF_READ_DQS_WIDTH) {
						rw_mgr_decr_vfifo_auto(group);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				case TCLDBG_SELECT_SHADOW_REG :
					rank = debug_data->command_parameters[0];
					if (rank < RW_MGR_MEM_NUMBER_OF_RANKS) {
						select_shadow_regs_for_update (rank, 0, 1);
						tclrpt_mark_interface_as_response_ready();
					} else {
						tclrpt_mark_interface_as_illegal_command();
					}
					break;
				#endif // ENABLE_DELAY_CHAIN_WRITE
				default :
					// Illegal command
					tclrpt_mark_interface_as_illegal_command();
					break;
			}
		}
	}
}