/*
 * dev_fbf.h - FBF (Block Device Controler) generic device API definition.
 * 
 * Author  Alain Greiner    (2016,2017,2018,2019)
 *
 * 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
 */

#ifndef _DEV_FBF_H
#define _DEV_FBF_H

#include <hal_kernel_types.h>
#include <shared_fbf.h>

/****  Forward declarations  ****/

struct chdev_s;

/*****************************************************************************************
 *     Generic Frame Buffer Controler definition
 *
 * This device provide access to an external graphic display, that is seen
 * as a fixed size frame buffer, mapped in the kernel address space.
 * The supported  pixel encoding types are defined in the <shared_fbf.h> file.
 *
 * It supports three command types:
 * GET_CONFIG : return frame buffer size and type.
 * READ       : move bytes from frame buffer to memory / deschedule the calling thread.
 * WRITE      : move bytes from memory to frame buffer / deschedule the calling thread.
 *
 * The READ and WRITE operations do not use the FBF device waiting queue, 
 * the server thread, and the IOC IRQ. The client thread does not deschedule:
 * it registers the command in the thread descriptor, and calls directly the FBF driver.
 * that makes a (user <-> kernel) memcpy.
 * 
 * Note: As we don't use any external DMA to move data, but a purely software approach,
 * there is no L2/L3 coherence issue.
 *****************************************************************************************/

/******************************************************************************************
 * This defines the (implementation independant) extension for the generic FBF device.
 *****************************************************************************************/

typedef struct fbf_extend_s
{
    uint32_t           width;         /*! number of pixels per line.                     */
    uint32_t           height;        /*! total number of lines.                         */
    uint32_t           subsampling;   /*! pixel encoding type.                           */
}
fbf_extend_t;

/******************************************************************************************
 * This enum defines the various implementations of the generic FBF peripheral.
 * It must be kept consistent with the define in arch_info.h file.
 *****************************************************************************************/

enum fbf_impl_e
{
    IMPL_FBF_SCL =   0,     
    IMPL_FBF_I86 =   1,  
} 
fbf_impl_t;

typedef struct fbf_command_s
{
    xptr_t      dev_xp;        /*! extended pointer on device descriptor                 */
    uint32_t    type;          /*! requested operation type.                             */
    uint32_t    length;        /*! number of bytes.                                      */
    uint32_t    offset;        /*! offset in frame buffer (bytes)                        */
    void      * buffer;        /*! pointer on memory buffer in user space                */
    uint32_t    error;         /*! operation status (0 if success)                       */
}
fbf_command_t;


/******************************************************************************************
 * This function returns a printable string for a given FBF command  <cmd_type>.
 ******************************************************************************************
 * @ cmd_type   :  FBF command type (defined in shared_fbf.h file).
 * @ returns a string pointer.
 *****************************************************************************************/
char * dev_fbf_cmd_str( uint32_t cmd_type );

/******************************************************************************************
 * This function completes the FBF chdev descriptor initialisation.
 * It calls the specific driver initialisation function, to initialise the hardware
 * device and the chdev extension. It must be called by a local thread.
 ******************************************************************************************
 * @ chdev      : pointer on FBF chdev descriptor.
 *****************************************************************************************/
void dev_fbf_init( struct chdev_s * chdev );

/******************************************************************************************
 * This function returns the frame buffer size and type.
 * It does NOT access the hardware, as the size and type have been registered
 * in the chdev descriptor extension.
 ******************************************************************************************
 * @ width     : [out] number of pixels per line.
 * @ height    : [out] total number of lines.
 * @ type      : [out] pixel encoding type.
 *****************************************************************************************/
void dev_fbf_get_config( uint32_t  * width,
                         uint32_t  * height,
                         uint32_t  * type );

/******************************************************************************************
 * This blocking function moves <length> bytes between the frame buffer, starting from
 * byte defined by <offset>, and an user buffer defined by the <user_buffer> argument.
 * It can be called by a client thread running in any cluster.
 * The transfer direction are defined by the <cmd_type> argument.
 * The request is registered in the client thread descriptor, but the client thread is
 * not descheduled, and calls directly the FBF driver.
 ******************************************************************************************
 * @ cmd_type    : FBF_READ / FBF_WRITE / FBF_SYNC_READ / FBF_SYN_WRITE.
 * @ user_buffer : pointer on memory buffer in user space.
 * @ length      : number of bytes.
 * @ offset      : first byte in frame buffer.    
 * @ returns 0 if success / returns EINVAL if error.
 *****************************************************************************************/
error_t dev_fbf_move_data( uint32_t   cmd_type,
                           void     * user_buffer,
                           uint32_t   length,
                           uint32_t   offset );

#endif	/* _DEV_FBF_H */
