gdc: add gdc driver
authorJiyu Yang <Jiyu.Yang@amlogic.com>
Wed, 6 Jun 2018 13:20:34 +0000 (21:20 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Fri, 29 Jun 2018 07:33:16 +0000 (00:33 -0700)
PD#165090: gdc add platform drivers base on the arm release.
TODO use v4l2 m2m device driver rewrite.

Change-Id: I1943f762041d005c17abd9b803b69ef68b08d290
Signed-off-by: Jiyu Yang <Jiyu.Yang@amlogic.com>
16 files changed:
MAINTAINERS
arch/arm64/boot/dts/amlogic/mesong12b.dtsi
arch/arm64/configs/meson64_defconfig
drivers/amlogic/media/Kconfig
drivers/amlogic/media/Makefile
drivers/amlogic/media/gdc/Kconfig [new file with mode: 0644]
drivers/amlogic/media/gdc/Makefile [new file with mode: 0644]
drivers/amlogic/media/gdc/app/gdc_main.c [new file with mode: 0644]
drivers/amlogic/media/gdc/app/gdc_module.c [new file with mode: 0644]
drivers/amlogic/media/gdc/inc/api/gdc_api.h [new file with mode: 0644]
drivers/amlogic/media/gdc/inc/gdc/gdc_config.h [new file with mode: 0644]
drivers/amlogic/media/gdc/inc/sys/system_gdc_io.h [new file with mode: 0644]
drivers/amlogic/media/gdc/inc/sys/system_log.h [new file with mode: 0644]
drivers/amlogic/media/gdc/src/fw_lib/acamera_gdc.c [new file with mode: 0644]
drivers/amlogic/media/gdc/src/platform/system_gdc_io.c [new file with mode: 0644]
drivers/amlogic/media/gdc/src/platform/system_log.c [new file with mode: 0644]

index 0c5d4e58fc8065a3510edf2a5f658391cec2482b..788cba4f7dbcc8823e79eea0aa1feb2a0530cec1 100644 (file)
@@ -14398,6 +14398,10 @@ AMLOGIC G12A Media codec io bus
 M:     Nanxin Qin <nanxin.qin@amlogic.com>
 F:     include/linux/amlogic/media/registers/regs/efuse_regs.h
 
+AMLOGIC Geometric Distorition Correction
+M:     Jiyu Yang <Jiyu.Yang@amlogic.com>
+F:     drivers/amlogic/media/gdc/*
+
 AMLOGIC G12A CVBS DRIVER
 M:     Nian Jing <nian.jing@amlogic.com>
 F:     drivers/amlogic/media/vout/cvbs/
index 7e7bc3a0de641a182200a61011c0e51a84fa2799..4496f1b8a47828e09fd3a6480fbbacfda013dc6a 100644 (file)
                };
        };
 
+       gdc:gdc {
+               #address-cells=<2>;
+               #size-cells=<2>;
+               status = "ok";
+               compatible = "amlogic, g12b-gdc";
+               reg = <0 0xFF950000 0 0x0000100
+                          0 0xFF63C16C 0 0x0000004
+                          0 0xFF63C100 0 0x0000004>;
+               interrupts = <0 144 1>;
+               interrupt-names = "GDC";
+               clocks = <&clkc CLKID_GDC_CORE_CLK_COMP
+                                 &clkc CLKID_GDC_AXI_CLK_COMP >;
+               clock-names = "core","axi";
+       };
+
        mesonstream {
                compatible = "amlogic, codec, streambuf";
                dev_name = "mesonstream";
index 17f04bb81bf6c832bd5b1c036504f3ba986893dc..c0c0fe4a5c9ba56ac513345e82b0f828c13a7cb6 100644 (file)
@@ -316,6 +316,7 @@ CONFIG_AMLOGIC_PIC_DEC=y
 CONFIG_AMLOGIC_MEDIA_ENHANCEMENT=y
 CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM=y
 CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y
+CONFIG_AMLOGIC_MEDIA_GDC=y
 CONFIG_AMLOGIC_DTV_DEMOD=y
 CONFIG_AMLOGIC_MMC=y
 CONFIG_AMLOGIC_NAND=y
index 2cde7c391c96f6591d94e2a7f4284f34583b83ae..bb5673d11933bc8e39288d126f97b27c99f7830a 100644 (file)
@@ -61,6 +61,7 @@ source "drivers/amlogic/media/deinterlace/Kconfig"
 source "drivers/amlogic/media/vin/Kconfig"
 source "drivers/amlogic/media/video_processor/Kconfig"
 source "drivers/amlogic/media/enhancement/Kconfig"
+source "drivers/amlogic/media/gdc/Kconfig"
 endif
 source "drivers/amlogic/media/dtv_demod/Kconfig"
 endmenu
index 9702f1b7a6f35eaa3075d32f34f4158ea8d37279..8db1870f34092bbd3f4db892177934b59258b1e2 100644 (file)
@@ -9,3 +9,4 @@ obj-$(CONFIG_AMLOGIC_MEDIA_VIN)         +=      vin/
 obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR)    +=      video_processor/
 obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT) += enhancement/
 obj-$(CONFIG_AMLOGIC_DTV_DEMOD) += dtv_demod/
+obj-$(CONFIG_AMLOGIC_MEDIA_GDC) += gdc/
diff --git a/drivers/amlogic/media/gdc/Kconfig b/drivers/amlogic/media/gdc/Kconfig
new file mode 100644 (file)
index 0000000..b1a0d63
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# gdc driver configuration
+#
+config AMLOGIC_MEDIA_GDC
+       bool "Amlogic gdc driver"
+       default n
+       help
+               Select to enable gdc driver.
diff --git a/drivers/amlogic/media/gdc/Makefile b/drivers/amlogic/media/gdc/Makefile
new file mode 100644 (file)
index 0000000..5892420
--- /dev/null
@@ -0,0 +1,18 @@
+FW_SRC := src/fw_lib/acamera_gdc.c \
+       src/platform/system_gdc_io.c \
+       src/platform/system_log.c \
+       app/gdc_main.c \
+       app/gdc_module.c
+
+FW_SRC_OBJ := $(FW_SRC:.c=.o)
+
+obj-$(CONFIG_AMLOGIC_MEDIA_GDC) += $(FW_SRC_OBJ)
+
+PWD=$(src)
+ccflags-y +=-I$(PWD)/app -I$(PWD)/inc
+ccflags-y +=-I$(PWD)/inc/api -I$(PWD)/inc/gdc -I$(PWD)/inc/sys
+ccflags-y +=-I$(PWD)/src/platform -I$(PWD)/src/fw_lib
+ccflags-y += -Idrivers/amlogic/media/common/ion_dev/
+ccflags-y += -Idrivers/staging/android/
+
+ccflags-y += -Wno-declaration-after-statement
diff --git a/drivers/amlogic/media/gdc/app/gdc_main.c b/drivers/amlogic/media/gdc/app/gdc_main.c
new file mode 100644 (file)
index 0000000..6b43d73
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * drivers/amlogic/media/gdc/app/gdc_main.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include "system_log.h"
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+//gdc api functions
+#include "gdc_api.h"
+
+irqreturn_t interrupt_handler_next(int irq, void *param)
+{
+       //handle the start of frame with gdc_process
+       struct gdc_settings *gdc_settings = (struct gdc_settings *)param;
+
+       gdc_get_frame(gdc_settings);
+
+       return IRQ_HANDLED;
+}
+
+int gdc_run(struct gdc_settings *g)
+{
+
+       gdc_stop(g);
+
+       LOG(LOG_INFO, "Done gdc load..\n");
+
+       //initialise the gdc by the first configuration
+       if (gdc_init(g) != 0) {
+               LOG(LOG_ERR, "Failed to initialise GDC block");
+               return -1;
+       }
+
+       LOG(LOG_INFO, "Done gdc config..\n");
+
+       //start gdc process with input address for y and uv planes
+       if (g->gdc_config.format == NV12) {
+               gdc_process(g,
+                               (uint32_t)g->y_base_addr,
+                               (uint32_t)g->uv_base_addr);
+       } else {
+               gdc_process_yuv420p(g, (uint32_t)g->y_base_addr,
+                               (uint32_t)g->u_base_addr,
+                               (uint32_t)g->v_base_addr);
+       }
+       LOG(LOG_DEBUG, "call gdc process\n");
+
+       return 0;
+}
diff --git a/drivers/amlogic/media/gdc/app/gdc_module.c b/drivers/amlogic/media/gdc/app/gdc_module.c
new file mode 100644 (file)
index 0000000..b0de1c6
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * drivers/amlogic/media/gdc/app/gdc_module.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/uio_driver.h>
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/uaccess.h>
+#include <meson_ion.h>
+#include <linux/delay.h>
+
+#include <linux/of_address.h>
+#include <api/gdc_api.h>
+#include "system_log.h"
+
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+//gdc configuration sequence
+#include "gdc_config.h"
+
+struct meson_gdc_dev_t *g_gdc_dev;
+
+static const struct of_device_id gdc_dt_match[] = {
+       {.compatible = "amlogic, g12b-gdc"},
+       {} };
+
+MODULE_DEVICE_TABLE(of, gdc_dt_match);
+
+//////
+static int meson_gdc_open(struct inode *inode, struct file *file)
+{
+       struct meson_gdc_dev_t *gdc_dev = g_gdc_dev;
+       struct platform_device *pdev = gdc_dev->pdev;
+       struct mgdc_fh_s *fh = NULL;
+       char ion_client_name[32];
+       int rc = 0;
+
+       fh = devm_kzalloc(&pdev->dev, sizeof(*fh), GFP_KERNEL);
+       if (fh == NULL) {
+               LOG(LOG_DEBUG, "devm alloc failed\n");
+               return -ENOMEM;
+       }
+
+       get_task_comm(fh->task_comm, current);
+       LOG(LOG_DEBUG, "%s, %d, call from %s\n",
+                       __func__, __LINE__, fh->task_comm);
+
+       file->private_data = fh;
+       snprintf(ion_client_name, sizeof(fh->task_comm),
+                       "gdc-%s", fh->task_comm);
+       if (!fh->ion_client)
+               fh->ion_client = meson_ion_client_create(-1, ion_client_name);
+
+       fh->gdev = gdc_dev;
+       init_waitqueue_head(&fh->irq_queue);
+
+       rc = devm_request_irq(&pdev->dev, gdc_dev->irq, interrupt_handler_next,
+                       IRQF_SHARED, "gdc", &fh->gs);
+       if (rc)
+               LOG(LOG_DEBUG, "cannot create irq func gdc\n");
+
+       return rc;
+}
+
+static int meson_gdc_release(struct inode *inode, struct file *file)
+{
+       struct mgdc_fh_s *fh = file->private_data;
+       struct meson_gdc_dev_t *gdc_dev = fh->gdev;
+       struct platform_device *pdev = gdc_dev->pdev;
+
+       LOG(LOG_DEBUG, "%s, %d\n", __func__, __LINE__);
+       if (fh->ion_client) {
+               ion_client_destroy(fh->ion_client);
+               fh->ion_client = NULL;
+       }
+
+       devm_free_irq(&pdev->dev,  gdc_dev->irq, &fh->gs);
+
+       return 0;
+}
+
+static long meson_gdc_ioctl(struct file *file, unsigned int cmd,
+               unsigned long arg)
+{
+       size_t len;
+       struct mgdc_fh_s *fh = file->private_data;
+       struct gdc_settings  *gs = &fh->gs;
+       struct gdc_config *gc = &gs->gdc_config;
+       long ret = 0;
+       ion_phys_addr_t addr;
+       void __user *argp = (void __user *)arg;
+
+       gs->fh = fh;
+
+       switch (cmd) {
+       case GDC_PROCESS:
+               ret = copy_from_user(gs, argp, sizeof(*gs));
+               if (ret < 0)
+                       LOG(LOG_DEBUG, "copy from user failed\n");
+
+               LOG(LOG_DEBUG, "sizeof(gs)=%ld, magic=%d\n",
+                               sizeof(*gs), gs->magic);
+
+               //configure gdc config, buffer address and resolution
+               ret = meson_ion_share_fd_to_phys(fh->ion_client,
+                               gs->out_fd, &addr, &len);
+
+               gs->buffer_addr = addr;
+               gs->buffer_size = len;
+
+               if (ret < 0)
+                       LOG(LOG_DEBUG, "import out fd %d failed\n", gs->out_fd);
+               gs->base_gdc = 0;
+               gs->current_addr = gs->buffer_addr;
+
+               ret = meson_ion_share_fd_to_phys(fh->ion_client,
+                               gc->config_addr, &addr, &len);
+
+               gc->config_addr = addr;
+
+               ret = meson_ion_share_fd_to_phys(fh->ion_client,
+                               gs->in_fd, &addr, &len);
+               if (gc->format == NV12) {
+                       gs->y_base_addr = addr;
+                       gs->uv_base_addr = addr +
+                               gc->input_y_stride * gc->input_height;
+               } else if (gc->format == YV12) {
+                       gs->y_base_addr = addr;
+                       gs->u_base_addr = addr
+                               + gc->input_y_stride * gc->input_height;
+
+                       gs->v_base_addr = gs->u_base_addr +
+                               gc->input_c_stride * gc->input_height / 2;
+               }
+
+               if (ret < 0)
+                       LOG(LOG_DEBUG, "import in fd %d failed\n", gs->in_fd);
+
+               gs->fh = fh;
+               ret = gdc_run(gs);
+               if (ret < 0)
+                       LOG(LOG_DEBUG, "gdc process ret = %ld\n", ret);
+
+               ret = wait_event_interruptible_timeout(fh->irq_queue,
+                               (gdc_busy_read() == 0),
+                               msecs_to_jiffies(30));
+               break;
+
+       default:
+               pr_info("unsupported cmd 0x%x\n", cmd);
+               break;
+       }
+
+       return ret;
+}
+
+static const struct file_operations meson_gdc_fops = {
+       .owner = THIS_MODULE,
+       .open = meson_gdc_open,
+       .release = meson_gdc_release,
+       .unlocked_ioctl = meson_gdc_ioctl,
+       .compat_ioctl = meson_gdc_ioctl,
+};
+
+static struct miscdevice meson_gdc_dev = {
+       .minor  = MISC_DYNAMIC_MINOR,
+       .name   = "gdc",
+       .fops   = &meson_gdc_fops,
+};
+
+static ssize_t gdc_reg_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       ssize_t len = 0;
+       int i;
+
+       len += sprintf(buf+len, "gdc adapter register below\n");
+       for (i = 0; i <= 0xff; i += 4) {
+               len += sprintf(buf+len, "\t[0xff950000 + 0x%08x, 0x%-8x\n",
+                                               i, system_gdc_read_32(i));
+       }
+
+       return len;
+}
+
+static ssize_t gdc_reg_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t len)
+{
+       LOG(LOG_DEBUG, "%s, %d\n", __func__, __LINE__);
+       return len;
+}
+static DEVICE_ATTR(gdc_reg, 0554, gdc_reg_show, gdc_reg_store);
+
+static ssize_t firmware1_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       LOG(LOG_DEBUG, "%s, %d\n", __func__, __LINE__);
+       return 1;
+}
+
+static ssize_t firmware1_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t len)
+{
+       LOG(LOG_DEBUG, "%s, %d\n", __func__, __LINE__);
+       //gdc_fw_init();
+       return 1;
+}
+static DEVICE_ATTR(firmware1, 0664, firmware1_show, firmware1_store);
+
+
+static int gdc_platform_probe(struct platform_device *pdev)
+{
+       struct resource *gdc_res;
+       struct meson_gdc_dev_t *gdc_dev = NULL;
+       void *clk_cntl = NULL;
+       void *pd_cntl = NULL;
+       uint32_t reg_value = 0;
+
+       // Initialize irq
+       gdc_res = platform_get_resource(pdev,
+                       IORESOURCE_MEM, 0);
+       if (!gdc_res) {
+               LOG(LOG_ERR, "Error, no IORESOURCE_MEM DT!\n");
+               return -ENOMEM;
+       }
+
+       if (init_gdc_io(pdev->dev.of_node) != 0) {
+               LOG(LOG_ERR, "Error on mapping gdc memory!\n");
+               return -ENOMEM;
+       }
+
+       device_create_file(&pdev->dev, &dev_attr_gdc_reg);
+       device_create_file(&pdev->dev, &dev_attr_firmware1);
+
+       gdc_dev = devm_kzalloc(&pdev->dev, sizeof(*gdc_dev),
+                       GFP_KERNEL);
+
+       if (gdc_dev == NULL) {
+               LOG(LOG_DEBUG, "devm alloc gdc dev failed\n");
+               return -ENOMEM;
+       }
+
+       gdc_dev->pdev = pdev;
+       spin_lock_init(&gdc_dev->slock);
+
+       gdc_dev->irq = platform_get_irq(pdev, 0);
+       if (gdc_dev->irq < 0) {
+               LOG(LOG_DEBUG, "cannot find irq for gdc\n");
+               return -EINVAL;
+       }
+
+#if 0
+       gdc_dev->clk_core = devm_clk_get(&pdev->dev, "core");
+       rc = clk_set_rate(gdc_dev->clk_core, 800000000);
+
+       gdc_dev->clk_axi = devm_clk_get(&pdev->dev, "axi");
+       rc = clk_set_rate(gdc_dev->clk_axi, 800000000);
+#else
+       clk_cntl = of_iomap(pdev->dev.of_node, 1);
+       iowrite32((3<<25)|(1<<24)|(0<<16)|(3<<9)|(1<<8)|(0<<0), clk_cntl);
+       pd_cntl = of_iomap(pdev->dev.of_node, 2);
+       reg_value = ioread32(pd_cntl);
+       LOG(LOG_DEBUG, "pd_cntl=%x\n", reg_value);
+       reg_value = reg_value & (~(3<<18));
+       LOG(LOG_DEBUG, "pd_cntl=%x\n", reg_value);
+       iowrite32(reg_value, pd_cntl);
+#endif
+
+       g_gdc_dev = gdc_dev;
+
+       return misc_register(&meson_gdc_dev);
+}
+
+static int gdc_platform_remove(struct platform_device *pdev)
+{
+
+       device_remove_file(&pdev->dev, &dev_attr_gdc_reg);
+       device_remove_file(&pdev->dev, &dev_attr_firmware1);
+
+       misc_deregister(&meson_gdc_dev);
+       return 0;
+}
+
+static struct platform_driver gdc_platform_driver = {
+       .driver = {
+               .name = "gdc",
+               .owner = THIS_MODULE,
+               .of_match_table = gdc_dt_match,
+       },
+       .probe  = gdc_platform_probe,
+       .remove = gdc_platform_remove,
+};
+
+module_platform_driver(gdc_platform_driver);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Amlogic Multimedia");
diff --git a/drivers/amlogic/media/gdc/inc/api/gdc_api.h b/drivers/amlogic/media/gdc/inc/api/gdc_api.h
new file mode 100644 (file)
index 0000000..2648666
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * drivers/amlogic/media/gdc/inc/api/gdc_api.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __GDC_API_H__
+#define __GDC_API_H__
+
+#include <linux/of_address.h>
+
+#define NV12 1
+#define YV12 2
+
+// each configuration addresses and size
+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
+};
+
+// overall gdc settings and state
+struct gdc_settings {
+       uint32_t magic;
+       //writing/reading to gdc base address, currently not read by api
+       uint32_t base_gdc;
+        //array of gdc configuration and sizes
+       struct gdc_config gdc_config;
+       //update this index for new config
+       //int gdc_config_total;
+       //start memory to write gdc output framse
+       uint32_t buffer_addr;
+       //size of memory output frames to determine
+       //if it is enough and can do multiple write points
+       uint32_t buffer_size;
+       //current output address of gdc
+       uint32_t current_addr;
+       //set when expecting an interrupt from gdc
+       int32_t is_waiting_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;
+       //opaque address in ddr added with offset to
+       //write the gdc config sequence
+       void *ddr_mem;
+       //when inititialised this callback will be called
+       //to update frame buffer addresses and offsets
+       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;
+};
+
+#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)
+/**
+ *   Configure the output gdc configuration
+ *
+ *   address/size and buffer address/size; and resolution.
+ *
+ *   More than one gdc settings can be accessed by index to a gdc_config_t.
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *   @param  gdc_config_num - selects the current gdc config to be applied
+ *
+ *   @return 0 - success
+ *      -1 - fail.
+ */
+int gdc_init(struct gdc_settings *gdc_settings);
+/**
+ *   This function stops the gdc block
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ */
+void gdc_stop(struct gdc_settings *gdc_settings);
+
+/**
+ *   This function starts the gdc block
+ *
+ *   Writing 0->1 transition is necessary for trigger
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ */
+void gdc_start(struct gdc_settings *gdc_settings);
+
+/**
+ *   This function points gdc to
+ *
+ *   its input resolution and yuv address and offsets
+ *
+ *   Shown inputs to GDC are Y and UV plane address and offsets
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *   @param  active_width -  input width resolution
+ *   @param  active_height - input height resolution
+ *   @param  y_base_addr -  input Y base address
+ *   @param  uv_base_addr - input UV base address
+ *   @param  y_line_offset - input Y line buffer offset
+ *   @param  uv_line_offset-  input UV line buffer offer
+ *
+ *   @return 0 - success
+ *      -1 - no interrupt from GDC.
+ */
+int gdc_process(struct gdc_settings *gdc_settings,
+               uint32_t y_base_addr,
+               uint32_t uv_base_addr);
+int gdc_process_yuv420p(struct gdc_settings *gdc_settings,
+               uint32_t y_base_addr,
+               uint32_t u_base_addr,
+               uint32_t v_base_addr);
+/**
+ *   This function gets the GDC output frame addresses
+ *
+ *   and offsets and updates the frame buffer via callback
+ *
+ *   if it is available Shown ouputs to GDC are
+ *
+ *   Y and UV plane address and offsets
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ *   @return 0 - success
+ *      -1 - unexpected interrupt from GDC.
+ */
+int gdc_get_frame(struct gdc_settings *gdc_settings);
+
+/**
+ *   This function points gdc to its input resolution
+ *
+ *   and yuv address and offsets
+ *
+ *   Shown inputs to GDC are Y and UV plane address and offsets
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ *   @return 0 - success
+ *      -1 - no interrupt from GDC.
+ */
+int gdc_run(struct gdc_settings *g);
+
+int32_t init_gdc_io(struct device_node *dn);
+
+#endif
diff --git a/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h b/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h
new file mode 100644 (file)
index 0000000..01fd6bc
--- /dev/null
@@ -0,0 +1,1890 @@
+/*
+ * drivers/amlogic/media/gdc/inc/gdc/gdc_config.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __GDC_CONFIG_H__
+#define __GDC_CONFIG_H__
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include "system_gdc_io.h"
+#include "gdc_api.h"
+
+struct gdc_settings;
+struct meson_gdc_dev_t {
+       struct platform_device *pdev;
+       void    *reg_base;
+       struct clk      *clk_core;
+       struct clk      *clk_axi;
+       spinlock_t      slock;
+       int      irq;
+};
+
+struct mgdc_fh_s {
+       struct list_head list;
+       wait_queue_head_t       irq_queue;
+       struct meson_gdc_dev_t *gdev;
+       char task_comm[32];
+       struct ion_client   *ion_client;
+       struct gdc_settings gs;
+};
+
+irqreturn_t interrupt_handler_next(int irq, void *param);
+// ----------------------------------- //
+// Instance 'gdc' of module 'gdc_ip_config'
+// ----------------------------------- //
+
+#define GDC_BASE_ADDR (0x00L)
+#define GDC_SIZE (0x100)
+
+// ----------------------------------- //
+// Group: ID
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Register: API
+// ----------------------------------- //
+
+#define GDC_ID_API_DEFAULT (0x0)
+#define GDC_ID_API_DATASIZE (32)
+#define GDC_ID_API_OFFSET (0x0)
+#define GDC_ID_API_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_id_api_read(void)
+{
+       return system_gdc_read_32(0x00L);
+}
+// ----------------------------------- //
+// Register: Product
+// ----------------------------------- //
+
+#define GDC_ID_PRODUCT_DEFAULT (0x0)
+#define GDC_ID_PRODUCT_DATASIZE (32)
+#define GDC_ID_PRODUCT_OFFSET (0x4)
+#define GDC_ID_PRODUCT_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_id_product_read(void)
+{
+       return system_gdc_read_32(0x04L);
+}
+// ----------------------------------- //
+// Register: Version
+// ----------------------------------- //
+
+#define GDC_ID_VERSION_DEFAULT (0x0)
+#define GDC_ID_VERSION_DATASIZE (32)
+#define GDC_ID_VERSION_OFFSET (0x8)
+#define GDC_ID_VERSION_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_id_version_read(void)
+{
+       return system_gdc_read_32(0x08L);
+}
+// ----------------------------------- //
+// Register: Revision
+// ----------------------------------- //
+
+#define GDC_ID_REVISION_DEFAULT (0x0)
+#define GDC_ID_REVISION_DATASIZE (32)
+#define GDC_ID_REVISION_OFFSET (0xc)
+#define GDC_ID_REVISION_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_id_revision_read(void)
+{
+       return system_gdc_read_32(0x0cL);
+}
+// ----------------------------------- //
+// Group: GDC
+// ----------------------------------- //
+// ----------------------------------- //
+// GDC controls
+// ----------------------------------- //
+// ----------------------------------- //
+// Register: config addr
+// ----------------------------------- //
+// ----------------------------------- //
+// Base address of configuration stream
+// (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_CONFIG_ADDR_DEFAULT (0x0)
+#define GDC_CONFIG_ADDR_DATASIZE (32)
+#define GDC_CONFIG_ADDR_OFFSET (0x10)
+#define GDC_CONFIG_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_config_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x10L, data);
+}
+static inline uint32_t gdc_config_addr_read(void)
+{
+       return system_gdc_read_32(0x10L);
+}
+// ----------------------------------- //
+// Register: config size
+// ----------------------------------- //
+// ----------------------------------- //
+// Size of the configuration stream    //
+// (in bytes, 32 bit word granularity) //
+// ----------------------------------- //
+
+#define GDC_CONFIG_SIZE_DEFAULT (0x0)
+#define GDC_CONFIG_SIZE_DATASIZE (32)
+#define GDC_CONFIG_SIZE_OFFSET (0x14)
+#define GDC_CONFIG_SIZE_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_config_size_write(uint32_t data)
+{
+       system_gdc_write_32(0x14L, data);
+}
+static inline uint32_t gdc_config_size_read(void)
+{
+       return system_gdc_read_32(0x14L);
+}
+// ----------------------------------- //
+// Register: datain width
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Width of the input image (in pixels)
+// ----------------------------------- //
+
+#define GDC_DATAIN_WIDTH_DEFAULT (0x0)
+#define GDC_DATAIN_WIDTH_DATASIZE (16)
+#define GDC_DATAIN_WIDTH_OFFSET (0x20)
+#define GDC_DATAIN_WIDTH_MASK (0xffff)
+
+// args: data (16-bit)
+static inline void gdc_datain_width_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x20L);
+
+       system_gdc_write_32(0x20L, ((curr & 0xffff0000) | data));
+}
+static inline uint16_t gdc_datain_width_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x20L) & 0xffff) >> 0);
+}
+// ----------------------------------- //
+// Register: datain_height
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Height of the input image (in pixels)
+// ----------------------------------- //
+
+#define GDC_DATAIN_HEIGHT_DEFAULT (0x0)
+#define GDC_DATAIN_HEIGHT_DATASIZE (16)
+#define GDC_DATAIN_HEIGHT_OFFSET (0x24)
+#define GDC_DATAIN_HEIGHT_MASK (0xffff)
+
+// args: data (16-bit)
+static inline void gdc_datain_height_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x24L);
+
+       system_gdc_write_32(0x24L, ((curr & 0xffff0000) | data));
+}
+static inline uint16_t gdc_datain_height_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x24L) & 0xffff) >> 0);
+}
+// ----------------------------------- //
+// Register: data1in addr
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Base address of the 1st plane in the
+// input frame buffer
+// (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA1IN_ADDR_DEFAULT (0x0)
+#define GDC_DATA1IN_ADDR_DATASIZE (32)
+#define GDC_DATA1IN_ADDR_OFFSET (0x28)
+#define GDC_DATA1IN_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data1in_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x28L, data);
+}
+static inline uint32_t gdc_data1in_addr_read(void)
+{
+       return system_gdc_read_32(0x28L);
+}
+// ----------------------------------- //
+// Register: data1in line offset
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address difference between adjacent
+// lines for the 1st plane in the input
+// frame buffer (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA1IN_LINE_OFFSET_DEFAULT (0x0)
+#define GDC_DATA1IN_LINE_OFFSET_DATASIZE (32)
+#define GDC_DATA1IN_LINE_OFFSET_OFFSET (0x2c)
+#define GDC_DATA1IN_LINE_OFFSET_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data1in_line_offset_write(uint32_t data)
+{
+       system_gdc_write_32(0x2cL, data);
+}
+static inline uint32_t gdc_data1in_line_offset_read(void)
+{
+       return system_gdc_read_32(0x2cL);
+}
+// ----------------------------------- //
+// Register: data2in addr
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address of the 2nd plane in the
+// input frame buffer
+// (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA2IN_ADDR_DEFAULT (0x0)
+#define GDC_DATA2IN_ADDR_DATASIZE (32)
+#define GDC_DATA2IN_ADDR_OFFSET (0x30)
+#define GDC_DATA2IN_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data2in_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x30L, data);
+}
+static inline uint32_t gdc_data2in_addr_read(void)
+{
+       return system_gdc_read_32(0x30L);
+}
+// ----------------------------------- //
+// Register: data2in line offset
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address difference between adjacent
+// lines for the 2nd plane in the input
+// frame buffer (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA2IN_LINE_OFFSET_DEFAULT (0x0)
+#define GDC_DATA2IN_LINE_OFFSET_DATASIZE (32)
+#define GDC_DATA2IN_LINE_OFFSET_OFFSET (0x34)
+#define GDC_DATA2IN_LINE_OFFSET_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data2in_line_offset_write(uint32_t data)
+{
+       system_gdc_write_32(0x34L, data);
+}
+static inline uint32_t gdc_data2in_line_offset_read(void)
+{
+       return system_gdc_read_32(0x34L);
+}
+// ----------------------------------- //
+// Register: data3in addr
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Base address of the 3rd plane in the
+// input frame buffer
+// (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA3IN_ADDR_DEFAULT (0x0)
+#define GDC_DATA3IN_ADDR_DATASIZE (32)
+#define GDC_DATA3IN_ADDR_OFFSET (0x38)
+#define GDC_DATA3IN_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data3in_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x38L, data);
+}
+static inline uint32_t gdc_data3in_addr_read(void)
+{
+       return system_gdc_read_32(0x38L);
+}
+// ----------------------------------- //
+// Register: data3in line offset
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address difference between adjacent
+// lines for the 3rd plane in the
+// input frame buffer (in bytes,
+// AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA3IN_LINE_OFFSET_DEFAULT (0x0)
+#define GDC_DATA3IN_LINE_OFFSET_DATASIZE (32)
+#define GDC_DATA3IN_LINE_OFFSET_OFFSET (0x3c)
+#define GDC_DATA3IN_LINE_OFFSET_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data3in_line_offset_write(uint32_t data)
+{
+       system_gdc_write_32(0x3cL, data);
+}
+static inline uint32_t gdc_data3in_line_offset_read(void)
+{
+       return system_gdc_read_32(0x3cL);
+}
+// ----------------------------------- //
+// Register: dataout width
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Width of the output image (in pixels)
+// ----------------------------------- //
+
+#define GDC_DATAOUT_WIDTH_DEFAULT (0x0)
+#define GDC_DATAOUT_WIDTH_DATASIZE (16)
+#define GDC_DATAOUT_WIDTH_OFFSET (0x40)
+#define GDC_DATAOUT_WIDTH_MASK (0xffff)
+
+// args: data (16-bit)
+static inline void gdc_dataout_width_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x40L);
+
+       system_gdc_write_32(0x40L, ((curr & 0xffff0000) | data));
+}
+static inline uint16_t gdc_dataout_width_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x40L) & 0xffff) >> 0);
+}
+// ----------------------------------- //
+// Register: dataout height
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Height of the output image (in pixels)
+// ----------------------------------- //
+
+#define GDC_DATAOUT_HEIGHT_DEFAULT (0x0)
+#define GDC_DATAOUT_HEIGHT_DATASIZE (16)
+#define GDC_DATAOUT_HEIGHT_OFFSET (0x44)
+#define GDC_DATAOUT_HEIGHT_MASK (0xffff)
+
+// args: data (16-bit)
+static inline void gdc_dataout_height_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x44L);
+
+       system_gdc_write_32(0x44L, ((curr & 0xffff0000) | data));
+}
+static inline uint16_t gdc_dataout_height_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x44L) & 0xffff) >> 0);
+}
+// ----------------------------------- //
+// Register: data1out addr
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Base address of the 1st plane in the
+// output frame buffer
+// (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA1OUT_ADDR_DEFAULT (0x0)
+#define GDC_DATA1OUT_ADDR_DATASIZE (32)
+#define GDC_DATA1OUT_ADDR_OFFSET (0x48)
+#define GDC_DATA1OUT_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data1out_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x48L, data);
+}
+static inline uint32_t gdc_data1out_addr_read(void)
+{
+       return system_gdc_read_32(0x48L);
+}
+// ----------------------------------- //
+// Register: data1out line offset
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address difference between adjacent
+// lines for the 1st plane in the
+// output frame buffer (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA1OUT_LINE_OFFSET_DEFAULT (0x0)
+#define GDC_DATA1OUT_LINE_OFFSET_DATASIZE (32)
+#define GDC_DATA1OUT_LINE_OFFSET_OFFSET (0x4c)
+#define GDC_DATA1OUT_LINE_OFFSET_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data1out_line_offset_write(uint32_t data)
+{
+       system_gdc_write_32(0x4cL, data);
+}
+static inline uint32_t gdc_data1out_line_offset_read(void)
+{
+       return system_gdc_read_32(0x4cL);
+}
+// ----------------------------------- //
+// Register: data2out addr
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Base address of the 2nd plane in the
+// output frame buffer  (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA2OUT_ADDR_DEFAULT (0x0)
+#define GDC_DATA2OUT_ADDR_DATASIZE (32)
+#define GDC_DATA2OUT_ADDR_OFFSET (0x50)
+#define GDC_DATA2OUT_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data2out_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x50L, data);
+}
+static inline uint32_t gdc_data2out_addr_read(void)
+{
+       return system_gdc_read_32(0x50L);
+}
+// ----------------------------------- //
+// Register: data2out line offset
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address difference between adjacent lines
+// for the 2ndt plane in the
+// output frame buffer (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA2OUT_LINE_OFFSET_DEFAULT (0x0)
+#define GDC_DATA2OUT_LINE_OFFSET_DATASIZE (32)
+#define GDC_DATA2OUT_LINE_OFFSET_OFFSET (0x54)
+#define GDC_DATA2OUT_LINE_OFFSET_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data2out_line_offset_write(uint32_t data)
+{
+       system_gdc_write_32(0x54L, data);
+}
+static inline uint32_t gdc_data2out_line_offset_read(void)
+{
+       return system_gdc_read_32(0x54L);
+}
+// ----------------------------------- //
+// Register: data3out addr
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Base address of the 3rd plane in the
+// output frame buffer  (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA3OUT_ADDR_DEFAULT (0x0)
+#define GDC_DATA3OUT_ADDR_DATASIZE (32)
+#define GDC_DATA3OUT_ADDR_OFFSET (0x58)
+#define GDC_DATA3OUT_ADDR_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data3out_addr_write(uint32_t data)
+{
+       system_gdc_write_32(0x58L, data);
+}
+static inline uint32_t gdc_data3out_addr_read(void)
+{
+       return system_gdc_read_32(0x58L);
+}
+// ----------------------------------- //
+// Register: data3out line offset
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Address difference between adjacent
+// lines for the 3rd plane in the
+// output frame buffer (in bytes, AXI word aligned)
+// ----------------------------------- //
+
+#define GDC_DATA3OUT_LINE_OFFSET_DEFAULT (0x0)
+#define GDC_DATA3OUT_LINE_OFFSET_DATASIZE (32)
+#define GDC_DATA3OUT_LINE_OFFSET_OFFSET (0x5c)
+#define GDC_DATA3OUT_LINE_OFFSET_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_data3out_line_offset_write(uint32_t data)
+{
+       system_gdc_write_32(0x5cL, data);
+}
+static inline uint32_t gdc_data3out_line_offset_read(void)
+{
+       return system_gdc_read_32(0x5cL);
+}
+// ----------------------------------- //
+// Register: status
+// ----------------------------------- //
+
+// ----------------------------------- //
+// word with status fields:
+// ----------------------------------- //
+
+#define GDC_STATUS_DEFAULT (0x0)
+#define GDC_STATUS_DATASIZE (32)
+#define GDC_STATUS_OFFSET (0x60)
+#define GDC_STATUS_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_status_read(void)
+{
+       return system_gdc_read_32(0x60L);
+}
+// ----------------------------------- //
+// Register: busy
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Busy 1 = processing in progress,
+//       0 = ready for next image
+// ----------------------------------- //
+
+#define GDC_BUSY_DEFAULT (0x0)
+#define GDC_BUSY_DATASIZE (1)
+#define GDC_BUSY_OFFSET (0x60)
+#define GDC_BUSY_MASK (0x1)
+
+// args: data (1-bit)
+static inline void gdc_busy_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+
+       system_gdc_write_32(0x60L, ((data & 0x1) << 0) | (curr & 0xfffffffe));
+}
+static inline uint8_t gdc_busy_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x1) >> 0);
+}
+// ----------------------------------- //
+// Register: error
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Error flag: last operation was finished with error (see bits 15:8)
+// ----------------------------------- //
+
+#define GDC_ERROR_DEFAULT (0x0)
+#define GDC_ERROR_DATASIZE (1)
+#define GDC_ERROR_OFFSET (0x60)
+#define GDC_ERROR_MASK (0x2)
+
+// args: data (1-bit)
+static inline void gdc_error_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x1) << 1) | (curr & 0xfffffffd);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_error_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x2) >> 1);
+}
+// ----------------------------------- //
+// Register: Reserved for future use 1
+// ----------------------------------- //
+
+#define GDC_RESERVED_FOR_FUTURE_USE_1_DEFAULT (0x0)
+#define GDC_RESERVED_FOR_FUTURE_USE_1_DATASIZE (6)
+#define GDC_RESERVED_FOR_FUTURE_USE_1_OFFSET (0x60)
+#define GDC_RESERVED_FOR_FUTURE_USE_1_MASK (0xfc)
+
+// args: data (6-bit)
+static inline void gdc_reserved_for_future_use_1_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x3f) << 2) | (curr & 0xffffff03);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_reserved_for_future_use_1_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0xfc) >> 2);
+}
+// ----------------------------------- //
+// Register: configuration error
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Configuration error (wrong configuration stream)
+// ----------------------------------- //
+
+#define GDC_CONFIGURATION_ERROR_DEFAULT (0x0)
+#define GDC_CONFIGURATION_ERROR_DATASIZE (1)
+#define GDC_CONFIGURATION_ERROR_OFFSET (0x60)
+#define GDC_CONFIGURATION_ERROR_MASK (0x100)
+
+// args: data (1-bit)
+static inline void gdc_configuration_error_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val =  ((data & 0x1) << 8) | (curr & 0xfffffeff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_configuration_error_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x100) >> 8);
+}
+// ----------------------------------- //
+// Register: user abort
+// ----------------------------------- //
+
+// ----------------------------------- //
+// User abort (stop/reset command)
+// ----------------------------------- //
+
+#define GDC_USER_ABORT_DEFAULT (0x0)
+#define GDC_USER_ABORT_DATASIZE (1)
+#define GDC_USER_ABORT_OFFSET (0x60)
+#define GDC_USER_ABORT_MASK (0x200)
+
+// args: data (1-bit)
+static inline void gdc_user_abort_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x1) << 9) | (curr & 0xfffffdff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_user_abort_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x200) >> 9);
+}
+// ----------------------------------- //
+// Register: AXI reader error
+// ----------------------------------- //
+
+// ----------------------------------- //
+// AXI reader error (e.g. error code returned by fabric)
+// ----------------------------------- //
+
+#define GDC_AXI_READER_ERROR_DEFAULT (0x0)
+#define GDC_AXI_READER_ERROR_DATASIZE (1)
+#define GDC_AXI_READER_ERROR_OFFSET (0x60)
+#define GDC_AXI_READER_ERROR_MASK (0x400)
+
+// args: data (1-bit)
+static inline void gdc_axi_reader_error_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x1) << 10) | (curr & 0xfffffbff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_axi_reader_error_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x400) >> 10);
+}
+// ----------------------------------- //
+// Register: AXI writer error
+// ----------------------------------- //
+
+// ----------------------------------- //
+// AXI writer error
+// ----------------------------------- //
+
+#define GDC_AXI_WRITER_ERROR_DEFAULT (0x0)
+#define GDC_AXI_WRITER_ERROR_DATASIZE (1)
+#define GDC_AXI_WRITER_ERROR_OFFSET (0x60)
+#define GDC_AXI_WRITER_ERROR_MASK (0x800)
+
+// args: data (1-bit)
+static inline void gdc_axi_writer_error_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x1) << 11) | (curr & 0xfffff7ff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_axi_writer_error_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x800) >> 11);
+}
+// ----------------------------------- //
+// Register: Unaligned access
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Unaligned access (address pointer is not aligned)
+// ----------------------------------- //
+
+#define GDC_UNALIGNED_ACCESS_DEFAULT (0x0)
+#define GDC_UNALIGNED_ACCESS_DATASIZE (1)
+#define GDC_UNALIGNED_ACCESS_OFFSET (0x60)
+#define GDC_UNALIGNED_ACCESS_MASK (0x1000)
+
+// args: data (1-bit)
+static inline void gdc_unaligned_access_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x1) << 12) | (curr & 0xffffefff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_unaligned_access_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x1000) >> 12);
+}
+// ----------------------------------- //
+// Register: Incompatible configuration
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Incompatible configuration (request
+// of unimplemented mode of operation,
+// e.g. unsupported image format,
+// unsupported module mode in the configuration stream)
+// ----------------------------------- //
+
+#define GDC_INCOMPATIBLE_CONFIGURATION_DEFAULT (0x0)
+#define GDC_INCOMPATIBLE_CONFIGURATION_DATASIZE (1)
+#define GDC_INCOMPATIBLE_CONFIGURATION_OFFSET (0x60)
+#define GDC_INCOMPATIBLE_CONFIGURATION_MASK (0x2000)
+
+// args: data (1-bit)
+static inline void gdc_incompatible_configuration_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val = ((data & 0x1) << 13) | (curr & 0xffffdfff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint8_t gdc_incompatible_configuration_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x60L) & 0x2000) >> 13);
+}
+// ----------------------------------- //
+// Register: Reserved for future use 2
+// ----------------------------------- //
+
+#define GDC_RESERVED_FOR_FUTURE_USE_2_DEFAULT (0x0)
+#define GDC_RESERVED_FOR_FUTURE_USE_2_DATASIZE (18)
+#define GDC_RESERVED_FOR_FUTURE_USE_2_OFFSET (0x60)
+#define GDC_RESERVED_FOR_FUTURE_USE_2_MASK (0xffffc000)
+
+// args: data (18-bit)
+static inline void gdc_reserved_for_future_use_2_write(uint32_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x60L);
+       uint32_t val =  ((data & 0x3ffff) << 14) | (curr & 0x3fff);
+
+       system_gdc_write_32(0x60L, val);
+}
+static inline uint32_t gdc_reserved_for_future_use_2_read(void)
+{
+       return (uint32_t)((system_gdc_read_32(0x60L) & 0xffffc000) >> 14);
+}
+// ----------------------------------- //
+// Register: config
+// ----------------------------------- //
+
+#define GDC_CONFIG_DEFAULT (0x0)
+#define GDC_CONFIG_DATASIZE (32)
+#define GDC_CONFIG_OFFSET (0x64)
+#define GDC_CONFIG_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline void gdc_config_write(uint32_t data)
+{
+       system_gdc_write_32(0x64L, data);
+}
+static inline uint32_t gdc_config_read(void)
+{
+       return system_gdc_read_32(0x64L);
+}
+// ----------------------------------- //
+// Register: start flag
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Start flag: transition from 0 to 1
+// latches the data on the configuration ports
+// and starts the processing
+// ----------------------------------- //
+
+#define GDC_START_FLAG_DEFAULT (0x0)
+#define GDC_START_FLAG_DATASIZE (1)
+#define GDC_START_FLAG_OFFSET (0x64)
+#define GDC_START_FLAG_MASK (0x1)
+
+// args: data (1-bit)
+static inline void gdc_start_flag_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x64L);
+       uint32_t val = ((data & 0x1) << 0) | (curr & 0xfffffffe);
+
+       system_gdc_write_32(0x64L, val);
+}
+static inline uint8_t gdc_start_flag_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x64L) & 0x1) >> 0);
+}
+// ----------------------------------- //
+// Register: stop flag
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Stop/reset flag: 0 - normal operation,
+// 1 means to initiate internal cleanup procedure
+// to abandon the current frame
+// and prepare for processing of the next frame.
+// The busy flag in status word should be
+// cleared at the end of this process
+// ----------------------------------- //
+
+#define GDC_STOP_FLAG_DEFAULT (0x0)
+#define GDC_STOP_FLAG_DATASIZE (1)
+#define GDC_STOP_FLAG_OFFSET (0x64)
+#define GDC_STOP_FLAG_MASK (0x2)
+
+// args: data (1-bit)
+static inline void gdc_stop_flag_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x64L);
+       uint32_t val = ((data & 0x1) << 1) | (curr & 0xfffffffd);
+
+       system_gdc_write_32(0x64L, val);
+}
+static inline uint8_t gdc_stop_flag_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x64L) & 0x2) >> 1);
+}
+// ----------------------------------- //
+// Register: Reserved for future use 3
+// ----------------------------------- //
+
+#define GDC_RESERVED_FOR_FUTURE_USE_3_DEFAULT (0x0)
+#define GDC_RESERVED_FOR_FUTURE_USE_3_DATASIZE (30)
+#define GDC_RESERVED_FOR_FUTURE_USE_3_OFFSET (0x64)
+#define GDC_RESERVED_FOR_FUTURE_USE_3_MASK (0xfffffffc)
+
+// args: data (30-bit)
+static inline void gdc_reserved_for_future_use_3_write(uint32_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x64L);
+       uint32_t val =  ((data & 0x3fffffff) << 2) | (curr & 0x3);
+
+       system_gdc_write_32(0x64L, val);
+}
+static inline uint32_t gdc_reserved_for_future_use_3_read(void)
+{
+       return (uint32_t)((system_gdc_read_32(0x64L) & 0xfffffffc) >> 2);
+}
+// ----------------------------------- //
+// Register: Capability mask
+// ----------------------------------- //
+
+#define GDC_CAPABILITY_MASK_DEFAULT (0x0)
+#define GDC_CAPABILITY_MASK_DATASIZE (32)
+#define GDC_CAPABILITY_MASK_OFFSET (0x68)
+#define GDC_CAPABILITY_MASK_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_capability_mask_read(void)
+{
+       return system_gdc_read_32(0x68L);
+}
+// ----------------------------------- //
+// Register: Eight bit data suppoirted
+// ----------------------------------- //
+
+// ----------------------------------- //
+// 8 bit data supported
+// ----------------------------------- //
+
+#define GDC_EIGHT_BIT_DATA_SUPPOIRTED_DEFAULT (0x0)
+#define GDC_EIGHT_BIT_DATA_SUPPOIRTED_DATASIZE (1)
+#define GDC_EIGHT_BIT_DATA_SUPPOIRTED_OFFSET (0x68)
+#define GDC_EIGHT_BIT_DATA_SUPPOIRTED_MASK (0x1)
+
+// args: data (1-bit)
+static inline void gdc_eight_bit_data_suppoirted_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x1) << 0) | (curr & 0xfffffffe);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_eight_bit_data_suppoirted_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x1) >> 0);
+}
+// ----------------------------------- //
+// Register: Ten bit data supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// 10 bit data supported
+// ----------------------------------- //
+
+#define GDC_TEN_BIT_DATA_SUPPORTED_DEFAULT (0x0)
+#define GDC_TEN_BIT_DATA_SUPPORTED_DATASIZE (1)
+#define GDC_TEN_BIT_DATA_SUPPORTED_OFFSET (0x68)
+#define GDC_TEN_BIT_DATA_SUPPORTED_MASK (0x2)
+
+// args: data (1-bit)
+static inline void gdc_ten_bit_data_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x1) << 1) | (curr & 0xfffffffd);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_ten_bit_data_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x2) >> 1);
+}
+// ----------------------------------- //
+// Register: Grayscale supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// grayscale supported
+// ----------------------------------- //
+
+#define GDC_GRAYSCALE_SUPPORTED_DEFAULT (0x0)
+#define GDC_GRAYSCALE_SUPPORTED_DATASIZE (1)
+#define GDC_GRAYSCALE_SUPPORTED_OFFSET (0x68)
+#define GDC_GRAYSCALE_SUPPORTED_MASK (0x4)
+
+// args: data (1-bit)
+static inline void gdc_grayscale_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x1) << 2) | (curr & 0xfffffffb);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_grayscale_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x4) >> 2);
+}
+// ----------------------------------- //
+// Register: RGBA888 supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// RGBA8:8:8/YUV4:4:4 mode supported
+// ----------------------------------- //
+
+#define GDC_RGBA888_SUPPORTED_DEFAULT (0x0)
+#define GDC_RGBA888_SUPPORTED_DATASIZE (1)
+#define GDC_RGBA888_SUPPORTED_OFFSET (0x68)
+#define GDC_RGBA888_SUPPORTED_MASK (0x8)
+
+// args: data (1-bit)
+static inline void gdc_rgba888_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1) << 3) | (curr & 0xfffffff7);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_rgba888_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x8) >> 3);
+}
+// ----------------------------------- //
+// Register: RGB YUV444 planar supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// RGB/YUV444 planar modes supported
+// ----------------------------------- //
+
+#define GDC_RGB_YUV444_PLANAR_SUPPORTED_DEFAULT (0x0)
+#define GDC_RGB_YUV444_PLANAR_SUPPORTED_DATASIZE (1)
+#define GDC_RGB_YUV444_PLANAR_SUPPORTED_OFFSET (0x68)
+#define GDC_RGB_YUV444_PLANAR_SUPPORTED_MASK (0x10)
+
+// args: data (1-bit)
+static inline void gdc_rgb_yuv444_planar_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x1) << 4) | (curr & 0xffffffef);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_rgb_yuv444_planar_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x10) >> 4);
+}
+// ----------------------------------- //
+// Register: YUV semiplanar supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// YUV semiplanar modes supported
+// ----------------------------------- //
+
+#define GDC_YUV_SEMIPLANAR_SUPPORTED_DEFAULT (0x0)
+#define GDC_YUV_SEMIPLANAR_SUPPORTED_DATASIZE (1)
+#define GDC_YUV_SEMIPLANAR_SUPPORTED_OFFSET (0x68)
+#define GDC_YUV_SEMIPLANAR_SUPPORTED_MASK (0x20)
+
+// args: data (1-bit)
+static inline void gdc_yuv_semiplanar_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x1) << 5) | (curr & 0xffffffdf);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_yuv_semiplanar_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x20) >> 5);
+}
+// ----------------------------------- //
+// Register: YUV422 linear mode supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// YUV4:2:2 linear mode supported (16 bit/pixel)
+// ----------------------------------- //
+
+#define GDC_YUV422_LINEAR_MODE_SUPPORTED_DEFAULT (0x0)
+#define GDC_YUV422_LINEAR_MODE_SUPPORTED_DATASIZE (1)
+#define GDC_YUV422_LINEAR_MODE_SUPPORTED_OFFSET (0x68)
+#define GDC_YUV422_LINEAR_MODE_SUPPORTED_MASK (0x40)
+
+// args: data (1-bit)
+static inline void gdc_yuv422_linear_mode_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1) << 6) | (curr & 0xffffffbf);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_yuv422_linear_mode_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x40) >> 6);
+}
+// ----------------------------------- //
+// Register: RGB10_10_10 supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// RGB10:10:10 mode supported
+// ----------------------------------- //
+
+#define GDC_RGB10_10_10_SUPPORTED_DEFAULT (0x0)
+#define GDC_RGB10_10_10_SUPPORTED_DATASIZE (1)
+#define GDC_RGB10_10_10_SUPPORTED_OFFSET (0x68)
+#define GDC_RGB10_10_10_SUPPORTED_MASK (0x80)
+
+// args: data (1-bit)
+static inline void gdc_rgb10_10_10_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1) << 7) | (curr & 0xffffff7f);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_rgb10_10_10_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x80) >> 7);
+}
+// ----------------------------------- //
+// Register: Bicubic interpolation supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// 4 tap bicubic interpolation supported
+// ----------------------------------- //
+
+#define GDC_BICUBIC_INTERPOLATION_SUPPORTED_DEFAULT (0x0)
+#define GDC_BICUBIC_INTERPOLATION_SUPPORTED_DATASIZE (1)
+#define GDC_BICUBIC_INTERPOLATION_SUPPORTED_OFFSET (0x68)
+#define GDC_BICUBIC_INTERPOLATION_SUPPORTED_MASK (0x100)
+
+// args: data (1-bit)
+static inline void gdc_bicubic_interpolation_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1) << 8) | (curr & 0xfffffeff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_bicubic_interpolation_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x100) >> 8);
+}
+// ----------------------------------- //
+// Register: Bilinear interpolation mode 1 supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// bilinear interpolation mode 1 supported {for U,V components}
+// ----------------------------------- //
+
+#define GDC_BILINEAR_INTERPOLATION_MODE_1_SUPPORTED_DEFAULT (0x0)
+#define GDC_BILINEAR_INTERPOLATION_MODE_1_SUPPORTED_DATASIZE (1)
+#define GDC_BILINEAR_INTERPOLATION_MODE_1_SUPPORTED_OFFSET (0x68)
+#define GDC_BILINEAR_INTERPOLATION_MODE_1_SUPPORTED_MASK (0x200)
+
+// args: data (1-bit)
+static inline void
+gdc_bilinear_interpolation_mode_1_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1) << 9) | (curr & 0xfffffdff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_bilinear_interpolation_mode_1_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x200) >> 9);
+}
+// ----------------------------------- //
+// Register: Bilinear interpolation mode 2 supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// bilinear interpolation mode 2 supported {for U,V components}
+// ----------------------------------- //
+
+#define GDC_BILINEAR_INTERPOLATION_MODE_2_SUPPORTED_DEFAULT (0x0)
+#define GDC_BILINEAR_INTERPOLATION_MODE_2_SUPPORTED_DATASIZE (1)
+#define GDC_BILINEAR_INTERPOLATION_MODE_2_SUPPORTED_OFFSET (0x68)
+#define GDC_BILINEAR_INTERPOLATION_MODE_2_SUPPORTED_MASK (0x400)
+
+// args: data (1-bit)
+static inline void
+gdc_bilinear_interpolation_mode_2_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1) << 10) | (curr & 0xfffffbff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_bilinear_interpolation_mode_2_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x400) >> 10);
+}
+// ----------------------------------- //
+// Register: Output of interpolation coordinates supported
+// ----------------------------------- //
+
+// ----------------------------------- //
+// output of interpolation coordinates is supported
+// ----------------------------------- //
+
+#define GDC_OUTPUT_OF_INTERPOLATION_COORDINATES_SUPPORTED_DEFAULT (0x0)
+#define GDC_OUTPUT_OF_INTERPOLATION_COORDINATES_SUPPORTED_DATASIZE (1)
+#define GDC_OUTPUT_OF_INTERPOLATION_COORDINATES_SUPPORTED_OFFSET (0x68)
+#define GDC_OUTPUT_OF_INTERPOLATION_COORDINATES_SUPPORTED_MASK (0x800)
+
+// args: data (1-bit)
+static inline void
+gdc_output_of_interpolation_coordinates_supported_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x1) << 11) | (curr & 0xfffff7ff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t
+gdc_output_of_interpolation_coordinates_supported_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x800) >> 11);
+}
+// ----------------------------------- //
+// Register: Reserved for future use 4
+// ----------------------------------- //
+
+#define GDC_RESERVED_FOR_FUTURE_USE_4_DEFAULT (0x0)
+#define GDC_RESERVED_FOR_FUTURE_USE_4_DATASIZE (4)
+#define GDC_RESERVED_FOR_FUTURE_USE_4_OFFSET (0x68)
+#define GDC_RESERVED_FOR_FUTURE_USE_4_MASK (0xf000)
+
+// args: data (4-bit)
+static inline void gdc_reserved_for_future_use_4_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0xf) << 12) | (curr & 0xffff0fff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_reserved_for_future_use_4_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0xf000) >> 12);
+}
+// ----------------------------------- //
+// Register: Size of output cache
+// ----------------------------------- //
+
+// ----------------------------------- //
+// log2(size of output cache in lines)-5 (0 - 32lines, 1 - 64 lines etc)
+// ----------------------------------- //
+
+#define GDC_SIZE_OF_OUTPUT_CACHE_DEFAULT (0x0)
+#define GDC_SIZE_OF_OUTPUT_CACHE_DATASIZE (3)
+#define GDC_SIZE_OF_OUTPUT_CACHE_OFFSET (0x68)
+#define GDC_SIZE_OF_OUTPUT_CACHE_MASK (0x70000)
+
+// args: data (3-bit)
+static inline void gdc_size_of_output_cache_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x7) << 16) | (curr & 0xfff8ffff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_size_of_output_cache_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x70000) >> 16);
+}
+// ----------------------------------- //
+// Register: Size of tile cache
+// ----------------------------------- //
+
+// ----------------------------------- //
+// log2(size of tile cache in 16x16 clusters)
+// ----------------------------------- //
+
+#define GDC_SIZE_OF_TILE_CACHE_DEFAULT (0x0)
+#define GDC_SIZE_OF_TILE_CACHE_DATASIZE (5)
+#define GDC_SIZE_OF_TILE_CACHE_OFFSET (0x68)
+#define GDC_SIZE_OF_TILE_CACHE_MASK (0xf80000)
+
+// args: data (5-bit)
+static inline void gdc_size_of_tile_cache_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val =  ((data & 0x1f) << 19) | (curr & 0xff07ffff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_size_of_tile_cache_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0xf80000) >> 19);
+}
+// ----------------------------------- //
+// Register: Nuimber of polyphase filter banks
+// ----------------------------------- //
+
+// ----------------------------------- //
+// log2(number of polyphase filter banks)
+// ----------------------------------- //
+
+#define GDC_NUIMBER_OF_POLYPHASE_FILTER_BANKS_DEFAULT (0x0)
+#define GDC_NUIMBER_OF_POLYPHASE_FILTER_BANKS_DATASIZE (3)
+#define GDC_NUIMBER_OF_POLYPHASE_FILTER_BANKS_OFFSET (0x68)
+#define GDC_NUIMBER_OF_POLYPHASE_FILTER_BANKS_MASK (0x7000000)
+
+// args: data (3-bit)
+static inline void gdc_nuimber_of_polyphase_filter_banks_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x7) << 24) | (curr & 0xf8ffffff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_nuimber_of_polyphase_filter_banks_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x7000000) >> 24);
+}
+// ----------------------------------- //
+// Register: AXI data width
+// ----------------------------------- //
+
+// ----------------------------------- //
+// log2(AXI_DATA_WIDTH)-5
+// ----------------------------------- //
+
+#define GDC_AXI_DATA_WIDTH_DEFAULT (0x0)
+#define GDC_AXI_DATA_WIDTH_DATASIZE (3)
+#define GDC_AXI_DATA_WIDTH_OFFSET (0x68)
+#define GDC_AXI_DATA_WIDTH_MASK (0x38000000)
+
+// args: data (3-bit)
+static inline void gdc_axi_data_width_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x7) << 27) | (curr & 0xc7ffffff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_axi_data_width_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0x38000000) >> 27);
+}
+// ----------------------------------- //
+// Register: Reserved for future use 5
+// ----------------------------------- //
+
+#define GDC_RESERVED_FOR_FUTURE_USE_5_DEFAULT (0x0)
+#define GDC_RESERVED_FOR_FUTURE_USE_5_DATASIZE (2)
+#define GDC_RESERVED_FOR_FUTURE_USE_5_OFFSET (0x68)
+#define GDC_RESERVED_FOR_FUTURE_USE_5_MASK (0xc0000000)
+
+// args: data (2-bit)
+static inline void gdc_reserved_for_future_use_5_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x68L);
+       uint32_t val = ((data & 0x3) << 30) | (curr & 0x3fffffff);
+
+       system_gdc_write_32(0x68L, val);
+}
+static inline uint8_t gdc_reserved_for_future_use_5_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0x68L) & 0xc0000000) >> 30);
+}
+// ----------------------------------- //
+// Register: default ch1
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Default value for 1st data channel (Y/R color)
+// to fill missing pixels (when coordinated
+// are out of bound). LSB aligned
+// ----------------------------------- //
+
+#define GDC_DEFAULT_CH1_DEFAULT (0x0)
+#define GDC_DEFAULT_CH1_DATASIZE (12)
+#define GDC_DEFAULT_CH1_OFFSET (0x70)
+#define GDC_DEFAULT_CH1_MASK (0xfff)
+
+// args: data (12-bit)
+static inline void gdc_default_ch1_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x70L);
+       uint32_t  val = ((data & 0xfff) << 0) | (curr & 0xfffff000);
+
+       system_gdc_write_32(0x70L, val);
+}
+static inline uint16_t gdc_default_ch1_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x70L) & 0xfff) >> 0);
+}
+// ----------------------------------- //
+// Register: default ch2
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Default value for 2nd data channel
+// (U/G color) to fill missing pixels
+// (when coordinated are out of bound) LSB aligned
+// ----------------------------------- //
+
+#define GDC_DEFAULT_CH2_DEFAULT (0x0)
+#define GDC_DEFAULT_CH2_DATASIZE (12)
+#define GDC_DEFAULT_CH2_OFFSET (0x74)
+#define GDC_DEFAULT_CH2_MASK (0xfff)
+
+// args: data (12-bit)
+static inline void gdc_default_ch2_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x74L);
+       uint32_t val = ((data & 0xfff) << 0) | (curr & 0xfffff000);
+
+       system_gdc_write_32(0x74L, val);
+}
+static inline uint16_t gdc_default_ch2_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x74L) & 0xfff) >> 0);
+}
+// ----------------------------------- //
+// Register: default ch3
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Default value for 3rd data channel
+// (V/B color) to fill missing pixels
+// (when coordinated are out of bound) LSB aligned
+// ----------------------------------- //
+
+#define GDC_DEFAULT_CH3_DEFAULT (0x0)
+#define GDC_DEFAULT_CH3_DATASIZE (12)
+#define GDC_DEFAULT_CH3_OFFSET (0x78)
+#define GDC_DEFAULT_CH3_MASK (0xfff)
+
+// args: data (12-bit)
+static inline void gdc_default_ch3_write(uint16_t data)
+{
+       uint32_t curr = system_gdc_read_32(0x78L);
+       uint32_t val = ((data & 0xfff) << 0) | (curr & 0xfffff000);
+
+       system_gdc_write_32(0x78L, val);
+}
+static inline uint16_t gdc_default_ch3_read(void)
+{
+       return (uint16_t)((system_gdc_read_32(0x78L) & 0xfff) >> 0);
+}
+// ----------------------------------- //
+// Group: GDC diagnostics
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Register: cfg_stall_count0
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on stalls on configutation FIFO to tile reader
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT0_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT0_DATASIZE (32)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT0_OFFSET (0x80)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT0_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_cfg_stall_count0_read(void)
+{
+       return system_gdc_read_32(0x80L);
+}
+// ----------------------------------- //
+// Register: cfg_stall_count1
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on stalls on configutation FIFO to CIM
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT1_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT1_DATASIZE (32)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT1_OFFSET (0x84)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT1_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_cfg_stall_count1_read(void)
+{
+       return system_gdc_read_32(0x84L);
+}
+// ----------------------------------- //
+// Register: cfg_stall_count2
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on stalls on configutation FIFO to PIM
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT2_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT2_DATASIZE (32)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT2_OFFSET (0x88)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT2_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_cfg_stall_count2_read(void)
+{
+       return system_gdc_read_32(0x88L);
+}
+// ----------------------------------- //
+// Register: cfg_stall_count3
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on stalls on configutation FIFO to write cache
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT3_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT3_DATASIZE (32)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT3_OFFSET (0x8c)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT3_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_cfg_stall_count3_read(void)
+{
+       return system_gdc_read_32(0x8cL);
+}
+// ----------------------------------- //
+// Register: cfg_stall_count4
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on stalls on configutation FIFO to tile writer
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT4_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT4_DATASIZE (32)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT4_OFFSET (0x90)
+#define GDC_DIAGNOSTICS_CFG_STALL_COUNT4_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_cfg_stall_count4_read(void)
+{
+       return system_gdc_read_32(0x90L);
+}
+// ----------------------------------- //
+// Register: int_read_stall_count
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on waiting on pixel interpolator read pixel stream
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_INT_READ_STALL_COUNT_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_INT_READ_STALL_COUNT_DATASIZE (32)
+#define GDC_DIAGNOSTICS_INT_READ_STALL_COUNT_OFFSET (0x94)
+#define GDC_DIAGNOSTICS_INT_READ_STALL_COUNT_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_int_read_stall_count_read(void)
+{
+       return system_gdc_read_32(0x94L);
+}
+// ----------------------------------- //
+// Register: int_coord_stall_count
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on waiting on coordinate stream of pixel interpolator
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_INT_COORD_STALL_COUNT_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_INT_COORD_STALL_COUNT_DATASIZE (32)
+#define GDC_DIAGNOSTICS_INT_COORD_STALL_COUNT_OFFSET (0x98)
+#define GDC_DIAGNOSTICS_INT_COORD_STALL_COUNT_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_int_coord_stall_count_read(void)
+{
+       return system_gdc_read_32(0x98L);
+}
+// ----------------------------------- //
+// Register: int_write_wait_count
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on waiting on pixel interpolator output pixel stream
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_INT_WRITE_WAIT_COUNT_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_INT_WRITE_WAIT_COUNT_DATASIZE (32)
+#define GDC_DIAGNOSTICS_INT_WRITE_WAIT_COUNT_OFFSET (0x9c)
+#define GDC_DIAGNOSTICS_INT_WRITE_WAIT_COUNT_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_int_write_wait_count_read(void)
+{
+       return system_gdc_read_32(0x9cL);
+}
+// ----------------------------------- //
+// Register: wrt_write_wait_count
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Cycles spent on waiting on sending word from write cache to tile writer
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_WRT_WRITE_WAIT_COUNT_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_WRT_WRITE_WAIT_COUNT_DATASIZE (32)
+#define GDC_DIAGNOSTICS_WRT_WRITE_WAIT_COUNT_OFFSET (0xa0)
+#define GDC_DIAGNOSTICS_WRT_WRITE_WAIT_COUNT_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_wrt_write_wait_count_read(void)
+{
+       return system_gdc_read_32(0xa0L);
+}
+// ----------------------------------- //
+// Register: int_dual_count
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Number of beats on output of tile writer
+// interface where 2 pixels were interpolated.
+// ----------------------------------- //
+
+#define GDC_DIAGNOSTICS_INT_DUAL_COUNT_DEFAULT (0x0)
+#define GDC_DIAGNOSTICS_INT_DUAL_COUNT_DATASIZE (32)
+#define GDC_DIAGNOSTICS_INT_DUAL_COUNT_OFFSET (0xa4)
+#define GDC_DIAGNOSTICS_INT_DUAL_COUNT_MASK (0xffffffff)
+
+// args: data (32-bit)
+static inline uint32_t gdc_diagnostics_int_dual_count_read(void)
+{
+       return system_gdc_read_32(0xa4L);
+}
+// ----------------------------------------------------//
+// Group: AXI Settings
+// ----------------------------------------------------//
+// ----------------------------------------------------//
+// Register: config reader max arlen
+// ----------------------------------------------------//
+// ----------------------------------------------------//
+// Maximum value to use for arlen (axi burst length).
+// "0000"= max 1 transfer/burst
+// upto "1111"= max 16 transfers/burst
+// ----------------------------------------------------//
+
+#define GDC_AXI_SETTINGS_CONFIG_READER_MAX_ARLEN_DEFAULT (0xF)
+#define GDC_AXI_SETTINGS_CONFIG_READER_MAX_ARLEN_DATASIZE (4)
+#define GDC_AXI_SETTINGS_CONFIG_READER_MAX_ARLEN_OFFSET (0xa8)
+#define GDC_AXI_SETTINGS_CONFIG_READER_MAX_ARLEN_MASK (0xf)
+
+// args: data (4-bit)
+static inline void gdc_axi_settings_config_reader_max_arlen_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xa8L);
+       uint32_t val = ((data & 0xf) << 0) | (curr & 0xfffffff0);
+
+       system_gdc_write_32(0xa8L, val);
+}
+static inline uint8_t gdc_axi_settings_config_reader_max_arlen_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xa8L) & 0xf) >> 0);
+}
+// ----------------------------------- //
+// Register: config reader fifo watermark
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Number of words space in fifo before AXI read burst(s) start
+// (legal values = max_burst_length(max_arlen+1)
+// to 2**fifo_aw, but workable value
+// for your system are probably less!).
+// Allowing n back to back bursts to generated
+// if watermark is set to n*burst length.
+// Burst(s) continue while fifo has enough space for next burst.
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_CONFIG_READER_FIFO_WATERMARK_DEFAULT (0x10)
+#define GDC_AXI_SETTINGS_CONFIG_READER_FIFO_WATERMARK_DATASIZE (8)
+#define GDC_AXI_SETTINGS_CONFIG_READER_FIFO_WATERMARK_OFFSET (0xa8)
+#define GDC_AXI_SETTINGS_CONFIG_READER_FIFO_WATERMARK_MASK (0xff00)
+
+// args: data (8-bit)
+static inline void
+gdc_axi_settings_config_reader_fifo_watermark_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xa8L);
+       uint32_t val = ((data & 0xff) << 8) | (curr & 0xffff00ff);
+
+       system_gdc_write_32(0xa8L, val);
+}
+static inline uint8_t gdc_axi_settings_config_reader_fifo_watermark_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xa8L) & 0xff00) >> 8);
+}
+// ----------------------------------- //
+// Register: config reader rxact maxostand
+// ----------------------------------- //
+// ----------------------------------- //
+// Max outstanding read transactions (bursts) allowed.
+// zero means no maximum(uses fifo size as max)
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_CONFIG_READER_RXACT_MAXOSTAND_DEFAULT (0x00)
+#define GDC_AXI_SETTINGS_CONFIG_READER_RXACT_MAXOSTAND_DATASIZE (8)
+#define GDC_AXI_SETTINGS_CONFIG_READER_RXACT_MAXOSTAND_OFFSET (0xa8)
+#define GDC_AXI_SETTINGS_CONFIG_READER_RXACT_MAXOSTAND_MASK (0xff0000)
+
+// args: data (8-bit)
+static inline void
+gdc_axi_settings_config_reader_rxact_maxostand_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xa8L);
+       uint32_t val = ((data & 0xff) << 16) | (curr & 0xff00ffff);
+
+       system_gdc_write_32(0xa8L, val);
+}
+static inline uint8_t gdc_axi_settings_config_reader_rxact_maxostand_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xa8L) & 0xff0000) >> 16);
+}
+// ----------------------------------- //
+// Register: tile reader max arlen
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Maximum value to use for arlen (axi burst length).
+// "0000"= max 1 transfer/burst , upto "1111"= max 16 transfers/burst
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_TILE_READER_MAX_ARLEN_DEFAULT (0xF)
+#define GDC_AXI_SETTINGS_TILE_READER_MAX_ARLEN_DATASIZE (4)
+#define GDC_AXI_SETTINGS_TILE_READER_MAX_ARLEN_OFFSET (0xac)
+#define GDC_AXI_SETTINGS_TILE_READER_MAX_ARLEN_MASK (0xf)
+
+// args: data (4-bit)
+static inline void gdc_axi_settings_tile_reader_max_arlen_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xacL);
+       uint32_t val = ((data & 0xf) << 0) | (curr & 0xfffffff0);
+
+       system_gdc_write_32(0xacL, val);
+}
+static inline uint8_t gdc_axi_settings_tile_reader_max_arlen_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xacL) & 0xf) >> 0);
+}
+// ----------------------------------- //
+// Register: tile reader fifo watermark
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Number of words space in fifo before AXI read burst(s) start
+// (legal values = max_burst_length(max_arlen+1) to 2**fifo_aw,
+// but workable value for your system are probably less!).
+// Allowing n back to back bursts to generated
+// if watermark is set to n*burst length.
+// Burst(s) continue while fifo has enough space for next burst.
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_TILE_READER_FIFO_WATERMARK_DEFAULT (0x10)
+#define GDC_AXI_SETTINGS_TILE_READER_FIFO_WATERMARK_DATASIZE (8)
+#define GDC_AXI_SETTINGS_TILE_READER_FIFO_WATERMARK_OFFSET (0xac)
+#define GDC_AXI_SETTINGS_TILE_READER_FIFO_WATERMARK_MASK (0xff00)
+
+// args: data (8-bit)
+static inline void
+gdc_axi_settings_tile_reader_fifo_watermark_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xacL);
+       uint32_t val = ((data & 0xff) << 8) | (curr & 0xffff00ff);
+
+       system_gdc_write_32(0xacL, val);
+}
+static inline uint8_t gdc_axi_settings_tile_reader_fifo_watermark_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xacL) & 0xff00) >> 8);
+}
+// ----------------------------------- //
+// Register: tile reader rxact maxostand
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Max outstanding read transactions
+// (bursts) allowed. zero means no maximum(uses fifo size as max).
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_TILE_READER_RXACT_MAXOSTAND_DEFAULT (0x00)
+#define GDC_AXI_SETTINGS_TILE_READER_RXACT_MAXOSTAND_DATASIZE (8)
+#define GDC_AXI_SETTINGS_TILE_READER_RXACT_MAXOSTAND_OFFSET (0xac)
+#define GDC_AXI_SETTINGS_TILE_READER_RXACT_MAXOSTAND_MASK (0xff0000)
+
+// args: data (8-bit)
+static inline void
+gdc_axi_settings_tile_reader_rxact_maxostand_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xacL);
+       uint32_t val = ((data & 0xff) << 16) | (curr & 0xff00ffff);
+
+       system_gdc_write_32(0xacL, val);
+}
+static inline uint8_t gdc_axi_settings_tile_reader_rxact_maxostand_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xacL) & 0xff0000) >> 16);
+}
+// ----------------------------------- //
+// Register: tile writer max awlen
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Maximum value to use for awlen (axi burst length).
+// "0000"= max 1 transfer/burst , upto "1111"= max 16 transfers/burst
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_TILE_WRITER_MAX_AWLEN_DEFAULT (0xF)
+#define GDC_AXI_SETTINGS_TILE_WRITER_MAX_AWLEN_DATASIZE (4)
+#define GDC_AXI_SETTINGS_TILE_WRITER_MAX_AWLEN_OFFSET (0xb0)
+#define GDC_AXI_SETTINGS_TILE_WRITER_MAX_AWLEN_MASK (0xf)
+
+// args: data (4-bit)
+static inline void gdc_axi_settings_tile_writer_max_awlen_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xb0L);
+       uint32_t val = ((data & 0xf) << 0) | (curr & 0xfffffff0);
+
+       system_gdc_write_32(0xb0L, val);
+}
+static inline uint8_t gdc_axi_settings_tile_writer_max_awlen_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xb0L) & 0xf) >> 0);
+}
+// ----------------------------------- //
+// Register: tile writer fifo watermark
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Number of words in fifo before AXI write burst(s) start
+// (legal values = max_burst_length(max_awlen+1) to 2**fifo_aw,
+// but workable value for your system are probably less!).
+// Allowing n back to back bursts to generated
+// if watermark is set to n*burst length.
+// Burst(s) continue while fifo has enough for next burst.
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_TILE_WRITER_FIFO_WATERMARK_DEFAULT (0x10)
+#define GDC_AXI_SETTINGS_TILE_WRITER_FIFO_WATERMARK_DATASIZE (8)
+#define GDC_AXI_SETTINGS_TILE_WRITER_FIFO_WATERMARK_OFFSET (0xb0)
+#define GDC_AXI_SETTINGS_TILE_WRITER_FIFO_WATERMARK_MASK (0xff00)
+
+// args: data (8-bit)
+static inline void
+gdc_axi_settings_tile_writer_fifo_watermark_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xb0L);
+       uint32_t val = ((data & 0xff) << 8) | (curr & 0xffff00ff);
+
+       system_gdc_write_32(0xb0L, val);
+}
+static inline uint8_t
+gdc_axi_settings_tile_writer_fifo_watermark_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xb0L) & 0xff00) >> 8);
+}
+// ----------------------------------- //
+// Register: tile writer wxact maxostand
+// ----------------------------------- //
+
+// ----------------------------------- //
+// Max outstanding write transactions (bursts)
+// allowed. zero means no maximum(uses internal limit of 2048)
+// ----------------------------------- //
+
+#define GDC_AXI_SETTINGS_TILE_WRITER_WXACT_MAXOSTAND_DEFAULT (0x00)
+#define GDC_AXI_SETTINGS_TILE_WRITER_WXACT_MAXOSTAND_DATASIZE (8)
+#define GDC_AXI_SETTINGS_TILE_WRITER_WXACT_MAXOSTAND_OFFSET (0xb0)
+#define GDC_AXI_SETTINGS_TILE_WRITER_WXACT_MAXOSTAND_MASK (0xff0000)
+
+// args: data (8-bit)
+static inline void
+gdc_axi_settings_tile_writer_wxact_maxostand_write(uint8_t data)
+{
+       uint32_t curr = system_gdc_read_32(0xb0L);
+       uint32_t val = ((data & 0xff) << 16) | (curr & 0xff00ffff);
+
+       system_gdc_write_32(0xb0L, val);
+}
+static inline uint8_t gdc_axi_settings_tile_writer_wxact_maxostand_read(void)
+{
+       return (uint8_t)((system_gdc_read_32(0xb0L) & 0xff0000) >> 16);
+}
+// ----------------------------------- //
+#endif //__GDC_CONFIG_H__
diff --git a/drivers/amlogic/media/gdc/inc/sys/system_gdc_io.h b/drivers/amlogic/media/gdc/inc/sys/system_gdc_io.h
new file mode 100644 (file)
index 0000000..097271d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * drivers/amlogic/media/gdc/inc/sys/system_gdc_io.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __SYSTEM_GDC_IO_H__
+#define __SYSTEM_GDC_IO_H__
+
+/**
+ *   Read 32 bit word from gdc memory
+ *
+ *   This function returns a 32 bits word from GDC memory with a given offset.
+ *
+ *   @param addr - the offset in GDC memory to read 32 bits word.
+ *
+ *   @return 32 bits memory value
+ */
+uint32_t system_gdc_read_32(uint32_t addr);
+
+
+/**
+ *   Write 32 bits word to gdc memory
+ *
+ *   This function writes a 32 bits word to GDC memory with a given offset.
+ *
+ *   @param addr - the offset in GDC memory to write data.
+ *   @param data - data to be written
+ */
+void system_gdc_write_32(uint32_t addr, uint32_t data);
+
+
+#endif /* __SYSTEM_GDC_IO_H__ */
diff --git a/drivers/amlogic/media/gdc/inc/sys/system_log.h b/drivers/amlogic/media/gdc/inc/sys/system_log.h
new file mode 100644 (file)
index 0000000..8b9e459
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * drivers/amlogic/media/gdc/inc/sys/system_log.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __SYSTEM_LOG_H__
+#define __SYSTEM_LOG_H__
+
+//changeable logs
+#include <linux/kernel.h>
+#define FW_LOG_LEVEL LOG_MAX
+
+enum log_level_e {
+       LOG_NOTHING,
+       LOG_EMERG,
+       LOG_ALERT,
+       LOG_CRIT,
+       LOG_ERR,
+       LOG_WARNING,
+       LOG_NOTICE,
+       LOG_INFO,
+       LOG_DEBUG,
+       LOG_IRQ,
+       LOG_MAX
+};
+
+extern const char *const gdc_log_level[LOG_MAX];
+
+#define FILE (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+
+#if 1
+#define LOG(level, fmt, arg...)                         \
+       do {                    \
+               if ((level) <= FW_LOG_LEVEL)            \
+               trace_printk("%s: %s(%d) %s: " fmt "\n",\
+                               FILE, __func__, __LINE__,         \
+                               gdc_log_level[level], ## arg);  \
+       } while (0)
+#else
+#define LOG(...)
+#endif
+
+#endif // __SYSTEM_LOG_H__
diff --git a/drivers/amlogic/media/gdc/src/fw_lib/acamera_gdc.c b/drivers/amlogic/media/gdc/src/fw_lib/acamera_gdc.c
new file mode 100644 (file)
index 0000000..6900f42
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * drivers/amlogic/media/gdc/src/fw_lib/acamera_gdc.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+//needed for gdc/gdc configuration
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+//data types and prototypes
+#include "gdc_api.h"
+#include "system_log.h"
+#include "gdc_config.h"
+
+
+/**
+ *   Configure the output gdc configuration address/size
+ *
+ *   and buffer address/size; and resolution.
+ *
+ *   More than one gdc settings can be accessed by index to a gdc_config_t.
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *   @param  gdc_config_num - selects the current gdc config to be applied
+ *
+ *   @return 0 - success
+ *      -1 - fail.
+ */
+int gdc_init(struct gdc_settings *gdc_settings)
+{
+
+       gdc_settings->is_waiting_gdc = 0;
+       gdc_settings->current_addr = gdc_settings->buffer_addr;
+
+       if ((gdc_settings->gdc_config.output_width == 0)
+                       || (gdc_settings->gdc_config.output_height == 0)) {
+               LOG(LOG_ERR, "Wrong GDC output resolution.\n");
+               return -1;
+       }
+       //stop gdc
+       gdc_start_flag_write(0);
+       //set the configuration address and size to the gdc block
+       gdc_config_addr_write(gdc_settings->gdc_config.config_addr);
+       gdc_config_size_write(gdc_settings->gdc_config.config_size);
+
+       //set the gdc output resolution
+       gdc_dataout_width_write(gdc_settings->gdc_config.output_width);
+       gdc_dataout_height_write(gdc_settings->gdc_config.output_height);
+
+       return 0;
+}
+
+/**
+ *   This function stops the gdc block
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ */
+void gdc_stop(struct gdc_settings *gdc_settings)
+{
+       gdc_settings->is_waiting_gdc = 0;
+       gdc_start_flag_write(0);
+}
+
+/**
+ *   This function starts the gdc block
+ *
+ *   Writing 0->1 transition is necessary for trigger
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ */
+void gdc_start(struct gdc_settings *gdc_settings)
+{
+       gdc_start_flag_write(0); //do a stop for sync
+       gdc_start_flag_write(1);
+       gdc_settings->is_waiting_gdc = 1;
+}
+
+/**
+ *   This function points gdc to its input resolution
+ *
+ *   and yuv address and offsets
+ *
+ *   Shown inputs to GDC are Y and UV plane address and offsets
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *   @param  active_width -  input width resolution
+ *   @param  active_height - input height resolution
+ *   @param  y_base_addr -  input Y base address
+ *   @param  uv_base_addr - input UV base address
+ *   @param  y_line_offset - input Y line buffer offset
+ *   @param  uv_line_offset-  input UV line buffer offer
+ *
+ *   @return 0 - success
+ *      -1 - no interrupt from GDC.
+ */
+int gdc_process(struct gdc_settings *gdc_settings,
+               uint32_t y_base_addr, uint32_t uv_base_addr)
+{
+       uint32_t gdc_out_base_addr = gdc_settings->current_addr;
+       uint32_t active_width = gdc_settings->gdc_config.output_width;
+       uint32_t active_height = gdc_settings->gdc_config.output_height;
+       uint32_t y_line_offset = active_width; //420 format
+       uint32_t uv_line_offset = active_width; //420 format
+
+       if (gdc_settings->is_waiting_gdc) {
+               gdc_start_flag_write(0);
+               LOG(LOG_CRIT, "No interrupt Still waiting...\n");
+               gdc_start_flag_write(1);
+
+               return -1;
+       }
+
+       LOG(LOG_DEBUG, "starting GDC process.\n");
+
+       gdc_datain_width_write(active_width);
+       gdc_datain_height_write(active_height);
+       //input y plane
+       gdc_data1in_addr_write(y_base_addr);
+       gdc_data1in_line_offset_write(y_line_offset);
+
+       //input uv plane
+       gdc_data2in_addr_write(uv_base_addr);
+       gdc_data2in_line_offset_write(uv_line_offset);
+
+       //gdc y output
+       gdc_data1out_addr_write(gdc_out_base_addr);
+       gdc_data1out_line_offset_write(y_line_offset);
+
+       //gdc uv output
+       gdc_out_base_addr += active_height * y_line_offset;
+       gdc_data2out_addr_write(gdc_out_base_addr);
+       gdc_data2out_line_offset_write(uv_line_offset);
+
+       gdc_start(gdc_settings);
+
+       return 0;
+}
+
+/**
+ *   This function points gdc to its input resolution
+ *
+ *   and yuv address and offsets
+ *
+ *   Shown inputs to GDC are Y and UV plane address and offsets
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *   @param  active_width -  input width resolution
+ *   @param  active_height - input height resolution
+ *   @param  y_base_addr -  input Y base address
+ *   @param  uv_base_addr - input UV base address
+ *   @param  y_line_offset - input Y line buffer offset
+ *   @param  uv_line_offset-  input UV line buffer offer
+ *
+ *   @return 0 - success
+ *      -1 - no interrupt from GDC.
+ */
+int gdc_process_yuv420p(struct gdc_settings *gdc_settings,
+       uint32_t y_base_addr, uint32_t u_base_addr, uint32_t v_base_addr)
+{
+       struct gdc_config  *gc = &gdc_settings->gdc_config;
+       uint32_t gdc_out_base_addr = gdc_settings->current_addr;
+       uint32_t input_width = gc->input_width;
+       uint32_t input_height = gc->input_height;
+       uint32_t input_stride = gc->input_y_stride;
+       uint32_t input_u_stride = gc->input_c_stride;
+       uint32_t input_v_stride = gc->input_c_stride;
+
+       LOG(LOG_DEBUG, "is_waiting_gdc=%d\n", gdc_settings->is_waiting_gdc);
+       if (gdc_settings->is_waiting_gdc) {
+               gdc_start_flag_write(0);
+               LOG(LOG_CRIT, "No interrupt Still waiting...\n");
+               gdc_start_flag_write(1);
+               return -1;
+       }
+
+       /////
+       LOG(LOG_DEBUG, "starting GDC process.\n");
+
+       //already set in gdc_init
+       //uint32_t output_width = gc->output_width;
+       uint32_t output_height = gc->output_height;
+       uint32_t output_stride = gc->output_y_stride;
+       uint32_t output_u_stride = gc->output_c_stride;
+       uint32_t output_v_stride = gc->output_c_stride;
+
+       gdc_datain_width_write(input_width);
+       gdc_datain_height_write(input_height);
+       //input y plane
+       gdc_data1in_addr_write(y_base_addr);
+       gdc_data1in_line_offset_write(input_stride);
+
+       //input u plane
+       gdc_data2in_addr_write(u_base_addr);
+       gdc_data2in_line_offset_write(input_u_stride);
+
+       //input v plane
+       gdc_data3in_addr_write(v_base_addr);
+       gdc_data3in_line_offset_write(input_v_stride);
+
+       //gdc y output
+       gdc_data1out_addr_write(gdc_out_base_addr);
+       gdc_data1out_line_offset_write(output_stride);
+
+       //gdc u output
+       gdc_out_base_addr += output_height * output_stride;
+       gdc_data2out_addr_write(gdc_out_base_addr);
+       gdc_data2out_line_offset_write(output_u_stride);
+
+       //gdc v output
+       gdc_out_base_addr += output_height * output_u_stride / 2;
+       gdc_data3out_addr_write(gdc_out_base_addr);
+       gdc_data3out_line_offset_write(output_v_stride);
+       gdc_start(gdc_settings);
+
+       return 0;
+}
+
+/**
+ *   This function gets the GDC output frame addresses
+ *
+ *   and offsets and updates the frame buffer via callback
+ *
+ *   if it is available Shown ouputs to GDC are
+ *
+ *   Y and UV plane address and offsets
+ *
+ *   @param  gdc_settings - overall gdc settings and state
+ *
+ *   @return 0 - success
+ *      -1 - unexpected interrupt from GDC.
+ */
+int gdc_get_frame(struct gdc_settings *gdc_settings)
+{
+       struct mgdc_fh_s *fh = gdc_settings->fh;
+       uint32_t y;
+       uint32_t y_offset;
+       uint32_t uv;
+       uint32_t uv_offset;
+
+       if (!gdc_settings->is_waiting_gdc) {
+               LOG(LOG_CRIT, "Unexpected interrupt from GDC.\n");
+               return -1;
+       }
+       ////
+
+       wake_up_interruptible(&fh->irq_queue);
+
+       //pass the frame buffer parameters if callback is available
+       if (gdc_settings->get_frame_buffer) {
+               y = gdc_data1out_addr_read();
+               y_offset = gdc_data1out_line_offset_read();
+               uv = gdc_data2out_addr_read();
+               uv_offset = gdc_data2out_line_offset_read();
+
+               gdc_settings->get_frame_buffer(y,
+                                       uv, y_offset, uv_offset);
+       }
+       //done of the current frame and stop gdc block
+       gdc_stop(gdc_settings);
+       //spin_unlock_irqrestore(&gdev->slock, flags);
+       return 0;
+}
diff --git a/drivers/amlogic/media/gdc/src/platform/system_gdc_io.c b/drivers/amlogic/media/gdc/src/platform/system_gdc_io.c
new file mode 100644 (file)
index 0000000..378789f
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * drivers/amlogic/media/gdc/src/platform/system_gdc_io.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include "system_log.h"
+
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+
+static void *p_hw_base;
+
+int32_t init_gdc_io(struct device_node *dn)
+{
+       p_hw_base = of_iomap(dn, 0);
+
+       pr_info("reg base = %p\n", p_hw_base);
+       if (!p_hw_base) {
+               LOG(LOG_DEBUG, "failed to map register, %p\n", p_hw_base);
+               return -1;
+       }
+
+       return 0;
+}
+
+void close_gdc_io(struct device_node *dn)
+{
+       LOG(LOG_DEBUG, "IO functionality has been closed");
+}
+
+uint32_t system_gdc_read_32(uint32_t addr)
+{
+       uint32_t result = 0;
+
+       if (p_hw_base == NULL)
+               LOG(LOG_ERR, "Failed to base address %d\n", addr);
+
+       result = ioread32(p_hw_base + addr);
+       LOG(LOG_DEBUG, "r [0x%04x]= %08x\n", addr, result);
+       return result;
+}
+
+void system_gdc_write_32(uint32_t addr, uint32_t data)
+{
+       if (p_hw_base == NULL)
+               LOG(LOG_ERR, "Failed to write %d to addr %d\n", data, addr);
+
+       void *ptr = (void *)(p_hw_base + addr);
+
+       iowrite32(data, ptr);
+       LOG(LOG_DEBUG, "w [0x%04x]= %08x\n", addr, data);
+}
diff --git a/drivers/amlogic/media/gdc/src/platform/system_log.c b/drivers/amlogic/media/gdc/src/platform/system_log.c
new file mode 100644 (file)
index 0000000..0f06e87
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * drivers/amlogic/media/gdc/src/platform/system_log.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include "system_log.h"
+const char *const gdc_log_level[LOG_MAX] = {"",
+       "EMERG", "ALERT", "CRIT", "ERR", "WARNING",
+       "NOTICE", "INFO", "LOG_DEBUG", "LOG_IRQ"};