| /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ |
| /* |
| * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
| */ |
| |
| #ifndef _GDC_H_ |
| #define _GDC_H_ |
| |
| #include <linux/types.h> |
| #include <linux/wait.h> |
| #include <linux/dma-direction.h> |
| #include <linux/dma-buf.h> |
| |
| #define CONFIG_PATH_LENG 128 |
| #define GDC_MAX_PLANE 3 |
| #define WORD_SIZE 16 |
| #define WORD_MASK (~(WORD_SIZE - 1)) |
| #define AXI_WORD_ALIGN(size) (((size) + WORD_SIZE - 1) & WORD_MASK) |
| |
| enum { |
| ARM_GDC, |
| AML_GDC, |
| HW_TYPE |
| }; |
| |
| enum { |
| ARMGDC_FW_V1, |
| AMLGDC_FW_V1, |
| AMLGDC_FW_V2, |
| GDC_MAX_FW |
| }; |
| |
| enum { |
| GDC_ENDAIN_DEFAULT = 0, /* no endian operation */ |
| GDC_ENDIAN_LITTLE = BIT(0), |
| GDC_ENDIAN_BIG_8BYTES = BIT(1), |
| GDC_ENDIAN_BIG_16BYTES = BIT(2) |
| }; |
| |
| struct aml_dma_cfg { |
| int fd; |
| void *dev; |
| void *vaddr; |
| struct dma_buf *dbuf; |
| struct dma_buf_attachment *attach; |
| struct sg_table *sg; |
| enum dma_data_direction dir; |
| }; |
| |
| struct gdc_dmabuf_cfg_s { |
| int dma_used; |
| u32 paddr_8g_msb; |
| struct aml_dma_cfg dma_cfg; |
| }; |
| |
| struct gdc_dma_cfg_t { |
| struct gdc_dmabuf_cfg_s config_cfg; |
| struct gdc_dmabuf_cfg_s input_cfg[GDC_MAX_PLANE]; |
| struct gdc_dmabuf_cfg_s output_cfg[GDC_MAX_PLANE]; |
| }; |
| |
| struct gdc_dma_cfg { |
| int fd; |
| void *dev; |
| void *vaddr; |
| struct dma_buf *dbuf; |
| struct dma_buf_attachment *attach; |
| struct sg_table *sg; |
| enum dma_data_direction dir; |
| }; |
| |
| /* each configuration addresses and size */ |
| struct gdc_config_s { |
| u32 format; |
| u32 config_addr; /* gdc config address */ |
| u32 config_size; /* gdc config size in 32bit */ |
| u32 input_width; /* gdc input width resolution */ |
| u32 input_height; /* gdc input height resolution */ |
| u32 input_y_stride; /* gdc input y stride resolution */ |
| u32 input_c_stride; /* gdc input uv stride */ |
| u32 output_width; /* gdc output width resolution */ |
| u32 output_height; /* gdc output height resolution */ |
| u32 output_y_stride; /* gdc output y stride */ |
| u32 output_c_stride; /* gdc output uv stride */ |
| }; |
| |
| struct gdc_cmd_s { |
| u32 outplane; |
| /* writing/reading to gdc base address, currently not read by api */ |
| u32 base_gdc; |
| /* array of gdc configuration and sizes */ |
| struct gdc_config_s gdc_config; |
| /* update this index for new config */ |
| /* int gdc_config_total; */ |
| /* start memory to write gdc output framse */ |
| u32 buffer_addr; |
| /* size of memory output frames to determine */ |
| /* if it is enough and can do multiple write points */ |
| u32 buffer_size; |
| /* current output address of gdc */ |
| u32 current_addr; |
| /* output address for u, v planes */ |
| union { |
| u32 uv_out_base_addr; |
| u32 u_out_base_addr; |
| }; |
| u32 v_out_base_addr; |
| /* set when expecting an interrupt from gdc */ |
| s32 is_waiting_gdc; |
| /* input address for y and u, v planes */ |
| u32 y_base_addr; |
| union { |
| u32 uv_base_addr; |
| u32 u_base_addr; |
| }; |
| u32 v_base_addr; |
| unsigned char wait_done_flag; |
| /* ARM_GDC or AML_GDC */ |
| u32 dev_type; |
| /* secure mem access */ |
| u32 use_sec_mem; |
| /* endian setting */ |
| u32 in_endian; |
| u32 out_endian; |
| }; |
| |
| struct gdc_context_s { |
| /* connect all process in one queue for RR process. */ |
| struct list_head list; |
| /* current wq configuration */ |
| u32 mmap_type; |
| dma_addr_t i_paddr; |
| dma_addr_t o_paddr; |
| dma_addr_t c_paddr; |
| void *i_kaddr; |
| void *o_kaddr; |
| void *c_kaddr; |
| unsigned long i_len; |
| unsigned long o_len; |
| unsigned long c_len; |
| struct gdc_dma_cfg y_dma_cfg; |
| struct gdc_dma_cfg uv_dma_cfg; |
| struct gdc_dma_cfg_t dma_cfg; |
| struct mutex d_mutext; /* for config context */ |
| |
| struct gdc_cmd_s cmd; |
| struct list_head work_queue; |
| struct list_head free_queue; |
| wait_queue_head_t cmd_complete; |
| int gdc_request_exit; |
| spinlock_t lock; /* for get and release item. */ |
| }; |
| |
| /* 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, /* default output bit width */ |
| OUT_BITW_10 = (1 << 20), |
| OUT_BITW_12 = (1 << 21), |
| OUT_BITW_16 = (1 << 22) |
| }; |
| |
| struct gdc_phy_setting { |
| u32 format; |
| u32 in_width; |
| u32 in_height; |
| u32 in_y_stride; /* 16-byte alignment */ |
| u32 in_c_stride; /* 16-byte alignment */ |
| u32 out_width; |
| u32 out_height; |
| u32 out_y_stride; /* 16-byte alignment */ |
| u32 out_c_stride; /* 16-byte alignment */ |
| u32 in_plane_num; |
| u32 out_plane_num; |
| ulong in_paddr[GDC_MAX_PLANE]; |
| ulong out_paddr[GDC_MAX_PLANE]; |
| ulong config_paddr; |
| u32 config_size; /* in 32bit */ |
| u32 use_sec_mem; /* secure mem access */ |
| u32 in_endian; |
| u32 out_endian; |
| }; |
| |
| struct firmware_load_s { |
| u32 size_32bit; |
| phys_addr_t phys_addr; |
| void __iomem *virt_addr; |
| }; |
| |
| struct firmware_rotate_s { |
| u32 format; |
| u32 in_width; |
| u32 in_height; |
| u32 out_width; |
| u32 out_height; |
| u32 degree; /* rotation degree, 90,180,270 */ |
| }; |
| |
| struct gdc_fw_func_ptr { |
| int (*calculate_rotate_fw)(struct firmware_rotate_s *fw_param, |
| void *fw_vaddr); |
| int (*reserved0)(void); |
| int (*reserved1)(void); |
| int (*reserved2)(void); |
| int (*reserved3)(void); |
| int (*reserved4)(void); |
| int (*reserved5)(void); |
| int (*reserved6)(void); |
| }; |
| |
| bool is_gdc_supported(void); |
| bool is_aml_gdc_supported(void); |
| struct gdc_context_s *create_gdc_work_queue(u32 dev_type); |
| int gdc_process_phys(struct gdc_context_s *context, |
| struct gdc_phy_setting *gs); |
| int destroy_gdc_work_queue(struct gdc_context_s *gdc_work_queue); |
| void release_config_firmware(struct firmware_load_s *fw_load); |
| /* load builtin firmware by fw_name */ |
| int load_firmware_by_name(char *fw_name, struct firmware_load_s *fw_load); |
| /* load builtin firmware by calculation for rotaion */ |
| int rotation_calc_and_load_firmware(struct firmware_rotate_s *fw_param, |
| struct firmware_load_s *fw_load); |
| |
| int register_gdc_fw_funcs(struct gdc_fw_func_ptr *func_ptr, char *version); |
| void unregister_gdc_fw_funcs(void); |
| int get_gdc_fw_version(void); |
| |
| #endif |