Files
2026-08-24 10:03:24 +08:00

387 lines
9.1 KiB
C

/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __GDC_API_H__
#define __GDC_API_H__
#include <stdbool.h>
#define WORD_SIZE 16
#define WORD_MASK (~(WORD_SIZE - 1))
#define AXI_WORD_ALIGN(size) ((size + WORD_SIZE - 1) & WORD_MASK)
#define BYTE_SIZE 8
#define BYTE_MASK (~(BYTE_SIZE - 1))
#define AXI_BYTE_ALIGN(size) ((size + BYTE_SIZE - 1) & BYTE_MASK)
typedef unsigned long phys_addr_t;
#define __iomem
// #define __DEBUG
#ifdef __DEBUG
#define D_GDC(fmt, args...) printf(fmt, ## args)
#else
#define D_GDC(fmt, args...)
#endif
#define E_GDC(fmt, args...) printf(fmt, ## args)
enum gdc_memtype_s {
AML_GDC_MEM_ION,
AML_GDC_MEM_DMABUF,
AML_GENERIC_DMABUF,
AML_GDC_MEM_INVALID,
};
enum dma_data_direction {
DMA_BIDIRECTIONAL = 0,
DMA_TO_DEVICE = 1,
DMA_FROM_DEVICE = 2,
DMA_NONE = 3,
};
/* format type and format bit width mask
* example: (NV12 | BIT_16) means nv12 16bit.
*/
#define FORMAT_TYPE_MASK 0xffff
#define FORMAT_IN_BITW_MASK 0x0f0000
#define FORMAT_OUT_BITW_MASK 0xf00000
enum {
NV12 = 1,
YV12,
Y_GREY,
YUV444_P,
RGB444_P,
FMT_MAX
};
enum {
IN_BITW_8 = 0, /* default input bit width */
IN_BITW_10 = (1 << 16),
IN_BITW_12 = (1 << 17),
IN_BITW_16 = (1 << 18),
OUT_BITW_8 = 0,
OUT_BITW_10 = (1 << 20),
OUT_BITW_12 = (1 << 21),
OUT_BITW_16 = (1 << 22)
};
enum {
ARM_GDC,
AML_GDC
};
typedef unsigned int uint32_t;
// each configuration addresses and size
typedef struct gdc_config {
uint32_t format;
uint32_t config_addr; //gdc config address
uint32_t config_size; //gdc config size in 32bit
uint32_t input_width; //gdc input width resolution
uint32_t input_height; //gdc input height resolution
uint32_t input_y_stride; //gdc input y stride resolution
uint32_t input_c_stride; //gdc input uv stride
uint32_t output_width; //gdc output width resolution
uint32_t output_height; //gdc output height resolution
uint32_t output_y_stride; //gdc output y stride
uint32_t output_c_stride; //gdc output uv stride
} gdc_config_t;
typedef struct gdc_buffer_info {
unsigned int mem_alloc_type;
unsigned int plane_number;
union {
unsigned int y_base_fd;
unsigned int shared_fd;
};
union {
unsigned int uv_base_fd;
unsigned int u_base_fd;
};
unsigned int v_base_fd;
} gdc_buffer_info_t;
// overall gdc settings and state
typedef struct gdc_settings {
uint32_t magic;
uint32_t base_gdc; //writing/reading to gdc base address, currently not read by api
gdc_config_t gdc_config; //array of gdc configuration and sizes
//int gdc_config_total; //update this index for new config
uint32_t buffer_addr; //start memory to write gdc output framse
uint32_t buffer_size; //size of memory output frames to determine if it is enough and can do multiple write points
uint32_t current_addr; //current output address of gdc
int32_t is_waiting_gdc; //set when expecting an interrupt from gdc
int32_t in_fd; //input buffer's share fd
int32_t out_fd; //output buffer's share fd
//input address for y and u, v planes
uint32_t y_base_addr;
union {
uint32_t uv_base_addr;
uint32_t u_base_addr;
};
uint32_t v_base_addr;
void *ddr_mem; //opaque address in ddr added with offset to write the gdc config sequence
void (*get_frame_buffer)(uint32_t y_base_addr,
uint32_t uv_base_addr,
uint32_t y_line_offset,
uint32_t uv_line_offset);
void *fh;
int32_t y_base_fd;
union {
int32_t uv_base_fd;
int32_t u_base_fd;
};
int32_t v_base_fd;
}gdc_settings_t;
typedef struct gdc_settings_ex {
uint32_t magic;
gdc_config_t gdc_config; //array of gdc configuration and sizes
gdc_buffer_info_t input_buffer;
gdc_buffer_info_t config_buffer;
gdc_buffer_info_t output_buffer;
} gdc_settings_ex_t;
/* for gdc dma buf define */
struct gdc_dmabuf_req_s {
int index;
unsigned int len;
unsigned int dma_dir;
};
struct gdc_dmabuf_exp_s {
int index;
unsigned int flags;
int fd;
};
/* end of gdc dma buffer define */
#define GDC_IOC_MAGIC 'G'
#define GDC_PROCESS _IOW(GDC_IOC_MAGIC, 0x00, struct gdc_settings)
#define GDC_PROCESS_NO_BLOCK _IOW(GDC_IOC_MAGIC, 0x01, struct gdc_settings)
#define GDC_RUN _IOW(GDC_IOC_MAGIC, 0x02, struct gdc_settings)
#define GDC_REQUEST_BUFF _IOW(GDC_IOC_MAGIC, 0x03, struct gdc_settings)
#define GDC_PROCESS_EX _IOW(GDC_IOC_MAGIC, 0x05, struct gdc_settings_ex)
#define GDC_REQUEST_DMA_BUFF _IOW(GDC_IOC_MAGIC, 0x06, struct gdc_dmabuf_req_s)
#define GDC_EXP_DMA_BUFF _IOW(GDC_IOC_MAGIC, 0x07, struct gdc_dmabuf_exp_s)
#define GDC_FREE_DMA_BUFF _IOW(GDC_IOC_MAGIC, 0x08, int)
#define GDC_SYNC_DEVICE _IOW(GDC_IOC_MAGIC, 0x09, int)
#define GDC_SYNC_CPU _IOW(GDC_IOC_MAGIC, 0x0a, int)
#define GDC_PROCESS_WITH_FW _IOW(GDC_IOC_MAGIC, 0x0b, \
struct gdc_settings_with_fw)
#define MAX_PLANE 3
enum {
INPUT_BUFF_TYPE = 0x1000,
OUTPUT_BUFF_TYPE,
CONFIG_BUFF_TYPE,
GDC_BUFF_TYPE_MAX
};
struct gdc_buf_cfg {
uint32_t type;
unsigned long len;
};
enum {
EQUISOLID = 1,
CYLINDER,
EQUIDISTANT,
CUSTOM,
AFFINE,
FW_TYPE_MAX
};
struct fw_equisolid_s {
/* float */
char strengthX[8];
/* float */
char strengthY[8];
int rotation;
};
struct fw_cylinder_s {
/* float */
char strength[8];
int rotation;
};
struct fw_equidistant_s {
/* float */
char azimuth[8];
int elevation;
int rotation;
int fov_width;
int fov_height;
bool keep_ratio;
int cylindricityX;
int cylindricityY;
};
struct fw_custom_s {
char *fw_name;
};
struct fw_affine_s {
int rotation;
};
struct fw_input_info_s {
int with;
int height;
int fov;
int diameter;
int offsetX;
int offsetY;
};
union transform_u {
struct fw_equisolid_s fw_equisolid;
struct fw_cylinder_s fw_cylinder;
struct fw_equidistant_s fw_equidistant;
struct fw_custom_s fw_custom;
struct fw_affine_s fw_affine;
};
struct fw_output_info_s {
int offsetX;
int offsetY;
int width;
int height;
union transform_u trans;
int pan;
int tilt;
/* float*/
char zoom[8];
};
struct firmware_info {
unsigned int format;
unsigned int trans_size_type;
char *file_name;
phys_addr_t phys_addr;
void __iomem *virt_addr;
unsigned int size;
struct page *cma_pages;
unsigned int loaded;
};
struct fw_info_s {
char *fw_name;
int fw_type;
struct page *cma_pages;
phys_addr_t phys_addr;
void __iomem *virt_addr;
struct fw_input_info_s fw_input_info;
struct fw_output_info_s fw_output_info;
};
struct gdc_settings_with_fw {
uint32_t magic;
gdc_config_t gdc_config;
struct gdc_buffer_info input_buffer;
struct gdc_buffer_info reserved;
struct gdc_buffer_info output_buffer;
struct fw_info_s fw_info;
};
struct gdc_usr_ctx_s {
int gdc_client;
int ion_fd;
int dma_heap_fd;
int custom_fw;
struct gdc_settings gs;
struct gdc_settings_ex gs_ex;
struct gdc_settings_with_fw gs_with_fw;
int mem_type;
int plane_number;
char *i_buff[MAX_PLANE];
char *o_buff[MAX_PLANE];
char *c_buff;
unsigned long i_len[MAX_PLANE];
unsigned long o_len[MAX_PLANE];
unsigned long c_len;
unsigned int dev_type;
};
typedef struct gdc_alloc_buffer_s {
unsigned int format;
unsigned int plane_number;
unsigned int len[MAX_PLANE];
} gdc_alloc_buffer_t;
/**
* This function create a contex for gdc work.
*
* @param ctx - contains client of gdc and ion.
*
* @return 0 - success
* -1 - fail
*/
int gdc_create_ctx(struct gdc_usr_ctx_s *ctx);
/**
* This function points gdc to its input resolution and yuv address and offsets
*
* @param ctx - contains client of gdc and ion.
*
* @return 0 - success
* -1 - no interrupt from GDC.
*/
int gdc_destroy_ctx(struct gdc_usr_ctx_s *ctx);
/**
* This function points gdc to its input resolution and yuv address and offsets
*
* @param gdc_settings - overall gdc settings
* @param in_buf_fd - input buffer's fd
* @param out_buf_fd - output buffer's fd
*
* @return 0 - success
* -1 - no interrupt from GDC.
*/
int gdc_process(struct gdc_usr_ctx_s *ctx);
int gdc_process_with_builtin_fw(struct gdc_usr_ctx_s *ctx);
/* gdc or ion: alloc memory, which will be releasd in gdc_destroy_ctx() */
int gdc_alloc_buffer (struct gdc_usr_ctx_s *ctx, uint32_t type,
struct gdc_alloc_buffer_s *buf, bool cache_flag);
/* gdc or ion: sync cache */
int gdc_sync_for_device(struct gdc_usr_ctx_s *ctx);
/* gdc or ion: invalid cache */
int gdc_sync_for_cpu(struct gdc_usr_ctx_s *ctx);
/** gdc: allocate a block of memory */
int gdc_alloc_mem(struct gdc_usr_ctx_s *ctx, uint32_t len, uint32_t type);
/** gdc: free a block of memory */
void gdc_release_mem(int shared_fd);
/** gdc: sync cache for a block of memory */
void gdc_sync_for_device_mem(struct gdc_usr_ctx_s *ctx, int shared_fd);
/** gdc: invalid cache for a block of memory */
void gdc_sync_for_cpu_mem(struct gdc_usr_ctx_s *ctx, int shared_fd);
#endif