format 使用一例 之 color & input

本文介绍了ABAP编程中如何使用颜色代码为输出添加背景色,并详细解释了八种颜色的具体应用。此外,还探讨了如何通过编程控制列表行及行内输入框,包括响应line-selection事件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 color

(1) Write 添加背景色

八种颜色,分别为 0-7 可以用8个常量代替输出

WRITE:/'col_key'COLORcol_key,
'col_total'COLORcol_total,
'col_group'COLORcol_group,
'col_background'COLORCOL_BACKGROUND,
'col_heading'COLORcol_heading,
'COL_NEGATIVE'COLORCOL_NEGATIVE,
'COL_POSITIVE'COLORCOL_POSITIVE,
'COL_NORMAL'COLORCOL_NORMAL
.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

0 COL_BACKGROUND Backgrounds

1 COL_HEADING Headers

2 COL_NORMAL List entries

3 COL-TOTAL Totals

4 COL_KEY Key columns

5 COL-POSITIVE Positive threshold values

6 COL_NEGATIVE Negative threshold values

7 COL_GROUP Control levels

如果在前面用 format color 颜色 on 或者 format color = 颜色 的话。

后面的输出默认则用这个颜色作为背景。

如果在前面用 format color off 的话

后面的输出则没有背景颜色。

假设前面没有定义背景颜色。但是后面的输出时 指定了颜色。则该输出使用该颜色。例如:write ‘liujincai’ color 颜色

假设前面定义了背景颜色。但是后面的输出时 指定了其它颜色。则该输出使用其它颜色。例如:write ‘liujincai’ color 颜色

假设前面定义了背景颜色。但是后面的输出时 没有指定颜色。则该输出使用前面定义的颜色。例如:write ‘liujincai’ color 颜色

假设前面定义了背景颜色。但是后面的输出时 关闭了颜色 。则该输出不使用颜色。例如:write ‘liujincai’ color off

二, input

(1) List行的控制以及行中输入框以及 line-selection 事件的响应。

DATA:input_field(100)TYPEc,
line_num
TYPEi.

START-
OF-SELECTION.
WRITE'Inputtext:'.
SETBLANKLINESON.
FORMATINPUT.
WRITE/input_field.
FORMATINPUTOFF.
WRITE:/'>>>OK<<<'COLOR5HOTSPOT.

ATLINE-SELECTION.
casesy-lisel.
when'>>>OK<<<'.
line_num=sy-lilli-
1.
READLINEline_numFIELDVALUEinput_field..
ifsy-subrcne0.exit.endif.
ifinput_field<>'liujincai'.
WRITE:'Theinputwas:',
/input_field.
else.
modifyCURRENTLINEfieldvalueinput_fieldfrom''.
endif.

endcase.

/* * SEMIDRIVE Copyright Statement * Copyright (c) SEMIDRIVE. All rights reserved * This software and all rights therein are owned by SEMIDRIVE, * and are protected by copyright law and other relevant laws, regulations and protection. * Without SEMIDRIVE&rsquo;s prior written consent and /or related rights, * please do not use this software or any potion thereof in any form or by any means. * You may not reproduce, modify or distribute this software except in compliance with the License. * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an &quot;AS IS&quot; basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * You should have received a copy of the License along with this program. * If not, see &lt;http://www.semidrive.com/licenses/&gt;. */ #include &lt;linux/kernel.h&gt; #include &lt;linux/module.h&gt; #include &lt;linux/component.h&gt; #include &lt;linux/fs.h&gt; #include &lt;linux/dma-buf.h&gt; #include &lt;linux/interrupt.h&gt; #include &lt;linux/iommu.h&gt; #include &lt;linux/pm_runtime.h&gt; #include &lt;linux/bitops.h&gt; #include &lt;linux/uaccess.h&gt; #include &lt;linux/list.h&gt; #include &lt;linux/string.h&gt; #include &lt;linux/bug.h&gt; #include &lt;linux/errno.h&gt; #include &lt;asm/current.h&gt; #ifdef CONFIG_OF #include &lt;linux/of.h&gt; #include &lt;linux/of_address.h&gt; #include &lt;linux/of_irq.h&gt; #include &lt;linux/of_device.h&gt; #include &lt;linux/of_platform.h&gt; #else #include &lt;linux/slab.h&gt; #include &lt;linux/io.h&gt; #include &lt;linux/irq.h&gt; #endif #include &quot;sdrv_g2d.h&quot; #include &quot;g2d_common.h&quot; static DEFINE_MUTEX(m_init); extern const struct g2d_ops g2d_normal_ops; extern const struct g2d_ops g2d_lite_ops; extern struct ops_entry spipe_g2d_entry; extern struct ops_entry gpipe_mid_g2d_entry; extern struct ops_entry gpipe_high_g2d_entry; extern int g2d_dump_registers(struct sdrv_g2d *dev); extern int g2d_post_config(struct sdrv_g2d *dev, struct g2d_input *ins); extern int g2d_fastcopy_set(struct sdrv_g2d *dev, addr_t iaddr, u32 width, u32 height, u32 istride, addr_t oaddr, u32 ostride); extern int g2d_fill_rect(struct sdrv_g2d *dev, struct g2d_bg_cfg *bgcfg, struct g2d_output_cfg *output); extern int g2d_set_coefficients_table(struct sdrv_g2d *gd, struct g2d_coeff_table *table); extern struct attribute *sdrv_g2d_attrs[]; static const struct attribute_group *sdrv_g2d_groups[]; ATTRIBUTE_GROUPS(sdrv_g2d); static int wait_timeout = 500; module_param(wait_timeout, int, 0660); MODULE_PARM_DESC(wait_timeout, &quot;wait timeout (ms)&quot;); static int dump_register_g2d = 0; module_param(dump_register_g2d, int, 0660); MODULE_PARM_DESC(dump_register_g2d, &quot;dump register g2d 0:off 1:on&quot;); int debug_g2d = 0; EXPORT_SYMBOL(debug_g2d); module_param(debug_g2d, int, 0660); MODULE_PARM_DESC(debug_g2d, &quot;debug g2d 0:off 1:on&quot;); static char *version = KO_VERSION; module_param(version, charp, S_IRUGO); LIST_HEAD(g2d_pipe_list_head); int g2d_major = 227; int g2d_minor = -1; static struct sdrv_g2d *g_g2d[G2D_NR_DEVS]; const char *PIPE_TYPE_STRING[] = { GP_ECHO_NAME, GP_MID_NAME, GP_HIGH_NAME, SPIPE_NAME }; struct sdrv_g2d_data g2d_data[] = { {.version = &quot;g2dlite-r0p0&quot;, .ops = &amp;g2d_lite_ops}, {.version = &quot;g2d-r0p1&quot;, .ops = &amp;g2d_normal_ops}, {}, }; static void dump_input(struct g2d_input *input) { struct g2d_output_cfg *output = &amp;input-&gt;output; struct g2d_layer *layer; struct g2d_bg_cfg *bg = &amp;input-&gt;bg_layer; int i = 0; if (bg-&gt;en) { G2D_ERROR(&quot;[dump bg layer] en:%d, color:0x%x, g_alpha:0x%x, zorder:%d, bpa:0x%x, \ astride:%d, rect(%d, %d, %d, %d), pd_type:%d, fd:%d \n&quot;, bg-&gt;en, bg-&gt;color, bg-&gt;g_alpha, bg-&gt;zorder, bg-&gt;bpa, bg-&gt;astride, bg-&gt;x, bg-&gt;y, bg-&gt;width, bg-&gt;height, bg-&gt;pd_type, bg-&gt;abufs.fd); } for (i = 0; i &lt; input-&gt;layer_num; i++) { layer = &amp;input-&gt;layer[i]; G2D_ERROR(&quot;[dumplayer] index = %d, *ENABLE = %d*, format: %c%c%c%c source (%d, %d, %d, %d) =&gt; dest (%d, %d, %d, %d)\n&quot;, layer-&gt;index, layer-&gt;enable, layer-&gt;format &amp; 0xff, (layer-&gt;format &gt;&gt; 8) &amp; 0xff, (layer-&gt;format &gt;&gt; 16) &amp; 0xff, (layer-&gt;format &gt;&gt; 24) &amp; 0xff, layer-&gt;src_x, layer-&gt;src_y, layer-&gt;src_w, layer-&gt;src_h, layer-&gt;dst_x, layer-&gt;dst_y, layer-&gt;dst_w, layer-&gt;dst_h); } G2D_ERROR(&quot;[dump output]: w,h(%d,%d) format:%c%c%c%c rota:%d nplanes:%d\n&quot;, output-&gt;width, output-&gt;height, output-&gt;fmt &amp; 0xff, (output-&gt;fmt &gt;&gt; 8) &amp; 0xff, (output-&gt;fmt &gt;&gt; 16) &amp; 0xff, (output-&gt;fmt &gt;&gt; 24) &amp; 0xff, output-&gt;rotation, output-&gt;nplanes); return; } struct sdrv_g2d *get_g2d_by_id(int id) { return g_g2d[id]; } int g2d_ops_register(struct ops_entry *entry, struct list_head *head) { struct ops_list *list; list = kzalloc(sizeof(struct ops_list), GFP_KERNEL); if (!list) return -ENOMEM; list-&gt;entry = entry; list_add(&amp;list-&gt;head, head); return 0; } void *g2d_ops_attach(const char *str, struct list_head *head) { struct ops_list *list; const char *ver; list_for_each_entry(list, head, head) { ver = list-&gt;entry-&gt;ver; if (!strcmp(str, ver)) return list-&gt;entry-&gt;ops; } G2D_ERROR(&quot;attach disp ops %s failed\n&quot;, str); return NULL; } irqreturn_t sdrv_g2d_irq_handler(int irq, void *data) { struct sdrv_g2d *gd = data; uint32_t val; if (!gd-&gt;du_inited) { G2D_ERROR(&quot;g2d du_inited does not init\n&quot;); return IRQ_HANDLED; } val = gd-&gt;ops-&gt;irq_handler(gd); if (val &amp; G2D_INT_MASK_FRM_DONE) { G2D_DBG(&quot;frame done\n&quot;); gd-&gt;frame_done = true; wake_up(&amp;gd-&gt;wq); } return IRQ_HANDLED; } int g2d_choose_pipe(struct sdrv_g2d *gd, int hwid, int type, uint32_t offset) { struct g2d_pipe *p = NULL; p = devm_kzalloc(&amp;gd-&gt;pdev-&gt;dev, sizeof(struct g2d_pipe), GFP_KERNEL); if (!p) return -ENOMEM; p-&gt;type = type; p-&gt;name = PIPE_TYPE_STRING[type]; p-&gt;ops = (struct pipe_operation*)g2d_pipe_ops_attach(p-&gt;name); if (!p-&gt;ops) { G2D_ERROR(&quot;error ops attached\n&quot;); return -EINVAL; } p-&gt;regs = gd-&gt;regs + (ulong)offset; p-&gt;iomem_regs = gd-&gt;iomem_regs + (ulong)offset; p-&gt;reg_offset = offset; p-&gt;id = hwid; p-&gt;gd = gd; gd-&gt;pipes[gd-&gt;num_pipe] = p; gd-&gt;num_pipe++; p-&gt;ops-&gt;init(p); G2D_DBG(&quot;pipe %d name %s registered\n&quot;, p-&gt;id, p-&gt;name); return 0; } #ifdef CONFIG_OF int sdrv_g2d_init(struct sdrv_g2d *gd, struct device_node *np) { int i, ret; int irq_num; struct resource res; const char *str; const struct sdrv_g2d_data *data; static int g2d_cnt = 0; if (!np || !gd) return -ENODEV; if(!of_device_is_available(np)) { G2D_ERROR(&quot;OF node %s not available or match\n&quot;, np-&gt;name); return -ENODEV; } if (!of_property_read_string(np, &quot;sdrv,ip&quot;, &amp;str)) { gd-&gt;name = str; } else { G2D_ERROR(&quot;sdrv,ip can not found\n&quot;); return -ENODEV; } if (of_address_to_resource(np, 0, &amp;res)) { G2D_ERROR(&quot;parse dt base address failed\n&quot;); return -ENODEV; } G2D_INFO(&quot;got %s res 0x%lx\n&quot;, gd-&gt;name, (unsigned long)res.start); gd-&gt;regs = (void *)res.start; gd-&gt;iomem_regs = devm_ioremap_nocache(&amp;gd-&gt;pdev-&gt;dev, res.start, resource_size(&amp;res)); if(IS_ERR(gd-&gt;iomem_regs)) { G2D_ERROR(&quot;Cannot find g2d regs 001\n&quot;); return PTR_ERR(gd-&gt;regs); } irq_num = irq_of_parse_and_map(np, 0); if (!irq_num) { G2D_ERROR(&quot;error: g2d parse irq num failed\n&quot;); return -EINVAL; } G2D_INFO(&quot;g2d irq_num = %d\n&quot;, irq_num); data = of_device_get_match_data(&amp;gd-&gt;pdev-&gt;dev); for (i = 0; i &lt; 3; i++) { if (!strcmp(gd-&gt;name, data[i].version)) { gd-&gt;ops = data[i].ops; G2D_INFO(&quot;%s ops[%d] attached\n&quot;, gd-&gt;name, i); break; } } if (gd-&gt;ops == NULL) { G2D_ERROR(&quot;core ops attach failed, have checked %d times\n&quot;, i); return -1; } gd-&gt;num_pipe = 0; // g2d init gd-&gt;ops-&gt;init(gd); gd-&gt;irq = irq_num; gd-&gt;cap.num_pipe = gd-&gt;num_pipe; for (i = 0; i &lt; gd-&gt;num_pipe; i++) { memcpy(&amp;gd-&gt;cap.pipe_caps[i], gd-&gt;pipes[i]-&gt;cap, sizeof(struct g2d_pipe_capability)); } gd-&gt;id = g2d_cnt; irq_set_status_flags(gd-&gt;irq, IRQ_NOAUTOEN); ret = devm_request_irq(&amp;gd-&gt;pdev-&gt;dev, gd-&gt;irq, sdrv_g2d_irq_handler, 0, dev_name(&amp;gd-&gt;pdev-&gt;dev), gd); //IRQF_SHARED if(ret) { G2D_ERROR(&quot;Failed to request DC IRQ: %d\n&quot;, gd-&gt;irq); return -ENODEV; } //wait queue init_waitqueue_head(&amp;gd-&gt;wq); gd-&gt;frame_done = false; g2d_cnt++; return 0; } #else int sdrv_g2d_init(struct sdrv_g2d *gd, struct platform_device *pdev) { int i, ret; int irq_num; struct device *dev = &amp;pdev-&gt;dev; struct resource *res; const char *str; const struct sdrv_g2d_data *data; struct g2d_platform_data *pdata; static int g2d_cnt = 0; if (!pdev || !gd) return -ENODEV; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); gd-&gt;regs = (void *)res-&gt;start; gd-&gt;iomem_regs = devm_ioremap_nocache(&amp;gd-&gt;pdev-&gt;dev, res-&gt;start, resource_size(res)); if(IS_ERR(gd-&gt;iomem_regs)) { G2D_ERROR(&quot;Cannot find g2d regs 001\n&quot;); return PTR_ERR(gd-&gt;regs); } pdata = (struct g2d_platform_data *)platform_get_drvdata(pdev); gd-&gt;name = &quot;g2d-r0p1&quot;; if (!gd-&gt;name) { G2D_ERROR(&quot;sdrv,ip can not found\n&quot;); return -ENODEV; } G2D_INFO(&quot;got %s res 0x%lx\n&quot;, gd-&gt;name, (unsigned long)gd-&gt;regs); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq_num = (int) res-&gt;start; if (!irq_num) { G2D_ERROR(&quot;error: g2d parse irq num failed\n&quot;); return -EINVAL; } G2D_INFO(&quot;g2d irq_num = %d\n&quot;, irq_num); data = g2d_data; for (i = 0; i &lt; 16; i++) { if (!strcmp(gd-&gt;name, data[i].version)) { gd-&gt;ops = data[i].ops; G2D_DBG(&quot;%s ops[%d] attached\n&quot;, gd-&gt;name, i); break; } } if (gd-&gt;ops == NULL) { G2D_ERROR(&quot;core ops attach failed, have checked %d times\n&quot;, i); return -1; } gd-&gt;num_pipe = 0; // g2d init gd-&gt;ops-&gt;init(gd); gd-&gt;irq = irq_num; gd-&gt;cap.num_pipe = gd-&gt;num_pipe; for (i = 0; i &lt; gd-&gt;num_pipe; i++) { memcpy(&amp;gd-&gt;cap.pipe_caps[i], gd-&gt;pipes[i]-&gt;cap, sizeof(struct g2d_pipe_capability)); } gd-&gt;id = g2d_cnt; irq_set_status_flags(gd-&gt;irq, IRQ_NOAUTOEN); ret = devm_request_irq(&amp;gd-&gt;pdev-&gt;dev, gd-&gt;irq, sdrv_g2d_irq_handler, 0, dev_name(&amp;gd-&gt;pdev-&gt;dev), gd); //IRQF_SHARED if(ret) { G2D_ERROR(&quot;Failed to request DC IRQ: %d\n&quot;, gd-&gt;irq); return -ENODEV; } //wait queue init_waitqueue_head(&amp;gd-&gt;wq); gd-&gt;frame_done = false; g2d_cnt++; return 0; } #endif static void sdrv_g2d_unit(struct sdrv_g2d *gd) { if (!gd) return; // if (gd-&gt;ops-&gt;uninit) // gd-&gt;ops-&gt;uninit(gd); } static int sdrv_g2d_open(struct inode *node, struct file *file) { int i; struct sdrv_g2d *gd = NULL; int num = MINOR(node-&gt;i_rdev); if (num &lt; 0) return -ENODEV; for (i = 0; i &lt; G2D_NR_DEVS; i++){ gd = get_g2d_by_id(i); if (gd-&gt;mdev.minor == num) break; } file-&gt;private_data = gd; G2D_DBG(&quot;open node %s\n&quot;, gd-&gt;name); return 0; } static int sdrv_init_iommu(struct sdrv_g2d *gd) { struct device *dev = &amp;gd-&gt;pdev-&gt;dev; struct device_node *iommu = NULL; struct property *prop = NULL; struct iommu_domain_geometry *geometry; u64 start, end; int ret = 0; gd-&gt;iommu_enable = false; iommu = of_parse_phandle(dev-&gt;of_node, &quot;iommus&quot;, 0); if(!iommu) { G2D_DBG(&quot;iommu not specified\n&quot;); return ret; } if (!of_device_is_available(iommu)) { G2D_DBG(&quot;smmu disabled\n&quot;); return ret; } prop = of_find_property(dev-&gt;of_node, &quot;smmu&quot;, NULL); if(!prop) { G2D_DBG(&quot;smmu bypassed\n&quot;); return ret; } gd-&gt;domain = iommu_get_domain_for_dev(dev); if(!gd-&gt;domain) { ret = -ENOMEM; goto err_free_mm;; } geometry = &amp;gd-&gt;domain-&gt;geometry; start = geometry-&gt;aperture_start; end = GENMASK(37, 0);// 38 bits address for KUNLUN G2D rdma G2D_DBG(&quot;IOMMU context initialized: %#llx - %#llx\n&quot;, start, end); gd-&gt;iommu_enable = true; of_node_put(iommu); return ret; err_free_mm: of_node_put(iommu); return ret; } static void sdrv_iommu_cleanup(struct sdrv_g2d *gd) { if(!gd-&gt;iommu_enable) return; iommu_domain_free(gd-&gt;domain); } static unsigned long _get_contiguous_size(struct sg_table *sgt) { struct scatterlist *s; dma_addr_t expected = sg_dma_address(sgt-&gt;sgl); unsigned int i; unsigned long size = 0; for_each_sg(sgt-&gt;sgl, s, sgt-&gt;nents, i) { if (sg_dma_address(s) != expected) break; expected = sg_dma_address(s) + sg_dma_len(s); size += sg_dma_len(s); } return size; } static int g2d_dmabuf_import(struct sdrv_g2d *gd, struct g2d_buf *buf) { struct dma_buf_attachment *attach; struct sg_table *sgt; struct dma_buf *dmabuf; int ret = 0; if (buf-&gt;fd &lt; 0) { G2D_ERROR(&quot;dmabuf handle invalid: %d\n&quot;, buf-&gt;fd); return -EINVAL; } buf-&gt;vaddr = (unsigned long)NULL; dmabuf = dma_buf_get(buf-&gt;fd); if (IS_ERR_OR_NULL(dmabuf)) { G2D_ERROR(&quot;g2d get dmabuf err from buf fd %d\n&quot;, buf-&gt;fd); return PTR_ERR(dmabuf); } attach = dma_buf_attach(dmabuf, &amp;gd-&gt;pdev-&gt;dev); if (IS_ERR(attach)) { G2D_ERROR(&quot;dma buf attach devices faild\n&quot;); goto out_put; } sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); if (IS_ERR(sgt)) { ret = PTR_ERR(sgt); G2D_ERROR(&quot;Error getting dmabuf scatterlist: errno %ld\n&quot;, PTR_ERR(sgt)); goto fail_detach; } buf-&gt;attach = attach; buf-&gt;size = _get_contiguous_size(sgt); buf-&gt;dma_addr = sg_dma_address(sgt-&gt;sgl); buf-&gt;sgt = sgt; buf-&gt;vaddr = (unsigned long)NULL; G2D_DBG(&quot;buf-&gt;size = 0x%llx \n&quot;, buf-&gt;size); if (!buf-&gt;size) { G2D_ERROR(&quot;dma buf map attachment faild, buf-&gt;size = %lld \n&quot;, buf-&gt;size); ret = -EINVAL; goto fail_unmap; } goto out_put; fail_unmap: dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); fail_detach: dma_buf_detach(dmabuf, attach); out_put: dma_buf_put(dmabuf); return ret; } static void g2d_dmabuf_release(struct sdrv_g2d *gd, struct g2d_buf *buf) { struct sg_table *sgt = buf-&gt;sgt; struct dma_buf *dmabuf; if (IS_ERR_OR_NULL(sgt)) { G2D_ERROR(&quot;dmabuf buffer is already unpinned \n&quot;); return; } if (IS_ERR_OR_NULL(buf-&gt;attach)) { G2D_ERROR(&quot;trying to unpin a not attached buffer\n&quot;); return; } dmabuf = dma_buf_get(buf-&gt;fd); if (IS_ERR_OR_NULL(dmabuf)) { G2D_ERROR(&quot;invalid dmabuf from dma_buf_get: %d&quot;, buf-&gt;fd); return; } G2D_DBG(&quot;buf-&gt;vaddr = 0x%ld\n&quot;, (unsigned long)buf-&gt;vaddr); if (buf-&gt;vaddr) { dma_buf_vunmap(dmabuf, (void *)buf-&gt;vaddr); buf-&gt;vaddr = (unsigned long)NULL; } dma_buf_unmap_attachment(buf-&gt;attach, sgt, 0); buf-&gt;dma_addr = 0; buf-&gt;sgt = NULL; dma_buf_detach(dmabuf, buf-&gt;attach); dma_buf_put(dmabuf); } static int g2d_alph_layer_mmap(struct sdrv_g2d *gd, struct g2d_bg_cfg *bgcfg) { int ret = 0; struct g2d_buf *buf = &amp;bgcfg-&gt;abufs; if (buf-&gt;fd &gt; 0) { ret = g2d_dmabuf_import(gd, buf); if (ret) { G2D_ERROR(&quot;g2d alph layer mmap faild \n&quot;); return ret; } bgcfg-&gt;aaddr = buf-&gt;dma_addr; G2D_DBG(&quot;alph layer used, fd is valid: fd = %d , phy addr = 0x%llx\n&quot;, buf-&gt;fd, bgcfg-&gt;aaddr); } else { G2D_DBG(&quot;alph layer used, fd is invalid, aaddr = 0x%llx \n&quot;, bgcfg-&gt;aaddr); } return ret; } static int g2d_layer_mmap(struct sdrv_g2d *gd, struct g2d_layer *layer) { int ret, i, j; struct g2d_buf *buf = &amp;layer-&gt;bufs[0]; uint32_t tmp_addr_h; uint32_t tmp_addr_l; if (buf-&gt;fd &lt;= 0) { G2D_ERROR(&quot;input layer buf fd invaild, fd(%d) &lt;= 0\n&quot;, buf-&gt;fd); return -EINVAL; } ret = g2d_dmabuf_import(gd, buf); if (ret) { G2D_ERROR(&quot;g2d input layer mmap faild \n&quot;); return ret; } G2D_DBG(&quot;layer-&gt;nplanes = %d\n&quot;, layer-&gt;nplanes); for (i = 0; i &lt; layer-&gt;nplanes; i++) { unsigned long addr = buf-&gt;dma_addr + layer-&gt;offsets[i]; layer-&gt;addr_l[i] = get_l_addr(addr); layer-&gt;addr_h[i] = get_h_addr(addr); G2D_DBG(&quot;layer[%d] addr_l[%d] = 0x%x addr_h[%d] = 0x%x\n&quot;, layer-&gt;index, i, layer-&gt;addr_l[i], i, layer-&gt;addr_h[i]); } if(layer-&gt;format == DRM_FORMAT_BGR888_PLANE) { if (layer-&gt;nplanes != 3) { G2D_ERROR(&quot;format set : DRM_FORMAT_BGR888_PLANE, but nplanes(%d) != 3 \n&quot;, layer-&gt;nplanes); return -1; } tmp_addr_l = layer-&gt;addr_l[0]; tmp_addr_h = layer-&gt;addr_h[0]; layer-&gt;addr_l[0] = layer-&gt;addr_l[2]; layer-&gt;addr_h[0] = layer-&gt;addr_h[2]; layer-&gt;addr_l[2] = tmp_addr_l; layer-&gt;addr_h[2] = tmp_addr_h; for (j = 0; j &lt; layer-&gt;nplanes; j++) { G2D_DBG(&quot;layer[%d] addr_l[%d] = 0x%x addr_h[%d] = 0x%x\n&quot;, layer-&gt;index, j, layer-&gt;addr_l[j], j, layer-&gt;addr_h[j]); } } return 0; } int g2d_output_layer_mmap(struct sdrv_g2d *gd, struct g2d_output_cfg *layer) { int ret; int j; uint64_t tmp_addr; struct g2d_buf *buf = &amp;layer-&gt;bufs[0]; if (buf-&gt;fd &lt;= 0) { G2D_ERROR(&quot;output layer buf fd invaild, fd(%d) &lt;= 0\n&quot;, buf-&gt;fd); return -EINVAL; } ret = g2d_dmabuf_import(gd, buf); if (ret) { G2D_ERROR(&quot;g2d output layer mmap faild \n&quot;); return ret; } for (j = 0; j &lt; layer-&gt;nplanes; j++) { layer-&gt;addr[j] = buf-&gt;dma_addr + layer-&gt;offsets[j]; G2D_DBG(&quot;layer-&gt;addr[%d] = 0x%llx \n&quot;, j, layer-&gt;addr[j]); } if(layer-&gt;fmt == DRM_FORMAT_BGR888_PLANE) { if (layer-&gt;nplanes != 3) { G2D_ERROR(&quot;fmt set : DRM_FORMAT_BGR888_PLANE, but nplanes(%d) != 3 \n&quot;, layer-&gt;nplanes); return -1; } tmp_addr = layer-&gt;addr[0]; layer-&gt;addr[0] = layer-&gt;addr[2]; layer-&gt;addr[2] = tmp_addr; for (j = 0; j &lt; layer-&gt;nplanes; j++) { G2D_DBG(&quot;fmt == DRM_FORMAT_BGR888_PLANE : layer-&gt;addr[%d] = 0x%llx \n&quot;, j, layer-&gt;addr[j]); } } return 0; } void g2d_alph_layer_unmap(struct sdrv_g2d *gd, struct g2d_bg_cfg *bgcfg) { struct g2d_buf *buf = &amp;bgcfg-&gt;abufs; G2D_DBG(&quot;g2d dmabuf:%d\n&quot;, buf-&gt;fd); if (buf-&gt;fd &lt;= 0) return; g2d_dmabuf_release(gd, buf); } void g2d_layer_unmap(struct sdrv_g2d *gd, struct g2d_layer *layer) { struct g2d_buf *buf = &amp;layer-&gt;bufs[0]; G2D_DBG(&quot;g2d dmabuf:%d\n&quot;, buf-&gt;fd); if (buf-&gt;fd &lt;= 0) return; g2d_dmabuf_release(gd, buf); } void g2d_output_layer_unmap(struct sdrv_g2d *gd, struct g2d_output_cfg *layer) { struct g2d_buf *buf = &amp;layer-&gt;bufs[0]; G2D_DBG(&quot;g2d dmabuf:%d\n&quot;, buf-&gt;fd); if (buf-&gt;fd &lt;= 0) return; g2d_dmabuf_release(gd, buf); } static int g2d_ioctl_begin(struct sdrv_g2d *gd, struct g2d_input *input) { int i; int ret; set_user_nice(current, -12); /*bg layer*/ if (input-&gt;bg_layer.en) { ret = g2d_alph_layer_mmap(gd, &amp;input-&gt;bg_layer); if (ret) { return ret; } } /*input layer*/ for (i = 0; i &lt; input-&gt;layer_num; i++) { struct g2d_layer *l = &amp;input-&gt;layer[i]; if (!l-&gt;enable) continue; ret = g2d_layer_mmap(gd, l); if (ret) { return ret; } } /*output layer*/ ret = g2d_output_layer_mmap(gd, &amp;input-&gt;output); if (ret) { return ret; } return 0; } static void g2d_ioctl_finish(struct sdrv_g2d *gd, struct g2d_input *input) { int i; /*bg layer*/ if (input-&gt;bg_layer.en) { g2d_alph_layer_unmap(gd, &amp;input-&gt;bg_layer); } /*input layer*/ for (i = 0; i &lt; input-&gt;layer_num; i++) { struct g2d_layer *l = &amp;input-&gt;layer[i]; if (!l-&gt;enable) continue; g2d_layer_unmap(gd, l); } /*output layer*/ g2d_output_layer_unmap(gd, &amp;input-&gt;output); } static int g2d_wait(struct sdrv_g2d *gd) { int status = 0; int rc; //g2d_dump_registers(gd); /* wait for stop done interrupt wait_event_timeout */ rc = wait_event_timeout(gd-&gt;wq, (gd-&gt;frame_done == true), msecs_to_jiffies(wait_timeout)); gd-&gt;frame_done = false; if (!rc) { status = -1; G2D_ERROR(&quot;g2d operation wait timeout %d\n&quot;, wait_timeout); g2d_dump_registers(gd); } else { if (dump_register_g2d == 1) { g2d_dump_registers(gd); } G2D_DBG(&quot;wait time %d\n&quot;, rc); } if (gd-&gt;ops-&gt;reset) gd-&gt;ops-&gt;reset(gd); return status; } static int g2d_fill_rect_ioctl(struct sdrv_g2d *gd, struct g2d_input *input) { int ret; ret = g2d_fill_rect(gd, &amp;input-&gt;bg_layer, &amp;input-&gt;output); if (ret &lt; 0) { G2D_ERROR(&quot;g2d fill rect set register err \n&quot;); goto OUT; } ret = g2d_wait(gd); OUT: if (ret &lt; 0) dump_input(input); return ret; } static int g2d_fastcopy_dmabuf(struct sdrv_g2d *gd, struct g2d_input *input) { int ret = -1; addr_t iaddr, oaddr; struct g2d_output_cfg *out_layer = &amp;input-&gt;output; struct g2d_bg_cfg *bg_layer = &amp;input-&gt;bg_layer; struct g2d_buf *buf; if (!bg_layer-&gt;en) { G2D_ERROR(&quot;bg_layer en is %d, fast copy cannot be used\n&quot;, bg_layer-&gt;en); return ret; } iaddr = bg_layer-&gt;aaddr; buf = &amp;out_layer-&gt;bufs[0]; oaddr = buf-&gt;dma_addr + out_layer-&gt;offsets[0]; if (iaddr % 4) { G2D_ERROR(&quot;The phy-addr(0x%lx) of the input needs to be 4-byte aligned\n&quot;, iaddr); return ret; } if (oaddr % 4) { G2D_ERROR(&quot;The phy-addr(0x%lx) of the output needs to be 4-byte aligned\n&quot;, oaddr); return ret; } if ((iaddr &lt;= 0) || (oaddr &lt;= 0)) { G2D_ERROR(&quot;input iaddr(0x%lx) or oaddr(0x%lx) = null\n&quot;, iaddr, oaddr); return ret; } ret = g2d_fastcopy_set(gd, iaddr, out_layer-&gt;width, out_layer-&gt;height, bg_layer-&gt;astride, oaddr, out_layer-&gt;stride[0]); if (ret &lt; 0) { G2D_ERROR(&quot;g2d_fastcopy set register err \n&quot;); goto OUT; } ret = g2d_wait(gd); OUT: if (ret &lt; 0) dump_input(input); return ret; } static int sdrv_g2d_post_config(struct sdrv_g2d *gd, struct g2d_input *input) { int ret = 0; ret = g2d_post_config(gd, input); if(ret &lt; 0) goto OUT; ret = g2d_wait(gd); OUT: if (ret &lt; 0) dump_input(input); return ret; } static int sdrv_g2d_tasks(struct sdrv_g2d *gd, unsigned int cmd, struct g2d_input *input) { int ret; mutex_lock(&amp;gd-&gt;m_lock); if (gd-&gt;monitor.is_monitor) gd-&gt;monitor.g2d_on_task = true; if (input-&gt;tables.set_tables) {//set filter tables g2d_set_coefficients_table(gd, &amp;input-&gt;tables); } switch (cmd) { case G2D_IOCTL_POST_CONFIG: ret = sdrv_g2d_post_config(gd, input); G2D_DBG(&quot; G2D_IOCTL_POST_CONFIG ret = %d\n&quot;, ret); break; case G2D_IOCTL_FAST_COPY: ret = g2d_fastcopy_dmabuf(gd, input); G2D_DBG(&quot;G2D_IOCTL_FAST_COPY end ret = %d\n&quot;, ret); break; case G2D_IOCTL_FILL_RECT: ret = g2d_fill_rect_ioctl(gd, input); G2D_DBG(&quot;G2D_IOCTL_FILL_RECT end ret = %d\n&quot;, ret); break; default: G2D_ERROR(&quot;Invalid ioctl cmd: 0x%x\n&quot;, cmd); ret = -EINVAL; break; } if (input-&gt;tables.set_tables) {//reset filter tables input-&gt;tables.set_tables = false; g2d_set_coefficients_table(gd, &amp;input-&gt;tables); } if (gd-&gt;monitor.is_monitor) gd-&gt;monitor.g2d_on_task = false; mutex_unlock(&amp;gd-&gt;m_lock); return ret; } void sdrv_dpc_to_g2d_layer(struct dpc_layer *int_layer, struct g2d_layer *out_layer) { out_layer-&gt;index = int_layer-&gt;index; //plane index out_layer-&gt;enable = int_layer-&gt;enable; out_layer-&gt;nplanes = int_layer-&gt;nplanes; out_layer-&gt;src_x = int_layer-&gt;src_x; out_layer-&gt;src_y = int_layer-&gt;src_y; out_layer-&gt;src_w = int_layer-&gt;src_w; out_layer-&gt;src_h = int_layer-&gt;src_h; out_layer-&gt;dst_x = int_layer-&gt;dst_x; out_layer-&gt;dst_y = int_layer-&gt;dst_y; out_layer-&gt;dst_w = int_layer-&gt;dst_w; out_layer-&gt;dst_h = int_layer-&gt;dst_h; out_layer-&gt;format = int_layer-&gt;format; out_layer-&gt;alpha = int_layer-&gt;alpha; out_layer-&gt;blend_mode = int_layer-&gt;blend_mode; out_layer-&gt;rotation = int_layer-&gt;rotation; out_layer-&gt;zpos = int_layer-&gt;zpos; out_layer-&gt;xfbc = int_layer-&gt;xfbc; out_layer-&gt;modifier = int_layer-&gt;modifier; out_layer-&gt;width = int_layer-&gt;width; out_layer-&gt;height = int_layer-&gt;height; memcpy(out_layer-&gt;addr_l, int_layer-&gt;addr_l, sizeof(out_layer-&gt;addr_l)); memcpy(out_layer-&gt;addr_h, int_layer-&gt;addr_h, sizeof(out_layer-&gt;addr_h)); memcpy(out_layer-&gt;pitch, int_layer-&gt;pitch, sizeof(out_layer-&gt;pitch)); memcpy(&amp;out_layer-&gt;comp, &amp;int_layer-&gt;comp, sizeof(struct pix_g2dcomp)); memcpy(&amp;out_layer-&gt;ctx, &amp;int_layer-&gt;ctx, sizeof(struct tile_ctx)); } int sdrv_g2d_convert_format(struct dpc_layer *layer, uint32_t g2d_out_format) { int ret = 0, i = 0; struct sdrv_g2d *gd = g_g2d[0]; struct g2d_input *input = NULL; uint32_t size = 0; static dma_addr_t paddr[2]; static void *vaddr[2]; static uint8_t index = 0; if (!gd) { G2D_ERROR(&quot;g2d hasn&#39;t exist\n&quot;); return -ENODEV; } input = kzalloc(sizeof(struct g2d_input), GFP_KERNEL); if (!input) { G2D_ERROR(&quot;alloc input error\n&quot;); return -ENOMEM; } size = layer-&gt;src_w * layer-&gt;src_h * 2; size = round_up(size, PAGE_SIZE); if (!vaddr[0]) { for (i = 0; i &lt; 2; i++) { vaddr[i] = dma_alloc_wc(&amp;gd-&gt;pdev-&gt;dev, size, &amp;paddr[i], GFP_KERNEL | __GFP_NOWARN); if(!vaddr[i]) { G2D_ERROR(&quot;failed to allocate buffer of size %u\n&quot;, size); goto alloc_dma_err; } pr_info(&quot;dma addr[%d]:0x%llx vaddr[%d]:0x%p\n&quot;, i ,paddr[i], i, vaddr[i]); } } input-&gt;layer_num = 1; memcpy(&amp;input-&gt;layer[0], layer, sizeof(struct g2d_layer)); sdrv_dpc_to_g2d_layer(layer, &amp;input-&gt;layer[0]); pr_debug(&quot;format:%x, w:%d, h:%d s:%d al:%x\n&quot;, layer-&gt;format, layer-&gt;src_w, layer-&gt;src_h, layer-&gt;pitch[0], layer-&gt;addr_l[0]); input-&gt;output.width = layer-&gt;dst_w; input-&gt;output.height = layer-&gt;dst_h; input-&gt;output.stride[0] = layer-&gt;dst_w * 2; input-&gt;output.fmt = g2d_out_format; input-&gt;output.nplanes = 1; input-&gt;output.addr[0] = paddr[index]; pr_debug(&quot;o format:%x, w:%d, h:%d s:%d a:%llx\n&quot;, input-&gt;output.fmt, input-&gt;output.width, input-&gt;output.height, input-&gt;output.stride[0], input-&gt;output.addr[0]); mutex_lock(&amp;gd-&gt;m_lock); ret = sdrv_g2d_post_config(gd, input); if (ret) { mutex_unlock(&amp;gd-&gt;m_lock); goto out; } mutex_unlock(&amp;gd-&gt;m_lock); layer-&gt;addr_l[0] = get_l_addr(input-&gt;output.addr[0]); layer-&gt;addr_h[0] = get_h_addr(input-&gt;output.addr[0]); layer-&gt;src_h = input-&gt;output.height; layer-&gt;src_w = input-&gt;output.width; layer-&gt;dst_h = input-&gt;output.height; layer-&gt;dst_w = input-&gt;output.width; layer-&gt;pitch[0] = input-&gt;output.stride[0]; index ++; if (index &gt;= 2) index = 0; out: kfree(input); return ret; alloc_dma_err: while (i) { dma_free_wc(&amp;gd-&gt;pdev-&gt;dev, size, vaddr[i], paddr[i]); i--; } kfree(input); return -ENOMEM; } EXPORT_SYMBOL(sdrv_g2d_convert_format); static int sdrv_g2d_func_work(struct sdrv_g2d *gd, unsigned int cmd, struct g2d_input *input) { int ret; if (!gd || !input) { G2D_ERROR(&quot;dev or input isn&#39;t inited.[dev:%p, ins:%p]\n&quot;, gd, input); return -EINVAL; } if ((input-&gt;output.height &lt;= 0) || (input-&gt;output.width &lt;= 0)) { G2D_ERROR(&quot;output input-&gt;output.height = %d, input-&gt;output.width = %d\n&quot;, input-&gt;output.height, input-&gt;output.width); return -EINVAL; } G2D_DBG(&quot;\r\n&quot;); ret = g2d_ioctl_begin(gd, input); if (ret) { G2D_ERROR(&quot;input parameter err\n&quot;); goto finish_out; } ret = sdrv_g2d_tasks(gd, cmd, input); finish_out: g2d_ioctl_finish(gd, input); return ret; } int sdrv_g2d_dma_copy(dma_addr_t dst, dma_addr_t src, size_t data_size) { int ret = 0; struct g2d_input *input; struct sdrv_g2d *gd = g_g2d[0]; int width, height, stride; width = 32; stride = width * 4; height = (data_size / stride) + ((data_size % stride) ? 1 : 0); G2D_DBG(&quot;data_size, width, stride, height : (%ld, %d, %d, %d)\n&quot;, data_size, width, stride, height); input = kzalloc(sizeof(struct g2d_input), GFP_ATOMIC | GFP_DMA); if (!input) { G2D_ERROR(&quot;kzalloc input failed\n&quot;); return -EFAULT; } input-&gt;bg_layer.en = 1; input-&gt;bg_layer.width = width; input-&gt;bg_layer.height = height; input-&gt;bg_layer.astride = stride; input-&gt;bg_layer.aaddr = (uint64_t)src; input-&gt;output.bufs[0].dma_addr = (uint64_t)dst; input-&gt;output.width = width; input-&gt;output.height = height; input-&gt;output.stride[0] = stride; ret = sdrv_g2d_tasks(gd, G2D_IOCTL_FAST_COPY, input); kfree(input); return ret; } EXPORT_SYMBOL(sdrv_g2d_dma_copy); static long sdrv_g2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = -1; int i=0, n = 0; struct sdrv_g2d *gd = file-&gt;private_data; struct g2d_input *input; struct g2d_inputx *inputx; if (_IOC_TYPE(cmd) != G2D_IOCTL_BASE) return -EINVAL; if (_IOC_NR(cmd) &gt; 4) return -EINVAL; if (_IOC_DIR(cmd) &amp; _IOC_READ) { ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); if (ret) return -EFAULT; } if (_IOC_DIR(cmd) &amp; _IOC_WRITE) { ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); if (ret) return -EFAULT; } inputx = kzalloc(sizeof(struct g2d_inputx), GFP_ATOMIC | GFP_DMA); if (!inputx) { G2D_ERROR(&quot;kzalloc input failed\n&quot;); return -EFAULT; } input = kzalloc(sizeof(struct g2d_input), GFP_ATOMIC | GFP_DMA); if (!input) { G2D_ERROR(&quot;kzalloc input failed\n&quot;); if (inputx) kfree(inputx); return -EFAULT; } memset(inputx,0,sizeof(struct g2d_inputx)); memset(input,0,sizeof(struct g2d_input)); if (cmd == G2D_IOCTL_GET_CAPABILITIES) { ret = copy_to_user((struct g2d_capability __user *)arg, &amp;gd-&gt;cap, sizeof(struct g2d_capability)); if (ret) { G2D_ERROR(&quot;get capabilities err \n&quot;); ret = -EFAULT; } } else { ret = copy_from_user(inputx, (struct g2d_inputx __user *)arg, sizeof(struct g2d_inputx)); if (ret) { G2D_ERROR(&quot;copy_from_user failed\n&quot;); ret = -EFAULT; goto unlock_out; } //for 32bit and 64 bit capibility; input-&gt;layer_num = inputx-&gt;layer_num; memcpy((void *)(&amp;input-&gt;bg_layer),(void *)(&amp;inputx-&gt;bg_layer),sizeof(struct g2d_bg_cfg_x)); input-&gt;bg_layer.abufs.dma_addr = input-&gt;bg_layer.cfg_buf.dma_addr; input-&gt;bg_layer.abufs.fd = input-&gt;bg_layer.cfg_buf.fd; input-&gt;bg_layer.abufs.size = input-&gt;bg_layer.cfg_buf.size; input-&gt;bg_layer.abufs.vaddr = input-&gt;bg_layer.cfg_buf.vaddr; memcpy((void *)(&amp;input-&gt;output), (void *)(&amp;inputx-&gt;output),sizeof(struct g2d_output_cfg_x)); for (i = 0; i &lt; 4; i++) { input-&gt;output.bufs[i].dma_addr = input-&gt;output.out_buf[i].dma_addr; input-&gt;output.bufs[i].fd = input-&gt;output.out_buf[i].fd; input-&gt;output.bufs[i].size = input-&gt;output.out_buf[i].size; input-&gt;output.bufs[i].vaddr = input-&gt;output.out_buf[i].vaddr; } memcpy((void *)(&amp;input-&gt;tables), (void *)(&amp;inputx-&gt;tables),sizeof(struct g2d_coeff_table)); for (n = 0; n &lt; G2D_LAYER_MAX_NUM;n ++) { memcpy((void *)(&amp;input-&gt;layer[n]),(void *)(&amp;inputx-&gt;layer[n]),sizeof(struct g2d_layer_x)); for (i = 0; i &lt; 4; i++) { input-&gt;layer[n].bufs[i].dma_addr = input-&gt;layer[n].in_buf[i].dma_addr; input-&gt;layer[n].bufs[i].fd = input-&gt;layer[n].in_buf[i].fd; input-&gt;layer[n].bufs[i].size = input-&gt;layer[n].in_buf[i].size; input-&gt;layer[n].bufs[i].vaddr = input-&gt;layer[n].in_buf[i].vaddr; } } ret = sdrv_g2d_func_work(gd, cmd, input); } unlock_out: if (input) kfree(input); if (inputx) kfree(inputx); return (long)ret; } #if defined(CONFIG_COMPAT) static long sdrv_g2d_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return sdrv_g2d_ioctl(file, cmd, arg); } #endif /* defined(CONFIG_COMPAT) */ ssize_t sdrv_g2d_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { struct sdrv_g2d *gd = file-&gt;private_data; char str[64] = {0}; ssize_t sz = sprintf(str, &quot;read from %s\n&quot;, gd-&gt;name); if (copy_to_user(buf, str, sz)){ G2D_ERROR(&quot;copy to user failed: %s\n&quot;, gd-&gt;name); } return sz; } static const struct file_operations g2d_fops = { .owner = THIS_MODULE, .open = sdrv_g2d_open, .read = sdrv_g2d_read, .unlocked_ioctl = sdrv_g2d_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sdrv_g2d_compat_ioctl, #endif }; static int g2d_misc_init(struct sdrv_g2d *gd) { int ret; struct miscdevice *m = &amp;gd-&gt;mdev;; m-&gt;minor = MISC_DYNAMIC_MINOR; m-&gt;name = kasprintf(GFP_KERNEL, &quot;g2d%d&quot;, gd-&gt;id); m-&gt;fops = &amp;g2d_fops; m-&gt;parent = NULL; m-&gt;groups = sdrv_g2d_groups; ret = misc_register(m); if (ret) { G2D_ERROR(&quot;failed to register miscdev\n&quot;); return ret; } G2D_INFO(&quot;%s misc register \n&quot;, m-&gt;name); return ret; } static int sdrv_g2d_probe(struct platform_device *pdev) { struct device *dev = &amp;pdev-&gt;dev; struct sdrv_g2d *gd = NULL; static int pipe_registered = 0; dma_addr_t dma_handle; int ret = 0, i; mutex_lock(&amp;m_init); G2D_INFO(&quot;G2D BUILD VERSION : %s \n&quot;, version); // 38 bits address for KUNLUN G2D rdma,use G2D_CPU_WRITE config 38bit; use G2D_CMD_WRITE config 32bit dma_set_mask(dev, DMA_BIT_MASK(32)); dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); gd = devm_kzalloc(&amp;pdev-&gt;dev, sizeof(struct sdrv_g2d), GFP_KERNEL); if (!gd) { G2D_ERROR(&quot;kalloc sdrv_g2d failed\n&quot;); ret = -1; goto OUT; } gd-&gt;du_inited = false; gd-&gt;pdev = pdev; if (!pipe_registered) { pipe_registered++; g2d_pipe_ops_register(&amp;spipe_g2d_entry); g2d_pipe_ops_register(&amp;gpipe_high_g2d_entry); g2d_pipe_ops_register(&amp;gpipe_mid_g2d_entry); } /*cmdfile init*/ gd-&gt;cmd_info[0].arg = (unsigned int*)dma_alloc_coherent(dev, G2D_CMDFILE_MAX_MEM * sizeof(unsigned int), &amp;dma_handle, GFP_KERNEL); gd-&gt;dma_buf = (unsigned long)dma_handle; if (gd-&gt;cmd_info[0].arg == NULL) { G2D_ERROR(&quot;malloc cmd_info failed\n&quot;); goto OUT; } G2D_INFO(&quot;gd-&gt;cmd_info[0].arg virtual address = 0x%lx, phy address 0x%lx,dma alloc coherent len = %ld\n&quot;, (unsigned long)gd-&gt;cmd_info[0].arg, gd-&gt;dma_buf, G2D_CMDFILE_MAX_MEM * sizeof(unsigned int)); for (i = 1 ; i &lt; G2D_CMDFILE_MAX_NUM; i++) { gd-&gt;cmd_info[i].arg = gd-&gt;cmd_info[i - 1].arg + G2D_CMDFILE_MAX_MEM / G2D_CMDFILE_MAX_NUM; } #ifdef CONFIG_OF G2D_INFO(&quot;CONFIG_OF scope\n&quot;); sdrv_init_iommu(gd); ret = sdrv_g2d_init(gd, dev-&gt;of_node); #else G2D_INFO(&quot;CONFIG_OF is closed\n&quot;); ret = sdrv_g2d_init(gd, pdev); #endif if (ret) goto OUT; mutex_init(&amp;gd-&gt;m_lock); gd-&gt;monitor.sampling_time = 5; ret = g2d_misc_init(gd); if (ret) goto OUT; else printk(&quot;%s : semidrive g2d driver registered.\n&quot;, __func__); platform_set_drvdata(pdev, gd); g_g2d[gd-&gt;id] = gd; gd-&gt;du_inited = true; enable_irq(gd-&gt;irq); ret = 0; OUT: mutex_unlock(&amp;m_init); return ret; } static int sdrv_g2d_remove(struct platform_device *pdev) { struct sdrv_g2d *gd = platform_get_drvdata(pdev); G2D_DBG(&quot;remove g2d %s\n&quot;, gd-&gt;name); if (gd) { sdrv_iommu_cleanup(gd); sdrv_g2d_unit(gd); misc_deregister(&amp;gd-&gt;mdev); } return 0; } #ifdef CONFIG_OF static const struct of_device_id g2d_of_table[] = { {.compatible = &quot;semidrive,g2d&quot;, .data = g2d_data}, {.compatible = &quot;semidrive,g2d_lite&quot;, .data = g2d_data}, {}, }; #endif static int sdrv_g2d_suspend(struct device *dev) { struct sdrv_g2d *gd = dev_get_drvdata(dev); G2D_INFO(&quot;%s start\n&quot;, __func__); gd-&gt;ops-&gt;reset(gd); G2D_INFO(&quot;gd-&gt;du_inited = %d, gd-&gt;num_pipe = %d\n&quot;, gd-&gt;du_inited, gd-&gt;num_pipe); G2D_INFO(&quot;%s end\n&quot;, __func__); return 0; } static int sdrv_g2d_resume(struct device *dev) { struct sdrv_g2d *gd = dev_get_drvdata(dev); struct g2d_pipe *p = NULL; int i; G2D_INFO(&quot;%s start\n&quot;, __func__); G2D_INFO(&quot;gd-&gt;du_inited = %d, gd-&gt;num_pipe = %d\n&quot;, gd-&gt;du_inited, gd-&gt;num_pipe); gd-&gt;ops-&gt;init(gd); for (i = 0; i &lt; gd-&gt;num_pipe; i++) { p = gd-&gt;pipes[i]; if (p &amp;&amp; p-&gt;ops-&gt;init) p-&gt;ops-&gt;init(p); else G2D_ERROR(&quot;p or p-&gt;ops-&gt;init is null\n&quot;); } gd-&gt;ops-&gt;reset(gd); G2D_INFO(&quot;%s end\n&quot;, __func__); return 0; } static const struct dev_pm_ops sdrv_g2d_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(sdrv_g2d_suspend, sdrv_g2d_resume) }; static struct platform_driver g2d_driver = { .probe = sdrv_g2d_probe, .remove = sdrv_g2d_remove, .driver = { .name = &quot;semidrive-g2d&quot;, .owner = THIS_MODULE, #ifdef CONFIG_OF .of_match_table = g2d_of_table, #endif .pm = &amp;sdrv_g2d_pm_ops, }, }; module_platform_driver(g2d_driver); MODULE_AUTHOR(&quot;Semidrive Semiconductor&quot;); MODULE_DESCRIPTION(&quot;Semidrive g2d&quot;); MODULE_LICENSE(&quot;GPL&quot;); 以上是linux内核g2d驱动文件sdrv_g2d.c #ifndef __SDRV_G2D_H__ #define __SDRV_G2D_H__ #include &lt;linux/platform_device.h&gt; #include &lt;linux/device.h&gt; #include &lt;linux/kernel.h&gt; #include &lt;linux/cdev.h&gt; #include &lt;linux/miscdevice.h&gt; #include &lt;linux/list.h&gt; #include &lt;asm/io.h&gt; #include &lt;linux/iommu.h&gt; #include &lt;linux/wait.h&gt; #include &lt;uapi/drm/drm_fourcc.h&gt; #include &lt;uapi/drm/sdrv_g2d_cfg.h&gt; #include &quot;g2d_common.h&quot; #define PR_INFO pr_info #define ERROR pr_err typedef unsigned long int addr_t; #ifndef ARRAY_SIZE #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #endif extern int debug_g2d; #define G2D_INFO(fmt, args...) do {\ PR_INFO(&quot;[g2d] [%20s] &quot; fmt, __func__, ##args);\ }while(0) #define G2D_DBG(fmt, args...) do {\ if (debug_g2d &gt;= 1) {\ PR_INFO(&quot;[g2d] &lt;%d&gt; [%20s] &quot; fmt, __LINE__, __func__, ##args);}\ }while(0) #define G2D_ERROR(fmt, args...) ERROR(&quot;[g2d] &lt;%d&gt; [%20s] Error: &quot; fmt, __LINE__, __func__, ##args) #define DDBG(x) G2D_DBG(#x &quot; -&gt; %d\n&quot;, x) #define XDBG(x) G2D_DBG(#x &quot; -&gt; 0x%x\n&quot;, x) #define PDBG(x) G2D_DBG(#x &quot; -&gt; %p\n&quot;, x) #define ENTRY() G2D_DBG(&quot;call &lt;%d&gt;\n&quot;, __LINE__) #define GP_ECHO_NAME &quot;g2d_gpipe_echo&quot; #define GP_MID_NAME &quot;g2d_gpipe_mid&quot; #define GP_HIGH_NAME &quot;g2d_gpipe_high&quot; #define SPIPE_NAME &quot;g2d_spipe&quot; #define G2D_NR_DEVS 4 /*Kunlun DP layer format TILE vsize*/ enum { TILE_VSIZE_1 = 0b000, TILE_VSIZE_2 = 0b001, TILE_VSIZE_4 = 0b010, TILE_VSIZE_8 = 0b011, TILE_VSIZE_16 = 0b100, }; /*Kunlun DP layer format TILE hsize*/ enum { TILE_HSIZE_1 = 0b000, TILE_HSIZE_8 = 0b001, TILE_HSIZE_16 = 0b010, TILE_HSIZE_32 = 0b011, TILE_HSIZE_64 = 0b100, TILE_HSIZE_128 = 0b101, }; /**/ enum { FBDC_U8U8U8U8 = 0xc, FBDC_U16 = 0x9, FBDC_R5G6B5 = 0x5, FBDC_U8 = 0x0, FBDC_NV21 = 0x37, FBDC_YUV420_16PACK = 0x65 }; enum kunlun_plane_property { PLANE_PROP_ALPHA, PLANE_PROP_BLEND_MODE, PLANE_PROP_FBDC_HSIZE_Y, PLANE_PROP_FBDC_HSIZE_UV, PLANE_PROP_CAP_MASK, PLANE_PROP_MAX_NUM }; enum { DRM_MODE_BLEND_PIXEL_NONE = 0, DRM_MODE_BLEND_PREMULTI, DRM_MODE_BLEND_COVERAGE }; enum { PLANE_DISABLE, PLANE_ENABLE }; enum { PROP_PLANE_CAP_RGB = 0, PROP_PLANE_CAP_YUV, PROP_PLANE_CAP_XFBC, PROP_PLANE_CAP_YUV_FBC, PROP_PLANE_CAP_ROTATION, PROP_PLANE_CAP_SCALING, }; enum { TYPE_GP_ECHO = 0, TYPE_GP_MID, TYPE_GP_HIGH, TYPE_SPIPE }; struct g2d_pipe; struct pipe_operation { int (*init)(struct g2d_pipe *); int (*set)(struct g2d_pipe *, int , struct g2d_layer *); void (*csc_coef_set)(struct g2d_pipe *, struct g2d_coeff_table *); }; struct g2d_pipe { void __iomem *iomem_regs; void __iomem *regs; unsigned long reg_offset; int id; // the ordered id from 0 struct sdrv_g2d *gd; const char *name; int type; struct pipe_operation *ops; struct g2d_pipe_capability *cap; struct g2d_pipe *next; }; struct g2d_monitor { int is_monitor; int is_init; ktime_t timeout; struct hrtimer timer; bool g2d_on_task; int occupancy_rate; int timer_count; int valid_times; int sampling_time; }; struct sdrv_g2d { struct platform_device *pdev; struct cdev cdev; struct miscdevice mdev; void __iomem *iomem_regs; void __iomem *regs; bool iommu_enable; struct iommu_domain *domain; struct mutex m_lock; struct wait_queue_head wq; bool frame_done; int id; const char *name; int irq; int write_mode; cmdfile_info cmd_info[G2D_CMDFILE_MAX_NUM]; unsigned long dma_buf; const struct g2d_ops *ops; struct g2d_capability cap; struct g2d_pipe *pipes[PIPE_MAX]; int num_pipe; int du_inited; struct g2d_monitor monitor; }; struct g2d_ops { int (*init)(struct sdrv_g2d *); int (*enable)(struct sdrv_g2d*, int); int (*reset)(struct sdrv_g2d *); int (*mlc_set)(struct sdrv_g2d *, int , struct g2d_input *); int (*fill_rect)(struct sdrv_g2d *, struct g2d_bg_cfg *, struct g2d_output_cfg *); int (*fastcopy)(struct sdrv_g2d *, addr_t , u32 , u32 , u32 , addr_t , u32); int (*config)(struct sdrv_g2d *); int (*irq_handler)(struct sdrv_g2d *); int (*rwdma)(struct sdrv_g2d *, struct g2d_input *); void (*close_fastcopy)(struct sdrv_g2d *); int (*wpipe_set)(struct sdrv_g2d *, int, struct g2d_output_cfg *); int (*check_stroke)(struct g2d_input *); int (*scaler_coef_set)(struct sdrv_g2d *, struct g2d_coeff_table *); }; struct sdrv_g2d_data { const char *version; const struct g2d_ops* ops; }; struct ops_entry { const char *ver; void *ops; }; int g2d_get_capability(struct g2d_capability *cap); unsigned int get_compval_from_comp(struct pix_g2dcomp *comp); unsigned int get_frm_ctrl_from_comp(struct pix_g2dcomp *comp); int sdrv_wpipe_pix_comp(uint32_t format, struct pix_g2dcomp *comp); int sdrv_pix_comp(uint32_t format, struct pix_g2dcomp *comp); bool g2d_format_is_yuv(uint32_t format); int g2d_format_wpipe_bypass(uint32_t format); struct ops_list { struct list_head head; struct ops_entry *entry; }; extern struct list_head g2d_pipe_list_head; int g2d_ops_register(struct ops_entry *entry, struct list_head *head); void *g2d_ops_attach(const char *str, struct list_head *head); #define g2d_pipe_ops_register(entry) g2d_ops_register(entry, &amp;g2d_pipe_list_head) #define g2d_pipe_ops_attach(str) g2d_ops_attach(str, &amp;g2d_pipe_list_head) int g2d_choose_pipe(struct sdrv_g2d *gd, int hwid, int type, uint32_t offset); struct sdrv_g2d *get_g2d_by_id(int id); extern struct ops_entry gpipe_mid_g2d_entry; extern struct ops_entry gpipe_high_g2d_entry; extern struct ops_entry spipe_g2d_entry; #endif //__SDRV_G2D_H__ 以上是linux内核的g2d驱动的头文件sdrv_g2d.h #ifndef __SDRV_G2D_CFG_H #define __SDRV_G2D_CFG_H #include &quot;sdrv_drm.h&quot; #ifdef __YOCTO_G2D_TEST__ typedef __u8 uint8_t; typedef __u16 uint16_t; typedef __u32 uint32_t; typedef unsigned long uint64_t; #endif #define G2D_LAYER_MAX_NUM 6 #ifndef G2DLITE_API_USE typedef enum { SWAP_A_RGB = 0b0000, SWAP_A_RBG = 0b0001, SWAP_A_GBR = 0b0010, SWAP_A_GRB = 0b0011, SWAP_A_BGR = 0b0100, SWAP_A_BRG = 0b0101, SWAP_B_ARG = 0b1000, SWAP_B_AGR = 0b1001, SWAP_B_RGA = 0b1010, SWAP_B_RAG = 0b1011, SWAP_B_GRA = 0b1100, SWAP_B_GAR = 0b1101 } COMP_SWAP_MODE; typedef enum { UV_YUV444_RGB = 0b00, UV_YUV422 = 0b01, UV_YUV440 = 0b10, UV_YUV420 = 0b11 } DATA_UV_MODE; typedef enum { LINEAR_MODE = 0b000, RLE_COMPR_MODE = 0b001, GPU_RAW_TILE_MODE = 0b010, GPU_CPS_TILE_MODE = 0b011, VPU_RAW_TILE_MODE = 0b100, VPU_CPS_TILE_MODE = 0b101, VPU_RAW_TILE_988_MODE = 0b110, } DATA_MODE; typedef enum { FMT_INTERLEAVED = 0b00, FMT_MONOTONIC = 0b01, FMT_SEMI_PLANAR = 0b10, FMT_PLANAR = 0b11 } FRM_BUF_STR_FMT; typedef enum { ROT_DEFAULT = 0b000, ROT_ROT = 0b001, ROT_VFLIP = 0b010, ROT_HFLIP = 0b100 } ROT_TYPE; #endif #ifndef G2DLITE_API_USE enum { BLEND_PIXEL_NONE = 0, BLEND_PIXEL_PREMULTI, BLEND_PIXEL_COVERAGE }; typedef enum { ROTATION_TYPE_NONE = 0b000, ROTATION_TYPE_ROT_90 = 0b001, ROTATION_TYPE_HFLIP = 0b010, ROTATION_TYPE_VFLIP = 0b100, ROTATION_TYPE_ROT_180 = ROTATION_TYPE_VFLIP | ROTATION_TYPE_HFLIP, ROTATION_TYPE_ROT_270 = ROTATION_TYPE_ROT_90 | ROTATION_TYPE_VFLIP | ROTATION_TYPE_HFLIP, ROTATION_TYPE_VF_90 = ROTATION_TYPE_VFLIP | ROTATION_TYPE_ROT_90, ROTATION_TYPE_HF_90 = ROTATION_TYPE_HFLIP | ROTATION_TYPE_ROT_90, } rotation_type; #endif typedef enum { PD_NONE = 0, PD_SRC = 0x1, PD_DST = 0x2 } PD_LAYER_TYPE; struct g2d_output_cfg{ uint32_t width; uint32_t height; uint32_t fmt; uint64_t addr[4]; uint32_t stride[4]; uint32_t rotation; uint32_t nplanes; uint32_t offsets[4]; struct tile_ctx out_ctx; struct g2d_buf_info out_buf[4]; struct g2d_buf bufs[4]; }; struct g2d_bg_cfg { uint32_t en; uint32_t color; uint8_t g_alpha; uint8_t zorder; uint64_t aaddr; uint8_t bpa; uint32_t astride; uint32_t x; uint32_t y; uint32_t width; uint32_t height; PD_LAYER_TYPE pd_type; struct g2d_buf_info cfg_buf; struct g2d_buf abufs; }; struct g2d_coeff_table { int set_tables; int hcoef_set; int hcoef[33][5]; int vcoef_set; int vcoef[33][4]; int csc_coef_set; int csc_coef[15]; }; struct g2d_input{ unsigned char layer_num; struct g2d_bg_cfg bg_layer; struct g2d_layer layer[G2D_LAYER_MAX_NUM]; struct g2d_output_cfg output; struct g2d_coeff_table tables; }; struct g2d_pipe_capability { uint32_t formats[100]; int nformats; int layer_type; int rotation; int scaling; int yuv; int yuv_fbc; int xfbc; }; struct g2d_capability { int num_pipe; struct g2d_pipe_capability pipe_caps[G2D_LAYER_MAX_NUM]; }; struct g2d_layer_x { __u8 index; //plane index __u8 enable; __u8 nplanes; __u32 addr_l[4]; __u32 addr_h[4]; __u32 pitch[4]; __u32 offsets[4]; __s16 src_x; __s16 src_y; __s16 src_w; __s16 src_h; __s16 dst_x; __s16 dst_y; __u16 dst_w; __u16 dst_h; __u32 format; struct pix_g2dcomp comp; struct tile_ctx ctx; __u32 alpha; __u32 blend_mode; __u32 rotation; __u32 zpos; __u32 xfbc; __u64 modifier; __u32 width; __u32 height; struct g2d_buf_info in_buf[4]; }; struct g2d_output_cfg_x{ uint32_t width; uint32_t height; uint32_t fmt; uint64_t addr[4]; uint32_t stride[4]; uint32_t rotation; uint32_t nplanes; uint32_t offsets[4]; struct tile_ctx out_ctx; struct g2d_buf_info out_buf[4]; }; struct g2d_bg_cfg_x { uint32_t en; uint32_t color; uint8_t g_alpha; uint8_t zorder; uint64_t aaddr; uint8_t bpa; uint32_t astride; uint32_t x; uint32_t y; uint32_t width; uint32_t height; PD_LAYER_TYPE pd_type; struct g2d_buf_info cfg_buf; }; struct g2d_inputx{ unsigned char layer_num; struct g2d_bg_cfg_x bg_layer; struct g2d_layer_x layer[G2D_LAYER_MAX_NUM]; struct g2d_output_cfg_x output; struct g2d_coeff_table tables; }; #define G2D_COMMAND_BASE 0x00 #define G2D_IOCTL_BASE &#39;g&#39; #define G2D_IO(nr) _IO(G2D_IOCTL_BASE,nr) #define G2D_IOR(nr,type) _IOR(G2D_IOCTL_BASE,nr,type) #define G2D_IOW(nr,type) _IOW(G2D_IOCTL_BASE,nr,type) #define G2D_IOWR(nr,type) _IOWR(G2D_IOCTL_BASE,nr,type) #define G2D_IOCTL_GET_CAPABILITIES G2D_IOWR(G2D_COMMAND_BASE + 1, struct g2d_capability) #define G2D_IOCTL_POST_CONFIG G2D_IOWR(G2D_COMMAND_BASE + 2, struct g2d_inputx) #define G2D_IOCTL_FAST_COPY G2D_IOWR(G2D_COMMAND_BASE + 3, struct g2d_inputx) #define G2D_IOCTL_FILL_RECT G2D_IOWR(G2D_COMMAND_BASE + 4, struct g2d_inputx) #endif //__SDRV_G2D_CFG_H 以上是linux内核提供给linux应用层调用的头文件。 请提供所有文件的中文详细注释,并结合lvgl 9.2.2版版本源码和/dev/g2d0设备,实现调用g2d硬件资源进行图形绘制linux应用代码。
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值