/*
 * soclib_mty.c - soclib_mty driver definition (used in TSAR-LETI architecture).
 *
 * Author  Alain Greiner (2016,2017,2018)
 *
 * 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-kernel; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <dev_txt.h>
#include <chdev.h>


/****************************************************************************************
 * This driver supports the "backup" TTY controler implemented in cluster 0
 * of the TSAR-LETI architecture, that is actually an over-simplified version
 * of the vci_tty_tsar component:
 *
 * 1) This hardware component handles only ONE TTY physical channel, that must 
 *    be virtualized by the driver to support several kernel TXT devices.
 * 2) For received characters, the hardware support one RX_IRQ, and one bit 
 *    in the MTY_STATUS register to signal that the MTY_READ register is full. 
 * 3) For transmitted characters, the hardware does NOT provide a TX_IRQ, 
 *    and does NOT provide status information about the MTY_WRITE register,
 *    but implement a low-level flow control mechanism: the response to the
 *    VCI write request in MTY_WRITE register is blocked until this register
 *    can be actually written...
 *
 * It implements the generic TXT device API:
 * - transfer one single character from TTY to command "buffer" if to_mem is non-zero.
 * - transfer "count" characters from command "buffer" to TTY if "to_mem is zero.
 *
 * It handles asynchronous control characters (^C / ^Z), that are translated to signals
 * transmited to the TXT owner process (foreground process).
 *
 * This driver implements one TX_FIFO for the transmited characters, writen by the "cmd"
 * function, and read by the "isr" function).
 * This driver implements one RX_FIFO for the received characters, writen by the "isr"
 * function, and read by the "cmd" function).
***************************************************************************************/

/****************************************************************************************
 *     SOCLIB_MTY registers offsets and masks
 ***************************************************************************************/

#define MTY_WRITE              0
#define MTY_STATUS             1
#define MTY_READ               2
#define MTY_CONFIG             3

/****************************************************************************************
 * masks for MTY_STATUS and MTY_CONFIG registers
 ***************************************************************************************/

#define MTY_STATUS_RX_FULL     1          // TTY_READ_REG full if 1

#define MTY_CONFIG_RX_ENABLE   1          // RX_IRQ enable if 1

/****************************************************************************************
 * This structure is used for both the RX_FIFO and the TX_FIFO.
 ***************************************************************************************/

#define MTY_FIFO_DEPTH  128

typedef struct mty_fifo_s 
{
    char          data[MTY_FIFO_DEPTH];   // one char per slot
    unsigned int  ptr;                    // next free slot index
    unsigned int  ptw;                    // next full slot index
    unsigned int  sts;                    // number of full slots
}
mty_fifo_t;

/****************************************************************************************
 * This function masks the TTY_RX IRQ.
 ****************************************************************************************
 * @ chdev     : pointer on the TXT chdev descriptor.
 ***************************************************************************************/
void soclib_mty_init( chdev_t * chdev );

/****************************************************************************************
 * This function implements both the TXT_READ & TXT_WRITE commands registered in the
 * client thread descriptor (in the txt_cmd field), even if ALMOS-MKH defines two
 * different chdevs (and consequently two diffeerent server threads) for the RX and TX
 * directions. The client thread is identified by the <thread_xp> argument.
 * These functions are supposed to be called by the server thread associated at a
 * given TXT channel for a given direction (TX or RX).
 * Depending on the command type, it access the TX_FIFO or RX_FIFO, and blocks the TXT
 * device server thread on the THREAD_BLOCKED_DEV_ISR, if the RX_FIFO is empty (for a
 * READ), or if the TX_FIFO is full for a WRITE). 
 * The actual transfer between the FIFOs and the TTY device registers is done by the ISR.
 * ****************************************************************************************
 * @ thread_xp : extended pointer on client thread descriptor.
 ***************************************************************************************/
void soclib_mty_cmd( xptr_t thread_xp );

/****************************************************************************************
 * This function implements the TXT_SYNC_WRITE command registered in the txt_aux_t
 * structure. As the MTY hardware component does not provide any status information,
 * it relies on the "blocking write" mechanism to the MTY_REGISTER for flow-control. 
 * It is used by the kernel do display debug messages on TXT0 terminal, without
 * interference with another TXT access to another terminal done by the same thread.
 ****************************************************************************************
 * @ thread_xp : pointer on the txt_aux_t structure containing the arguments.
 ***************************************************************************************/
void soclib_mty_aux( void * args );

/****************************************************************************************
 * This ISR is executed to handle both TX and RX transfers:
 * It is also in charge of multiplexing / demultiplexing the characters between
 * one single physical channel, and several virtual channels.
 * There is one couple of TX_FIFO / RX_FIFO per virtual channel, and each FIFO can be
 * located in a different cluster (in the same cluster as the associated chdev).
 *
 * For both TX and TX, a character on the physical channel is encoded as two bytes:
 * The first byte contains the virtual channel index. The second byte contains 
 * the ascii character value. 
 *
 * - For RX, this ISR is called to move one character from the MTY_READ register to
 *   the relevant RX_FIFO when the MTY_RX_IRQ is activated (when the MTY_STATUS_RX_FULL 
 *   bit, and the MTY_CONFIG_RX_ENABLE bit are both set), indicating that the MTY_READ
 *   register is full and can be read. As there is one single physical channel,
 *   there is one single MTY_RX_IRQ, that is routed to one single core that dispatch
 *   each received character to the relevant (likely remote) RX_FIFO.
 *   This core is supposed to be located in the same cluster as the MTY peripheral.
 *    
 * - For TX, there is no TX_IRQ handled by the MTY controller, and no status bit.
 *   Therefore, this ISR is called to move one character from one TX_FIFO to the
 *   MTY_WRITE register at each TICK event, and relies on the "blocking write"
 *   mechanism to the MTY_REGISTER for flow-control. 
 *   As there is one single physical channel, this ISR is executed by one single core 
 *   that scan the (likely remote) TX_FIFOs associated to all virtual channels, 
 *   and transmit the first found character, with a round_robin policy between channels.
 *   This core is supposed to be located in the same cluster as the MTY peripheral.
 *
 * The RX_IRQ is always enabled to catch the control characters (^C / ^D / ^Z),
 * that are not copied in the RX_FIFO, but directly analysed by the ISR
 * and signaled to the TXT owner process (foreground process).
 ****************************************************************************************
 * @ chdev     : local pointer on TXT chdev descriptor.
 ***************************************************************************************/
void soclib_mty_isr( chdev_t * chdev );

