src/occ_gpe0/apss_init.c
/*
 * Function Specification
 *
 * Name: apss_init_gpio
 *
 * Description: Initialize the APSS GPIO ports
 *
 * End Function Specification
 */
Function Specification
Name: apss_init_gpio

Initialize the APSS GPIO ports

End Function Specification
Function Specification Name : apss_init_gpio Initialize the APSS GPIO ports End Function Specification
void apss_init_gpio(ipc_msg_t* cmd, void* arg)
{
    uint32_t            rc;
    uint32_t            ipc_send_rc;
    ipc_async_cmd_t     *async_cmd = (ipc_async_cmd_t*)cmd;
    initGpioArgs_t      *args = (initGpioArgs_t*)async_cmd->cmd_data;
    uint64_t            regValue = 0;
    PK_TRACE("apss_init_gpio: started.");
    do
    {
        rc = wait_spi_completion(&(args->error), SPIPSS_P2S_STATUS_REG, 10);
        if (rc)
        {
            PK_TRACE("apss_init_gpio: Timed out waiting for ops to complete. rc = 0x%08x", rc);
            break;
        }
        regValue = 0x410FC00004000000;
        rc = putscom_abs(SPIPSS_P2S_CTRL_REG0, regValue);
        if (rc)
        {
            PK_TRACE("apss_init_gpio: SPIPSS_P2S_CTRL_REG0 putscom failed. rc = 0x%08x", rc);
            gpe_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG0, rc, regValue);
            break;
        }
        regValue = 0x8090400000000000;
        rc = putscom_abs(SPIPSS_P2S_CTRL_REG1, regValue);
        if (rc)
        {
            PK_TRACE("apss_init_gpio: SPIPSS_P2S_CTRL_REG1 putscom failed. rc = 0x%08x", rc);
            gpe_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG1, rc, regValue);
            break;
        }
        regValue = 0x0019000000000000;
        rc = putscom_abs(SPIPSS_P2S_CTRL_REG2, regValue);
        if (rc)
        {
            PK_TRACE("apss_init_gpio: SPIPSS_P2S_CTRL_REG2 putscom failed. rc = 0x%08x", rc);
            gpe_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG2, rc, regValue);
            break;
        }
        uint64_t port = 0;
        for (port=0; port <= 1; port++)
        {
            regValue = args->config0.direction;
            regValue = regValue << 48;
            regValue |= 0x4000000000000000;
            regValue |= (port << 56);
            rc = putscom_abs(SPIPSS_P2S_WDATA_REG, regValue);
            if (rc)
            {
                PK_TRACE("apss_init_gpio: SPIPSS_P2S_WDATA_REG putscom failed. value:0x%X. rc = 0x%08x",
                         regValue, rc);
                gpe_set_ffdc(&(args->error), SPIPSS_P2S_WDATA_REG, rc, regValue);
                break;
            }
            rc = apss_start_spi_command(args,0);
            if (rc)
            {
                PK_TRACE("apss_init_gpio: SPI command start failed. rc = 0x%08x", rc);
                break;
            }
            regValue = args->config0.drive;
            regValue = regValue << 48;
            regValue |= 0x5000000000000000;
            regValue |= (port << 56);
            rc = putscom_abs(SPIPSS_P2S_WDATA_REG, regValue);
            if (rc)
            {
                PK_TRACE("apss_init_gpio: SPIPSS_P2S_WDATA_REG putscom failed. value:0x%X. rc = 0x%08x",
                         regValue, rc);
                gpe_set_ffdc(&(args->error), SPIPSS_P2S_WDATA_REG, rc, regValue);
                break;
            }
            if (port == 0)
            {
                rc = apss_start_spi_command(args, 0);
            }else
            {
                rc = apss_start_spi_command(args, 1);
            }
            if (rc)
            {
                PK_TRACE("apss_init_gpio: SPI command start failed. rc = 0x%08x", rc);
                break;
            }
        }
        if (rc)
        {
            break;
        }
         Set APSS_RESET_GPIO output high before enabling it's output
        regValue = APSS_RESET_GPIO;
        rc = putscom_abs(PU_GPIO_OUTPUT_OR, regValue);
        if(rc)
        {
            PK_TRACE("apss_init: APSS_RESET_GPIO_OUTPUT low failed. rc:0x%08x",rc);
            gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_PUT_FAILED, rc);
            break;
        }
         Read output enable pins.
        rc = getscom_abs(PU_GPIO_OUTPUT_EN, &regValue);
        if(rc)
        {
            PK_TRACE("apss_init: Read APSS_RESET_GPIO_OUTPUT_EN failed. rc:0x%08x",rc);
            gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_GET_FAILED, rc);
            break;
        }
         Enable APSS_RESET_GPIO as output
        regValue |= APSS_RESET_GPIO;
        rc = putscom_abs(PU_GPIO_OUTPUT_EN, regValue);
        if(rc)
        {
            PK_TRACE("apss_init: APSS_RESET_GPIO_OUTPUT_EN failed. rc:0x%08x",rc);
            gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_PUT_FAILED, rc);
            break;
        }
    }while(0);
     send back a successful response.  OCC will check rc and ffdc
    ipc_send_rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
    if(ipc_send_rc)
    {
        PK_TRACE("apss_init_gpio: Failed to send response back. rc = 0x%08x. Halting GPE0",
                 ipc_send_rc);
        gpe_set_ffdc(&(args->error), 0x00, ipc_send_rc, regValue);
        pk_halt();
    }
    if(rc == 0)  if ipc_send_rc is 0, wont reach this instruction (pk_halt)
    {
        PK_TRACE("apss_init_gpio: completed successfully.");
    }
}
void apss_init_gpio ( ipc_msg_t * cmd , void * arg ) { uint32_t rc ; uint32_t ipc_send_rc ; ipc_async_cmd_t * async_cmd = ( ipc_async_cmd_t * ) cmd ; initGpioArgs_t * args = ( initGpioArgs_t * ) async_cmd -> cmd_data ; uint64_t regValue = 0 ; PK_TRACE ( " " ) ; do { rc = wait_spi_completion ( & ( args -> error ) , SPIPSS_P2S_STATUS_REG , 10 ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; break ; } regValue = 0x410FC00004000000 ; rc = putscom_abs ( SPIPSS_P2S_CTRL_REG0 , regValue ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; gpe_set_ffdc ( & ( args -> error ) , SPIPSS_P2S_CTRL_REG0 , rc , regValue ) ; break ; } regValue = 0x8090400000000000 ; rc = putscom_abs ( SPIPSS_P2S_CTRL_REG1 , regValue ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; gpe_set_ffdc ( & ( args -> error ) , SPIPSS_P2S_CTRL_REG1 , rc , regValue ) ; break ; } regValue = 0x0019000000000000 ; rc = putscom_abs ( SPIPSS_P2S_CTRL_REG2 , regValue ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; gpe_set_ffdc ( & ( args -> error ) , SPIPSS_P2S_CTRL_REG2 , rc , regValue ) ; break ; } uint64_t port = 0 ; for ( port = 0 ; port <= 1 ; port ++ ) { regValue = args -> config0 . direction ; regValue = regValue << 48 ; regValue |= 0x4000000000000000 ; regValue |= ( port << 56 ) ; rc = putscom_abs ( SPIPSS_P2S_WDATA_REG , regValue ) ; if ( rc ) { PK_TRACE ( " " , regValue , rc ) ; gpe_set_ffdc ( & ( args -> error ) , SPIPSS_P2S_WDATA_REG , rc , regValue ) ; break ; } rc = apss_start_spi_command ( args , 0 ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; break ; } regValue = args -> config0 . drive ; regValue = regValue << 48 ; regValue |= 0x5000000000000000 ; regValue |= ( port << 56 ) ; rc = putscom_abs ( SPIPSS_P2S_WDATA_REG , regValue ) ; if ( rc ) { PK_TRACE ( " " , regValue , rc ) ; gpe_set_ffdc ( & ( args -> error ) , SPIPSS_P2S_WDATA_REG , rc , regValue ) ; break ; } if ( port == 0 ) { rc = apss_start_spi_command ( args , 0 ) ; } else { rc = apss_start_spi_command ( args , 1 ) ; } if ( rc ) { PK_TRACE ( " " , rc ) ; break ; } } if ( rc ) { break ; } regValue = APSS_RESET_GPIO ; rc = putscom_abs ( PU_GPIO_OUTPUT_OR , regValue ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; gpe_set_ffdc ( & ( args -> error ) , 0 , GPE_RC_SCOM_PUT_FAILED , rc ) ; break ; } rc = getscom_abs ( PU_GPIO_OUTPUT_EN , & regValue ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; gpe_set_ffdc ( & ( args -> error ) , 0 , GPE_RC_SCOM_GET_FAILED , rc ) ; break ; } regValue |= APSS_RESET_GPIO ; rc = putscom_abs ( PU_GPIO_OUTPUT_EN , regValue ) ; if ( rc ) { PK_TRACE ( " " , rc ) ; gpe_set_ffdc ( & ( args -> error ) , 0 , GPE_RC_SCOM_PUT_FAILED , rc ) ; break ; } } while ( 0 ) ; ipc_send_rc = ipc_send_rsp ( cmd , IPC_RC_SUCCESS ) ; if ( ipc_send_rc ) { PK_TRACE ( " " , ipc_send_rc ) ; gpe_set_ffdc ( & ( args -> error ) , 0x00 , ipc_send_rc , regValue ) ; pk_halt ( ) ; } if ( rc == 0 ) { PK_TRACE ( " " ) ; } }
Function Specification
 Name: apss_init_gpio
Function Specification Name : apss_init_gpio
//Note: arg was set to 0 in ipc func table (ipc_func_tables.c), so don't use it // Wait for SPI operations to be complete (up to 10usec timeout) //FFDC set in wait_spi_completion //////////////////////////// // Setup the control regs // frame_size=16, out_count=16, in_delay1=never, in_count2=16 // bridge_enable, clock_divider=36, 2 frames // inter_frame_delay=50 (5usec) //Loop through the 2 ports setup ////////////////////// // Direction (APSS cmd 0x4xxx); Configure GPIO mode (input or output) // Start SPI transaction //FFDC already added //--------------- // Drive (APSS cmd 0x5xxx) // Start SPI transaction //No need to wait since it's the last command. //FFDC already set //End of port while loop. // Enable GPIO that's used for APSS resets // // Set APSS_RESET_GPIO output high before enabling it's output // Read output enable pins. // Enable APSS_RESET_GPIO as output // send back a successful response.  OCC will check rc and ffdc // if ipc_send_rc is 0, wont reach this instruction (pk_halt)