/*
 * dev_fbf.h - FBF (Block Device Controler) generic device API definition.
 * 
 * Author  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-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>

/****  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.
 * Each pixel takes one byte defining 256 levels of gray.
 *
 * It supports five command types:
 * - SIZE  : return the Frame buffer width and height.
 * - ALLOC : give exclusive ownership of the frame buffer to the requesting process.
 * - FREE  : release the exclusive ownership to the kernel.
 * - READ  : move a given number of bytes from the frame buffer to a memory buffer.
 * - WRITE : move a given number of bytes from a memory buffer to the frame buffer.
 *
 * It does not creates the associated server thread.
 * - The SIZE, ALLOC, FREE commands are directly handled by the FBF device.
 * - The READ & WRITE commands are actually registered in the DMA device waiting queue,
 *   using the local DMA channel defined by the calling core lid.
 *****************************************************************************************/

/******************************************************************************************
 * 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.                             */
}
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;

/******************************************************************************************
 * This defines the (implementation independant)  command passed to the driver.
 *****************************************************************************************/

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

/******************************************************************************************
 * This function completes the FBF chdev descriptor initialisation.
 * It calls the specific driver initialisation function, to initialise the hardware
 * device and the specific data structures when required by the implementation.
 * It must be called by a local thread.
 *
 * TODO In this first approach, the "width" and "height" parameters are defined 
 * by the CONFIG_FBF_WIDTH & CONFIG_FBF_HEIGHT in the kernel_config.h file.
 * These parameters should be provided by the driver, accessing dedicated
 * adressable registers in the FBF controler.
 ******************************************************************************************
 * @ chdev      : pointer on FBF chdev descriptor.
 *****************************************************************************************/
void dev_fbf_init( struct chdev_s * chdev );

/******************************************************************************************
 * This function returns the fixed size frame buffer features.
 ******************************************************************************************
 * @ width     : number of pixels (bytes) per line.
 * @ heigth    : total number of lines.
 *****************************************************************************************/
void dev_fbf_get_size( uint32_t  * width,
                       uint32_t  * height );

/******************************************************************************************
 * This function try to get the exclusive ownership of the frame buffer.
 ******************************************************************************************
 * @ return 0 if success / return EINVAL if frame buffer already allocated.
 *****************************************************************************************/
error_t dev_fbf_alloc( void );

/******************************************************************************************
 * This function releases the exclusive ownership of the frame buffer.
 *****************************************************************************************/
void dev_fbf_free( void );

/******************************************************************************************
 * This blocking function try to tranfer <length> bytes from the frame buffer, starting 
 * from <offset>, to the memory buffer defined by <buffer> argument.
 * The corresponding request is actually registered in the local DMA device waiting
 * queue that has the same index as the calling core. The calling thread is descheduled,
 * waiting on transfer completion. It will be resumed by the DMA IRQ signaling completion.
 ******************************************************************************************
 * @ buffer    : local pointer on target buffer in memory.
 * @ length    : number of bytes.
 * @ offset    : first byte in frame buffer.    
 * @ returns 0 if success / returns EINVAL if error.
 *****************************************************************************************/
error_t dev_fbf_read( char         * buffer,
                      uint32_t       length,
                      uint32_t       offset );

/******************************************************************************************
 * This blocking function try to tranfer <length> bytes from a memory buffer defined 
 * by <buffer> argument, to the frame buffer, starting from <offset>.
 * The corresponding request is actually registered in the local DMA device waiting
 * queue, that has the same index as the calling core. The calling thread is descheduled,
 * waiting on transfer completion. It will be resumed by the DMA IRQ signaling completion.
 ******************************************************************************************
 * @ buffer    : local pointer on source buffer in memory.
 * @ length    : number of bytes.
 * @ offset    : first byte in frame buffer.    
 * @ returns 0 if success / returns EINVAL if error.
 *****************************************************************************************/
error_t dev_fbf_write( char         * buffer,
                       uint32_t       length,
                       uint32_t       offset );

#endif	/* _DEV_FBF_H */
