Skip to content

Commit

Permalink
Add ipmi command to configure clock switch and save it in eeprom
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavosr8 committed Sep 27, 2023
1 parent 23d2590 commit b039402
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 58 deletions.
11 changes: 11 additions & 0 deletions modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/led.c)
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/ipmb.c ${MODULE_PATH}/ipmi.c)
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/printf-stdarg.c)
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/error.c)
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/eeprom_24xx02.c)

message(STATUS "Selected modules to compile: ${TARGET_MODULES}")

Expand All @@ -24,6 +25,16 @@ if (";${TARGET_MODULES};" MATCHES ";FRU;")
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_FRU")
endif()

if (";${TARGET_MODULES};" MATCHES ";CLOCK_CONFIG;")
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/clock_config.c )
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_CLOCK_CONFIG")
endif()

if (";${TARGET_MODULES};" MATCHES ";EEPROM_24XX02;")
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/eeprom_24xx02.c )
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_EEPROM_24XX02")
endif()

if (";${TARGET_MODULES};" MATCHES ";SDR;")
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/sdr.c )
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_SDR")
Expand Down
73 changes: 40 additions & 33 deletions modules/adn4604.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,30 @@
#include "adn4604_usercfg.h"
#include "i2c.h"
#include "i2c_mapping.h"
#include "clock_config.h"
#include "eeprom_24xx02.h"

adn_connect_map_t con;

void adn4604_init( void )
{
uint16_t out_enable_flag = {
ADN4604_EN_OUT_0 << 0 |
ADN4604_EN_OUT_1 << 1 |
ADN4604_EN_OUT_2 << 2 |
ADN4604_EN_OUT_3 << 3 |
ADN4604_EN_OUT_4 << 4 |
ADN4604_EN_OUT_5 << 5 |
ADN4604_EN_OUT_6 << 6 |
ADN4604_EN_OUT_7 << 7 |
ADN4604_EN_OUT_8 << 8 |
ADN4604_EN_OUT_9 << 9 |
ADN4604_EN_OUT_10 << 10 |
ADN4604_EN_OUT_11 << 11 |
ADN4604_EN_OUT_12 << 12 |
ADN4604_EN_OUT_13 << 13 |
ADN4604_EN_OUT_14 << 14 |
ADN4604_EN_OUT_15 << 15
((clock_config[0] & 0x80) >> 7) << 0 |
((clock_config[1] & 0x80) >> 7) << 1 |
((clock_config[2] & 0x80) >> 7) << 2 |
((clock_config[3] & 0x80) >> 7) << 3 |
((clock_config[4] & 0x80) >> 7) << 4 |
((clock_config[5] & 0x80) >> 7) << 5 |
((clock_config[6] & 0x80) >> 7) << 6 |
((clock_config[7] & 0x80) >> 7) << 7 |
((clock_config[8] & 0x80) >> 7) << 8 |
((clock_config[9] & 0x80) >> 7) << 9 |
((clock_config[10] & 0x80) >> 7) << 10 |
((clock_config[11] & 0x80) >> 7) << 11 |
((clock_config[12] & 0x80) >> 7) << 12 |
((clock_config[13] & 0x80) >> 7) << 13 |
((clock_config[14] & 0x80) >> 7) << 14 |
((clock_config[15] & 0x80) >> 7) << 15
};

/* Disable UPDATE' pin by pulling it GPIO_LEVEL_HIGH */
Expand All @@ -69,30 +71,35 @@ void adn4604_init( void )
vTaskDelay( 50 );
}

/* Configure the interconnects */
con.out0 = ADN4604_CFG_OUT_0;
con.out1 = ADN4604_CFG_OUT_1;
con.out2 = ADN4604_CFG_OUT_2;
con.out3 = ADN4604_CFG_OUT_3;
con.out4 = ADN4604_CFG_OUT_4;
con.out5 = ADN4604_CFG_OUT_5;
con.out6 = ADN4604_CFG_OUT_6;
con.out7 = ADN4604_CFG_OUT_7;
con.out8 = ADN4604_CFG_OUT_8;
con.out9 = ADN4604_CFG_OUT_9;
con.out10 = ADN4604_CFG_OUT_10;
con.out11 = ADN4604_CFG_OUT_11;
con.out12 = ADN4604_CFG_OUT_12;
con.out13 = ADN4604_CFG_OUT_13;
con.out14 = ADN4604_CFG_OUT_14;
con.out15 = ADN4604_CFG_OUT_15;
/* Read the clock configuration from the eeprom */
eeprom_24xx02_read(CHIP_ID_RTC_EEPROM, 0x0, clock_config, 16, 10);

/* Configure the interconnects*/
con.out0 = clock_config[0] & 0x0F;
con.out1 = clock_config[1] & 0x0F;
con.out2 = clock_config[2] & 0x0F;
con.out3 = clock_config[3] & 0x0F;
con.out4 = clock_config[4] & 0x0F;
con.out5 = clock_config[5] & 0x0F;
con.out6 = clock_config[6] & 0x0F;
con.out7 = clock_config[7] & 0x0F;
con.out8 = clock_config[8] & 0x0F;
con.out9 = clock_config[9] & 0x0F;
con.out10 = clock_config[10] & 0x0F;
con.out11 = clock_config[11] & 0x0F;
con.out12 = clock_config[12] & 0x0F;
con.out13 = clock_config[13] & 0x0F;
con.out14 = clock_config[14] & 0x0F;
con.out15 = clock_config[15] & 0x0F;

adn4604_xpt_config( ADN_XPT_MAP0_CON_REG, con );

/* Enable desired outputs */
for ( uint8_t i = 0; i < 16; i++ ) {
if ( ( out_enable_flag >> i ) & 0x1 ) {
adn4604_tx_control( i, TX_ENABLED );
} else {
adn4604_tx_control( i, TX_DISABLED );
}
}

Expand Down
1 change: 1 addition & 0 deletions modules/adn4604.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ typedef struct __attribute__((__packed__)) {
out15:4;
#endif
} adn_connect_map_t;
extern adn_connect_map_t con;

typedef struct adn_connect_cfg{
uint8_t map_reg;
Expand Down
17 changes: 17 additions & 0 deletions modules/clock_config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "clock_config.h"

uint8_t clock_config[16];

IPMI_HANDLER(ipmi_custom_cmd_write_clock_config, NETFN_CUSTOM, IPMI_CUSTOM_CMD_WRITE_CLOCK_CONFIG, ipmi_msg *req, ipmi_msg *rsp)
{
memcpy(clock_config, req->data, req->data_len);
payload_send_message(FRU_AMC, PAYLOAD_MESSAGE_CLOCK_CONFIG);
rsp->completion_code = IPMI_CC_OK;
}

IPMI_HANDLER(ipmi_custom_cmd_read_clock_config, NETFN_CUSTOM, IPMI_CUSTOM_CMD_READ_CLOCK_CONFIG, ipmi_msg *req, ipmi_msg *rsp)
{
rsp->data_len = 16;
memcpy(rsp->data, clock_config, rsp->data_len);
rsp->completion_code = IPMI_CC_OK;
}
7 changes: 7 additions & 0 deletions modules/clock_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdint.h>
#include <string.h>
#include "ipmi.h"
#include "fru.h"
#include "payload.h"

extern uint8_t clock_config[16];
2 changes: 2 additions & 0 deletions modules/ipmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@
*/
#define IPMI_CUSTOM_CMD_MMC_GET_FREE_HEAP 0x01
#define IPMI_CUSTOM_CMD_GET_GIT_HASH 0x02
#define IPMI_CUSTOM_CMD_WRITE_CLOCK_CONFIG 0x03
#define IPMI_CUSTOM_CMD_READ_CLOCK_CONFIG 0x04
/**
* @}
*/
Expand Down
1 change: 1 addition & 0 deletions port/board/afc-bpm/v3_1/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ endif()
#List all modules used by this board
set(TARGET_MODULES
"FRU"
"CLOCK_CONFIG"
"PAYLOAD"
"SDR"
"SCANSTA1101"
Expand Down
85 changes: 76 additions & 9 deletions port/board/afc-bpm/v3_1/payload.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
#include "fru.h"
#include "led.h"
#include "board_led.h"
#include "clock_config.h"
#include "i2c_mapping.h"
#include "eeprom_24xx02.h"

/* payload states
* 0 - No power
Expand Down Expand Up @@ -190,7 +193,7 @@ void payload_init( void )
while ( gpio_read_pin( PIN_PORT(GPIO_MMC_ENABLE), PIN_NUMBER(GPIO_MMC_ENABLE) ) == 1 ) {};
}

xTaskCreate( vTaskPayload, "Payload", 120, NULL, tskPAYLOAD_PRIORITY, &vTaskPayload_Handle );
xTaskCreate( vTaskPayload, "Payload", 256, NULL, tskPAYLOAD_PRIORITY, &vTaskPayload_Handle );

amc_payload_evt = xEventGroupCreate();
#ifdef MODULE_RTM
Expand Down Expand Up @@ -239,18 +242,82 @@ void vTaskPayload( void *pvParameters )

current_evt = xEventGroupGetBits( amc_payload_evt );

if( current_evt & PAYLOAD_MESSAGE_CLOCK_CONFIG ){

adn4604_reset();
eeprom_24xx02_write(CHIP_ID_RTC_EEPROM, 0x0, clock_config, 16, 10);
uint16_t out_enable_flag = {
((clock_config[0] & 0x80) >> 7) << 0 |
((clock_config[1] & 0x80) >> 7) << 1 |
((clock_config[2] & 0x80) >> 7) << 2 |
((clock_config[3] & 0x80) >> 7) << 3 |
((clock_config[4] & 0x80) >> 7) << 4 |
((clock_config[5] & 0x80) >> 7) << 5 |
((clock_config[6] & 0x80) >> 7) << 6 |
((clock_config[7] & 0x80) >> 7) << 7 |
((clock_config[8] & 0x80) >> 7) << 8 |
((clock_config[9] & 0x80) >> 7) << 9 |
((clock_config[10] & 0x80) >> 7) << 10 |
((clock_config[11] & 0x80) >> 7) << 11 |
((clock_config[12] & 0x80) >> 7) << 12 |
((clock_config[13] & 0x80) >> 7) << 13 |
((clock_config[14] & 0x80) >> 7) << 14 |
((clock_config[15] & 0x80) >> 7) << 15};

/* Disable UPDATE' pin by pulling it GPIO_LEVEL_HIGH */
gpio_set_pin_state( PIN_PORT(GPIO_ADN_UPDATE), PIN_NUMBER(GPIO_ADN_UPDATE), GPIO_LEVEL_HIGH );

/* There's a delay circuit in the Reset pin of the clock switch, we must wait until it clears out */
while( gpio_read_pin( PIN_PORT(GPIO_ADN_RESETN), PIN_NUMBER(GPIO_ADN_RESETN) ) == 0 ) {
vTaskDelay( 50 );
}

/* Configure the interconnects*/
con.out0 = clock_config[0] & 0x0F;
con.out1 = clock_config[1] & 0x0F;
con.out2 = clock_config[2] & 0x0F;
con.out3 = clock_config[3] & 0x0F;
con.out4 = clock_config[4] & 0x0F;
con.out5 = clock_config[5] & 0x0F;
con.out6 = clock_config[6] & 0x0F;
con.out7 = clock_config[7] & 0x0F;
con.out8 = clock_config[8] & 0x0F;
con.out9 = clock_config[9] & 0x0F;
con.out10 = clock_config[10] & 0x0F;
con.out11 = clock_config[11] & 0x0F;
con.out12 = clock_config[12] & 0x0F;
con.out13 = clock_config[13] & 0x0F;
con.out14 = clock_config[14] & 0x0F;
con.out15 = clock_config[15] & 0x0F;

adn4604_xpt_config( ADN_XPT_MAP0_CON_REG, con );

/* Enable desired outputs */
for ( uint8_t i = 0; i < 16; i++ ) {
if ( ( out_enable_flag >> i ) & 0x1 ) {
adn4604_tx_control( i, TX_ENABLED );
} else {
adn4604_tx_control( i, TX_DISABLED );
}
}

adn4604_active_map( ADN_XPT_MAP0 );
adn4604_update();

xEventGroupClearBits(amc_payload_evt, PAYLOAD_MESSAGE_CLOCK_CONFIG);
}
if ( current_evt & PAYLOAD_MESSAGE_QUIESCE ) {

/*
* If you issue a shutdown fru command in the MCH shell, the payload power
* task will receive a PAYLOAD_MESSAGE_QUIESCE message and set the
* QUIESCED_req flag to '1' and the MCH will shutdown the 12VP0 power,
* making the payload power task go to PAYLOAD_NO_POWER state.
* If you issue a shutdown fru command in the MCH shell, the payload power
* task will receive a PAYLOAD_MESSAGE_QUIESCE message and set the
* QUIESCED_req flag to '1' and the MCH will shutdown the 12VP0 power,
* making the payload power task go to PAYLOAD_NO_POWER state.
* So, if we are in the PAYLOAD_QUIESCED state and receive a
* PAYLOAD_MESSAGE_QUIESCE message, the QUIESCED_req flag
* PAYLOAD_MESSAGE_QUIESCE message, the QUIESCED_req flag
* should be '0'
*/

if (state == PAYLOAD_QUIESCED) {
QUIESCED_req = 0;
} else {
Expand Down Expand Up @@ -328,7 +395,7 @@ void vTaskPayload( void *pvParameters )
new_state = PAYLOAD_NO_POWER;
}
break;

case PAYLOAD_RESET:
/*Reset DCDC converters*/
setDC_DC_ConvertersON( false );
Expand Down
1 change: 1 addition & 0 deletions port/board/afc-bpm/v3_1/payload.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extern enum {
#define PAYLOAD_MESSAGE_WARM_RST (1 << 1)
#define PAYLOAD_MESSAGE_REBOOT (1 << 2)
#define PAYLOAD_MESSAGE_QUIESCE (1 << 3)
#define PAYLOAD_MESSAGE_CLOCK_CONFIG (1 << 4)
/**
* @}
*/
Expand Down
1 change: 1 addition & 0 deletions port/board/afc-timing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ endif()
#List all modules used by this board
set(TARGET_MODULES
"FRU"
"CLOCK_CONFIG"
"PAYLOAD"
"SDR"
"SCANSTA1101"
Expand Down
Loading

0 comments on commit b039402

Please sign in to comment.