4.0 ipu_soc,ipu_channel_t ,ipu_channel_params_t结构体详解
2016-08-23 16:19
211 查看
1.ipu_soc结构体:
2.ipu_channel_t枚举:
再来看看这个_MAKE_CHAN宏:
从这里就可以看出来,ipu_channel_t只是根据5个值左移形成的一个数字。
那么想要从channel中获取它的ID号怎么办?只需要将它右移24位即可,就能得到,就是下面一个宏:
再来看看channel_2_dma函数:
这个函数能够根据不同的type类型从channel里面提取出所使用的dmachannel。
同时根据_MAKE_CHAN宏中几个变量的名字,就能够理解ipu_channel_t中各个位的含义:
0~5位:输出dmachannel号
6~11位:alpha通道号
12~17位:graph通道号
18~23位:video输入dmachannel号
24~ :channel的序列号
3. ipu_channel_params_t联合:
typedef union {
struct {
uint32_t csi; //csi设备号,0或1
uint32_t mipi_id; //mipi ID号
uint32_t mipi_vc; //mipi虚拟通道号
bool mipi_en; //是否使能mipi接口
bool interlaced; //数据是否是隔行的
} csi_mem;
struct {
uint32_t in_width; //输入数据的宽度
uint32_t in_height; //输入数据的高度
uint32_t in_pixel_fmt; //输入数据的像素格式
uint32_t out_width; //输出数据的宽度
uint32_t out_height; //输出数据的高度
uint32_t out_pixel_fmt; //输出数据的像素格式
uint32_t outh_resize_ratio; //输出水平方向上重定义大小系数
uint32_t outv_resize_ratio; //输出垂直方向上重定义大小系数
uint32_t csi; //csi 设备号
uint32_t mipi_id; //mipi ID号
uint32_t mipi_vc; //mipi 虚拟通道号
bool mipi_en; //是否是能mipi接口
} csi_prp_enc_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
uint32_t outh_resize_ratio;
uint32_t outv_resize_ratio;
} mem_prp_enc_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
} mem_rot_enc_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
uint32_t outh_resize_ratio;
uint32_t outv_resize_ratio;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
uint32_t in_g_pixel_fmt;
uint8_t alpha;
uint32_t key_color;
bool alpha_chan_en;
ipu_motion_sel motion_sel;
enum v4l2_field field_fmt;
uint32_t csi;
uint32_t mipi_id;
uint32_t mipi_vc;
bool mipi_en;
} csi_prp_vf_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
display_port_t disp;
uint32_t out_left;
uint32_t out_top;
} csi_prp_vf_adc;
struct {
uint32_t in_width; //输入宽度
uint32_t in_height; //输入高度
uint32_t in_pixel_fmt; //输入像素格式
uint32_t out_width; //输出宽度
uint32_t out_height; //输出高度
uint32_t out_pixel_fmt; //输出像素格式
uint32_t outh_resize_ratio; //输出水平方向上重定义大小的比例
uint32_t outv_resize_ratio; //输出垂直方向上重定义大小的比例
bool graphics_combine_en; //是否使能second channel的标志位
bool global_alpha_en; //是否使能third channel的标志位
bool key_color_en;
uint32_t in_g_pixel_fmt;
uint8_t alpha;
uint32_t key_color;
bool alpha_chan_en;
ipu_motion_sel motion_sel;
enum v4l2_field field_fmt;
} mem_prp_vf_mem;
struct {
uint32_t temp;
} mem_prp_vf_adc;
struct {
uint32_t temp;
} mem_rot_vf_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
uint32_t outh_resize_ratio;
uint32_t outv_resize_ratio;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
uint32_t in_g_pixel_fmt;
uint8_t alpha;
uint32_t key_color;
bool alpha_chan_en;
} mem_pp_mem;
struct {
uint32_t temp;
} mem_rot_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
display_port_t disp;
uint32_t out_left;
uint32_t out_top;
} mem_pp_adc;
struct {
uint32_t di;
bool interlaced; //数据是否是隔行的
uint32_t in_pixel_fmt;
uint32_t out_pixel_fmt;
} mem_dc_sync;
struct {
uint32_t temp;
} mem_sdc_fg;
struct {
uint32_t di;
bool interlaced; //数据是否是隔行的
uint32_t in_pixel_fmt;
uint32_t out_pixel_fmt;
bool alpha_chan_en;
} mem_dp_bg_sync;
struct {
uint32_t temp;
} mem_sdc_bg;
struct {
uint32_t di;
bool interlaced; //数据是否是隔行的
uint32_t in_pixel_fmt;
uint32_t out_pixel_fmt;
bool alpha_chan_en;
} mem_dp_fg_sync;
struct {
uint32_t di;
} direct_async;
struct {
display_port_t disp;
mcu_mode_t ch_mode;
uint32_t out_left;
uint32_t out_top;
} adc_sys1;
struct {
display_port_t disp;
mcu_mode_t ch_mode;
uint32_t out_left;
uint32_t out_top;
} adc_sys2;
} ipu_channel_params_t;
这个ipu_channel_params_t这个联合,在这个联合中对于每一种channel都有一个对应的结构体类型来保存channel的参数。如果想要获取哪一个channel的信息,就从这个联合中的对应channel里面找即可。同时,在initchannel的时候,也是通过对这个联合里面对应的channel参数赋值。
struct ipu_soc { unsigned int id; //ipu的ID号 unsigned int devtype; //ipu的一些信息,包含cm,ic等模块的地址偏移值 bool online; //表示这个ipu是否正在使用中 /*clk*/ struct clk *ipu_clk; struct clk *di_clk[2]; struct clk *di_clk_sel[2]; struct clk *pixel_clk[2]; bool pixel_clk_en[2]; struct clk *pixel_clk_sel[2]; struct clk *csi_clk[2]; struct clk *prg_clk; /*irq*/ int irq_sync; int irq_err; struct ipu_irq_node irq_list[IPU_IRQ_COUNT]; //在request_irq函数中会根据传入的irq号在这个数组中选择对应的下标,来存取有关这个irq的 //信息如irq服务函数,名字,flags等参数。 /*reg*/ /* ipu内部模块经过ioremap后的地址 */ void __iomem *cm_reg; void __iomem *idmac_reg; void __iomem *dp_reg; void __iomem *ic_reg; void __iomem *dc_reg; void __iomem *dc_tmpl_reg; void __iomem *dmfc_reg; void __iomem *di_reg[2]; void __iomem *smfc_reg; void __iomem *csi_reg[2]; void __iomem *cpmem_base; void __iomem *tpmem_base; void __iomem *vdi_reg; struct device *dev; ipu_channel_t csi_channel[2]; //每个ipu有两个csi设备,将此时csi设备对应的channel根据csi号保存在这个csi_channel[]数组中 ipu_channel_t using_ic_dirct_ch; //表示那个channel直接使用IC设备 unsigned char dc_di_assignment[10]; bool sec_chan_en[24]; //对应的channel是否使能了second channel bool thrd_chan_en[24]; //对应的channel是否使能了third channel bool chan_is_interlaced[52]; //对应的channel中的数据是否是隔行的,每个channel对应其中的一位,每一位是一个bool类型的值 uint32_t channel_init_mask; //这是一个32位的数,其中每一位代表一个channel号,如果初始化一个channel的话,就将这个channel对应的位置1 uint32_t channel_enable_mask; //每一位对应一个channel号,如果使能了一个channel 的话,就将这个channel对应的位置1,与上面那个channel_init_mask类似。 /*use count*/ /* 下面几个是IPU内部模块的引用计数 */ int dc_use_count; //dc引用计数 int dp_use_count; //dp引用计数 int dmfc_use_count; //dmfc引用计数 int smfc_use_count; //smfc引用计数 int ic_use_count; //ic引用计数 int rot_use_count; //rot引用计数 int vdi_use_count; //vdi引用计数 int di_use_count[2]; //di引用计数,每个ipu只有两个di int csi_use_count[2]; //csi引用计数,每个ipu只有两个csi struct mutex mutex_lock; spinlock_t int_reg_spin_lock; spinlock_t rdy_reg_spin_lock; int dmfc_size_28; int dmfc_size_29; int dmfc_size_24; int dmfc_size_27; int dmfc_size_23; enum csc_type_t fg_csc_type; enum csc_type_t bg_csc_type; bool color_key_4rgb; bool dc_swap; struct completion dc_comp; struct completion csi_comp; struct rot_mem { void *vaddr; dma_addr_t paddr; int size; } rot_dma[2]; int vdoa_en; //是否使能VDOA struct task_struct *thread[2]; //两个内核线程 /* * Bypass reset to avoid display channel being * stopped by probe since it may starts to work * in bootloader. */ bool bypass_reset; /* 这个值是从dts文件中获得的bypass_reset,因为在开发板启动过程中,需要使能屏幕来显示,所以显示通道可能已经在bootloader中开启了, * 在这里设置这个值,使得显示通道在probe函数中不会关闭,也就是这个参数的含义(旁路)。*/ /* AXI protocol id */ unsigned int ch0123_axi; unsigned int ch23_axi; unsigned int ch27_axi; unsigned int ch28_axi; unsigned int normal_axi; /* 不同的channel可能会对应不同的 AXI protocol,在ipu_probe函数中对这些值进行了赋值,在ipu_platform_type结构体中指定的。 */ bool smfc_idmac_12bit_3planar_bs_fixup; /* workaround little stripes */ };
2.ipu_channel_t枚举:
typedef enum { CHAN_NONE = -1, MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48), MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49), MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50), MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20), MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21), MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22), MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA), MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA), MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA), MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA), MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA), MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA), MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0), MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0), DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA), DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA), CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0), CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1), CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2), CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3), CSI_MEM = CSI_MEM0, CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20), CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21), /* for vdi mem->vdi->ic->mem , add graphics plane and alpha*/ MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21), MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21), MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21), /* for vdi mem->vdi->mem */ MEM_VDI_MEM_P = _MAKE_CHAN(24, 8, NO_DMA, NO_DMA, 5), MEM_VDI_MEM = _MAKE_CHAN(25, 9, NO_DMA, NO_DMA, 5), MEM_VDI_MEM_N = _MAKE_CHAN(26, 10, NO_DMA, NO_DMA, 5), /* fake channel for vdoa to link with IPU */ MEM_VDOA_MEM = _MAKE_CHAN(27, NO_DMA, NO_DMA, NO_DMA, NO_DMA), MEM_PP_ADC = CHAN_NONE, ADC_SYS2 = CHAN_NONE, } ipu_channel_t;
再来看看这个_MAKE_CHAN宏:
#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \ ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out) #define NO_DMA 0x3F
从这里就可以看出来,ipu_channel_t只是根据5个值左移形成的一个数字。
那么想要从channel中获取它的ID号怎么办?只需要将它右移24位即可,就能得到,就是下面一个宏:
#define IPU_CHAN_ID(ch) (ch >> 24)
再来看看channel_2_dma函数:
static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type) { return ((uint32_t) ch >> (6 * type)) & 0x3F; };
这个函数能够根据不同的type类型从channel里面提取出所使用的dmachannel。
typedef enum { IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */ IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */ IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */ IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */ IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER, IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER, } ipu_buffer_t;
同时根据_MAKE_CHAN宏中几个变量的名字,就能够理解ipu_channel_t中各个位的含义:
0~5位:输出dmachannel号
6~11位:alpha通道号
12~17位:graph通道号
18~23位:video输入dmachannel号
24~ :channel的序列号
3. ipu_channel_params_t联合:
typedef union {
struct {
uint32_t csi; //csi设备号,0或1
uint32_t mipi_id; //mipi ID号
uint32_t mipi_vc; //mipi虚拟通道号
bool mipi_en; //是否使能mipi接口
bool interlaced; //数据是否是隔行的
} csi_mem;
struct {
uint32_t in_width; //输入数据的宽度
uint32_t in_height; //输入数据的高度
uint32_t in_pixel_fmt; //输入数据的像素格式
uint32_t out_width; //输出数据的宽度
uint32_t out_height; //输出数据的高度
uint32_t out_pixel_fmt; //输出数据的像素格式
uint32_t outh_resize_ratio; //输出水平方向上重定义大小系数
uint32_t outv_resize_ratio; //输出垂直方向上重定义大小系数
uint32_t csi; //csi 设备号
uint32_t mipi_id; //mipi ID号
uint32_t mipi_vc; //mipi 虚拟通道号
bool mipi_en; //是否是能mipi接口
} csi_prp_enc_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
uint32_t outh_resize_ratio;
uint32_t outv_resize_ratio;
} mem_prp_enc_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
} mem_rot_enc_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
uint32_t outh_resize_ratio;
uint32_t outv_resize_ratio;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
uint32_t in_g_pixel_fmt;
uint8_t alpha;
uint32_t key_color;
bool alpha_chan_en;
ipu_motion_sel motion_sel;
enum v4l2_field field_fmt;
uint32_t csi;
uint32_t mipi_id;
uint32_t mipi_vc;
bool mipi_en;
} csi_prp_vf_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
display_port_t disp;
uint32_t out_left;
uint32_t out_top;
} csi_prp_vf_adc;
struct {
uint32_t in_width; //输入宽度
uint32_t in_height; //输入高度
uint32_t in_pixel_fmt; //输入像素格式
uint32_t out_width; //输出宽度
uint32_t out_height; //输出高度
uint32_t out_pixel_fmt; //输出像素格式
uint32_t outh_resize_ratio; //输出水平方向上重定义大小的比例
uint32_t outv_resize_ratio; //输出垂直方向上重定义大小的比例
bool graphics_combine_en; //是否使能second channel的标志位
bool global_alpha_en; //是否使能third channel的标志位
bool key_color_en;
uint32_t in_g_pixel_fmt;
uint8_t alpha;
uint32_t key_color;
bool alpha_chan_en;
ipu_motion_sel motion_sel;
enum v4l2_field field_fmt;
} mem_prp_vf_mem;
struct {
uint32_t temp;
} mem_prp_vf_adc;
struct {
uint32_t temp;
} mem_rot_vf_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
uint32_t outh_resize_ratio;
uint32_t outv_resize_ratio;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
uint32_t in_g_pixel_fmt;
uint8_t alpha;
uint32_t key_color;
bool alpha_chan_en;
} mem_pp_mem;
struct {
uint32_t temp;
} mem_rot_mem;
struct {
uint32_t in_width;
uint32_t in_height;
uint32_t in_pixel_fmt;
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
display_port_t disp;
uint32_t out_left;
uint32_t out_top;
} mem_pp_adc;
struct {
uint32_t di;
bool interlaced; //数据是否是隔行的
uint32_t in_pixel_fmt;
uint32_t out_pixel_fmt;
} mem_dc_sync;
struct {
uint32_t temp;
} mem_sdc_fg;
struct {
uint32_t di;
bool interlaced; //数据是否是隔行的
uint32_t in_pixel_fmt;
uint32_t out_pixel_fmt;
bool alpha_chan_en;
} mem_dp_bg_sync;
struct {
uint32_t temp;
} mem_sdc_bg;
struct {
uint32_t di;
bool interlaced; //数据是否是隔行的
uint32_t in_pixel_fmt;
uint32_t out_pixel_fmt;
bool alpha_chan_en;
} mem_dp_fg_sync;
struct {
uint32_t di;
} direct_async;
struct {
display_port_t disp;
mcu_mode_t ch_mode;
uint32_t out_left;
uint32_t out_top;
} adc_sys1;
struct {
display_port_t disp;
mcu_mode_t ch_mode;
uint32_t out_left;
uint32_t out_top;
} adc_sys2;
} ipu_channel_params_t;
这个ipu_channel_params_t这个联合,在这个联合中对于每一种channel都有一个对应的结构体类型来保存channel的参数。如果想要获取哪一个channel的信息,就从这个联合中的对应channel里面找即可。同时,在initchannel的时候,也是通过对这个联合里面对应的channel参数赋值。
相关文章推荐
- PetShop 4.0 详解之一(系统架构设计)
- .NET PetShop4.0详解
- PetShop 4.0 详解之四(PetShop之ASP.NET缓存)
- PetShop 4.0 官方详解
- PetShop 4.0 详解之三(PetShop数据访问层之消息处理)
- PetShop 4.0 详解一 系统架构
- PetShop 4.0 详解之五(PetShop之业务逻辑层设计)
- 在PetShop 4.0中ASP.NET缓存的实现详解
- PetShop 4.0(C#)详解一至八
- petshop4.0 详解之五(PetShop之业务逻辑层设计)
- PetShop 4.0 详解之四
- PetShop 4.0 详解之一(系统架构设计)
- PetShop 4.0 详解之三(PetShop数据访问层之消息处理)
- PetShop 4.0 详解之五
- PetShop 4.0 官方详解
- PetShop 4.0 详解之八(PetShop表示层设计)
- PetShop 4.0 详解之三
- PetShop 4.0 详解之六(PetShop表示层设计)
- PetShop 4.0 详解之四(PetShop之ASP.NET缓存)
- PetShop 4.0 详解之五(PetShop之业务逻辑层设计)