diff options
author | Andres Lugo-Reyes <aalugore@us.ibm.com> | 2017-05-12 16:42:46 -0500 |
---|---|---|
committer | William A. Bryan <wilbryan@us.ibm.com> | 2017-05-30 14:25:52 -0400 |
commit | 9f08b00882a07b45cccf8282d97f4bbdcb560307 (patch) | |
tree | e8e805513061d8e8af80d67a7d5b176930ee7893 /src | |
parent | dc2bca3d0a6bfef8d0fe442ce76bb989741ff4ea (diff) | |
download | talos-occ-9f08b00882a07b45cccf8282d97f4bbdcb560307.tar.gz talos-occ-9f08b00882a07b45cccf8282d97f4bbdcb560307.zip |
WOF: Bring up
Change-Id: I1738f4261604f231d15ba4c7a54f84c8bf6f1f97
RTC: 131186
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40471
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src')
-rwxr-xr-x | src/occ_405/amec/amec_parm.h | 2 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_parm_table.c | 2 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_slave_smh.c | 2 | ||||
-rwxr-xr-x | src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c | 11 | ||||
-rwxr-xr-x | src/occ_405/linkocc.cmd | 22 | ||||
-rwxr-xr-x | src/occ_405/main.c | 52 | ||||
-rw-r--r-- | src/occ_405/wof/wof.c | 346 | ||||
-rw-r--r-- | src/occ_405/wof/wof.h | 82 |
8 files changed, 346 insertions, 173 deletions
diff --git a/src/occ_405/amec/amec_parm.h b/src/occ_405/amec/amec_parm.h index d001bb4..6870053 100755 --- a/src/occ_405/amec/amec_parm.h +++ b/src/occ_405/amec/amec_parm.h @@ -153,6 +153,8 @@ typedef enum PARM_PSTATE_TBL_SRAM_ADDR, PARM_VFRT_CALLBACK_ERR, PARM_PGPE_WOF_OFF, + PARM_VFRT_MM_OFFSET, + PARM_VFRT_REQ_RC, // End WOF Parameters AMEC_PARM_NUMBER_OF_PARAMETERS } AMEC_PARM_ENUM; diff --git a/src/occ_405/amec/amec_parm_table.c b/src/occ_405/amec/amec_parm_table.c index 46439c1..6f32083 100755 --- a/src/occ_405/amec/amec_parm_table.c +++ b/src/occ_405/amec/amec_parm_table.c @@ -227,6 +227,8 @@ amec_parm_t g_amec_parm_list[] = { AMEC_PARM_UINT32(PARM_PSTATE_TBL_SRAM_ADDR, "PstatesSramAddr", &g_amec_sys.wof.pstate_tbl_sram_addr), AMEC_PARM_UINT8(PARM_VFRT_CALLBACK_ERR, "vfrtCallbackErr", &g_amec_sys.wof.vfrt_callback_error), AMEC_PARM_UINT8(PARM_PGPE_WOF_OFF, "pgpeWofOff", &g_amec_sys.wof.pgpe_wof_off), + AMEC_PARM_UINT32(PARM_VFRT_MM_OFFSET, "vfrt_mm_offset", &g_amec_sys.wof.vfrt_mm_offset), + AMEC_PARM_UINT8(PARM_VFRT_REQ_RC, "wof_vfrt_req_rc", &g_amec_sys.wof.wof_vfrt_req_rc ), // End WOF parameters }; diff --git a/src/occ_405/amec/amec_slave_smh.c b/src/occ_405/amec/amec_slave_smh.c index abdede7..2137d35 100755 --- a/src/occ_405/amec/amec_slave_smh.c +++ b/src/occ_405/amec/amec_slave_smh.c @@ -522,9 +522,7 @@ void amec_slv_state_4(void) //------------------------------------------------------- // Run WOF Algorithm //------------------------------------------------------- -/* TODO WOF full function testing on HW RTC 158075 call_wof_main(); -*/ } diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c index 92b21ea..4bb2b6b 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c @@ -328,6 +328,17 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr, l_freq, G_proc_fmax_mhz); l_freq = G_proc_fmax_mhz; } + + // If Ultra Turbo is 0, disable WOF + if( l_freq == 0 ) + { + set_clear_wof_disabled( SET, WOF_RC_UTURBO_IS_ZERO ); + } + else + { + set_clear_wof_disabled( CLEAR, WOF_RC_UTURBO_IS_ZERO ); + } + l_table[OCC_MODE_UTURBO] = l_freq; CMDH_TRAC_INFO("UT frequency = %d MHz", l_freq); diff --git a/src/occ_405/linkocc.cmd b/src/occ_405/linkocc.cmd index 03f509b..ab9fe0f 100755 --- a/src/occ_405/linkocc.cmd +++ b/src/occ_405/linkocc.cmd @@ -533,14 +533,14 @@ SECTIONS #if EXECUTABLE_FREE_SPACE _DATA_SECTION_SIZE = . - _DATA_SECTION_BASE; __WRITEABLE_DATA_LEN__ = . - __WRITEABLE_DATA_ADDR__ ; - _EX_FREE_SECTION_SIZE = _PING_PONG_BUFFER_BASE - _EX_FREE_SECTION_BASE; + _EX_FREE_SECTION_SIZE = _GPE_SHARED_DATA_BASE - _EX_FREE_SECTION_BASE; #else - _DATA_SECTION_SIZE = _PING_PONG_BUFFER_BASE - _DATA_SECTION_BASE; - __WRITEABLE_DATA_LEN__ = _PING_PONG_BUFFER_BASE - __WRITEABLE_DATA_ADDR__ ; + _DATA_SECTION_SIZE = _GPE_SHARED_DATA_BASE - _DATA_SECTION_BASE; + __WRITEABLE_DATA_LEN__ = _GPE_SHARED_DATA_BASE - __WRITEABLE_DATA_ADDR__ ; _EX_FREE_SECTION_SIZE = 0; #endif - _SSX_FREE_END = _PING_PONG_BUFFER_BASE - 1; + _SSX_FREE_END = _GPE_SHARED_DATA_BASE - 1; //////////////////////////////// @@ -551,7 +551,7 @@ SECTIONS // needs to be changed in gpe0_main.c and gpe1_main.c. //////////////////////////////// __CUR_COUNTER__ = .; - _GPE_SHARED_DATA_BASE = 0xfffb3d00; + _GPE_SHARED_DATA_BASE = 0xfffb3c00; _GPE_SHARED_DATA_SIZE = 0x100; . = _GPE_SHARED_DATA_BASE; #if !PPC405_MMU_SUPPORT @@ -569,15 +569,15 @@ SECTIONS //////////////////////////////// // Ping/Pong Buffer Section // - // Contains two 128-byte buffers used to tell the PGPE which vfrt to use + // Contains two 256-byte buffers used to tell the PGPE which vfrt to use // //////////////////////////////// __CUR_COUNTER__ = .; - _PING_PONG_BUFFER_BASE = 0xfffb3e00; - _PING_BUFFER_BASE = 0xfffb3e00; - _PING_BUFFER_SIZE = 0x80; - _PONG_BUFFER_BASE = 0xfffb3e80; - _PONG_BUFFER_SIZE = 0x80; + _PING_PONG_BUFFER_BASE = 0xfffb3d00; + _PING_BUFFER_BASE = 0xfffb3d00; + _PING_BUFFER_SIZE = 0x100; + _PONG_BUFFER_BASE = 0xfffb3e00; + _PONG_BUFFER_SIZE = 0x100; . = _PING_BUFFER_BASE; #if !PPC405_MMU_SUPPORT . = . - writethrough_offset; diff --git a/src/occ_405/main.c b/src/occ_405/main.c index d69edf2..da41d9c 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -96,6 +96,9 @@ OCCPstateParmBlock G_oppb; // OCC Pstate Parameters Block Structure extern uint16_t G_proc_fmax_mhz; // max(turbo,uturbo) frequencies extern int G_ss_pgpe_rc; +// Buffer to hold the wof header +DMA_BUFFER(temp_bce_request_buffer_t G_temp_bce_buff) = {{0}}; + // Set main thread timer for one second #define MAIN_THRD_TIMER_SLICE ((SsxInterval) SSX_SECONDS(1)) @@ -516,18 +519,33 @@ void read_wof_header(void) MAIN_TRAC_INFO("read_wof_header() 0x%08X", G_pgpe_header.wof_tables_addr); +#ifdef WOF_PGPE_SUPPORT // Read active quads address, wof tables address, and wof tables len g_amec->wof.req_active_quads_addr = G_pgpe_header.requested_active_quad_sram_addr; g_amec->wof.vfrt_tbls_main_mem_addr = G_pgpe_header.wof_tables_addr; g_amec->wof.vfrt_tbls_len = G_pgpe_header.wof_tables_length; g_amec->wof.pgpe_wof_state_addr = G_pgpe_header.wof_state_address; - + g_amec->wof.pstate_tbl_sram_addr = G_pgpe_header.occ_pstate_table_sram_addr; // Read in quad state addresses here once g_amec->wof.quad_state_0_addr = G_pgpe_header.actual_quad_status_sram_addr; g_amec->wof.quad_state_1_addr = g_amec->wof.quad_state_0_addr + sizeof(uint64_t); //skip quad state 0 +#else + // No WOF PGPE support. Hard code addresses and externalize to amester + g_amec->wof.quad_state_0_addr = G_pgpe_header.beacon_sram_addr + sizeof(uint32_t); + g_amec->wof.quad_state_1_addr = g_amec->wof.quad_state_0_addr + sizeof(uint64_t); + g_amec->wof.pgpe_wof_state_addr = g_amec->wof.quad_state_1_addr + sizeof(uint64_t); + g_amec->wof.req_active_quads_addr = g_amec->wof.pgpe_wof_state_addr + sizeof(uint64_t)+7; + g_amec->wof.vfrt_tbls_main_mem_addr = PPMR_ADDRESS_HOMER+WOF_TABLES_OFFSET; + g_amec->wof.pstate_tbl_sram_addr = PSTATE_TBL_ADDR; + + // Set some of the fields in the pgpe header struct for next set of calcs + G_pgpe_header.wof_tables_addr = g_amec->wof.vfrt_tbls_main_mem_addr; + +#endif + if (G_pgpe_header.wof_tables_addr != 0 && G_pgpe_header.wof_tables_addr%128 == 0) { @@ -536,14 +554,11 @@ void read_wof_header(void) // use block copy engine to read WOF header BceRequest l_wof_header_req; - // 128 byte aligned buffer to read the data - temp_bce_request_buffer_t l_temp_bce_buff = {{0}}; - // Create request l_ssxrc = bce_request_create(&l_wof_header_req, // block copy object &G_pba_bcde_queue, // main to sram copy engine G_pgpe_header.wof_tables_addr, // mainstore address - (uint32_t) &l_temp_bce_buff, // SRAM start address + (uint32_t) &G_temp_bce_buff, // SRAM start address MIN_BCE_REQ_SIZE, // size of copy SSX_WAIT_FOREVER, // no timeout NULL, // no call back @@ -587,9 +602,32 @@ void read_wof_header(void) // Copy the data into Global WOF header struct memcpy(&G_wof_header, - l_temp_bce_buff.data, + G_temp_bce_buff.data, sizeof(wof_header_data_t)); +#ifndef WOF_PGPE_SUPPORT + // No WOF_PGPE_SUPPORT. Hard code the values + // Taken from P9_Power_management_HcodeHWP_spec.pdf + // Version 0.50 + g_amec->wof.version = 1; + g_amec->wof.vfrt_block_size = 256; + g_amec->wof.vfrt_blck_hdr_sz = 8; + g_amec->wof.vfrt_data_size = 1; + g_amec->wof.active_quads_size = 6; + g_amec->wof.core_count = 24; + g_amec->wof.vdn_start = 2500; + g_amec->wof.vdn_step = 1000; + g_amec->wof.vdn_size = 8; + g_amec->wof.vdd_start = 0; + g_amec->wof.vdd_step = 500; + g_amec->wof.vdd_size = 21; + g_amec->wof.vratio_start = 409; + g_amec->wof.vratio_step = 417; + g_amec->wof.vratio_size = 24; + g_amec->wof.fratio_start = 10000; + g_amec->wof.fratio_step = 1000; + g_amec->wof.fratio_size = 5; +#else // verify the validity of the magic number uint32_t magic_number = in32(G_pgpe_header.wof_tables_addr); MAIN_TRAC_INFO("read_wof_header() Magic No: 0x%08X", magic_number); @@ -635,6 +673,7 @@ void read_wof_header(void) break; } + MAIN_TRAC_INFO("MAIN: VFRT block size %d", G_wof_header.vfrt_block_size); // Make wof header data visible to amester g_amec->wof.version = G_wof_header.version; g_amec->wof.vfrt_block_size = G_wof_header.vfrt_block_size; @@ -663,6 +702,7 @@ void read_wof_header(void) g_amec->wof.package_name_hi = G_wof_header.package_name_hi; g_amec->wof.package_name_lo = G_wof_header.package_name_lo; +#endif // Initialize wof init state to zero g_amec->wof.wof_init_state = WOF_DISABLED; diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c index 1f4ae23..db40119 100644 --- a/src/occ_405/wof/wof.c +++ b/src/occ_405/wof/wof.c @@ -52,6 +52,13 @@ extern pstateStatus G_proc_pstate_status; uint8_t G_sram_vfrt_ping_buffer[MIN_BCE_REQ_SIZE] __attribute__ ((section(".vfrt_ping_buffer"))); uint8_t G_sram_vfrt_pong_buffer[MIN_BCE_REQ_SIZE] __attribute__ ((section(".vfrt_pong_buffer"))); +// BCE Request object for retrieving VFRT's from Mainstore +BceRequest G_vfrt_req; + +// Buffer to hold vfrt from main memory +DMA_BUFFER(temp_bce_request_buffer_t G_vfrt_temp_buff) = {{0}}; + +// Wof header struct wof_header_data_t G_wof_header __attribute__ ((section (".global_data"))); // Quad state structs to temporarily hold the data from the doublewords to @@ -139,34 +146,32 @@ void call_wof_main( void ) set_clear_wof_disabled( CLEAR, WOF_RC_PGPE_WOF_DISABLED ); } + // If error logged in callback, record now + if( g_wof->vfrt_callback_error ) + { + INTR_TRAC_ERR("Got a bad RC in wof_vfrt_callback: 0x%x", + g_wof->wof_vfrt_req_rc); + set_clear_wof_disabled( SET, WOF_RC_VFRT_REQ_FAILURE ); + // After official error recorded, prevent this code + // from running from same setting of the var. + g_wof->vfrt_callback_error = 0; + } // Make sure wof has not been disabled if( g_wof->wof_disabled ) { - // If error loggedin callback, record now - if( g_wof->vfrt_callback_error ) - { - set_clear_wof_disabled( SET, WOF_RC_VFRT_REQ_FAILURE ); - // After official error recorded, prevent this code - // from running from same setting of the var. - g_wof->vfrt_callback_error = 0; - } - if( g_wof->pgpe_wof_off ) { set_clear_wof_disabled( SET, WOF_RC_PGPE_WOF_DISABLED ); g_wof->pgpe_wof_off = 0; } - // WOF has been flagged as disabled. Skip algorithm break; } // Make sure Pstate Protocol is on if(G_proc_pstate_status != PSTATES_ENABLED) { - // No need to call disable wof as the PGPE would - // already have disabled wof. Just flag reason. - CMDH_TRAC_ERR("WOF Disabled! Pstate Protocol off"); + INTR_TRAC_ERR("WOF Disabled! Pstate Protocol off"); set_clear_wof_disabled( SET, WOF_RC_PSTATE_PROTOCOL_OFF ); break; } @@ -195,23 +200,22 @@ void call_wof_main( void ) { if( L_vfrt_last_chance ) { - CMDH_TRAC_ERR("WOF Disabled! Initial VFRT request timeout"); + INTR_TRAC_ERR("WOF Disabled!" + " Init VFRT request timeout"); set_clear_wof_disabled( SET, WOF_RC_VFRT_REQ_TIMEOUT); } else { + INTR_TRAC_INFO("one more chance sending initial VFRT"); L_vfrt_last_chance = true; } } - else - { - // If we got here, init state was set in - // wof_vfrt_callback - L_vfrt_last_chance = false; - } break; case INITIAL_VFRT_SUCCESS: + // We made it this far. Reset Last chance + L_vfrt_last_chance = false; + // Send wof control on gpe request // If enable_success returns true, init state was set enable_success = enable_wof(); @@ -219,11 +223,13 @@ void call_wof_main( void ) { if( L_wof_control_last_chance ) { - CMDH_TRAC_ERR("WOF Disabled! Control req timeout(1)"); + INTR_TRAC_ERR("WOF Disabled! Control req timeout(1)"); set_clear_wof_disabled(SET, WOF_RC_CONTROL_REQ_TIMEOUT); } else { + INTR_TRAC_ERR("One more chance for WOF " + "control request(1)"); L_wof_control_last_chance = true; } } @@ -241,11 +247,13 @@ void call_wof_main( void ) { if( L_wof_control_last_chance ) { - CMDH_TRAC_ERR("WOF Disabled! Control req timeout(2)"); + INTR_TRAC_ERR("WOF Disabled! Control req timeout(2)"); set_clear_wof_disabled(SET, WOF_RC_CONTROL_REQ_TIMEOUT); } else { + INTR_TRAC_ERR("One more chance for WOF " + "control request(2)"); L_wof_control_last_chance = true; } } @@ -254,8 +262,9 @@ void call_wof_main( void ) default: break; - } - } + } // Switch statement + }// initial state machine + // If we have made it to at least WOF enabled no previous data // state run wof routine normally ensuring wof was not disabled // in previous 5 states @@ -285,8 +294,18 @@ void call_wof_main( void ) calc_vfrt_mainstore_addr(); // Send new VFRT send_vfrt_to_pgpe( g_wof->next_vfrt_main_mem_addr ); + if(async_request_is_idle(&G_wof_vfrt_req.request)) + { + g_wof->gpe_req_rc = gpe_request_schedule(&G_wof_vfrt_req); + } + else + { + INTR_TRAC_INFO("VFRT Request is not idle when" + "requested active quads changed"); + } } } + // Toggle for next tick L_run_wof = true; } else @@ -296,11 +315,12 @@ void call_wof_main( void ) { if( L_vfrt_last_chance ) { - CMDH_TRAC_ERR("WOF Disabled! VFRT req timeout"); + INTR_TRAC_ERR("WOF Disabled! VFRT req timeout"); set_clear_wof_disabled(SET,WOF_RC_VFRT_REQ_TIMEOUT); } else { + INTR_TRAC_INFO("One more chance for vfrt request"); L_vfrt_last_chance = true; } } @@ -308,6 +328,8 @@ void call_wof_main( void ) { // Request is idle. Run wof algorithm wof_main(); + + // Set control variables for next tick L_run_wof = false; L_vfrt_last_chance = false; // Finally make sure we are in the fully enabled state @@ -333,12 +355,12 @@ void call_wof_main( void ) */ void wof_main(void) { + // Read out the sensor data needed for calculations read_sensor_data(); // Read out PGPE data from shared SRAM read_shared_sram(); - // Calculate the core voltage per quad calculate_core_voltage(); @@ -350,7 +372,6 @@ void wof_main(void) // Calculate the AC currents calculate_AC_currents(); - // Calculate ceff_ratio_vdd and ceff_ratio_vdn calculate_ceff_ratio_vdd(); calculate_ceff_ratio_vdn(); @@ -377,6 +398,14 @@ void wof_main(void) // Send the new vfrt to the PGPE send_vfrt_to_pgpe( g_wof->next_vfrt_main_mem_addr ); + if(async_request_is_idle(&G_wof_vfrt_req.request)) + { + g_wof->gpe_req_rc = gpe_request_schedule(&G_wof_vfrt_req); + } + else + { + INTR_TRAC_ERR("VFRT REQUEST at end of wof_main() timed out"); + } } /** @@ -448,21 +477,22 @@ uint8_t calc_quad_step_from_start( void ) * Description: Calculates the VFRT address based on the Ceff vdd/vdn and quad * steps. * - * Return: The desired VFRT address + * Return: The desired VFRT main memory address */ uint32_t calc_vfrt_mainstore_addr( void ) { // Wof tables address calculation - // (Base_addr + (sizeof VFRT * (total active quads * ( (g_wof->vdn_step_from_start * vdd_size) + (g_wof->vdd_step_from_start) ) + (g_wof->quad_step_from_start)))) - uint32_t offset = G_wof_header.vfrt_block_size * - (( G_wof_header.active_quads_size * - ((g_wof->vdn_step_from_start * G_wof_header.vdd_size) + + // (Base_addr + + // (sizeof VFRT * (total active quads * ( (g_wof->vdn_step_from_start * vdd_size) + (g_wof->vdd_step_from_start) ) + (g_wof->quad_step_from_start)))) + g_wof->vfrt_mm_offset = g_wof->vfrt_block_size * + (( g_wof->active_quads_size * + ((g_wof->vdn_step_from_start * g_wof->vdd_size) + g_wof->vdd_step_from_start) ) + g_wof->quad_step_from_start); // Skip the wof header at the beginning of wof tables - uint32_t wof_tables_base = G_pgpe_header.wof_tables_addr + WOF_HEADER_SIZE; + uint32_t wof_tables_base = g_wof->vfrt_tbls_main_mem_addr + WOF_HEADER_SIZE; - return wof_tables_base + offset; + return wof_tables_base + g_wof->vfrt_mm_offset; } @@ -476,7 +506,7 @@ uint32_t calc_vfrt_mainstore_addr( void ) * the calculation. * -Pointer to vfrt table temp buffer */ -void copy_vfrt_to_sram( copy_vfrt_to_sram_parms_t * i_parms) +void copy_vfrt_to_sram( void ) { /* * @@ -487,10 +517,7 @@ void copy_vfrt_to_sram( copy_vfrt_to_sram_parms_t * i_parms) */ // Static variable to trac which buffer is open for use // 0 = PING; 1 = PONG; - int l_gperc; // gpe schedule return code uint8_t * l_buffer_address; - - if(g_wof->curr_ping_pong_buf == (uint32_t)G_sram_vfrt_ping_buffer) { // Switch to pong buffer @@ -501,29 +528,17 @@ void copy_vfrt_to_sram( copy_vfrt_to_sram_parms_t * i_parms) // Switch to ping buffer l_buffer_address = G_sram_vfrt_ping_buffer; } - // Update global "next" ping pong buffer for callback function g_wof->next_ping_pong_buf = (uint32_t)l_buffer_address; // Copy the vfrt data into the buffer memcpy( l_buffer_address, - i_parms->vfrt_table->data, - G_wof_header.vfrt_block_size ); + &G_vfrt_temp_buff, + g_wof->vfrt_block_size ); // Set the parameters for the GpeRequest G_wof_vfrt_parms.homer_vfrt_ptr = (HomerVFRTLayout_t*)l_buffer_address; G_wof_vfrt_parms.active_quads = g_wof->req_active_quad_update; - - // Send IPC command to PGPE with new vfrt address and active quads - // Should not need to check if request is idle as wof_main does before - // the WOF calculations begin. - l_gperc = gpe_request_schedule( &G_wof_vfrt_req ); - - // Confirm Successful scheduling of WOF VFRT task - if(l_gperc != 0) - { - // TODO: Cannot create an error log within a callback function. Need to handle. - } } /** @@ -563,6 +578,7 @@ void wof_vfrt_callback( void ) { // Disable WOF g_wof->vfrt_callback_error = 1; + g_wof->wof_vfrt_req_rc = G_wof_vfrt_parms.msg_cb.rc; } } @@ -584,10 +600,16 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr ) do { + static bool print = true; + if( print ) + { + //print_data(); + print = false; + } // First check if the address is 128-byte aligned. error if not. if( i_vfrt_main_mem_addr % 128 ) { - CMDH_TRAC_ERR("VFRT Main Memory address NOT 128-byte aligned:" + INTR_TRAC_ERR("VFRT Main Memory address NOT 128-byte aligned:" " 0x%08x", i_vfrt_main_mem_addr); set_clear_wof_disabled(SET, WOF_RC_VFRT_ALIGNMENT_ERROR); @@ -605,31 +627,22 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr ) // get VFRT based on new values else { - // New VFRT needed from Mainstore, create BCE request to get it. - BceRequest l_vfrt_req; - - // 128-byte aligned temp buffer to hold data - temp_bce_request_buffer_t l_temp_bce_buff = {{0}}; - - // Create structure to hold parameters for callback function - copy_vfrt_to_sram_parms_t l_callback_parms; - l_callback_parms.vfrt_table = &l_temp_bce_buff; // Create request l_ssxrc = bce_request_create( - &l_vfrt_req, // block copy object + &G_vfrt_req, // block copy object &G_pba_bcde_queue, // main to sram copy engine i_vfrt_main_mem_addr, //mainstore address - (uint32_t) &l_temp_bce_buff, // SRAM start address - MIN_BCE_REQ_SIZE, // size of copy + (uint32_t) &G_vfrt_temp_buff, // SRAM start address + MIN_BCE_REQ_SIZE, // size of copy SSX_WAIT_FOREVER, // no timeout (AsyncRequestCallback)copy_vfrt_to_sram, - (void *)&l_callback_parms, + NULL, ASYNC_CALLBACK_IMMEDIATE ); if(l_ssxrc != SSX_OK) { - CMDH_TRAC_ERR("send_vfrt_to_pgpe: BCDE request create failure rc=[%08X]", -l_ssxrc); + INTR_TRAC_ERR("send_vfrt_to_pgpe: BCDE request create failure rc=[%08X]", -l_ssxrc); /* * @errortype * @moduleid SEND_VFRT_TO_PGPE @@ -645,11 +658,11 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr ) } // Do the actual copy - l_ssxrc = bce_request_schedule( &l_vfrt_req ); + l_ssxrc = bce_request_schedule( &G_vfrt_req ); if(l_ssxrc != SSX_OK) { - CMDH_TRAC_ERR("send_vfrt_to_pgpe: BCE request schedule failure rc=[%08X]", -l_ssxrc); + INTR_TRAC_ERR("send_vfrt_to_pgpe: BCE request schedule failure rc=[%08X]", -l_ssxrc); /* * @errortype * @moduleid SEND_VFRT_TO_PGPE @@ -705,10 +718,14 @@ void read_shared_sram( void ) // Read f_clip, v_clip, f_ratio, and v_ratio pgpe_wof_state_t l_wofstate; l_wofstate.value = in64(g_wof->pgpe_wof_state_addr); + // g_wof->f_clip = l_wofstate.fields.fclip_ps; g_wof->v_clip = l_wofstate.fields.vclip_mv; - g_wof->f_ratio = l_wofstate.fields.fratio; - g_wof->v_ratio = l_wofstate.fields.vratio; + //TODO RTC 174543: hard code values to 1 +// g_wof->f_ratio = l_wofstate.fields.fratio; +// g_wof->v_ratio = l_wofstate.fields.vratio; + g_wof->f_ratio = 1; + g_wof->v_ratio = 1; // Get the requested active quad update read_req_active_quads(); @@ -759,12 +776,12 @@ void calculate_core_voltage( void ) // 0 = BYPASS, 1 = REGULATION if( (g_wof->quad_ivrm_states & l_quad_mask ) == 0 ) { - l_voltage = g_wof->voltvddsense_sensor;; + l_voltage = g_wof->voltvddsense_sensor; } else { // Calculate the address of the pstate for the current quad. - uint32_t pstate_addr = G_pgpe_header.occ_pstate_table_sram_addr + + uint32_t pstate_addr = g_wof->pstate_tbl_sram_addr + (g_wof->quad_x_pstates[l_quad_idx] * sizeof(OCCPstateTable_entry_t)); // Get the Pstate @@ -830,8 +847,8 @@ void calculate_core_leakage( void ) g_wof->core_leakage_percent = G_oppb.nest_leakage_percent; // Multiply by core leakage percentage - g_wof->all_cores_off_iso = g_wof->all_cores_off_iso * - g_wof->core_leakage_percent / 100; + g_wof->all_cores_off_iso = + (g_wof->all_cores_off_iso * g_wof->core_leakage_percent) / 100; // Calculate ALL_GOOD_CACHES_ON_ISO g_wof->all_good_caches_on_iso = @@ -839,7 +856,8 @@ void calculate_core_leakage( void ) G_oppb.iddq.avgtemp_all_good_cores_off, l_chip_v_idx, g_wof->tempnest_sensor, - l_v_chip ) - g_wof->all_cores_off_iso; + l_v_chip ); + g_wof->all_good_caches_on_iso -= g_wof->all_cores_off_iso; // Calculate ALL_CACHES_OFF_ISO g_wof->all_caches_off_iso = @@ -847,21 +865,22 @@ void calculate_core_leakage( void ) G_oppb.iddq.avgtemp_all_cores_off_caches_off, l_chip_v_idx, g_wof->tempnest_sensor, - l_v_chip ) - g_wof->all_cores_off_iso; + l_v_chip ); + g_wof->all_caches_off_iso -= g_wof->all_cores_off_iso; // idc Quad uses same variables as all_cores_off_iso so just use that and // divide by 6 to get just one quad g_wof->idc_quad = g_wof->all_cores_off_iso / MAXIMUM_QUADS; // Calculate quad_cache for all quads - l_quad_cache = ( g_wof->all_good_caches_on_iso - g_wof->all_caches_off_iso * + l_quad_cache = ( g_wof->all_good_caches_on_iso - (g_wof->all_caches_off_iso * ( MAXIMUM_QUADS - G_oppb.iddq.good_quads_per_sort) / - MAXIMUM_QUADS ) / G_oppb.iddq.good_quads_per_sort; + MAXIMUM_QUADS) ) / G_oppb.iddq.good_quads_per_sort; // Loop through all Quads and their respective Cores to calculate // leakage. - int quad_idx = 0; // Quad Index (0-5) - uint8_t core_idx = 0; // Actual core index (0-23) + int quad_idx = 0; // Quad Index (0-5) + uint8_t core_idx = 0; // Actual core index (0-23) int core_loop_idx = 0; // On a per quad basis (0-3) for(quad_idx = 0; quad_idx < MAXIMUM_QUADS; quad_idx++) @@ -870,7 +889,6 @@ void calculate_core_leakage( void ) { // Increment the number of quads found to be off num_quads_off++; - } else // Quad i is on { @@ -886,7 +904,6 @@ void calculate_core_leakage( void ) g_wof->cores_on_per_quad[quad_idx] = num_cores_on_in_quad(quad_idx); - // Take a snap shot of the quad temperature for later calculations g_wof->tempq[quad_idx] = AMECSENSOR_ARRAY_PTR(TEMPQ0, quad_idx)->sample; @@ -903,7 +920,6 @@ void calculate_core_leakage( void ) { if(core_powered_on(core_idx)) { - // Get the core temperature from TEMPPROCTHRMC sensor temperature = AMECSENSOR_ARRAY_PTR(TEMPPROCTHRMC0, core_idx)->sample; @@ -919,6 +935,7 @@ void calculate_core_leakage( void ) // Save selected temperature g_wof->tempprocthrmc[core_idx] = temperature; + // Calculate QUAD_GOOD_CORES_ONLY g_wof->quad_good_cores_only[quad_idx] = scale_and_interpolate (G_oppb.iddq.ivdd_quad_good_cores_on_good_caches_on[quad_idx], @@ -934,9 +951,8 @@ void calculate_core_leakage( void ) g_wof->tempprocthrmc[core_idx], g_wof->v_core_100uV[quad_idx]) + - g_wof->all_cores_off_iso * - G_oppb.iddq.good_normal_cores[quad_idx] / 24; - + (g_wof->all_cores_off_iso * G_oppb.iddq.good_normal_cores[quad_idx]) + / 24; // Calculate quad_on_cores[quad] g_wof->quad_on_cores[quad_idx] = @@ -960,8 +976,8 @@ void calculate_core_leakage( void ) // incorporate calculations for cores that were off into leakage // Calculate quadx_BAD_OFF_cores g_wof->quad_bad_off_cores[quad_idx] = - g_wof->all_cores_off_iso * - G_oppb.iddq.good_normal_cores[quad_idx]/24; + (g_wof->all_cores_off_iso * G_oppb.iddq.good_normal_cores[quad_idx]) + / 24; // Scale to nest temp and add to overall leakage idc_vdd += @@ -996,7 +1012,6 @@ void calculate_core_leakage( void ) */ void calculate_nest_leakage( void ) { - // Get the VOLTVDN sensor to choose the appropriate nest voltage // index int l_nest_v_idx = get_voltage_index( g_wof->voltvdn_sensor ); @@ -1061,7 +1076,6 @@ uint32_t calculate_effective_capacitance( uint32_t i_iAC, // Divide by frequency and return the final value. // (I / (V^1.3 * F)) == I / V^1.3 /F return c_eff / i_frequency; - } /** @@ -1073,7 +1087,9 @@ uint32_t calculate_effective_capacitance( uint32_t i_iAC, void calculate_ceff_ratio_vdn( void ) { // Get ceff_tdp_vdn from OCCPPB - g_wof->ceff_tdp_vdn = G_oppb.ceff_tdp_vdn; + // TODO RTC: 174543 - remove hardcoded values once present + //g_wof->ceff_tdp_vdn = G_oppb.ceff_tdp_vdn; + g_wof->ceff_tdp_vdn = 1; // Calculate ceff_vdn // iac_vdn/ (VOLTVDN^1.3 * Fnest) @@ -1085,11 +1101,10 @@ void calculate_ceff_ratio_vdn( void ) // Prevent divide by zero if( g_wof->ceff_tdp_vdn == 0 ) { - CMDH_TRAC_ERR("WOF Disabled! Ceff VDN divide by 0"); + INTR_TRAC_ERR("WOF Disabled! Ceff VDN divide by 0"); // Return 0 g_wof->ceff_ratio_vdn = 0; - set_clear_wof_disabled(SET, WOF_RC_DIVIDE_BY_ZERO); } else @@ -1107,7 +1122,9 @@ void calculate_ceff_ratio_vdn( void ) void calculate_ceff_ratio_vdd( void ) { // Read iac_tdp_vdd from OCCPstateParmBlock struct - g_wof->iac_tdp_vdd = G_oppb.lac_tdp_vdd_turbo_10ma; + // TODO RTC: 174543 - remove hardcoded values once present + // g_wof->iac_tdp_vdd = G_oppb.lac_tdp_vdd_turbo_10ma; + g_wof->iac_tdp_vdd = 10; // Get Vturbo and convert to 100uV (mV -> 100uV) = mV*10 // Multiply by Vratio @@ -1122,7 +1139,6 @@ void calculate_ceff_ratio_vdd( void ) calculate_effective_capacitance( g_wof->iac_tdp_vdd, V, F ); - // Calculate ceff_vdd // iac_vdd / (Vclip^1.3 * Fclip) g_wof->ceff_vdd = @@ -1133,12 +1149,10 @@ void calculate_ceff_ratio_vdd( void ) // Prevent divide by zero if( g_wof->ceff_tdp_vdd == 0 ) { - CMDH_TRAC_ERR("WOF Disabled! Ceff VDD divide by 0"); + INTR_TRAC_ERR("WOF Disabled! Ceff VDD divide by 0"); // Return 0 g_wof->ceff_ratio_vdd = 0; - - // Disable wof set_clear_wof_disabled(SET, WOF_RC_DIVIDE_BY_ZERO); } else @@ -1312,13 +1326,13 @@ void set_clear_wof_disabled( uint8_t i_action, // If error has already been logged, trace and skip if( L_errorLogged ) { - CMDH_TRAC_ERR("Another WOF error was encountered!" + INTR_TRAC_ERR("Another WOF error was encountered!" " wof_disabled=0x%08x", g_wof->wof_disabled); } else { - CMDH_TRAC_ERR("WOF encountered an error. wof_disabled =" + INTR_TRAC_ERR("WOF encountered an error. wof_disabled =" " 0x%08x", g_wof->wof_disabled ); // If wof is disabled in driver, skip generating all error logs if( g_wof->wof_disabled & WOF_RC_DRIVER_WOF_DISABLED ) @@ -1326,7 +1340,7 @@ void set_clear_wof_disabled( uint8_t i_action, static bool trace = true; if(trace) { - CMDH_TRAC_INFO("WOF is disabled in the driver."); + INTR_TRAC_INFO("WOF is disabled in the driver."); trace = false; } break; @@ -1400,9 +1414,10 @@ void set_clear_wof_disabled( uint8_t i_action, } else { - CMDH_TRAC_ERR("Invalid action given. Ignoring for now..."); + INTR_TRAC_ERR("Invalid action given. Ignoring for now..."); } }while( 0 ); + } /** @@ -1418,7 +1433,7 @@ void disable_wof( void ) // Disable wof on 405 g_wof->wof_init_state = WOF_DISABLED; - CMDH_TRAC_ERR("WOF is being disabled. Reasoncode: %x", + INTR_TRAC_ERR("WOF is being disabled. Reasoncode: 0x%08x", g_wof->wof_disabled ); uint32_t reasonCode = 0; int user_data_rc = 0; @@ -1431,7 +1446,7 @@ void disable_wof( void ) // Check to see if a previous wof control IPC message observed an error if( g_wof->control_ipc_rc != 0 ) { - CMDH_TRAC_ERR("Unknown error from wof control IPC message"); + INTR_TRAC_ERR("Unknown error from wof control IPC message"); /** @ * @errortype * @moduleid DISABLE_WOF @@ -1463,7 +1478,7 @@ void disable_wof( void ) * @devdesc OCC Failed to schedule a GPE job for enabling wof */ reasonCode = GPE_REQUEST_SCHEDULE_FAILURE; - CMDH_TRAC_ERR("disable_wof() - Error when sending WOF Control" + INTR_TRAC_ERR("disable_wof() - Error when sending WOF Control" " OFF IPC command! RC = %x", user_data_rc ); } } @@ -1497,7 +1512,7 @@ void disable_wof( void ) */ bool enable_wof( void ) { - CMDH_TRAC_ERR("WOF is being enabled..."); + INTR_TRAC_IMP("WOF is being enabled..."); uint32_t reasonCode = 0; bool result = true; uint32_t bit_to_set = 0; @@ -1505,14 +1520,14 @@ bool enable_wof( void ) // Make sure IPC command is idle. if(!async_request_is_idle( &G_wof_control_req.request ) ) { - result = false;; + result = false; } else { // Check to see if a previous wof control IPC message observed an error if( g_wof->control_ipc_rc != 0 ) { - CMDH_TRAC_ERR("Unknown error from wof control IPC message"); + INTR_TRAC_ERR("Unknown error from wof control IPC message"); rc = g_wof->control_ipc_rc; bit_to_set = WOF_RC_CONTROL_REQ_FAILURE; g_wof->control_ipc_rc = 0; @@ -1537,7 +1552,7 @@ bool enable_wof( void ) if( rc != 0 ) { - CMDH_TRAC_ERR("enable_wof() - Error when sending WOF Control" + INTR_TRAC_ERR("enable_wof() - Error when sending WOF Control" " ON IPC command! RC = %x", rc); /** @ * @errortype @@ -1554,7 +1569,6 @@ bool enable_wof( void ) else { // Set Init state - CMDH_TRAC_INFO("wof control on sent waiting!"); g_wof->wof_init_state = WOF_CONTROL_ON_SENT_WAITING; result = true; } @@ -1606,11 +1620,14 @@ void wof_control_callback( void ) } else { + // Record that PGPE has WOF turned off g_wof->pgpe_wof_off = 1; } } else { + // Record the error return code we saw in this callback to be + // picked up on next tick g_wof->control_ipc_rc = G_wof_control_parms.msg_cb.rc; } } @@ -1627,16 +1644,67 @@ void send_initial_vfrt_to_pgpe( void ) // Set the steps for VDN, VDD, and Quads to the max value g_wof->vdn_step_from_start = g_wof->vdn_size - 1; g_wof->vdd_step_from_start = g_wof->vdd_size - 1; - g_wof->quad_step_from_start = g_wof->num_active_quads - 1; + g_wof->quad_step_from_start = MAXIMUM_QUADS - 1; // Calculate the address of the final vfrt g_wof->next_vfrt_main_mem_addr = calc_vfrt_mainstore_addr(); // Send the final vfrt to shared OCC-PGPE SRAM. send_vfrt_to_pgpe( g_wof->next_vfrt_main_mem_addr ); + if(async_request_is_idle(&G_wof_vfrt_req.request)) + { + g_wof->gpe_req_rc = gpe_request_schedule(&G_wof_vfrt_req); + } + else + { + INTR_TRAC_INFO("Intial vfrt request was NOT idle"); + } + + // Check to make sure IPC request was scheduled correctly + if( g_wof->gpe_req_rc != 0 ) + { + INTR_TRAC_ERR("send_initial_vfrt: Error sending initial VFRT! gperc=%d", + g_wof->gpe_req_rc); + //Error in scheduling wof_vfrt task + /* @ + * @errortype + * @moduleid SEND_INIT_VFRT + * @reasoncode GPE_REQUEST_SCHEDULE_FAILURE + * @userdata1 rc - gpe_request_schedule return code + * @userdata2 0 + * @userdata4 OCC_NO_EXTENDED_RC + * @devdesc OCC Failed to schedule a GPE job for wof vfrt + */ + errlHndl_t l_errl = createErrl( + SEND_INIT_VFRT, // modId + GPE_REQUEST_SCHEDULE_FAILURE, // reasoncode + OCC_NO_EXTENDED_RC, // Extended reason code + ERRL_SEV_UNRECOVERABLE, // Severity + NULL, // Trace Buf + DEFAULT_TRACE_SIZE, // Trace Size + g_wof->gpe_req_rc, // userdata1 + 0 // userdata2 + ); + + // Callout firmware + addCalloutToErrl(l_errl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + + // Commit error log + commitErrl(&l_errl); + + // Reset the global return code after logging the error + g_wof->gpe_req_rc = 0; + } // Update Init state - g_wof->wof_init_state = INITIAL_VFRT_SENT_WAITING; + if(g_wof->wof_init_state < INITIAL_VFRT_SENT_WAITING) + { + g_wof->wof_init_state = INITIAL_VFRT_SENT_WAITING; + } + } /** @@ -1670,7 +1738,7 @@ void read_req_active_quads( void ) /** * get_voltage_index * - * Desctiption: Using the input voltage, returns the index to the lower bound + * Description: Using the input voltage, returns the index to the lower bound * of the two voltages surrounding the input voltage in * G_iddq_voltages * @@ -1773,3 +1841,53 @@ uint32_t scale_and_interpolate( uint16_t * i_leak_arr, (int32_t) scaled_upper_leak ); } + +/** + * print_data + * + * Description: For internal use only. Prints information on the current + * state of the wof algorithm. + */ +void print_data( void ) +{ + INTR_TRAC_INFO("ADDRESSES:"); + INTR_TRAC_INFO("vfrt_tbls_main_mem_addr: 0x%08x", g_wof->vfrt_tbls_main_mem_addr); + INTR_TRAC_INFO("pgpe_wof_state_addr: 0x%08x", g_wof->pgpe_wof_state_addr); + INTR_TRAC_INFO("req_active_quads_addr: 0x%08x", g_wof->req_active_quads_addr); + INTR_TRAC_INFO("quad_state_0_addr: 0x%08x", g_wof->quad_state_0_addr); + INTR_TRAC_INFO("quad_state_1_addr: 0x%08x", g_wof->quad_state_1_addr); + INTR_TRAC_INFO("pstate_tbl_sram_addr: 0x%08x", g_wof->pstate_tbl_sram_addr); + INTR_TRAC_INFO("pong buffer address: 0x%08x", (&G_sram_vfrt_pong_buffer)); + INTR_TRAC_INFO("ping buffer address: 0x%08x", (&G_sram_vfrt_ping_buffer)); + INTR_TRAC_INFO("curr ping/pong addr: 0x%08x", g_wof->curr_ping_pong_buf); + INTR_TRAC_INFO("next ping/pong addr: 0x%08x", g_wof->next_ping_pong_buf); + INTR_TRAC_INFO(""); + INTR_TRAC_INFO("version: %d", g_wof->version); + INTR_TRAC_INFO("vfrt_block_size: %d",g_wof->vfrt_block_size); + INTR_TRAC_INFO("vfrt_blck_hdr_sz: %d",g_wof->vfrt_blck_hdr_sz); + INTR_TRAC_INFO("vfrt_data_size: %d ",g_wof->vfrt_data_size); + INTR_TRAC_INFO("active_quads_size: %d",g_wof->active_quads_size); + INTR_TRAC_INFO("core_count: %d",g_wof->core_count); + INTR_TRAC_INFO("vdn_start: %d",g_wof->vdn_start); + INTR_TRAC_INFO("vdn_step: %d",g_wof->vdn_step); + INTR_TRAC_INFO("vdn_size: %d",g_wof->vdn_size); + INTR_TRAC_INFO("vdd_start: %d",g_wof->vdd_start); + INTR_TRAC_INFO("vdd_step: %d",g_wof->vdd_step); + INTR_TRAC_INFO("vdd_size: %d",g_wof->vdd_size); + INTR_TRAC_INFO("vdn_step_from_start:%d",g_wof->vdn_step_from_start); + INTR_TRAC_INFO("vdd_step_from_start:%d",g_wof->vdd_step_from_start); + INTR_TRAC_INFO("num_active_quads: %d",g_wof->num_active_quads); + INTR_TRAC_INFO("quad_step_4rm_start:%d",g_wof->quad_step_from_start); + INTR_TRAC_INFO("vratio_start: %d",g_wof->vratio_start); + INTR_TRAC_INFO("vratio_step: %d",g_wof->vratio_step); + INTR_TRAC_INFO("vratio_size: %d",g_wof->vratio_size); + INTR_TRAC_INFO("fratio_start: %d",g_wof->fratio_start); + INTR_TRAC_INFO("fratio_step: %d",g_wof->fratio_step); + INTR_TRAC_INFO("fratio_size: %d",g_wof->fratio_size); + INTR_TRAC_INFO("fratio: %d",g_wof->f_ratio); + INTR_TRAC_INFO("vratio: %d",g_wof->v_ratio); + INTR_TRAC_INFO("fclip: %d",g_wof->f_clip); + INTR_TRAC_INFO("vclip: %d",g_wof->v_clip); + INTR_TRAC_INFO("req_active_quads: %x", g_wof->req_active_quad_update); + INTR_TRAC_INFO("vfrt_mm_offset: 0x%08x", g_wof->vfrt_mm_offset); +} diff --git a/src/occ_405/wof/wof.h b/src/occ_405/wof/wof.h index b9e6469..481f88e 100644 --- a/src/occ_405/wof/wof.h +++ b/src/occ_405/wof/wof.h @@ -25,20 +25,19 @@ #ifndef _WOF_H #define _WOF_H - - //****************************************************************************** // Define //****************************************************************************** #define ACTIVE_QUAD_SZ_MIN 1 #define ACTIVE_QUAD_SZ_MAX 6 -#define MIN_BCE_REQ_SIZE 128 -#define WOF_HEADER_SIZE 32 +#define MIN_BCE_REQ_SIZE 256 +#define WOF_HEADER_SIZE 128 #define CORE_IDDQ_MEASUREMENTS 6 #define QUAD_POWERED_OFF 0xFF #define PGPE_WOF_OFF 0 #define PGPE_WOF_ON 1 #define NUM_CORES_PER_QUAD 4 +#define WOF_TABLES_OFFSET 0xC0000// Relative to PPMR_ADDRESS_HOMER //****************************************************************************** // Bit Vector Masks //****************************************************************************** @@ -47,22 +46,28 @@ //****************************************************************************** // WOF Reason Code Masks //****************************************************************************** -#define WOF_RC_NO_WOF_HEADER_MASK 0x0001 -#define WOF_RC_INVALID_ACTIVE_QUADS 0x0002 -#define WOF_RC_INVALID_VDD_VDN 0x0004 -#define WOF_RC_PGPE_REQ_NOT_IDLE 0x0008 -#define WOF_RC_PGPE_WOF_DISABLED 0x0010 -#define WOF_RC_PSTATE_PROTOCOL_OFF 0x0020 -#define WOF_RC_VFRT_REQ_TIMEOUT 0x0040 -#define WOF_RC_CONTROL_REQ_TIMEOUT 0x0080 -#define WOF_RC_STATE_CHANGE 0x0100 -#define WOF_RC_MODE_CHANGE 0x0200 -#define WOF_RC_MODE_NO_SUPPORT_MASK 0x0400 -#define WOF_RC_DIVIDE_BY_ZERO 0x0800 -#define WOF_RC_VFRT_REQ_FAILURE 0x1000 -#define WOF_RC_CONTROL_REQ_FAILURE 0x2000 -#define WOF_RC_VFRT_ALIGNMENT_ERROR 0x4000 -#define WOF_RC_DRIVER_WOF_DISABLED 0x8000 +#define WOF_RC_NO_WOF_HEADER_MASK 0x00000001 +#define WOF_RC_INVALID_ACTIVE_QUADS 0x00000002 +#define WOF_RC_INVALID_VDD_VDN 0x00000004 +#define WOF_RC_PGPE_REQ_NOT_IDLE 0x00000008 +#define WOF_RC_PGPE_WOF_DISABLED 0x00000010 +#define WOF_RC_PSTATE_PROTOCOL_OFF 0x00000020 +#define WOF_RC_VFRT_REQ_TIMEOUT 0x00000040 +#define WOF_RC_CONTROL_REQ_TIMEOUT 0x00000080 +#define WOF_RC_STATE_CHANGE 0x00000100 +#define WOF_RC_MODE_CHANGE 0x00000200 +#define WOF_RC_MODE_NO_SUPPORT_MASK 0x00000400 +#define WOF_RC_DIVIDE_BY_ZERO 0x00000800 +#define WOF_RC_VFRT_REQ_FAILURE 0x00001000 +#define WOF_RC_CONTROL_REQ_FAILURE 0x00002000 +#define WOF_RC_VFRT_ALIGNMENT_ERROR 0x00004000 +#define WOF_RC_DRIVER_WOF_DISABLED 0x00008000 +#define WOF_RC_UTURBO_IS_ZERO 0x00010000 + +//*************************************************************************** +// Temp space used to save hard coded addresses +//*************************************************************************** +#define PSTATE_TBL_ADDR 0xFFF2B85C // Reason codes which should NOT create an error log should be added here #define ERRL_RETURN_CODES ~(WOF_RC_MODE_CHANGE | \ @@ -72,12 +77,12 @@ // Enumeration to define the WOF initialization steps enum wof_init_states { - WOF_DISABLED, - INITIAL_VFRT_SENT_WAITING, - INITIAL_VFRT_SUCCESS, - WOF_CONTROL_ON_SENT_WAITING, - PGPE_WOF_ENABLED_NO_PREV_DATA, - WOF_ENABLED, + WOF_DISABLED, //0 + INITIAL_VFRT_SENT_WAITING, //1 + INITIAL_VFRT_SUCCESS, //2 + WOF_CONTROL_ON_SENT_WAITING, //3 + PGPE_WOF_ENABLED_NO_PREV_DATA, //4 + WOF_ENABLED, //5 }; // Enumeration @@ -87,7 +92,7 @@ enum wof_disabled_actions SET, }; - +//#define WOF_PGPE_SUPPORT 1 #define WOF_MAGIC_NUMBER 0x57465448 // "WFTH" // Structure to hold relevant data from the WOF header in Mainstore @@ -124,12 +129,11 @@ typedef struct __attribute__ ((packed)) uint8_t reserved_2[40]; } wof_header_data_t; - // Structure used in g_amec typedef struct { // Bit vector where each bit signifies a different failure case - uint16_t wof_disabled; + uint32_t wof_disabled; // Data from wof header for debug uint8_t version; uint16_t vfrt_block_size; @@ -277,23 +281,19 @@ typedef struct // Keeps track of whether we got an error in wof_vfrt_callback to be // logged later uint8_t vfrt_callback_error; - // Keeps track of whether or not we just turned off wof on the PGPE + // Keeps track of whether or /not we just turned off wof on the PGPE uint8_t pgpe_wof_off; + // Offset into main memory with the beginning of the wof vfrt data as base + uint32_t vfrt_mm_offset; + // Return code returned from a bad VFRT request + uint8_t wof_vfrt_req_rc; } amec_wof_t; -typedef struct +typedef struct __attribute__ ((packed)) { uint8_t data[MIN_BCE_REQ_SIZE]; } temp_bce_request_buffer_t __attribute ((aligned(128))); - -// Parameter structure used to pass information to the copy_vfrt_to_sram -// call back function. -typedef struct -{ - temp_bce_request_buffer_t * vfrt_table; -} copy_vfrt_to_sram_parms_t; - //****************************************************************************** // Function Prototypes //****************************************************************************** @@ -313,7 +313,7 @@ uint8_t calc_quad_step_from_start( void ); uint32_t calc_vfrt_mainstore_addr( void ); -void copy_vfrt_to_sram( copy_vfrt_to_sram_parms_t * i_parms ); +void copy_vfrt_to_sram( void ); void wof_vfrt_callback( void ); @@ -374,4 +374,6 @@ uint32_t scale_and_interpolate( uint16_t * i_leak_arr, int i_idx, uint16_t i_base_temp, uint16_t i_voltage ); + +void print_data(void); #endif |