/****************************************************************************
 *  License : All rights reserved for TES Electronic Solutions GmbH
 *            See included /docs/license.txt for details
 *  Project : D/AVE HD
 *  Purpose : User mode driver internal structures
 ****************************************************************************
 * Version Control Information :
 *  $Revision: 9535 $
 *  $Date: 2016-08-04 19:45:11 +0200 (Do, 04. Aug 2016) $
 *  $LastChangedBy: michael.golczewski $
 ****************************************************************************
 * Change History (autogenerated):
 ****************************************************************************/    

#ifndef DAVEHD_INTERNAL_H_INCLUDED
#define DAVEHD_INTERNAL_H_INCLUDED

/*----------------------------------------------------------------------------------------------------------*/

#include "davehd_debug.h"
#include "davehd_registerfile.h"
#include "davehd_cmdlist.h"
#include "davehd_kernel_client.h"

/* PRQA S 3406 ++ *//* $Misra: #INLINE_FUNCTION_DEFINED_IN_HEADER $*/

/*----------------------------------------------------------------------------------------------------------*/
/* Register groups that are tracked for changes per job.*/
/**/
typedef enum tagdhd_jobgroups {
  E_DHD_JOBGROUP_GROUP2,                
  E_DHD_JOBGROUP_GROUP3,
  E_DHD_JOBGROUP_GROUP4,
  E_DHD_JOBGROUP_GROUP6,
  E_DHD_JOBGROUP_GROUP8,
  E_DHD_JOBGROUP_GROUP10,
  E_DHD_JOBGROUP_GROUP11,
  E_DHD_JOBGROUP_GROUP12,

  E_DHD_JOBGROUP_NONE,                  /* the last group is a pseudo group not to be communicated to the kernel*/
  E_DHD_JOBGROUP_CNT
} dhd_jobgroups_t;

/*----------------------------------------------------------------------------------------------------------*/
/* Internal driver context. Each user mode driver instance is based on this structure.*/
/**/
typedef struct tagdhd_device_data {  
  dhd_handle_t                  m_kernel_mode_handle;                   /* KMD connection id*/
  dhd_handle_t                  m_bridge;                               /* handle for callgate (platform specific)   */
  dhd_uint32_t                  m_sizeof;                               /* structure id*/
  dhd_panic_callback_t          m_panic_callback;                       /* callback to be used in case of driver panic*/
  void                         *m_api_data;                             /* private data of the highlevel api  */

  dhd_uint8_t                  *m_stream_shadow;                        /* cpu accessable shadow mem if stream is not mapped memory*/
  dhd_uint32_t                 *m_write_pos;                            /* pointer to next free data word in current job*/
  dhd_uint32_t                  m_free_words;                           /* number of free dwords at write pos*/

  dhd_jobid_t                   m_last_jobid;                           /* latest job id issued so far*/
  dhd_uint32_t                  m_last_jobgen;                          /* generation of latest job id  */

  dhd_device_description_t      m_description;                          /* HW device information*/
  dhd_reg_registerfile_t        m_shadow_state;                         /* buffered version of hw register file*/
  dhd_reg_registerfile_mask_t   m_pending_mask;                         /* bitmask indicating pending registers in state*/

  struct tagdhd_gpu_job        *m_job_struct_pool;                      /* PRQA S 3313 *//* $Misra: No definition for this structure for a clean include structure. $*/ /* pool for running jobs  */
  struct tagdhd_gpu_job        *m_free_job_struct;                      /* next free job header*/
  struct tagdhd_gpu_job        *m_active_job;                           /* job currently under construction or 0 if not yet allocated*/
  dhd_uint16_t                  m_job_pool_size;                        /* maximum number of jobs in this context*/
  dhd_uint16_t                  m_job_words;                            /* default jobsize in words*/

  dhd_edge_data_t              *m_edge_buffer;                          /* user specified geometry buffer pointers*/
  dhd_uv_data_t                *m_uv_buffer;
  dhd_rhw_data_t               *m_rhw_buffer;
  dhd_uint32_t                 *m_col_buffer;
  dhd_depth_data_t             *m_depth_buffer;
  dhd_uint32_t                  m_edge_pitch;
  dhd_uint32_t                  m_uv_pitch;
  dhd_uint32_t                  m_rhw_pitch;
  dhd_uint32_t                  m_depth_pitch;
  dhd_uint32_t                  m_col_pitch;
  dhd_uint32_t                  m_active_pfcs;                          /* set bit for each currently enabled performance counter*/
#ifdef DHD_JOB_CHECKSUM_SUPPORTED
  dhd_uint32_t                  m_checksum;                             /* driver calculated checksum state*/
#endif

  dhd_uint32_t                 *m_col_unit_base;                        /* pointer to first shadow state of active color unit*/
  dhd_uint32_t                 *m_tex_unit_base;                        /* pointer to first shadow state of active texture unit*/

  dhd_cmdlist_t                *m_cmdlist;                              /* pointer to command list used for recording driver commands, 0 in case of normal rendering*/

  dhd_uint16_t                  m_edge_count;                           /* user specified geometry buffer sizes*/
  dhd_uint16_t                  m_uv_count;     
  dhd_uint16_t                  m_rhw_count;     
  dhd_uint16_t                  m_depth_count;     
  dhd_uint16_t                  m_col_count;   

  dhd_uint16_t                  m_framebuffer_width;                    /* framebuffer dimension*/
  dhd_uint16_t                  m_framebuffer_height;
  dhd_uint16_t                  m_util_xmin;                            /* utilities cliprect*/
  dhd_uint16_t                  m_util_ymin;
  dhd_uint16_t                  m_util_xmax;
  dhd_uint16_t                  m_util_ymax;

  dhd_uint8_t                   m_col_unit_index;                       /* index of active color unit*/
  dhd_uint8_t                   m_col_unit_shift;                       /* pending mask bit offset for active color unit    */
  dhd_uint8_t                   m_tex_unit_index;                       /* index of active texture unit*/
  dhd_uint8_t                   m_tex_unit_shift;                       /* pending mask bit offset for active texture unit*/
   
  dhd_uint8_t                   m_group_size[E_DHD_JOBGROUP_CNT];       /* hw maximum size of groups*/

  dhd_uint32_t                  m_flag_tlist_enabled : 1;               /* current actions are logged for tlist dumping*/
  dhd_uint32_t                  m_avoid_burstsplit   : 1;  
#ifdef DHD_JOB_CHECKSUM_SUPPORTED
  dhd_uint32_t                  m_checksum_enabled   : 1;               /* checksum protection state*/
#endif

} dhd_device_data_t;

/* Ensure the external size declaration is large enough. necessary because davehd_internal.h is not visible to */
/* change DHD_DEVICE_DATA_SIZE in davehd_driver.h when this assert fires*/
#if defined(__ghs__)
#pragma ghs nowarning 301
#endif /*defined(__ghs__)*/
DHD_CASSERT( DHD_DEVICE_DATA_SIZE >= sizeof( dhd_device_data_t ), DEVICE_DATA_SIZE_TOO_SMALL )
#if defined(__ghs__)
#pragma ghs endnowarning
#endif /*defined(__ghs__)*/

/*----------------------------------------------------------------------------------------------------------*/
/* Internal buffer data. */
/**/
struct tagdhd_buffer_internal {
  dhd_enum_t                    m_locked;                               /* set if currently locked (combination of dhd_access_mode_t flags)*/
  dhd_uint8_t                  *m_shadow_address;                       /* pointer to shadow memory or 0 if none*/
  dhd_buffer_flags_t            m_flags;                                /* current buffer flags*/
  dhd_uint16_t                  m_lock_x, m_lock_y, m_lock_w, m_lock_h; /* locked region in pixels    */
};

/*----------------------------------------------------------------------------------------------------------*/
/* Read access to job generation from jobid.*/
/**/
dhd_uint32_t dhd_get_job_generation(dhd_jobid_t a_job);
#ifdef PRQA
#pragma PRQA_NO_SIDE_EFFECTS dhd_get_job_generation
#endif


DHD_INLINE dhd_enum_t dhd_validate_device(const dhd_device_data_t *a_device);
DHD_INLINE dhd_device_data_t *dhd_get_device(dhd_handle_t a_device);
/*----------------------------------------------------------------------------------------------------------*/
/* Quick validation (by null pointer and magic number check) of a dhd_device_data_t*/
/**/
DHD_INLINE dhd_enum_t dhd_validate_device(const dhd_device_data_t *a_device) {   /* PRQA S 3450 *//* $Misra: #INLINE_FUNCTION_NO_DECLARATION $*/ /* PRQA S 3480 *//* $Misra: #INLINE_FUNCTION_DEFINED_IN_HEADER $*/
  if ( (a_device == 0) || (a_device->m_sizeof != sizeof(dhd_device_data_t)) ) {
    return E_DHD_ERROR_INVALID_PTR;
  }
  return E_DHD_OK;
}

/*----------------------------------------------------------------------------------------------------------*/
/* Cast device handle to device struct. Includes validation in debug mode*/
/**/
/* This function will result in a DHD_PANIC in case the device handle was invalid. If the calling*/
/* function has a returncode, calling dhd_validate_device and returning an error is recommended instead of */
/* dhd_get_device.*/
/**/
DHD_INLINE dhd_device_data_t *dhd_get_device(dhd_handle_t a_device) {   /* PRQA S 3450 *//* $Misra: #INLINE_FUNCTION_NO_DECLARATION $*/ /* PRQA S 3480 *//* $Misra: #INLINE_FUNCTION_DEFINED_IN_HEADER $*/
  dhd_device_data_t *device = (dhd_device_data_t *) a_device;
  DHD_DEBUG(
    if ( dhd_validate_device(device) != E_DHD_OK ) {
      DHD_PANIC(0, "invalid device handle");
    }
  )
  return device;
}

#endif /*DAVEHD_INTERNAL_H_INCLUDED*/
