/*
 * soclib_xcu.h - soclib XCU driver API definition.
 *
 * Alain Greiner    (2016)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _SOCLIB_XCU_H_
#define _SOCLIB_XCU_H_

#include <hal_types.h>
#include <chdev.h>

/******************************************************************************************
 *    SOCLIB_XCU  Registers Mnemonics
 *****************************************************************************************/

#define XCU_WTI_REG            0
#define XCU_PTI_PER            1
#define XCU_PTI_VAL            2
#define XCU_PTI_ACK            3
#define XCU_MSK_PTI            4
#define XCU_MSK_PTI_ENABLE     5
#define XCU_MSK_PTI_DISABLE    6
#define XCU_PTI_ACTIVE         6
#define XCU_MSK_HWI            8
#define XCU_MSK_HWI_ENABLE     9
#define XCU_MSK_HWI_DISABLE    10
#define XCU_HWI_ACTIVE         10
#define XCU_MSK_WTI            12
#define XCU_MSK_WTI_ENABLE     13
#define XCU_MSK_WTI_DISABLE    14
#define XCU_WTI_ACTIVE         14
#define XCU_PRIO               15
#define XCU_CONFIG             16

/******************************************************************************************
 * This function initialises the local XCU masks registers for a given
 * core identified by its local index.
 ******************************************************************************************
 * @ icu       : pointer on the local ICU chdev descriptor.
 * @ lid       : core local index.
 *****************************************************************************************/
void soclib_xcu_init( chdev_t * icu,
                      lid_t     lid );

/******************************************************************************************
 * This function set bits in the local XCU mask register for a given IRQ type,
 * and a given core. It must be called by a local thread.
 * Only the bits with "1" value in mask argument are set, other bits are not modified.
 * All input IRQs of requested types corresponding to "1" bits in mask are enabled.
 ******************************************************************************************
 * @ icu     : pointer on local XCU chdev descriptor
 * @ mask    : mask value
 * @ type    : HWI_TYPE / PTI_TYPE / WTI_TYPE
 * @ lid     : local core index == output IRQ index
 *****************************************************************************************/
void  soclib_xcu_enable_irq( chdev_t  * icu,
                             uint32_t   mask, 
                             uint32_t   type, 
                             lid_t      lid );

/******************************************************************************************
 * This function clear bits in the local XCU mask register for a given IRQ type,
 * and a given core. It must be called by a local thread.
 * Only the bits with "1" value in mask argument are cleared, other bits are not modified.
 * All input IRQs of requested types corresponding to "1" bits in mask are disabled.
 ******************************************************************************************
 * @ icu     : pointer on local XCU chdev descriptor
 * @ mask    : mask value
 * @ type    : HWI_TYPE / PTI_TYPE / WTI_TYPE
 * @ lid     : local core index == output IRQ index
 *****************************************************************************************/
void  soclib_xcu_disable_irq( chdev_t  * icu,
                              uint32_t   mask, 
                              uint32_t   type, 
                              lid_t      lid );

/******************************************************************************************
 * This function returns the values contained in the HWI/WTI/PTI mask registers for
 * a given core. It must be called by a local thread.
 ******************************************************************************************
 * @ icu      : pointer on local XCU chdev descriptor
 * @ lid      : local core index == output IRQ index
 * @ hwi_mask : [out] HWI mask for selected core 
 * @ wti_mask : [out] WTI mask for selected core
 * @ pti_mask : [out] PTI mask for selected core
 *****************************************************************************************/
void soclib_xcu_get_masks( chdev_t   * icu,
                           lid_t       lid,
                           uint32_t  * hwi_mask,
                           uint32_t  * wti_mask,
                           uint32_t  * pti_mask );

/******************************************************************************************
 * This function set the period value for a local XCU timer.
 ******************************************************************************************
 * @ icu        : pointer on the local XCU chdev descriptor
 * @ index      : timer index = PTI index
 * @ period     : Value to be written 
 *****************************************************************************************/
void  soclib_xcu_set_period( chdev_t  * icu,
                             uint32_t   index,
                             uint32_t   period );

/******************************************************************************************
 * This function acknowledge a PTI IRQ for a local XCU timer.
 ******************************************************************************************
 * @ icu        : pointer on the local XCU chdev descriptor
 * @ index      : timer index = PTI index
 * @ the returned value in not significant, but acknowledge requires a read.
 *****************************************************************************************/
uint32_t soclib_xcu_ack_timer( chdev_t  * icu,
                               uint32_t   index );

/******************************************************************************************
 * This function returns the highest priority active interrupt of each type.
 * If no active interrupt => status == 0 / else => status = index + 1
 ******************************************************************************************
 * @ icu        : pointer on the local XCU chdev descriptor
 * @ lid        : core local index.
 * @ hwi_status : buffer for returned HWI status
 * @ wti_status : buffer for returned WTI status
 * @ pti_status : buffer for returned PTI status
 *****************************************************************************************/
void  soclib_xcu_get_status( chdev_t  * icu,
                             lid_t      lid,
                             uint32_t * hwi_status,
                             uint32_t * wti_status,
                             uint32_t * pti_status );

/******************************************************************************************
 * This function send an IPI (Inter Processor Interrupt) to a remote XCU,
 * by writing in a WTI mailbox.
 ******************************************************************************************
 * @ icu_xp  : extended pointer on target ICU device descriptor.
 * @ lid     : target core local index == WTI mailbox index.
 *****************************************************************************************/
void  soclib_xcu_send_ipi( xptr_t     icu_xp,
                           lid_t      lid );

/******************************************************************************************
 * This function returns the local pointer on a WTI mailbox identified by its index.
 * This function does not access the SOCLIB_XCU hardware device. 
 ******************************************************************************************
 * @ icu     : pointer on the local XCU chdev descriptor
 * @ index   : WTI mailbox index.
 *****************************************************************************************/
uint32_t * soclib_xcu_wti_ptr( chdev_t  * icu,
                               uint32_t   index );


#endif	/* _SOCLIB_XCU_H_ */
